Hi guys,
I’m very new to wxpython and I’m not good at explaining but I will try my best to explain my problem.
So I have a BufferedWindow class which i took from here: https://wiki.wxpython.org/DoubleBufferedDrawing . My SimulationWindow class overrides the BufferedWindow and it starts a separate thread that calls the UpdateDrawing() method from BufferedWindow very frequently, so it’s updating the drawing from the SimulationWindow very fast.
Then, I have a wx.Panel over the SimulationWindow (wx.Panel is its child and has a smaller size than the window) so the panel is painted over the window. I don’t know if this is the best approach, but I needed the panel to overlap the window, so the window kept its origin in the frame’s origin, and I haven’t found other solution than this. Then, in that panel is a wx.TreeCtrl. Now, the SimulationWindow is split in 2 parts: one with the panel on the left and one with the free region of the window. I need just the free region to be drawn.
My problem is: the wx.TreeCtrl object is flickering. That’s because in UpdateDrawing(), after Refresh() is called in the SimulationWindow(), it is called upon all its children and grandchildren i.e. the wx.TreeCtrl.
My question is: How can I call Refresh() in my window without calling it in the children?
I tried to set the rect argument of Refresh() to repaint just the region I want and it worked: the TreeCtrl wasn’t flickering anymore. But the problem is that I might add more windows objects on the SimulationWindow and I might need more rectangles to set the proper region to update. So is there any other solution to this?
I attached a very simplified version of my code here.
Thank you for your help!
main.py (2.7 KB)
I'm sorry, but your fundamental concept is fatally flawed. You cannot do any drawing on window from a secondary thread. ALL drawing on a window must occur from the thread that created the window. The operating systems do not do any thread protection. It sometimes works on Windows, but it always fails on MacOS and usually fails on Linux.
As to your paint question, triggering a paint on a parent window automatically triggers paint events on the children. However, you don't have to do all of your drawing in a paint handler. You can do it in a timer handler, or in a function you call using CallAfter.
···
On Jan 13, 2019, at 11:40 AM, RazorBest <razzvy20@gmail.com> wrote:
So I have a BufferedWindow class which i took from here: DoubleBufferedDrawing - wxPyWiki . My SimulationWindow class overrides the BufferedWindow and it starts a separate thread that calls the UpdateDrawing() method from BufferedWindow very frequently, so it's updating the drawing from the SimulationWindow very fast.
—
Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.
luni, 14 ianuarie 2019, 07:22:06 UTC, Tim Roberts a scris:
I’m sorry, but your fundamental concept is fatally flawed. You cannot do any drawing on window from a secondary thread. ALL drawing on a window must occur from the thread that created the window. The operating systems do not do any thread protection. It sometimes works on Windows, but it always fails on MacOS and usually fails on Linux.
As to your paint question, triggering a paint on a parent window automatically triggers paint events on the children. However, you don’t have to do all of your drawing in a paint handler. You can do it in a timer handler, or in a function you call using CallAfter.
Thank you for your reply. You were right: the main thread was almost working but it was failing when I was closing the window. As for the paint function, I did as you said and it worked. Now, I’m using a timer instead of the thread, that calls the UpdateDrawing() method and is doing the drawing with wx.BufferedDC instead of wx.BufferedPaintDC (outside of a paint event).
Thank you!