Reputation: 4430
I'm having problems getting my wxPython window to refresh. It's currently plotting a graph using wxmpl which can be zoomed, panned, etc. On occasion the user may plot a large amount of data and zoom in on a small portion, which can cause it to 'freeze up'. By that I mean the plot itself is not updated, and the axis labels are drawn on top of each other. It is modifying the plot, just not displaying the updated info correctly. If you resize the window the plot is redrawn correctly.
I've spend an inordinate amount of time digging through source code and documentation for wx, wxmpl, and matplotlib... The best solution I've come up with is resizing the window to force a repaint (thus displaying the updated plot correctly).
# All of these fail - displays the same, incorrect plot
# (view is a wxmpl.PlotPanel object, which inherits from wx.Window among other things)
view.Refresh()
view.Update()
view.draw()
# This works, but is clearly less than ideal
view.SetSize((view.GetSize().width, view.GetSize().height+1))
view.SetSize((view.GetSize().width, view.GetSize().height-1))
There's got to be a better way - what I really want to know is what wx.Window.SetSize does to redraw the window, and just call that instead. Or, is there another method that I missed somewhere?
Upvotes: 7
Views: 4477
Reputation: 2435
In a computational expensive application, where you are expecting something to be calculated for over 0.1 sec and probably have some user input it is not recommended usually to make those intense drawing in the GUI thread.
Not aware of your specific situation, but general approach if that you move all time consuming tasks (be it computation, image adjustment (e.g. scaling)) to the non GUI thread. Just a normal Python thread is fine, and once you have an long part complete, you refresh your GUI. During computation of course it would be a user friendly to display some sort of "waiting" sign. Also disable other controls, so bored user will not be able to change anything midway to your computation.
I was stuck with that issue since my early days with Java and later with Python, mostly in connection to network operations (which NEVER should be in GUI thread).
In case it is image adjusment (or graphics generation), which takes much time, background thread can prepare image in wxMemoryDC and then wxDC::Blit it to the window of your choice. I am not aware if this can be done with your component wxmpl.PlotPanel, so you will have to research this.
Upvotes: 0
Reputation: 2435
I would also try Show(False) and then Show(True) on the PlotPanel.
Upvotes: 1
Reputation: 1421
The panel.Layout() command is a great option because it is exactly the same method that is called when you resize your window. I also had trouble with the refresh and update methods. Layout seems to work when those two fail.
Upvotes: 3
Reputation: 717
If you can't place it anywhere else, you could try
wx.Yield()
instead of Refresh
or Update
.
Upvotes: 1