En Fri, 13 Mar 2009 17:59:34 -0200, <aloons...@gmail.com> escribió:
On 12 mrt, 18:43, "Gabriel Genellina" <gagsl-...@yahoo.com.ar> wrote:
En Thu, 12 Mar 2009 07:21:35 -0200, <arn...@sphaero.org> 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.net/viewvc/retypingdante/trunk/inferno/src/rtd_Wkeylog.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

--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to