Frame only closes when mouse over

In the program below, I have to move the mouse over the frame before the frame is actually destroyed. Why is this? And how can I avoid it?

wxPython version: 2.8.7.1 (gtk2-unicode)

Ubuntu 8.04

···

import os

import wx

class My_Timer(wx.EvtHandler):
def init(self):
wx.EvtHandler.init(self)

    self.Bind(wx.EVT_TIMER, self.on_timer)

           
    self.timer = wx.Timer(self)
    self.timer.Start(1000)
#
def on_timer(self, e):
    print "bam"
    frame.Destroy()

if name == “main”:

app = wx.App()
frame = wx.Frame(None)

My_Timer()

frame.Show()
app.MainLoop()

I fixed this by issuing a paint event on shutdown:

def onClose(self, event):

self.Destroy()

wx.PostEvent(self.GetEventHandler(), wx.PaintEvent())
···

From:
wxpython-users-bounces+baxelrod=coroware.com@lists.wxwidgets.org
[mailto:wxpython-users-bounces+baxelrod=coroware.com@lists.wxwidgets.org] On Behalf Of Jesse Aldridge
Sent: Wednesday, August 06, 2008
12:15 AM
To:
wxpython-users@lists.wxwidgets.org
Subject: [wxpython-users] Frame
only closes when mouse over

In the program below, I have to move the mouse over the frame before
the frame is actually destroyed. Why is this? And how can I avoid
it?

wxPython version: 2.8.7.1 (gtk2-unicode)

Ubuntu 8.04


import os

import wx

class My_Timer(wx.EvtHandler):

def __init__(self):

    wx.EvtHandler.__init__(self)

   

    self.Bind(wx.EVT_TIMER,

self.on_timer)

    self.timer = wx.Timer(self)

    self.timer.Start(1000)

#

def on_timer(self, e):

    print "bam"

    frame.Destroy()

if name == “main”:

app = wx.App()

frame = wx.Frame(None)

My_Timer()



frame.Show()

app.MainLoop()

Jesse Aldridge wrote:

In the program below, I have to move the mouse over the frame before the frame is actually destroyed. Why is this? And how can I avoid it?

wxPython version: 2.8.7.1 <http://2.8.7.1> (gtk2-unicode)
Ubuntu 8.04

--------------

import os

import wx
   class My_Timer(wx.EvtHandler):
    def __init__(self):
        wx.EvtHandler.__init__(self)
               self.Bind(wx.EVT_TIMER, self.on_timer)
                       self.timer = wx.Timer(self)
        self.timer.Start(1000)
    #
    def on_timer(self, e):
        print "bam"
        frame.Destroy()
#
   if __name__ == "__main__":

    app = wx.App()
    frame = wx.Frame(None)

    My_Timer()
       frame.Show()
    app.MainLoop()

You have a design problem here. I'm surprised this works at all on Linux; it does NOT work on Windows. You create a My_Timer object, but then immediate destroy it. The binding must somehow save a reference which keeps the object from going away.

However, even beyond that, remember that this is a periodic timer. It will keep on firing every second, calling frame.Destroy() again and again on an object which has already been destroyed.

There is almost never a reason to create a wx.EvtHandler instance directly. Instead. the wx.Timer should be created inside some frame class, and the event bound to one of its methods.

···

--
Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.

Cool, this works. Thanks.

···

On Wed, Aug 6, 2008 at 9:31 AM, Ben Axelrod baxelrod@coroware.com wrote:

I fixed this by issuing a paint event on shutdown:

def onClose(self, event):

self.Destroy()
wx.PostEvent(self.GetEventHandler(), wx.PaintEvent())

From:
wxpython-users-bounces+baxelrod=coroware.com@lists.wxwidgets.org
[mailto:wxpython-users-bounces+baxelrod=coroware.com@lists.wxwidgets.org] On Behalf Of Jesse Aldridge
Sent: Wednesday, August 06, 2008
12:15 AM
To:
wxpython-users@lists.wxwidgets.org
Subject: [wxpython-users] Frame
only closes when mouse over

In the program below, I have to move the mouse over the frame before
the frame is actually destroyed. Why is this? And how can I avoid
it?

wxPython version: 2.8.7.1 (gtk2-unicode)

Ubuntu 8.04


import os

import wx

class My_Timer(wx.EvtHandler):

def __init__(self):

    wx.EvtHandler.__init__(self)

   

    self.Bind(wx.EVT_TIMER,

self.on_timer)

    self.timer = wx.Timer(self)

    self.timer.Start(1000)

#

def on_timer(self, e):

    print "bam"

    frame.Destroy()

if name == “main”:

app = wx.App()

frame = wx.Frame(None)



My_Timer()



frame.Show()

app.MainLoop()

wxpython-users mailing list

