es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Hacer clic con el ratón produce un comportamiento inesperado utilizando wxPython y wx.Panel.

Estoy escribiendo una aplicación en la que se pretende ejecutar los siguientes pasos:
1 – El usuario hace clic en el área azul (wx.Panel) y aparece un círculo blanco;
2 – El usuario hace clic en el botón Seleccionar inicio;
3 – El usuario hace clic en el círculo blanco y cambia a verde (dibujando un círculo verde sobre el blanco).
El problema es que cuando se ejecuta el paso 3, el círculo verde no aparece donde se hace clic el mouse. Por ejemplo, haciendo clic en el área azul registra un punto en (223, 486). Después de hacer clic en el botón de seleccionar inicio y luego hacer clic en el círculo blanco, se registra un punto en (211, 464) y un círculo verde aparece fuera del círculo blanco. No entiendo por qué sucede esto y agradecería cualquier ayuda para resolver el problema.
Utilizando Python 2.7 con wxPython 3.0.3.0 en MacOS

import wx

class Test(wx.Frame):
    def __init__(self, parent, title):
        super(Test, self).__init__(parent, title = title, size = (820,900))

        self.startSelected = False
        self.radius = 10

        self.panel = wx.Panel(self, size=(800,800))
        self.panel.SetBackgroundColour(wx.Colour(0,0,200))

        self.panel.Bind(wx.EVT_LEFT_DOWN, self.onMouseDown)

        self.gbs = wx.GridBagSizer(0,0)   

        self.startBtn = wx.Button(self, wx.ID_ANY, label = 'Seleccionar Inicio')
        self.startBtn.Bind(wx.EVT_BUTTON, self.selectStart)

        self.gbs.Add(self.panel, span = (1,4), pos=(1,1),flag=wx.EXPAND | wx.ALL)
        self.gbs.Add(self.startBtn, pos=(2,1))

        self.SetSizer(self.gbs)

    def onMouseDown(self, e):
        pt = e.GetPosition()
        print pt.x, pt.y

        if e.LeftDown():
            if self.startSelected:

                color = wx.Colour(0,255,0)
                self.paint(pt, color)

            else:
                color = wx.Colour(255,255,255)
                self.paint(pt, color)                 

    def paint(self, pt, color):
        dc = wx.ClientDC(self)
        b = wx.Brush(color)
        dc.SetBrush(b)
        dc.DrawCircle(pt.x, pt.y, self.radius)

    def selectStart(self, e):
        self.startSelected = True

if __name__ == '__main__':
    app = wx.App()
    Test(None, 'Prueba')
    app.MainLoop()
Tags:  , ,

Answer

  1. Avatar for davy.ai

    El problema en este código es que wx.ClientDC está siendo creado con el argumento self, lo que significa que está dibujando en todo el marco en lugar de solo en el panel. Para solucionar esto, wx.ClientDC debe ser creado con self.panel en su lugar.

    Aquí está el código corregido:

    import wx
    
    class Test(wx.Frame):
        def __init__(self, parent, title):
            super(Test, self).__init__(parent, title = title, size = (820,900))
    
            self.startSelected = False
            self.radius = 10
    
            self.panel = wx.Panel(self, size=(800,800))
            self.panel.SetBackgroundColour(wx.Colour(0,0,200))
    
            self.panel.Bind(wx.EVT_LEFT_DOWN, self.onMouseDown)
    
            self.gbs = wx.GridBagSizer(0,0)
    
            self.startBtn = wx.Button(self.panel, wx.ID_ANY, label = 'Select Start')
            self.startBtn.Bind(wx.EVT_BUTTON, self.selectStart)
    
            self.gbs.Add(self.panel, span = (1,4), pos=(1,1),flag=wx.EXPAND | wx.ALL)
            self.gbs.Add(self.startBtn, pos=(2,1))
    
            self.SetSizer(self.gbs)
    
        def onMouseDown(self, e):
            pt = e.GetPosition()
            print pt.x, pt.y
    
            if e.LeftDown():
                if self.startSelected:
    
                    color = wx.Colour(0,255,0)
                    self.paint(pt, color)
    
                else:
                    color = wx.Colour(255,255,255)
                    self.paint(pt, color)
    
        def paint(self, pt, color):
            dc = wx.ClientDC(self.panel)
            b = wx.Brush(color)
            dc.SetBrush(b)
            dc.DrawCircle(pt.x, pt.y, self.radius)
    
        def selectStart(self, e):
            self.startSelected = True
    
    if __name__ == '__main__':
        app = wx.App()
        Test(None, 'Test')
        app.MainLoop()
    

Comments are closed.