Python 自动更新非';无法直接访问
我想创建一个简单的图形用户界面,用于通过串行数据传输的常量数据。我决定用tkinter。值Python 自动更新非';无法直接访问,python,user-interface,tkinter,Python,User Interface,Tkinter,我想创建一个简单的图形用户界面,用于通过串行数据传输的常量数据。我决定用tkinter。值读数已更新,并应显示在标签中。我为容器和其他页面创建了单独的类。我将容器定义为: class Gui(Tk): def __init__(self, *args, **kwargs): Tk.__init__(self, *args, **kwargs) container = Frame(self) container.pack(side="top", fill = "both",
读数
已更新,并应显示在标签中。我为容器和其他页面创建了单独的类。我将容器定义为:
class Gui(Tk):
def __init__(self, *args, **kwargs):
Tk.__init__(self, *args, **kwargs)
container = Frame(self)
container.pack(side="top", fill = "both", expand = TRUE)
container.grid_rowconfigure(0, weight = 1)
self.frames={}
for F in (StartPage, PageOne):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row = 0, column = 0, sticky = "nsew")
frame.UpdateMe()
self.show_frame(StartPage)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
以及显示标签的页面:
class PageOne(Frame):
def __init__(self, parent, controller):
Frame.__init__(self,parent)
global reading
self.label1text = StringVar()
self.label1 = Label(self, textvariable = label1text)
self.label1.pack()
button1 = Button (self, text = "Show Start Page", command = lambda: controller.show_frame(StartPage))
button1.pack()
self.label1text.set(reading)
def UpdateMe(self):
global reading
self.lable1text.set(reading)
现在,要初始化GUI:
root = Gui()
root.mainloop()
但是,由于
mainloop()
是阻塞的,因此后面的任何参数都不会被执行;我可以通过update
和update\u idletasks
解决这个问题。然而,当我只创建了Gui()
的一个实例时,我仍然不知道如何在PageOne()中调用函数UpdateMe()
。有什么方法可以解决这个问题或者修正我对类和对象编程的理解吗?因为如果不初始化Tk()
(对于您的情况,它是Gui()
),您就无法创建StringVar
,所以需要在Gui()中创建reading
变量
和PageOne。label1
将其用作其textvariable
。以下是基于您的代码的示例:
from tkinter import *
from random import randint
class Gui(Tk):
def __init__(self, *args, **kwargs):
Tk.__init__(self, *args, **kwargs)
container = Frame(self)
container.pack(side="top", fill="both", expand=True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.reading = StringVar() # create the StringVar for PageOne
self.frames = {}
for F in (StartPage, PageOne):
frame = F(container, self)
frame.grid(row=0, column=0, sticky="nsew")
self.frames[F] = frame
self.show_frame(StartPage)
def show_frame(self, cont):
self.frames[cont].tkraise()
class StartPage(Frame):
def __init__(self, parent, controller):
Frame.__init__(self, parent)
button1 = Button (self, text="Show Page 1", command=lambda: controller.show_frame(PageOne))
button1.pack(fill="both", expand=True)
class PageOne(Frame):
def __init__(self, parent, controller):
Frame.__init__(self, parent)
self.label1 = Label(self, textvariable=controller.reading) # refer to Gui.reading StringVar
self.label1.pack(fill='x')
button1 = Button (self, text="Show Start Page", command=lambda: controller.show_frame(StartPage))
button1.pack(fill='x')
# use .after() to simulate the update of reading variable periodically
def update_reading():
app.reading.set(randint(0, 10000))
print('reading:', app.reading.get())
app.after(1000, update_reading)
app = Gui()
update_reading() # start the simulation task of updating reading variable
app.mainloop()
请注意,我创建了一个函数update\u reading()
,以模拟使用after()
函数定期更新reading
变量。因为在不初始化Tk()
的情况下无法创建StringVar
(对于您的情况,它是Gui()
),因此,您需要在Gui()和PageOne中创建reading
变量。label1
将其用作其textvariable
。以下是基于您的代码的示例:
from tkinter import *
from random import randint
class Gui(Tk):
def __init__(self, *args, **kwargs):
Tk.__init__(self, *args, **kwargs)
container = Frame(self)
container.pack(side="top", fill="both", expand=True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.reading = StringVar() # create the StringVar for PageOne
self.frames = {}
for F in (StartPage, PageOne):
frame = F(container, self)
frame.grid(row=0, column=0, sticky="nsew")
self.frames[F] = frame
self.show_frame(StartPage)
def show_frame(self, cont):
self.frames[cont].tkraise()
class StartPage(Frame):
def __init__(self, parent, controller):
Frame.__init__(self, parent)
button1 = Button (self, text="Show Page 1", command=lambda: controller.show_frame(PageOne))
button1.pack(fill="both", expand=True)
class PageOne(Frame):
def __init__(self, parent, controller):
Frame.__init__(self, parent)
self.label1 = Label(self, textvariable=controller.reading) # refer to Gui.reading StringVar
self.label1.pack(fill='x')
button1 = Button (self, text="Show Start Page", command=lambda: controller.show_frame(StartPage))
button1.pack(fill='x')
# use .after() to simulate the update of reading variable periodically
def update_reading():
app.reading.set(randint(0, 10000))
print('reading:', app.reading.get())
app.after(1000, update_reading)
app = Gui()
update_reading() # start the simulation task of updating reading variable
app.mainloop()
请注意,我创建了一个函数update\u reading()
,用after()
函数模拟定期更新reading
变量。您能将reading
设为StringVar
并将其用作self.label1
的textvariable
吗?然后,每当更新读取
时,标签也会更新,无需调用frame.UpdateMe()
。我尝试了您建议的方法。窗口将显示,但标签将为空。我已经通过使用另一个线程验证了reading的值正在更改。您能用您目前的更改更新您的问题吗?您能将reading
aStringVar
作为self.label1
的textvariable
吗?然后,每当更新读取
时,标签也会更新,无需调用frame.UpdateMe()
。我尝试了您建议的方法。窗口将显示,但标签将为空。我已经用另一个线程验证了阅读的价值正在改变。你能用你目前所做的改变更新你的问题吗?