Search code examples
pythonwxpythondrawing

wxpython: How to pass XY coordinator and draw it out?


I'm new for python but willing to learn. I have a set of hardware to receive touch coordinators and draw line accordingly to coordinators.

My problem is that the wxpython won't draw line if coordinator changes. Here is my code : https://github.com/eleghostliu/homework/blob/master/DrawXY_byWxPython/PythonApplication1/PythonApplication1.py

can someone give advise, thanks.


Solution

  • You registered for EVT_PAINT, yet you are not triggering the event as the data changes. The frame has no idea whether data changed or not, unless you specifically inform it.

    You can trigger the event simply by calling

    frame.Refresh()

    You can hook it in several ways. For instance, you could pass frame.Refresh bound method as a parameter to MainProcess so that it can make the function call to refresh the frame. Something like the following:

    WARNING: Erroneous code piece

    # Start a socket server
    def MainProcess(refresh_callback):
        while True:
            refresh_callback()
    ***********************************************
    frame = DrawPanel()
    frame.Show()
    start_new_thread(MainProcess, (frame.Refresh,))
    

    Edit:

    The above code piece calling UI methods directly is wrong!

    Worker thread should not directly manipulate GUI, instead it should inform the GUI thread about a change, and the GUI thread which is the main thread will handle it in its context. There are again several approaches here, the quickest to implement is through wx.CallAfter.

    Which you can incorporate as below, instead of directly calling the function:

    wx.CallAfter(refresh_callback)

    Another way to handle the communication between worker thread and GUI thread is via wx.PostEvent.

    class DrawPanel(wx.Frame):
        """Draw a line to a panel."""
        def notify(self):
            wx.PostEvent(self, wx.PaintEvent())
    

    Then from the secondary thread, you can safely call frame.notify() whenever new data arrives.

    For a more elegant solution involving wx.CallAfter, refer to https://www.blog.pythonlibrary.org/2010/05/22/wxpython-and-threads/ where pubsub is used.