FAQ Index - Search - Recent Changes - Everything - Add entry

<< Previous Entry | FAQ Entry 20.16 | Next 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()

PyGTK FAQ Wizard | PyGTK Homepage | Feedback to faq at pygtk.org