Tkinter/threading issue
Thomas Jollans
thomas at jollybox.de
Sun Aug 15 16:28:44 EDT 2010
On Sunday 15 August 2010, it occurred to Jerrad Genson to exclaim:
> Hello,
>
> I'm learning Tkinter, and I have an issue that I'd appreciate help
> with. I have a program that initializes a GUI (I'll call this the "GUI
> process"), then spawns another process that listens on a network via
> the TCP/IP protocol for incoming strings (I'll call this the "server
> process"). Everything works well up to this point.
Okay, so you want your TCP (or is it UDP? not that it matters - but "TCP/IP"
is not a protocol) server to sit in a separate process. May I ask why? Either
way, you first need to trigger something inside the GUI process when a network
packet arrives. The easiest way would of course be to have the server in the
same process...
Anyway, IPC. You say you're using Ubuntu. If you're only targetting UNIX-like
systems, you can use os.fork() to create the new process -- you're probably
doing so anyway (?) -- and use socket.socketpair or os.pipe to create a pipe
between parent and child. If you're launching the process with
subprocess.Popen, you can simply use the standard files (stdin, stdout,...) as
a pipe. If the processes are completely separate, you'd need to use some
convention to create a socket between the two, eithe a AF_LOCAL/AF_UNIX
socket, or, if you want to support Windows and the likes, a local loopback TCP
socket (->127.0.0.1)
Once you've got a pipe between the two processes - or the network server
within your GUI process - you just have to wait for a message to come flying
in, and then update the widget.
There are a couple of ways of waiting for a message without disrupting the
GUI: you can either create a separate thread in which you, wait for input, or
you can add a piece of code to the main loop (I don't know how difficult this
is with Tkinter -- shouldn't be too tricky) that checks if there's any news,
typically by calling select.select with a zero timeout.
>
> What I want to happen next is for the server process to update a label
> in the GUI process when it receives a message from the network. First
> I tried passing a control variable for the label's text into the
> server process, but when I updated the control variable, nothing
> happened(no error messages, no feedback of any kind).
>
> I tried piping the message from the server process into the GUI
> process using os.write() and os.read() - and this works, but not the
> way I need it to. I need the label to be updated automatically,
> without any intervention from the user (at the moment, it only works
> when the user clicks an "Update" button). I tried having the GUI
> process check the pipe for messages automatically, but when I do this
> it hangs when there's nothing in the pipe.
>
> I've tried other avenues as well, but probably nothing worth
> mentioning. If you have any suggestions, I would be very grateful.
More information about the Python-list
mailing list