Re: [pysystray-users] Threads and "global variable"
Status: Beta
Brought to you by:
essiene
From: Christian K. <chr...@gm...> - 2006-09-15 00:27:54
|
Hi Essien, Thanks for your response! > > I am stuck at what seems like a simple thing: I have spawned one thread > > automatically on load of the taskbar icon. That was easy. Now I need > > this thread to change it's behaviour depending on what menu items I > > selected. I have a global variable that each menu item can set, but the > > thread doesn't see it. > > > > After what I could google on it it seems the threads run in their own > > space. I found some examples for communication between threads but only > > for class-threads and not the type function-thread that pysystray uses, > > plus it seems complicated. > > > Indeed threads can't communicate via 'global' anythings really, unless > via some complex mechanisms... Windows I think builds up that frame work > for threads into a message passing system i think. must have read that > somewhere. > > What is the most simplistic approach to change a parameter "globally" so > > that the thread can see it? I tried a get_val() function but that > > doesn't work either and the thread always sees 0. > > > > The way I see, it, what you could do would be to use sockets. On UNIX i > would say use socket.AF_LOCAL but in windows, you can just use the > normal INET sockets. > > It seems to me that your on_load thread is the main thread that others > can control no? In that case, you can make it a server, that listens for > values from clients. Then each of your menu items will do a simple > socket.socket(), connect(), send(). The server picks up the message and > works with it. > > You can make this all simple by building a simple module to abstract the > client messages, so you could have: > > > foobar.client_send(foobar.COOL_VALUE) > > then in the server you could do, > > while 1: > msg = foobar_server.get_msg() > if msg == foobar.COOL_VALUE: > #meh > if msg == foobar.UNCOOL_VALUE: > #more meh! > > that's the way I would do it :) Thanks again for the suggestion, but it raised more questions from a n00b like me when it comes to Win32 programming. How do I open the socket? How do I check if a message is waiting before I get it, in case I need the thread to be always running? I actually tried to open a local socket using 'localhost' and '127.0.0.1' and got a "connection refused" error, so I gave up. However, I found an (IMHO) easier option using a queue. Here is my solution: import Queue ... msg_queue = Queue.Queue() ... @systray.threaded def my_lil_thread(): new_value = 0 while (1): if not msg_queue.empty(): new_value = msg_queue.get() if new_value == 123 # Do whatever... ... # Then in the callback for a menu item: msg_queue.put(123) # Cause my_lil_thread to do whatever I believe it works because the thread "inherits" all global objects that exist in the module at the time the thread is started (or defined, I don't know) and because msg_queue is a reference that remains static once the queue is opened, and the queue itself is a sharable object that is accessible from all threads. It is probably not the right way to do it and a Python expert might scream in horror but it works fine! :-) Cheers, Chris |