Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > PythonWin, python thread and PostQuitMessage?

Reply
Thread Tools

PythonWin, python thread and PostQuitMessage?

 
 
arnaud@sphaero.org
Guest
Posts: n/a
 
      03-12-2009
Hi All,

I'm not so much involved in any Windows programming however I needed
to write a client for the Windows platform. I have this very simple
question which I've been unable to answer. I'm listening for keyboard
strokes using the pyhook library. I'm doing this in a dedicated
thread. The gui just controls the thread. When I want to pause
listening for keyboard strokes I wanted to do a PostQuitMessage() to
the thread. However this does not work since it either kills the whole
app or just does not happen in the thread it's supposed to. I've now
made an ugly workaround using PumpWaitingMessages and a delay.

def run(self):
print "Wkeylog run called"
# Hook Keyboard
self.hm.HookKeyboard()
while self.log:
win32gui.PumpWaitingMessages()
time.sleep(0.02)

i can now just cancel the process by setting self.log to False. I
wanted to do just:

def run(self):
print "Wkeylog run called"
# Hook Keyboard
self.hm.HookKeyboard()
win32gui.PumpMessages()

However I'm unable to stop this process. Can anyone shred al light
here?

Rg,

Arnaud
 
Reply With Quote
 
 
 
 
Gabriel Genellina
Guest
Posts: n/a
 
      03-12-2009
En Thu, 12 Mar 2009 07:21:35 -0200, <(E-Mail Removed)> escribió:

> I'm not so much involved in any Windows programming however I needed
> to write a client for the Windows platform. I have this very simple
> question which I've been unable to answer. I'm listening for keyboard
> strokes using the pyhook library. I'm doing this in a dedicated
> thread. The gui just controls the thread. When I want to pause
> listening for keyboard strokes I wanted to do a PostQuitMessage() to
> the thread. However this does not work since it either kills the whole
> app or just does not happen in the thread it's supposed to. I've now
> made an ugly workaround using PumpWaitingMessages and a delay.


If you have a GUI, then very likely it has its own message loop, so you
should not create another.

> def run(self):
> print "Wkeylog run called"
> # Hook Keyboard
> self.hm.HookKeyboard()
> while self.log:
> win32gui.PumpWaitingMessages()
> time.sleep(0.02)
>
> i can now just cancel the process by setting self.log to False. I
> wanted to do just:
>
> def run(self):
> print "Wkeylog run called"
> # Hook Keyboard
> self.hm.HookKeyboard()
> win32gui.PumpMessages()


Then, if you remove PumpMesages and PumpWaitingMessages, there is nothing
left... so this thread is useless.
Perhaps you want to *process* keyboard events in another thread - in this
case, use a Queue object to send events to the worker thread, from the
main thread where the message loop resides.

--
Gabriel Genellina

 
Reply With Quote
 
 
 
 
aloonstra@gmail.com
Guest
Posts: n/a
 
      03-13-2009
On 12 mrt, 18:43, "Gabriel Genellina" <(E-Mail Removed)> wrote:
> En Thu, 12 Mar 2009 07:21:35 -0200, <(E-Mail Removed)> escribió:
>
> > I'm not so much involved in any Windows programming however I needed
> > to write a client for the Windows platform. I have this very simple
> > question which I've been unable to answer. I'm listening for keyboard
> > strokes using the pyhook library. I'm doing this in a dedicated
> > thread. The gui just controls the thread. When I want to pause
> > listening for keyboard strokes I wanted to do a PostQuitMessage() to
> > the thread. However this does not work since it either kills the whole
> > app or just does not happen in the thread it's supposed to. I've now
> > made an ugly workaround using PumpWaitingMessages and a delay.

>
> If you have a GUI, then very likely it has its own message loop, so you *
> should not create another.
>
>
>
> > def run(self):
> > * *print "Wkeylog run called"
> > * *# Hook Keyboard
> > * *self.hm.HookKeyboard()
> > * *while self.log:
> > * * * * * *win32gui.PumpWaitingMessages()
> > * * * * * *time.sleep(0.02)

>
> > i can now just cancel the process by setting self.log to False. I
> > wanted to do just:

>
> > def run(self):
> > * *print "Wkeylog run called"
> > * *# Hook Keyboard
> > * *self.hm.HookKeyboard()
> > * *win32gui.PumpMessages()

