EVT_PAINT not being created in Linux?

In my PyAUI app I have a pane which is from a class I've written
called `StateReprViewer`. (It is a subclass of `wx.TextCtrl`.) That
class binds `EVT_PAINT` like so:

self.Bind(wx.EVT_PAINT, self.on_paint)

And the handler looks like this:

def on_paint(self, event):
        event.Skip()
        if self.needs_update_flag:
            # ... update stuff in the widget

On Windows it works fine. On Ubuntu the `on_paint` just doesn't get
called. (I confirmed this by putting a `print('hello!')` in the
handler.) Even when I call `Refresh` on the widget it does not get
called.

However, just for testing I did this:

self.Bind(wx.EVT_IDLE, self.on_paint)

And this *did* make `on_paint` execute, and I saw the 'hello!' and the
widget updating itself.

What is happening here?

Ram.

···

--
To unsubscribe, send email to wxPython-users+unsubscribe@googlegroups.com
or visit http://groups.google.com/group/wxPython-users?hl=en

Hi,

In my PyAUI app I have a pane which is from a class I've written
called `StateReprViewer`. (It is a subclass of `wx.TextCtrl`.) That
class binds `EVT_PAINT` like so:

self.Bind(wx.EVT_PAINT, self.on_paint)

And the handler looks like this:

def on_paint(self, event):
event.Skip()
if self.needs_update_flag:
# ... update stuff in the widget

On Windows it works fine. On Ubuntu the `on_paint` just doesn't get
called. (I confirmed this by putting a `print('hello!')` in the
handler.) Even when I call `Refresh` on the widget it does not get
called.

However, just for testing I did this:

self.Bind(wx.EVT_IDLE, self.on_paint)

And this *did* make `on_paint` execute, and I saw the 'hello!' and the
widget updating itself.

What is happening here?

Some of the native widgets, depending on the widget and on the
platform, will not allow you to bind a paint event to them or they
will look funny/broken if you try to do it. I don't think you can do
that with a wx.TextCtrl, and in my opinion you shouldn't do it on any
platform anyway. Can you tell us what are you trying to do by
overriding the default paint event for a wx.TextCtrl?

Andrea.

"Imagination Is The Only Weapon In The War Against Reality."
http://xoomer.alice.it/infinity77/

==> Never *EVER* use RemovalGroup for your house removal. You'll
regret it forever.
The Doomed City: Removal Group: the nightmare <==

···

On 19 April 2010 12:02, cool-RR wrote:

--
To unsubscribe, send email to wxPython-users+unsubscribe@googlegroups.com
or visit http://groups.google.com/group/wxPython-users?hl=en

Okay, I’ll explain. The goal of the StateReprViewer is to show the repr of the current active state. (At every point in time the GuiProject has an active state, which is a State object.) So it’s a text control which writes a bunch of text to itself.

So, every time I change the active state, I raise the needs_update_flag on the StateReprViewer and call Refresh.

The “update” is fetching the active state, and writing its repr string to the text control.

The reason I don’t just do the update the moment the active state changes, is that multiple updates may be requested before one drawing has been done, and it will be a waste to do them all. Therefore, only when the widget is getting drawn the update actually gets done.

I’m starting to think that the solution may be not to subclass a TextCtrl but create one that is a child of StateReprViewer. Unless you have another idea,

Ram.

···

On Mon, Apr 19, 2010 at 1:07 PM, Andrea Gavana andrea.gavana@gmail.com wrote:

Hi,

On 19 April 2010 12:02, cool-RR wrote:

In my PyAUI app I have a pane which is from a class I’ve written

called StateReprViewer. (It is a subclass of wx.TextCtrl.) That

class binds EVT_PAINT like so:

self.Bind(wx.EVT_PAINT, self.on_paint)

And the handler looks like this:

def on_paint(self, event):

   event.Skip()
   if self.needs_update_flag:
       # ... update stuff in the widget

On Windows it works fine. On Ubuntu the on_paint just doesn’t get

called. (I confirmed this by putting a print('hello!') in the

handler.) Even when I call Refresh on the widget it does not get

called.

However, just for testing I did this:

self.Bind(wx.EVT_IDLE, self.on_paint)

