0

I have the following script which outputs altitude data from the gpsd module to the console and keeps it up to date. I would like to display the same data within a tkinter interface but whatever i've tried I can't seem to get it to refresh the data like the console does. It outputs the initial data ok but doesn't give me the latest data. I'm very much a novice so maybe i'm doing something stupid.

I've attached the initial code that just outputs to the console as that it what i'm basing it on.

Thanks, Dan.

import os
from gps import *
from time import *
import time
import threading


gpsd = None #seting the global variable

os.system('clear') #clear the terminal (optional)

class GpsPoller(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        global gpsd #bring it in scope
        gpsd = gps(mode=WATCH_ENABLE) #starting the stream of info
        self.current_value = None
        self.running = True #setting the thread running to true

    def run(self):
        global gpsd
        while gpsp.running:
            gpsd.next() #this will continue to loop and grab EACH set of gpsd info to clear the buffer

if __name__ == '__main__':
    gpsp = GpsPoller() # create the thread
    try:
        gpsp.start() # start it up
        while True:

            os.system('clear')

            print 'altitude (m)' , gpsd.fix.altitude

            time.sleep(5) #set to whatever

    except (KeyboardInterrupt, SystemExit): #when you press ctrl+c
        print "\nKilling Thread..."
        gpsp.running = False
        gpsp.join() # wait for the thread to finish what it's doing
    print "Done.\nExiting."

1 Answers1

0

Assuming that gpsd.next() is relatively fast (under 200ms or so), you don't need threading to make it work with tkinter. You can use the event loop to run a job periodically. If gpsd.next() takes a long time, you might want to use a thread or multiprocessing, because this technique will make the GUI lag every time the function is called if the function takes a human-perceptible amount of time to run.

The following example shows how to update the data every second using the tkinter event loop to do the polling. You can change the speed by changing the first argument to self.after. I don't have the gps module installed so I am unable to test the code, but this gives the general idea:

import Tkinter as tk
import gps

class Example(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)

        self.gps_label = tk.Label(self, text="", width=40)
        self.gps_label.pack(fill="both", expand=True, padx=20, pady=20)

        # initialize gps
        self.gpsd = gps.gps(mode=WATCH_ENABLE)
        self._update_gps_data()

    def _update_gps_data(self):
        data = self.gpsd.next()
        self.gps_label.configure(text="gps data: " + data)

        # run again in one second (1000 ms)
        self.after(1000, self._update_gps_data)

if __name__ == "__main__":
    root = tk.Tk()
    Example(root).pack(fill="both", expand=True)
    root.mainloop()
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685