>
> Then, if you remove PumpMesages and PumpWaitingMessages, there is nothing *
> left... so this thread is useless.
> Perhaps you want to *process* keyboard events in another thread - in this *
> case, use a Queue object to send events to the worker thread, from the *
> main thread where the message loop resides.
>
> --
> Gabriel Genellina


You are right however this case is a bit different. The application is
a keylogger which listens for keyboard events. The GUI is done using
Wx. They are different message loops. Under Linux I have no problem
however in the case of Windows I don't know how to stop the keylogger.

The Keylogger for Windows is very simple, see:
http://retypingdante.svn.sourceforge...py?view=markup

As you can see in the cancel function I cannot use
win32gui.PostQuitMessage(1) since it kills the whole app, including
Wx, and not just the thread. I cannot mix the eventloops of Windows
and Wx AFAIK so I put it in its own thread. I'm already using Queue
objects to pass the data between threads.

Arnaud
 
Reply With Quote
 
Gabriel Genellina
Guest
Posts: n/a
 
      03-13-2009
En Fri, 13 Mar 2009 17:59:34 -0200, <(E-Mail Removed)> escribió:
> On 12 mrt, 18:43, "Gabriel Genellina" <(E-Mail Removed)> wrote:
>> En Thu, 12 Mar 2009 07:21:35 -0200, <(E-Mail Removed)> escribió:
>>
>> > I'm not so much involved in any Windows programming however I needed
>> > to write a client for the Windows platform. I have this very simple
>> > question which I've been unable to answer. I'm listening for keyboard
>> > strokes using the pyhook library. I'm doing this in a dedicated
>> > thread. The gui just controls the thread. When I want to pause
>> > listening for keyboard strokes I wanted to do a PostQuitMessage() to
>> > the thread. However this does not work since it either kills the whole
>> > app or just does not happen in the thread it's supposed to. I've now
>> > made an ugly workaround using PumpWaitingMessages and a delay.

>>
>> If you have a GUI, then very likely it has its own message loop, so you
>> should not create another.
>>
>>
>>
>> > def run(self):
>> > * *print "Wkeylog run called"
>> > * *# Hook Keyboard
>> > * *self.hm.HookKeyboard()
>> > * *while self.log:
>> > * * * * * *win32gui.PumpWaitingMessages()
>> > * * * * * *time.sleep(0.02)

>>
>> > i can now just cancel the process by setting self.log to False. I
>> > wanted to do just:

>>
>> > def run(self):
>> > * *print "Wkeylog run called"
>> > * *# Hook Keyboard
>> > * *self.hm.HookKeyboard()
>> > * *win32gui.PumpMessages()

>>
>> Then, if you remove PumpMesages and PumpWaitingMessages, there is
>> nothing *
>> left... so this thread is useless.
>> Perhaps you want to *process* keyboard events in another thread - in
>> this *
>> case, use a Queue object to send events to the worker thread, from the *
>> main thread where the message loop resides.

>
> You are right however this case is a bit different. The application is
> a keylogger which listens for keyboard events. The GUI is done using
> Wx. They are different message loops. Under Linux I have no problem
> however in the case of Windows I don't know how to stop the keylogger.
>
> The Keylogger for Windows is very simple, see:
> http://retypingdante.svn.sourceforge...py?view=markup


This code uses PumpMessages just because it's a console application, and
those do not have a message loop by default. A windowed application
written in wx *already* has a message loop, so you don't have to provide
your own.

Stopping the keylogger, in that code, means calling the cancel() method,
by any means you want. It has nothing to do with a message loop, AFAICT.

> As you can see in the cancel function I cannot use
> win32gui.PostQuitMessage(1) since it kills the whole app, including
> Wx, and not just the thread. I cannot mix the eventloops of Windows
> and Wx AFAIK so I put it in its own thread. I'm already using Queue
> objects to pass the data between threads.


I still don't understand why you use a separate message loop. wx provides
its own, and it should be enough - worse, a second message loop may
adversely affect the application. And without a separate message loop, the
separate thread has no sense either.

Anyway, if you insist, it's more efficient to wait using an Event object:

def __init__(...):
...
self.finished = threading.Event()

def run(self):
self.hm.HookKeyboard()
self.finished.wait()

def cancel(self):
self.hm.UnhookKeyboard()
self.finished.set()

--
Gabriel Genellina

 
Reply With Quote
 
aloonstra@gmail.com
Guest
Posts: n/a
 
      03-14-2009
