Reputation: 3
I'm trying to get dynamic cyclic (every half a second) label updates from a Webservice in Python where I parse a JSON string and return its contents to the GUI (made with Glade 3.8.1).
I have started from a basic example and the code I've written so far looks like this:
import sys
import json
import urllib2
import time
try:
import pygtk
pygtk.require("2.0")
except:
pass
try:
import gtk.glade
import gtk
except:
sys.exit(1)
class cRioHMI():
def on_MainWindow_destroy(self, data = None):
print "quit with cancel"
gtk.main_quit()
def on_gtk_quit_activate(self, data = None):
print "quit from menu"
gtk.main_quit()
def on_btnTest_clicked(self, widget):
print "Button Pressed"
def on_gtk_about_activate(self, data = None):
print "About Page Accessed"
self.response = self.about.run()
self.about.hide()
def __init__(self):
self.gladefile = "Assets/HMI.glade"
self.builder = gtk.Builder()
self.builder.add_from_file(self.gladefile)
self.builder.connect_signals(self)
self.window = self.builder.get_object("MainWindow")
self.about = self.builder.get_object("AboutDialogue")
self.templable = self.builder.get_object("lbl_Temperature")
self.window.show()
def update_Values(self, data = None):
response = urllib2.urlopen('http://10.10.10.11:8001/WebUI/Temperatures/GetTemperatures')
data = json.load(response)
temperature = data['Temperature2'][1]
self.templable.set_text(str(temperature))
time.sleep(.5)
if __name__ == "__main__":
HMI = cRioHMI()
gtk.main()
When I use the code from the update_Values method on a click event, the code performs as expected
def on_btnTest_clicked(self, widget):
response = urllib2.urlopen('http://10.10.10.11:8001/WebUI/Temperatures/GetTemperatures')
data = json.load(response)
temperature = data['Temperature2'][1]
self.templable.set_text(str(temperature))
time.sleep(.5)
print "Button Pressed"
What is the best way to do that? Please note, that I'm new to python.
Upvotes: 0
Views: 720
Reputation: 2258
You can use gobject.timeout_add
(see the documentation here).
So in your __init__
you would have something like gobject.timeout_add(1000, self.updateValues)
. If you return False the timeout will not be called again.
You should also not use time.sleep
. This is a blocking call. That means your GUI will freeze as it cannot handle incoming events. The same thing will happen with the urllib2.urlopen
call, if it takes too much time. To prevent this you can run updateValues in a separate Thread. Then you would have to use gobject.idle_add
to set the text of the label (see documentation).
Here is a small example. It is just a counter (and would not need threading) but I marked the place where your urllib2.urlopen would go with a comment:
#!/usr/bin/env python2
from threading import Thread
from pygtk import gtk, gobject
class Window(gtk.Window):
def __init__(self):
gtk.Window.__init__(self)
self.connect('delete-event', gtk.main_quit)
self.label = gtk.Label('1')
self.add(self.label)
gobject.timeout_add_seconds(1, self.threaded)
def threaded(self):
thread = Thread(target=self.updateValues)
thread.start()
return True
def updateValues(self):
# urllib.urlopen calls
n = int(self.label.get_text())
gobject.idle_add(self.label.set_text, str(n + 1))
win = Window()
win.show_all()
gobject.threads_init()
gtk.main()
Upvotes: 2