Refresh() causes redrawing of parents

Hello everyone!

This time I’ve created a gauge, which works, but I need help with redrawing.
Link to the code: https://pastebin.com/BeQAv3fc

My goal was to make such a structure:

  • Create a Frame
  • Inside of a Frame create a panel called “GaugeBackground” which contains a clock face (scale for indicator)
  • Inside of a “GaugeBackground” create a animated panel “AnimationPanel” which draws an indicator.

The thing is I have to redraw only the AnimationPanel which is responsible of drawing an indicator. I don’t want to redraw a “GaugeBackground” because the clock face is built of many lines, and redrawing it has a big performance impact on my low power PC.

The Refresh() documentation says: “Causes this window, and all of its children recursively, to be repainted.”
That means that using Refresh() in my “AnimationPanel” should repaint only the indicator! The “GaugeBackground” is not a child of “AnimationPanel”.
Unfortunately my “GaugeBackground” still gets repainted and this slows down my computer…
The clock face doesn’t change, so it’s not needed to repaint it every time…

Question: How to fix it? What should i do to repaint the indicator ONLY?

Btw. I wanted to make a workaround and store a clock face in a bitmap in memory, it should be way faster to display a stored bitmap than draw the clock face over again, but I couldn’t manage to do it :frowning: (but it would be still just a workaround which would require to redraw this bitmap)

Disclaimers:

  1. I use Linux - this may be important, I found some info, that GTK may cause something like this, but I’m not sure. Even if that’s the case I still would like to manage it somehow… Every class has a print(“Called: OnPaint X”) so it’s printed when the OnPaint is called.
    In my case I get:
    Called: OnPaint Frame
    Called: OnPaint GaugeBackground
    Called: OnPaint AnimationPanel

  2. I wanted to provide simple and easy to verify code, that’s why “clock face” is only a text “clock face”. In real example i just draw elements like in a clock.

  3. The timeout in example is set to 250ms, in real example I refresh a with higher refresh rate. I set it to 250ms so it doesn’t print so often.

Thank you in advance :slight_smile:

On Windows it seems to work as expected.

Did you try HaveRects and GetRect? Do they cover the whole area or only the area that’s covered by the Animation Panel?

(see wx.PaintEvent — wxPython Phoenix 4.1.2a1 documentation )

DietmarSchwertberger
I tried to run this on my old Windows machine.
As you said on Windows only AnimationPanel is refreshed BUT the “Clock face” text is not visible.
I found an info in documentation, that transparency on Windows in PaintDC is not supported. Unfortunately i don’t know how to use HaveRects and GetRect to solve my problem.

Back to the main topic (as I work on Linux):
In the time of waiting for response I tried to implement my workaround Linux solution I mentioned in first post.
Link to the new code: https://pastebin.com/ssUzuiy1
Unfortunately storing a “Clock face” as a Bitmap painting resulted in new problem.
(again: I wanted to draw multiple lines only once and later just show the picture of it)
The problem is as follows: my implementation of the Bitmap containing “Clock face” does not support transparency!
Basically Bitmap covers whole area of the “Clock face” with black rectangle.
That means that this workaround is not sufficient, as the Bitmap covers everything with huge black rectangle.

To illustrate it I changed the “GaugeBackground” to blue, now u can see that the part of it is occupied by the black rectangle which is the Bitmap. I can draw on the bitmap with transparency (see “Clock face” text and this yellow rectangle) but the background of this transparency will be blackness of the bitmap…

Things get even worse when I want to refresh “GaugeBackground” as it will cover the indicator with black bitmap (see line 70 by uncommenting “#wx.StaticBitmap(self, -1, self.bitmap)”)

Please, can anyone help me? All I want is to draw the the Clock face once, and then update only the indicator…