On 13 mrt, 23:30, "Gabriel Genellina" <(E-Mail Removed)> wrote:
> En Fri, 13 Mar 2009 17:59:34 -0200, <(E-Mail Removed)> escribió:
>
>
>
> > On 12 mrt, 18:43, "Gabriel Genellina" <(E-Mail Removed)> wrote:
> >> En Thu, 12 Mar 2009 07:21:35 -0200, <(E-Mail Removed)> escribió:

>
> >> > I'm not so much involved in any Windows programming however I needed
> >> > to write a client for the Windows platform. I have this very simple
> >> > question which I've been unable to answer. I'm listening for keyboard
> >> > strokes using the pyhook library. I'm doing this in a dedicated
> >> > thread. The gui just controls the thread. When I want to pause
> >> > listening for keyboard strokes I wanted to do a PostQuitMessage() to
> >> > the thread. However this does not work since it either kills the whole
> >> > app or just does not happen in the thread it's supposed to. I've now
> >> > made an ugly workaround using PumpWaitingMessages and a delay.

>
> >> If you have a GUI, then very likely it has its own message loop, so you *
> >> should not create another.

>
> >> > def run(self):
> >> > * *print "Wkeylog run called"
> >> > * *# Hook Keyboard
> >> > * *self.hm.HookKeyboard()
> >> > * *while self.log:
> >> > * * * * * *win32gui.PumpWaitingMessages()
> >> > * * * * * *time.sleep(0.02)

>
> >> > i can now just cancel the process by setting self.log to False. I
> >> > wanted to do just:

>
> >> > def run(self):
> >> > * *print "Wkeylog run called"
> >> > * *# Hook Keyboard
> >> > * *self.hm.HookKeyboard()
> >> > * *win32gui.PumpMessages()

>
> >> Then, if you remove PumpMesages and PumpWaitingMessages, there is *
> >> nothing *
> >> left... so this thread is useless.
> >> Perhaps you want to *process* keyboard events in another thread - in *
> >> this *
> >> case, use a Queue object to send events to the worker thread, from the *
> >> main thread where the message loop resides.

>
> > You are right however this case is a bit different. The application is
> > a keylogger which listens for keyboard events. The GUI is done using
> > Wx. They are different message loops. Under Linux I have no problem
> > however in the case of Windows I don't know how to stop the keylogger.

>
> > The Keylogger for Windows is very simple, see:
> >http://retypingdante.svn.sourceforge...gdante/trunk/i...

>
> This code uses PumpMessages just because it's a console application, and *
> those do not have a message loop by default. A windowed application *
> written in wx *already* has a message loop, so you don't have to provide *
> your own.
>
> Stopping the keylogger, in that code, means calling the cancel() method, *
> by any means you want. It has nothing to do with a message loop, AFAICT.
>
> > As you can see in the cancel function I cannot use
> > win32gui.PostQuitMessage(1) since it kills the whole app, including
> > Wx, and not just the thread. I cannot mix the eventloops of Windows
> > and Wx AFAIK so I put it in its own thread. I'm already using Queue
> > objects to pass the data between threads.

>
> I still don't understand why you use a separate message loop. wx provides *
> its own, and it should be enough - worse, a second message loop may *
> adversely affect the application. And without a separate message loop, the *
> separate thread has no sense either.
>
> Anyway, if you insist, it's more efficient to wait using an Event object:
>
> def __init__(...):
> * *...
> * *self.finished = threading.Event()
>
> def run(self):
> * *self.hm.HookKeyboard()
> * *self.finished.wait()
>
> def cancel(self):
> * *self.hm.UnhookKeyboard()
> * *self.finished.set()
>
> --
> Gabriel Genellina


You're right. Last night I dived into all this message looping thing
and I don't even have to use PumpMessages(). I got it working from
within wx using its messageloop. So I don't need a seperate thread no
more.

Thanks for your suggestions.

Arnaud
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
html5lib not thread safe. Is the Python SAX library thread-safe? John Nagle Python 5 03-12-2012 04:07 PM
Thread limit and thread stack size blair.bethwaite@gmail.com Python 0 11-26-2008 12:26 AM
boost.thread library and the thread is running Miroslaw Makowiecki C++ 1 08-09-2007 07:14 PM
What is the difference between Thread.sleep(10) and Thread.currentThread().sleep(10) ? Gonzalo Moreno Java 2 04-05-2004 05:41 PM
PyNew_Interpreter(): "Fatal Python error, invalid thread state for this thread" question vincent wehren Python 0 12-11-2003 08:09 PM



Advertisments