Tkinter无法更新标签文本

时间:2019-10-09 11:05:43

标签: python user-interface tkinter

我正在尝试将GPS传感器与RPI一起使用,并使用Tkinter使其GUI成为可能。我想更新我的GPS值并在GUI中显示。但是在GUI中,它仅显示初始值。在后端,GPS值正在更新,但无法在GUI中显示。

import tkinter as tk
import serial
import time
import webbrowser as wb


ser = serial.Serial('/dev/ttyUSB0', 9600)

class IotCar(tk.Tk):

    def __init__(self, *args, **kwargs):

        tk.Tk.__init__(self, *args, **kwargs)

        width=tk.Tk.winfo_screenwidth(self)
        height=tk.Tk.winfo_screenheight(self)
        tk.Tk.geometry(self, '{}x{}'.format(width, height))


        container=tk.Frame(self)
        container.pack(side='top', fill='both', expand='True')
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)
        self.frames = {}
        for each_frame in (StartPage, HomePage):
            frame = each_frame(container, self)
            self.frames[each_frame]=frame
            frame.grid(row=0, column=0, sticky='nsew')
        self.show_page(StartPage)

    def show_page(self, cont):

        frame=self.frames[cont]
        frame.tkraise()

class StartPage(tk.Frame):

    def __init__(self, parent, controller):

        tk.Frame.__init__(self, parent)
        next_button = tk.Button(self, text='Next', command=lambda:
                                controller.show_page(HomePage)).pack(side=tk.TOP,padx=5, pady=5)
class HomePage(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.gps_pos()
        self.lat1 = tk.StringVar()
        self.lon1=tk.StringVar(self)
        self.label_lat = tk.Label(self.HomePage, text='Latitude', justify=tk.LEFT, padx=10).pack()
        self.label_lat1 = tk.Label(self.HomePage, textvariable=self.lat1, justify=tk.LEFT,
                              borderwidth=2, relief='ridge').pack()
        self.label_lon = tk.Label(self, text='Longitude', justify=tk.LEFT, padx=10).pack()
        self.label_lon1 = tk.Label(self, text=self.lon1, justify=tk.LEFT,
                             borderwidth=2, relief='ridge').pack()

    def gps_pos(self):
        print('Entered into gps')
        ser.flushInput()
        ser.flushOutput()
        ser.write(b'AT+CGPSPWR=1\r')
        ser.write(b'AT+CGPSOUT=32\r')
        while True:
            gps=str(ser.readline())
            gps=gps[2:].split(',')
            if gps[0]=='$GPRMC' and gps[3]!='':
                lat=gps[1]
                lon=gps[1]
                break;
        self.after(3000,self.gps_pos)
        print(lat, lon)
        self.lat1.set(lat1)
app = IotCar()
app.mainloop()

请帮助我了解其中的错误。预先谢谢你。

1 个答案:

答案 0 :(得分:0)

由于我没有串行模块,所以我无法运行此脚本,但是我修改了一些内容,这在标签中填充了文本(代码中的注释)。您需要一个函数,该函数将为标签中的“文本”参数分配一个值。

import tkinter as tk
import time
import webbrowser as wb


class IotCar(tk.Tk):

    def __init__(self, *args, **kwargs):

        tk.Tk.__init__(self, *args, **kwargs)

        width=tk.Tk.winfo_screenwidth(self)
        height=tk.Tk.winfo_screenheight(self)
        tk.Tk.geometry(self, '{}x{}'.format(width, height))


        container=tk.Frame(self)
        container.pack(side='top', fill='both', expand='True')
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)
        self.frames = {}
        for each_frame in (StartPage, HomePage):
            frame = each_frame(container, self)
            self.frames[each_frame]=frame
            frame.grid(row=0, column=0, sticky='nsew')
        self.show_page(StartPage)

    def show_page(self, cont):

        frame=self.frames[cont]
        frame.tkraise()

class StartPage(tk.Frame):

    def __init__(self, parent, controller):

        tk.Frame.__init__(self, parent)
        next_button = tk.Button(self, text='Next', command=lambda:
                                controller.show_page(HomePage)).pack(side=tk.TOP,padx=5, pady=5)
class HomePage(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)

        self.lat1 = tk.StringVar()
        self.lon1 = tk.StringVar(self)
        self.label_lat = tk.Label(self, text='Latitude', justify=tk.LEFT, padx=10)
        self.label_lat.pack()

        self.label_lat1 = tk.Label(self, justify=tk.LEFT,
                              borderwidth=2, relief='ridge') # I have removed the "text" parameter because my function will update it.
        self.label_lat1.pack()

        self.label_lon = tk.Label(self, text='Longitude', justify=tk.LEFT, padx=10)
        self.label_lon.pack()
        self.label_lon1 = tk.Label(self, justify=tk.LEFT,
                             borderwidth=2, relief='ridge') # I have removed the "text" parameter because my function will update it.
        self.label_lon1.pack()
        button = tk.Button(self, text="update label", bg= "#aaaaaa", fg ="#483F44",
         font=("Arial", 10, "bold"), relief="groove", command = lambda: helloworld()) # This button will run the helloworld function
        button.pack()

        def helloworld():
            self.label_lat1["text"] = "Hello" #This will update the text parameter in label_lat1 with "Hello"
            self.label_lon1["text"] = "World" #This will update the text parameter in label_lon1 with "World"

app = IotCar()
app.mainloop()

需要注意的几件事是,与定义其参数时分开包装/放置/栅格化标签,我认为您当前设置小部件的方式是给它提供None类型,这就是为什么您不能分配它的原因发短信给它:

#You write
self.label_lat1 = tk.Label(self.HomePage, textvariable=self.lat1, justify=tk.LEFT,
                              borderwidth=2, relief='ridge').pack()

#My example
self.label_lat1 = tk.Label(self, justify=tk.LEFT,
                              borderwidth=2, relief='ridge')
self.label_lat1.pack()

然后,您需要一个将运行一个函数的命令,并且在该函数中将具有一个变量,该变量将为标签分配文本值(即,我的代码中的helloworld函数)。

查看您的代码,我相信您将需要修改打包小部件的方式,然后在函数中执行类似的操作

def gps_pos(self):

    print(lat, lon)
    self.label_lat1["text"] = lat 
    self.label_lon1["text"] = lon

以下是有关如何布局tkinter gui和其他常见问题解答的非常有用的答案。我自己发现它非常有用 Switch between two frames in tkinter