'Draw in wx.PaintDC

I am trying to create a canvas and draw on it based on the position of the mouse cursor. Example:

class Lienzo:
  def __init__(self):
    super().__init__()

    self.app2 = wx.App()
    self.ventana2 = wx.Frame(None,id= wx.ID_ANY,title= "Area de dibujo",size= (800,600))
    self.icono = wx.Icon("imagenes/logo.png")
    self.ventana2.SetIcon(self.icono)
    self.panel2 = wx.Panel(self.ventana2,pos= (0,0),size= (800,600))

    self.contLienzo = wx.Panel(self.panel2,pos= (20,100),size= (500,400), style=wx.BORDER_SIMPLE)
    self.contLienzo.Bind(wx.EVT_LEFT_DOWN, self.pressMouse)
    self.contLienzo.Bind(wx.EVT_LEFT_UP, self.releaseMouse)
    self.contLienzo.Bind(wx.EVT_PAINT, self.dibujar)
    
    self.ventana2.Show()
    self.app2.MainLoop()

  def pressMouse(self,event):
    self.pos1 = event.GetPosition()

  def releaseMouse(self,event):
    self.pos2 = event.GetPosition()

  def dibujar(self,event3):
    self.lienzo = wx.PaintDC(self.contLienzo)
    self.lapiz = wx.Pen("black",width=1,style= wx.PENSTYLE_SOLID)
    self.lienzo.SetPen(self.lapiz)         
    self.lienzo.DrawLine(self.pos1.x,self.pos1.y,self.pos2.x,self.pos2.y) 

obj = Lienzo()

I tried to use wx.PaintDC's DrawLine function in the releaseMouse() function but it didn't work either. How can I get the cursor position when pressing and releasing the mouse button?



Solution 1:[1]

wxPython only invokes the OnPaint method when the frame is painted (on first drawing, resizing or Refresh) (See the docs)

So you must override the OnPaint method with your code and make sure to call the Refresh method when you want to invoke painting; in this case in releaseMouse

import wx

class MainFrame(wx.Frame):
    def __init__(self, *args, **kwargs):
        super().__init__(None, *args, **kwargs)
        self.Center()
        self.Show()

        self.pos1, self.pos2 = None, None
        self.Bind(wx.EVT_PAINT, self.OnPaint)
        self.Bind(wx.EVT_LEFT_DOWN, self.pressMouse)
        self.Bind(wx.EVT_LEFT_UP, self.releaseMouse)

    def pressMouse(self, event):
        self.pos1 = event.GetPosition()

    def releaseMouse(self, event):
        self.pos2 = event.GetPosition()
        self.Refresh()

    def OnPaint(self, event=None):
        if self.pos1:
            dc = wx.PaintDC(self)
            dc.Clear()
            dc.SetPen(wx.Pen(wx.RED, 4))
            dc.DrawLine(self.pos1[0], self.pos1[1], self.pos2[0], self.pos2[1])


if __name__ == '__main__':
    wx_app = wx.App()
    MainFrame()
    wx_app.MainLoop()

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1