And this did make on_paint execute, and I saw the ‘hello!’ and the

widget updating itself.

What is happening here?

Some of the native widgets, depending on the widget and on the

platform, will not allow you to bind a paint event to them or they

will look funny/broken if you try to do it. I don’t think you can do

that with a wx.TextCtrl, and in my opinion you shouldn’t do it on any

platform anyway. Can you tell us what are you trying to do by

overriding the default paint event for a wx.TextCtrl?

Andrea.

To unsubscribe, send email to wxPython-users+unsubscribe@googlegroups.com

or visit http://groups.google.com/group/wxPython-users?hl=en

Hi,

Hi,

> In my PyAUI app I have a pane which is from a class I've written
> called `StateReprViewer`. (It is a subclass of `wx.TextCtrl`.) That
> class binds `EVT_PAINT` like so:
>
> self.Bind(wx.EVT_PAINT, self.on_paint)
>
> And the handler looks like this:
>
> def on_paint(self, event):
> event.Skip()
> if self.needs_update_flag:
> # ... update stuff in the widget
>
> On Windows it works fine. On Ubuntu the `on_paint` just doesn't get
> called. (I confirmed this by putting a `print('hello!')` in the
> handler.) Even when I call `Refresh` on the widget it does not get
> called.
>
> However, just for testing I did this:
>
> self.Bind(wx.EVT_IDLE, self.on_paint)
>
> And this *did* make `on_paint` execute, and I saw the 'hello!' and the
> widget updating itself.
>
> What is happening here?

Some of the native widgets, depending on the widget and on the
platform, will not allow you to bind a paint event to them or they
will look funny/broken if you try to do it. I don't think you can do
that with a wx.TextCtrl, and in my opinion you shouldn't do it on any
platform anyway. Can you tell us what are you trying to do by
overriding the default paint event for a wx.TextCtrl?

Andrea.

Okay, I'll explain. The goal of the `StateReprViewer` is to show the `repr`
of the current active state. (At every point in time the `GuiProject` has an
active state, which is a `State` object.) So it's a text control which
writes a bunch of text to itself.
So, every time I change the active state, I raise the `needs_update_flag` on
the `StateReprViewer` and call `Refresh`.
The "update" is fetching the active state, and writing its repr string to
the text control.
The reason I don't just do the update the moment the active state changes,
is that multiple updates may be requested before one drawing has been done,
and it will be a waste to do them all. Therefore, only when the widget is
getting drawn the update actually gets done.
I'm starting to think that the solution may be not to subclass a `TextCtrl`
but create one that is a child of `StateReprViewer`. Unless you have another
idea,

I still think you are worrying too much about the "wasting of method
calls". There are 2 ways to do what you want:

1) Easy: Whan a state changes, call
StateReprViewer.SetValue(new_state) and don't touch the paint event;
2) Less easier: Write your own custom widget that will look like a
wx.TextCtrl but there will be no harm in overriding its paint event
(as it would be based on wx.PyControl), then do what you were doing in
your original on_paint handler.

Andrea.

"Imagination Is The Only Weapon In The War Against Reality."
http://xoomer.alice.it/infinity77/

==> Never *EVER* use RemovalGroup for your house removal. You'll
regret it forever.
The Doomed City: Removal Group: the nightmare <==

···

On 19 April 2010 12:19, cool-RR wrote:

On Mon, Apr 19, 2010 at 1:07 PM, Andrea Gavana <andrea.gavana@gmail.com> > wrote:

On 19 April 2010 12:02, cool-RR wrote:

--
To unsubscribe, send email to wxPython-users+unsubscribe@googlegroups.com
or visit http://groups.google.com/group/wxPython-users?hl=en

I think I’ll just have a text control as a sub-widget this time.

Can you point me to the actual source of MainLoop? I am guessing this is in wxWidgets:

http://svn.wxwidgets.org/viewvc/wx/wxWidgets/trunk

But I don’t know in which directory.

Thanks,

Ram.

···

On Mon, Apr 19, 2010 at 1:24 PM, Andrea Gavana andrea.gavana@gmail.com wrote:

Some of the native widgets, depending on the widget and on the

platform, will not allow you to bind a paint event to them or they