wxpython-users@lists.wxwidgets.org

http://lists.wxwidgets.org/mailman/listinfo/wxpython-users

You have a design problem here. I’m surprised this works at all on Linux; it does NOT work on Windows. You create a My_Timer object, but then immediate destroy it. The binding must somehow save a reference which keeps the object from going away.

Here’s my new version incorporating the previous suggestions. Does this one work for you on Windows?

import os

import wx

class My_Timer(wx.EvtHandler):
def init(self):

    wx.EvtHandler.__init__(self)
   
    self.Bind(wx.EVT_TIMER, self.on_timer)
           
    self.timer = wx.Timer(self)
    self.timer.Start(1000)
···
#
def on_timer(self, e):

    print "bam"
    frame.Close()

class My_Frame(wx.Frame):
def init(self):
wx.Frame.init(self, None)
self.Bind(wx.EVT_CLOSE, self.on_close)

#
def on_close(self, e):
    print "closing"
    self.Destroy()
    wx.PostEvent(self.GetEventHandler(), wx.PaintEvent())

if name == “main”:

app = wx.App()

frame = My_Frame()   
timer = My_Timer()

frame.Show()
app.MainLoop()

There is almost never a reason to create a wx.EvtHandler instance directly. Instead. the wx.Timer should be created inside some frame class, and the event bound to one of its methods.

The reason I am creating a wx.EvtHandler directly is that I want to have a general way of allowing wxPython applications to receive commands from external sources. The handler uses the timer to poll for a file on the disk, created by some external source. If the file is found, it’s contents are read and processed by the app and then the file is destroyed. The reason I don’t want to bind this functionality to a single frame is that for some apps, such as those that use multiple frames, it makes sense to keep the External Command Handler decoupled from the rest of the app. Do you know of a better way to accomplish the same thing?

Jesse Aldridge wrote:

    You have a design problem here. I'm surprised this works at all
    on Linux; it does NOT work on Windows. You create a My_Timer
    object, but then immediate destroy it. The binding must somehow
    save a reference which keeps the object from going away.

Here's my new version incorporating the previous suggestions. Does this one work for you on Windows?

This has the exact same problem. The problem actually exists because you have a "print" command going to a log window, instead of to a console. Because the log window is displayed, the application won't exit, and as long as the app won't exit, the timer will continue to fire, and every time it fires, it gets an error at "frame.Close()" because the frame has been destroyed. If you change this:
    app = wx.App()
to this:
    app = wx.App( 0 )
then stdout is connected to the console, the extra window is not created, the application exits when "frame" closes, so the timer cannot continue to fire.

The reason I am creating a wx.EvtHandler directly is that I want to have a general way of allowing wxPython applications to receive commands from external sources. The handler uses the timer to poll for a file on the disk, created by some external source. If the file is found, it's contents are read and processed by the app and then the file is destroyed. The reason I don't want to bind this functionality to a single frame is that for some apps, such as those that use multiple frames, it makes sense to keep the External Command Handler decoupled from the rest of the app. Do you know of a better way to accomplish the same thing?

Absolutely: the "pubsub" module, which has been discussed on this mailing list quite a bit in the last couple of weeks. It lets you register event "publishers" and event "subscribers". Published events are then distributed to all of the subscribers who wanted to know about that event.

···

--
Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.

If you change this:

app = wx.App()

to this:

app = wx.App( 0 )

then stdout is connected to the console, the extra window is not created, the application exits when “frame” closes, so the timer cannot continue to fire.

Hmm, that’s weird. In order to get the redirected ouput on my machine, I have to pass wx.App(1). It seems the default value of the redirect parameter is opposite on Windows and Linux. How odd.

Absolutely: the “pubsub” module, which has been discussed on this mailing list quite a bit in the last couple of weeks. It lets you register event “publishers” and event “subscribers”. Published events are then distributed to all of the subscribers who wanted to know about that event.

Cool. I’ll look into it.

Ok, so I looked at pubsub. Its purpose seems to be decoupling things within an individual app, right? I guess I wasn’t clear, but what I want is a way to communicate between different applications. It doesn’t seem like pubsub offers that capability. But maybe I’m just missing something…

sounds like you need either subprocess, if you don't have the code for
those other applications, or some sort of IPC tool, if you do have
access to the code for those other apps.

I've never used it but have heard good things about PyRO.

···

On Wed, Aug 6, 2008 at 8:03 PM, Jesse Aldridge <jessealdridge@gmail.com> wrote:

Ok, so I looked at pubsub. Its purpose seems to be decoupling things within
an individual app, right? I guess I wasn't clear, but what I want is a way
to communicate between *different applications*. It doesn't seem like
pubsub offers that capability. But maybe I'm just missing something...

--
Stand Fast,
tjg. [Timothy Grant]