faqts : Computers : Programming : Languages : Python : Tkinter : Events

+ Search
Add Entry AlertManage Folder Edit Entry Add page to http://del.icio.us/
Did You Find This Entry Useful?

21 of 25 people (84%) answered Yes
Recently 10 of 10 people (100%) answered Yes

Entry

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)
where:
* 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 | 
(bit-wise OR):
   Tkinter.tkinter.READABLE
   Tkinter.tkinter.WRITABLE
   Tkinter.tkinter.EXCEPTION
* the specified file handling subroutine has the following template:
   subroutine(file, stateMask)
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 
prefectly acceptable.
* 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 
re-creating it.
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)
userText.pack()
userText.focus_set()
# create a TCP/IP socket to the echo port (port 7)
mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
mysock.connect((host,7))
# obtain user text and write to the socket
def writeSocket (evt):
        try:
                mysock.send (userText.get())
        except socket.error, e:
                print "send failed:", e
        userText.delete(0,Tkinter.END)
# read the socket and print to standard output
def readSocket (sock, stateMask):
        try:
                print sock.recv(1000)
        except socket.error, e:
                print "recv failed:", e
# event handler to send user data to the socket
userText.bind('<KeyPress-Return>', writeSocket)
# file handler to call readSocket when the socket has data to be read
Tkinter.tkinter.createfilehandler(mysock, Tkinter.tkinter.READABLE, 
readSocket)
root.mainloop()