will look funny/broken if you try to do it. I don’t think you can do

that with a wx.TextCtrl, and in my opinion you shouldn’t do it on any

platform anyway. Can you tell us what are you trying to do by

overriding the default paint event for a wx.TextCtrl?

Andrea.

Okay, I’ll explain. The goal of the StateReprViewer is to show the repr

of the current active state. (At every point in time the GuiProject has an

active state, which is a State object.) So it’s a text control which

writes a bunch of text to itself.

So, every time I change the active state, I raise the needs_update_flag on

the StateReprViewer and call Refresh.

The “update” is fetching the active state, and writing its repr string to

the text control.

The reason I don’t just do the update the moment the active state changes,

is that multiple updates may be requested before one drawing has been done,

and it will be a waste to do them all. Therefore, only when the widget is

getting drawn the update actually gets done.

I’m starting to think that the solution may be not to subclass a TextCtrl

but create one that is a child of StateReprViewer. Unless you have another

idea,

I still think you are worrying too much about the "wasting of method

calls". There are 2 ways to do what you want:

  1. Easy: Whan a state changes, call

StateReprViewer.SetValue(new_state) and don’t touch the paint event;

  1. Less easier: Write your own custom widget that will look like a

wx.TextCtrl but there will be no harm in overriding its paint event

(as it would be based on wx.PyControl), then do what you were doing in

your original on_paint handler.

Andrea.

To unsubscribe, send email to wxPython-users+unsubscribe@googlegroups.com

or visit http://groups.google.com/group/wxPython-users?hl=en

Hi,

>> Some of the native widgets, depending on the widget and on the
>> platform, will not allow you to bind a paint event to them or they
>> will look funny/broken if you try to do it. I don't think you can do
>> that with a wx.TextCtrl, and in my opinion you shouldn't do it on any
>> platform anyway. Can you tell us what are you trying to do by
>> overriding the default paint event for a wx.TextCtrl?
>>
>> Andrea.
>
> Okay, I'll explain. The goal of the `StateReprViewer` is to show the
> `repr`
> of the current active state. (At every point in time the `GuiProject`
> has an
> active state, which is a `State` object.) So it's a text control which
> writes a bunch of text to itself.
> So, every time I change the active state, I raise the
> `needs_update_flag` on
> the `StateReprViewer` and call `Refresh`.
> The "update" is fetching the active state, and writing its repr string
> to
> the text control.
> The reason I don't just do the update the moment the active state
> changes,
> is that multiple updates may be requested before one drawing has been
> done,
> and it will be a waste to do them all. Therefore, only when the widget
> is
> getting drawn the update actually gets done.
> I'm starting to think that the solution may be not to subclass a
> `TextCtrl`
> but create one that is a child of `StateReprViewer`. Unless you have
> another
> idea,

I still think you are worrying too much about the "wasting of method
calls". There are 2 ways to do what you want:

1) Easy: Whan a state changes, call
StateReprViewer.SetValue(new_state) and don't touch the paint event;
2) Less easier: Write your own custom widget that will look like a
wx.TextCtrl but there will be no harm in overriding its paint event
(as it would be based on wx.PyControl), then do what you were doing in
your original on_paint handler.

Andrea.

I think I'll just have a text control as a sub-widget this time.
Can you point me to the actual source of `MainLoop`? I am guessing this is
in wxWidgets:
http://svn.wxwidgets.org/viewvc/wx/wxWidgets/trunk
But I don't know in which directory.

I have no idea about that: the way wxWidgets manages class names
against file names is, to me at least, one of the less intuitive
approaches I have ever seen. But this is probably because I know next
to nothing about C++.

If you want to take a look at a possible implementation of MainLoop
(custom MainLoop with wxPython), there is a sample in the wxPython
distribution, and you can also view it here:

http://svn.wxwidgets.org/viewvc/wx/wxPython/trunk/samples/mainloop/mainloop.py?revision=47031&view=markup

Good luck.

Andrea.

"Imagination Is The Only Weapon In The War Against Reality."
http://xoomer.alice.it/infinity77/

==> Never *EVER* use RemovalGroup for your house removal. You'll
regret it forever.
The Doomed City: Removal Group: the nightmare <==

···

