Close an app after a certain time

Hi,
I would close an app after a certain time,for example 15' by user
inactivity.This app is form by 40 among frames and dialogs and it's
launched by an app.pyw file where I declare a wx.App class.
How I could track the app inactivity, that is, user don't interact
with the app?
How I could approach this task?
Thanks for suggestion.

Beppe

Beppe wrote:

Hi,
I would close an app after a certain time,for example 15' by user
inactivity.This app is form by 40 among frames and dialogs and it's
launched by an app.pyw file where I declare a wx.App class.
How I could track the app inactivity, that is, user don't interact
with the app?
How I could approach this task?
Thanks for suggestion.

Beppe

Just off the top of my head, no idea if this would work, but hopefully might give you some clues/hints

store some boolean variable somewhere, e.g self.idle. Create a timer that periodically fires off every x milliseconds, that checks if self.idle is True, and if so, it "counts". If not, it resets the count to 0 and does nothing. Once the count hits x time, you could exit.

In your mouse/key event handlers, you could simply update self.idle to be False, and then when the timer is next fires and the user hasn't done anything, then the count can begin again.

Again, that's just a simple concept, but may help somewhat.

···

--
Steven Sproat, BSc
http://www.basicrpg.com/

Thanks Steven,
your hint is much interesting even if I would write
so much code to intercept the mouse event in every frame
of my app.
I'm thinking on another approach.
Using wx.EVT_IDLE, making...

class App(wx.App):

    def OnInit(self):

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

   def OnIdle(self, event):
        print event

I have notice that the IdleEvent trace change when I use
the app...but here I'm stop.

<wx._core.IdleEvent; proxy of <Swig Object of type 'wxIdleEvent *' at
0x7fff658c2230> >
<wx._core.IdleEvent; proxy of <Swig Object of type 'wxIdleEvent *' at
0x7fff658c21d0> >
<wx._core.IdleEvent; proxy of <Swig Object of type 'wxIdleEvent *' at
0x7fff658c2230> >
<wx._core.IdleEvent; proxy of <Swig Object of type 'wxIdleEvent *' at
0x7fff658c21d0> >
<wx._core.IdleEvent; proxy of <Swig Object of type 'wxIdleEvent *' at
0x7fff658c2230> >
<wx._core.IdleEvent; proxy of <Swig Object of type 'wxIdleEvent *' at
0x7fff658c2000> >
<wx._core.IdleEvent; proxy of <Swig Object of type 'wxIdleEvent *' at
0x7fff658c2060> >
<wx._core.IdleEvent; proxy of <Swig Object of type 'wxIdleEvent *' at
0x7fff658c1e30> >
<wx._core.IdleEvent; proxy of <Swig Object of type 'wxIdleEvent *' at
0x7fff658c1e90> >
<wx._core.IdleEvent; proxy of <Swig Object of type 'wxIdleEvent *' at
0x7fff658c41d0> >
<wx._core.IdleEvent; proxy of <Swig Object of type 'wxIdleEvent *' at
0x7fff658c41d0> >

Beppe

···

On Nov 30, 6:54 pm, Steven Sproat <spro...@gmail.com> wrote:

Beppe wrote:
> Hi,
> I would close an app after a certain time,for example 15' by user
> inactivity.This app is form by 40 among frames and dialogs and it's
> launched by an app.pyw file where I declare a wx.App class.
> How I could track the app inactivity, that is, user don't interact
> with the app?
> How I could approach this task?
> Thanks for suggestion.

> Beppe

Just off the top of my head, no idea if this would work, but hopefully
might give you some clues/hints

store some boolean variable somewhere, e.g self.idle. Create a timer
that periodically fires off every x milliseconds, that checks if
self.idle is True, and if so, it "counts". If not, it resets the count
to 0 and does nothing. Once the count hits x time, you could exit.

In your mouse/key event handlers, you could simply update self.idle to
be False, and then when the timer is next fires and the user hasn't done
anything, then the count can begin again.

Again, that's just a simple concept, but may help somewhat.

--
Steven Sproat, BSchttp://www.basicrpg.com/

Yep, that works. The OP might want to look at this link:

  http://cvs.savannah.gnu.org/viewvc/gnumed/gnumed/client/wxpython/gmGuiMain.py?root=gnumed&view=markup

and search for "user_activity" to see a working
implementation. The trick is that hooking once into
a global mouse/keyboard event handler is sufficient.

Karsten

···

On Mon, Nov 30, 2009 at 05:54:22PM +0000, Steven Sproat wrote:

Just off the top of my head, no idea if this would work, but hopefully
might give you some clues/hints

store some boolean variable somewhere, e.g self.idle. Create a timer
that periodically fires off every x milliseconds, that checks if
self.idle is True, and if so, it "counts". If not, it resets the count
to 0 and does nothing. Once the count hits x time, you could exit.

In your mouse/key event handlers, you could simply update self.idle to
be False, and then when the timer is next fires and the user hasn't done
anything, then the count can begin again.

--
GPG key ID E4071346 @ wwwkeys.pgp.net
E167 67FD A291 2BEA 73BD 4537 78B9 A9F9 E407 1346

Beppe wrote:

