| FAQ Index - Search - Recent Changes - Everything - Add entry |
20.16. So how do I use gobject.io_add_watch (used to be input_add) ?
this will get and print index.html's html source without blocking or freezing your GUI (notice that if there are no special requirements, FAQ 20.21 explains how to do the same thing in a simpler and cleaner way):
import socket
import gobject
import gtk
def handle_data(source, condition):
data = source.recv(1024)
if len(data) > 0:
return True # run again
else:
return False # stop looping (or else gtk+ goes CPU 100%)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(15)
sock.connect(('pygtk.org', 80))
sock.send('GET /index.html HTTP/1.1\nHost: pygtk.org\n\n')
gobject.io_add_watch(sock, gobject.IO_IN, handle_data)
w = gtk.Window()
w.add(gtk.Button('abc'))
w.show_all()
gtk.main()
io_add_watch() can watch on objects return by urllib.urlopen() too. However, the urlopen() operation takes some time, hence freezing the GUI for a fraction of second.
Please keep in mind that io_add_watch() works for sockets on all platforms, but if you want to watch files you have to use GNU/Linux or other Unices
Advanced Usage:
as you can see once you get EOF gtk+ forces you to give up on reading more possible stuff there. That is not sane for all usages but it's what it's done. I sat down and tried to workaround this. I ended up with something I hope you will find useful:
import socket
import gobject
import gtk
import signal
def get_file():
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(15)
sock.connect(('pygtk.org', 80))
sock.send('GET /index.html HTTP/1.1\nHost: pygtk.org\n\n')
return sock
def handle_data(source, condition):
data = source.recv(12)
print len(data)
if len(data) > 0:
return True #run forever
else:
print 'closed'
print 'so get new data...'
sock = get_file()
gobject.io_add_watch(sock, gobject.IO_IN, handle_data)
return False # stop looping
sock = get_file()
gobject.io_add_watch(sock, gobject.IO_IN, handle_data)
w = gtk.Window()
w.set_border_width(15)
msg = '''\
Play with resizing the window...
RESULT:
It will only block on sock.connect()
which is normal because to use the socket you have to connect
here we wait for maximum 15 seconds and then we timeout'''
w.add(gtk.Label(msg))
w.show_all()
signal.signal(signal.SIGINT, signal.SIG_DFL) # ^C exits the application
gtk.main()
