How do I handle asynchronous file and socket I/O in a Tk-based graphical user interface?
Can I combine a "select" call on some of my file objects with the Tkinter event loop?
Jun 17th, 2000 00:42
unknown unknown, Rob Hooft, Grant Edwards, Russell E. Owen
Tk file handlers
To handle asynchronous reading and writing of files and sockets in a
Tk GUI, Tk offers file handlers. The following is my attempt to
document them thoroughly. This is based on information from Grant
Edwards, who first taught me about them, my own tests and reading
about Tk. I have not yet looked at the tkinter code, and that would
probably be educational.
The subroutine call is:
Tkinter.tkinter.createfilehandler(file, stateMask, subroutine)
* file is a file or socket
* stateMask specifies the file state or states that will trigger the
file handler. It can be any of the following combined with |
* the specified file handling subroutine has the following template:
Based on the Tk documentation, the following is probably true:
* only one file handler can exist for a given file, so to handle
different states have your one file handling subroutine use the
stateMask argument to tell it what to do.
* If you call Tkinter.tkinter.createfilehandler on a file that has an
existing handler, the new handler replaces the old one. This is
* You can delete a file handler by calling deletefilehandler(socket)
* You can temporarily disable a file handler by calling it with a
stateMask of Null, then re-enable it by calling it with the desired
stateMask. This is more efficient than deleting a file handler and
Finally, the Tk documentation mentions an optional clientData
argument for file handlers. I tried to send this, as an experiment,
but got an error saying the Tkinter.tkinter.createfilehandler
subroutine wants exactly three arguments.
Here is a working example. To use, first edit in a host name, then run.
import socket, Tkinter
host = 'your.host.name.here'
# set up a window for user input
root = Tkinter.Tk()
userText = Tkinter.Entry(root, takefocus=1)
# create a TCP/IP socket to the echo port (port 7)
mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# obtain user text and write to the socket
def writeSocket (evt):
except socket.error, e:
print "send failed:", e
# read the socket and print to standard output
def readSocket (sock, stateMask):
except socket.error, e:
print "recv failed:", e
# event handler to send user data to the socket
# file handler to call readSocket when the socket has data to be read