On 19 April 2010 13:33, cool-RR wrote:

On Mon, Apr 19, 2010 at 1:24 PM, Andrea Gavana <andrea.gavana@gmail.com> > wrote:

--
To unsubscribe, send email to wxPython-users+unsubscribe@googlegroups.com
or visit http://groups.google.com/group/wxPython-users?hl=en

Wow, to override `MainLoop` like that gives a lot of control,
definitely enough control for my purposes. But I'd worry about (a)
speed (b) subtle bugs because of the differences from the original
`MainLoop`.

Now I'm dizzy from too much power... I'll think things over.

Ram.

···

On Mon, Apr 19, 2010 at 3:01 PM, Andrea Gavana <andrea.gavana@gmail.com> wrote:

Can you point me to the actual source of `MainLoop`? I am guessing this is
in wxWidgets:
http://svn.wxwidgets.org/viewvc/wx/wxWidgets/trunk
But I don't know in which directory.

I have no idea about that: the way wxWidgets manages class names
against file names is, to me at least, one of the less intuitive
approaches I have ever seen. But this is probably because I know next
to nothing about C++.

If you want to take a look at a possible implementation of MainLoop
(custom MainLoop with wxPython), there is a sample in the wxPython
distribution, and you can also view it here:

http://svn.wxwidgets.org/viewvc/wx/wxPython/trunk/samples/mainloop/mainloop.py?revision=47031&view=markup

Good luck.

Andrea.

--
To unsubscribe, send email to wxPython-users+unsubscribe@googlegroups.com
or visit http://groups.google.com/group/wxPython-users?hl=en

Hi,

Can you point me to the actual source of `MainLoop`? I am guessing this is
in wxWidgets:
http://svn.wxwidgets.org/viewvc/wx/wxWidgets/trunk
But I don't know in which directory.

I have no idea about that: the way wxWidgets manages class names
against file names is, to me at least, one of the less intuitive
approaches I have ever seen. But this is probably because I know next
to nothing about C++.

If you want to take a look at a possible implementation of MainLoop
(custom MainLoop with wxPython), there is a sample in the wxPython
distribution, and you can also view it here:

http://svn.wxwidgets.org/viewvc/wx/wxPython/trunk/samples/mainloop/mainloop.py?revision=47031&view=markup

Good luck.

Andrea.

Wow, to override `MainLoop` like that gives a lot of control,
definitely enough control for my purposes. But I'd worry about (a)
speed (b) subtle bugs because of the differences from the original
`MainLoop`.

Now I'm dizzy from too much power... I'll think things over.

Well, you'll only need to try and see with your application in order
to solve (a) and (b). I have never used this approach so I don't have
any particular suggestion regading your worries.

Andrea.

"Imagination Is The Only Weapon In The War Against Reality."
http://xoomer.alice.it/infinity77/

==> Never *EVER* use RemovalGroup for your house removal. You'll
regret it forever.
The Doomed City: Removal Group: the nightmare <==

···

On 19 April 2010 15:02, cool-RR wrote:

On Mon, Apr 19, 2010 at 3:01 PM, Andrea Gavana <andrea.gavana@gmail.com> wrote:

--
To unsubscribe, send email to wxPython-users+unsubscribe@googlegroups.com
or visit http://groups.google.com/group/wxPython-users?hl=en

cool-RR wrote:

Wow, to override `MainLoop` like that gives a lot of control,
definitely enough control for my purposes. But I'd worry about (a)
speed (b)

don't worry about speed until you actually have speed issues:

"premature optimization is the root of all evil"

cool-RR wrote:

So this will get called for every event being processed? Won't this slow everything up?

not unnecessarily noticeably -- try it.

Also, how do I hack this into something that gets called once after every iteration of the loop?

what do you mean by a iteration of the loop. I think the mainloop is something like this:

while 1:
     if event_in_queue:
         process event.

More to it of course, but the point is that each iteration of the loop, IS each event. You can use EVT_IDLE to capture when the event queue _becomes_ empty, but that can either be very often, or not for along time, depending on what the app (and the user) is doing.

I'd say either do it really often as Robin Suggested, or use a wx.timer to do it approx intervals.

-Chris

···

--
Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@noaa.gov