your hint is much interesting even if I would write
so much code to intercept the mouse event in every frame
of my app.

You could use a decorator -- so only one additional line per event.

I'm thinking on another approach.
Using wx.EVT_IDLE, making...

This would mostly work, however:

You get an IDLE event went the event stack empties. Generally, that happens pretty frequently in between user interactions. However, in theory, if the user was doing a lot -- the event stack could not empty for along time. This may not be a practical problem, however.

class App(wx.App):

    def OnInit(self):

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

   def OnIdle(self, event):
        print event

I have notice that the IdleEvent trace change when I use
the app...but here I'm stop.

Similar to what Steven suggested:

In OnIdle, re-start a timer for x seconds.

When the timer fires, close the app (or put up a dialog, or...)

since the timer will be re-started on each IDLE event, it will only fire when there has not been an IDLE event in a long time.

Perhaps there should be an optional monitor of the event stack built in to wx?

-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

Great job,you have open my mind...
I maked a mistake in my way.
The right approach ,and the easy way I think, is to manage the mouse
events.I drawn on by yours suggestion,in particular reading Karsten's
link (user_activity),by the way such a beautifull code...,and make

class App(wx.App):

    def OnInit(self):

        self.idle = 0
        self.OnTimer(None)
        self.timer = wx.Timer(self)
        self.timer.Start(1000)
        self.Bind(wx.EVT_TIMER, self.OnTimer)
        self.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouseEvents)

    def OnMouseEvents(self,event):
        self.idle = 0
        #print self.idle
        event.Skip()

    def OnTimer(self, evt = None):
        t = time.localtime(time.time())
        self.idle += 1
        #print self.idle
        if self.idle == 5:#to manage with a value retrived from db!!!!
            #print 'bang'
            self.OnExit()
            self.Destroy()

thanks a lot to everyone.

···

On Nov 30, 9:02 pm, Christopher Barker <Chris.Bar...@noaa.gov> wrote:

Beppe wrote:
> your hint is much interesting even if I would write
> so much code to intercept the mouse event in every frame
> of my app.

You could use a decorator -- so only one additional line per event.

> I'm thinking on another approach.
> Using wx.EVT_IDLE, making...

This would mostly work, however:

You get an IDLE event went the event stack empties. Generally, that
happens pretty frequently in between user interactions. However, in
theory, if the user was doing a lot -- the event stack could not empty
for along time. This may not be a practical problem, however.

> class App(wx.App):

> def OnInit(self):

> self.Bind(wx.EVT_IDLE, self.OnIdle)

> def OnIdle(self, event):
> print event

> I have notice that the IdleEvent trace change when I use
> the app...but here I'm stop.

Similar to what Steven suggested:

In OnIdle, re-start a timer for x seconds.

When the timer fires, close the app (or put up a dialog, or...)

since the timer will be re-started on each IDLE event, it will only fire
when there has not been an IDLE event in a long time.

Perhaps there should be an optional monitor of the event stack built in
to wx?

-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.Bar...@noaa.gov

All events can be sent to a FilterEvent method in your derived wx.App class, so you can check for them there. Be sure to only check for mouse or key events as some other kinds of events could still be sent even when the app is idle. You'll need to return -1 to allow the event to still be processed normally and not filtered out. Support for overriding FilterEvent is new, so you'll need the latest version of wxPython.

If you want to minimize overhead then you can bind event handlers for the specific events you are looking for to the app object. All events that are not handled by the widgets are sent to the app object before the system gives up and tells the platform that the event is not handled. So this way you can get notified of any mouse or keyboard events that are not handled (or handled and Skip()ed) by you, and do not need to Bind the handlers to everything.

···

On 11/30/09 11:38 AM, Beppe wrote:

your hint is much interesting even if I would write
so much code to intercept the mouse event in every frame
of my app.

--
Robin Dunn
Software Craftsman

Beppe wrote:

The right approach ,and the easy way I think, is to manage the mouse
events.I drawn on by yours suggestion,in particular reading Karsten's
link (user_activity),by the way such a beautifull code...,and make

Another way to do it is with OneShot timer that you re-set:

  class App(wx.App):

      def OnInit(self):

          self.timer = wx.Timer(self)
          self.timer.Start(1000, oneShot=True)
          self.Bind(wx.EVT_TIMER, self.OnTimer)
          self.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouseEvents)

      def OnMouseEvents(self, event):
          self.timer.Start(1000, oneShot=True)
          event.Skip()

      def OnTimer(self, evt = None):
              self.OnExit()
              self.Destroy()

···

--
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

Well, I like to be able to understand my own code a couple
of weeks after I wrote it :slight_smile:

Glad you like it and equally glad it helped !

Karsten

···

On Mon, Nov 30, 2009 at 12:47:44PM -0800, Beppe wrote:

Great job,you have open my mind...
I maked a mistake in my way.
The right approach ,and the easy way I think, is to manage the mouse
events.I drawn on by yours suggestion,in particular reading Karsten's
link (user_activity),by the way such a beautifull code

--
GPG key ID E4071346 @ wwwkeys.pgp.net
E167 67FD A291 2BEA 73BD 4537 78B9 A9F9 E407 1346