Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 自动更新非';无法直接访问_Python_User Interface_Tkinter - Fatal编程技术网

Python 自动更新非';无法直接访问

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",

我想创建一个简单的图形用户界面,用于通过串行数据传输的常量数据。我决定用tkinter。值
读数
已更新,并应显示在标签中。我为容器和其他页面创建了单独的类。我将容器定义为:

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
a
StringVar
作为
self.label1
textvariable
吗?然后,每当更新
读取
时,标签也会更新,无需调用
frame.UpdateMe()
。我尝试了您建议的方法。窗口将显示,但标签将为空。我已经用另一个线程验证了阅读的价值正在改变。你能用你目前所做的改变更新你的问题吗?