--
To unsubscribe, send email to wxPython-users+unsubscribe@googlegroups.com
or visit http://groups.google.com/group/wxPython-users?hl=en

I’m supposed to be able to bind my own on_paint to a wx.Panel, right?

Ram.

···

On Mon, Apr 19, 2010 at 1:07 PM, Andrea Gavana andrea.gavana@gmail.com wrote:

Hi,

On 19 April 2010 12:02, cool-RR wrote:

In my PyAUI app I have a pane which is from a class I’ve written

called StateReprViewer. (It is a subclass of wx.TextCtrl.) That

class binds EVT_PAINT like so:

self.Bind(wx.EVT_PAINT, self.on_paint)

And the handler looks like this:

def on_paint(self, event):

   event.Skip()
   if self.needs_update_flag:
       # ... update stuff in the widget

On Windows it works fine. On Ubuntu the on_paint just doesn’t get

called. (I confirmed this by putting a print('hello!') in the

handler.) Even when I call Refresh on the widget it does not get

called.

However, just for testing I did this:

self.Bind(wx.EVT_IDLE, self.on_paint)

And this did make on_paint execute, and I saw the ‘hello!’ and the

widget updating itself.

What is happening here?

Some of the native widgets, depending on the widget and on the

platform, will not allow you to bind a paint event to them or they

will look funny/broken if you try to do it. I don’t think you can do

that with a wx.TextCtrl, and in my opinion you shouldn’t do it on any

platform anyway. Can you tell us what are you trying to do by

overriding the default paint event for a wx.TextCtrl?

Andrea.

To unsubscribe, send email to wxPython-users+unsubscribe@googlegroups.com

or visit http://groups.google.com/group/wxPython-users?hl=en

Hi,

Hi,

> In my PyAUI app I have a pane which is from a class I've written
> called `StateReprViewer`. (It is a subclass of `wx.TextCtrl`.) That
> class binds `EVT_PAINT` like so:
>
> self.Bind(wx.EVT_PAINT, self.on_paint)
>
> And the handler looks like this:
>
> def on_paint(self, event):
> event.Skip()
> if self.needs_update_flag:
> # ... update stuff in the widget
>
> On Windows it works fine. On Ubuntu the `on_paint` just doesn't get
> called. (I confirmed this by putting a `print('hello!')` in the
> handler.) Even when I call `Refresh` on the widget it does not get
> called.
>
> However, just for testing I did this:
>
> self.Bind(wx.EVT_IDLE, self.on_paint)
>
> And this *did* make `on_paint` execute, and I saw the 'hello!' and the
> widget updating itself.
>
> What is happening here?

Some of the native widgets, depending on the widget and on the
platform, will not allow you to bind a paint event to them or they
will look funny/broken if you try to do it. I don't think you can do
that with a wx.TextCtrl, and in my opinion you shouldn't do it on any
platform anyway. Can you tell us what are you trying to do by
overriding the default paint event for a wx.TextCtrl?

Andrea.

I'm supposed to be able to bind my own `on_paint` to a wx.Panel, right?

Yes. Although I would be careful on binding paint events to native
widgets. wx.Panel probably won't complain, but in general you should
use wx.Py* controls if you want to draw things yourself. It is not a
rule, but I believe some of the native widgets will kick you if you
try to override their default paint stuff.

Andrea.

"Imagination Is The Only Weapon In The War Against Reality."
http://xoomer.alice.it/infinity77/

==> Never *EVER* use RemovalGroup for your house removal. You'll
regret it forever.
The Doomed City: Removal Group: the nightmare <==

···

On 20 April 2010 11:34, cool-RR wrote:

On Mon, Apr 19, 2010 at 1:07 PM, Andrea Gavana <andrea.gavana@gmail.com> > wrote:

On 19 April 2010 12:02, cool-RR wrote:

--
To unsubscribe, send email to wxPython-users+unsubscribe@googlegroups.com
or visit http://groups.google.com/group/wxPython-users?hl=en

Not quite true. The wx.Py* classes exist so you can override methods that are needed to make a properly behaved control, like AcceptsFocus, DoGetBestSize, etc. For painting and other low-level events the only times you may run into troubles is for native widget classes derived from wx.Control. The others should all behave as expected.

···

On 4/20/10 3:48 AM, Andrea Gavana wrote:

I'm supposed to be able to bind my own `on_paint` to a wx.Panel, right?

Yes. Although I would be careful on binding paint events to native
widgets. wx.Panel probably won't complain, but in general you should
use wx.Py* controls if you want to draw things yourself.

--
Robin Dunn
Software Craftsman

--
To unsubscribe, send email to wxPython-users+unsubscribe@googlegroups.com
or visit http://groups.google.com/group/wxPython-users?hl=en

Some platforms allow us to intercept low-level events for the native widgets, some don't. So wxWidgets basically just declares this functionality to be "undefined"

···

On 4/19/10 4:02 AM, cool-RR wrote:

In my PyAUI app I have a pane which is from a class I've written
called `StateReprViewer`. (It is a subclass of `wx.TextCtrl`.) That
class binds `EVT_PAINT` like so:

self.Bind(wx.EVT_PAINT, self.on_paint)

And the handler looks like this:

def on_paint(self, event):
         event.Skip()
         if self.needs_update_flag:
             # ... update stuff in the widget

On Windows it works fine. On Ubuntu the `on_paint` just doesn't get
called. (I confirmed this by putting a `print('hello!')` in the
handler.) Even when I call `Refresh` on the widget it does not get
called.

However, just for testing I did this:

self.Bind(wx.EVT_IDLE, self.on_paint)

And this *did* make `on_paint` execute, and I saw the 'hello!' and the
widget updating itself.

What is happening here?

--
Robin Dunn
Software Craftsman

--
To unsubscribe, send email to wxPython-users+unsubscribe@googlegroups.com
or visit http://groups.google.com/group/wxPython-users?hl=en

At last the BDFL! Thank you Robin for the clarification, I stand more
than corrected and I'll think 15 times before posting strange
conclusions the next time :slight_smile:

Andrea.

"Imagination Is The Only Weapon In The War Against Reality."
http://xoomer.alice.it/infinity77/

==> Never *EVER* use RemovalGroup for your house removal. You'll
regret it forever.
The Doomed City: Removal Group: the nightmare <==

···

On 20 April 2010 20:32, Robin Dunn wrote:

On 4/20/10 3:48 AM, Andrea Gavana wrote:

I'm supposed to be able to bind my own `on_paint` to a wx.Panel, right?

Yes. Although I would be careful on binding paint events to native
widgets. wx.Panel probably won't complain, but in general you should
use wx.Py* controls if you want to draw things yourself.

Not quite true. The wx.Py* classes exist so you can override methods that
are needed to make a properly behaved control, like AcceptsFocus,
DoGetBestSize, etc. For painting and other low-level events the only times
you may run into troubles is for native widget classes derived from
wx.Control. The others should all behave as expected.

--
To unsubscribe, send email to wxPython-users+unsubscribe@googlegroups.com
or visit http://groups.google.com/group/wxPython-users?hl=en

I think that with double-buffering I might be able to rid myself of most of the troubles that led to that issue, thanks.

Ram.

···

On Mon, Apr 19, 2010 at 8:22 PM, Christopher Barker Chris.Barker@noaa.gov wrote:

cool-RR wrote:

Wow, to override MainLoop like that gives a lot of control,

definitely enough control for my purposes. But I’d worry about (a)

speed (b)

don’t worry about speed until you actually have speed issues:

“premature optimization is the root of all evil”

cool-RR wrote:

So this will get called for every event being processed? Won’t this slow everything up?

not unnecessarily noticeably – try it.

Also, how do I hack this into something that gets called once after every iteration of the loop?

what do you mean by a iteration of the loop. I think the mainloop is something like this:

while 1:

if event_in_queue:

    process event.

More to it of course, but the point is that each iteration of the loop, IS each event. You can use EVT_IDLE to capture when the event queue becomes empty, but that can either be very often, or not for along time, depending on what the app (and the user) is doing.

I’d say either do it really often as Robin Suggested, or use a wx.timer to do it approx intervals.

-Chris

To unsubscribe, send email to wxPython-users+unsubscribe@googlegroups.com

or visit http://groups.google.com/group/wxPython-users?hl=en