【问题标题】:In tkinter, how can I access variables created in one window in a different one?在 tkinter 中,如何访问在另一个窗口中创建的变量?
【发布时间】:2015-11-19 03:16:07
【问题描述】:

我似乎不知道如何在我的应用程序的一个窗口中创建或修改变量,然后在另一个窗口中访问它。另外,如何在 StartPage 中的 spinboxes 上检索选定的值?

这是我正在使用的代码:

import tkinter as tk

TITLE_FONT = ("Helvetica", 18, "bold")

class SampleApp(tk.Tk):

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

        # the container is where we'll stack a bunch of frames
        # on top of each other, then the one we want visible
        # will be raised above the others
        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 F in (StartPage, PageOne, PageTwo):
            frame = F(container, self)
            self.frames[F] = frame
            # put all of the pages in the same location;
            # the one on the top of the stacking order
            # will be the one that is visible.
            frame.grid(row=0, column=0, sticky="nsew")

        self.show_frame(StartPage)

    def show_frame(self, c):
        '''Show a frame for the given class'''
        frame = self.frames[c]
        frame.tkraise()


class StartPage(tk.Frame):

    def __init__(self, parent, controller):

        tk.Frame.__init__(self, parent)
        label = tk.Label(self, text="CALCULO DE PRECIOS", font=TITLE_FONT)
        label.pack(side="top", fill="x", pady=10)

        test1 = tk.Spinbox(self, values=(1, 2, 4, 8))
        test1.pack()

        test2 = tk.Spinbox(self, values=(1, 2, 4, 8))
        test2.pack()

        button1 = tk.Button(self, width=20, text="Calculo Final",
                            command=lambda: controller.show_frame(PageOne))
        button2 = tk.Button(self, width=20, text="Calculo Actividades",
                            command=lambda: controller.show_frame(PageTwo))
        button1.pack()
        button2.pack()

class PageOne(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        label = tk.Label(self, text="CALCULO FINAL", font=TITLE_FONT)
        label.pack(side="top", fill="x", pady=10)
        button = tk.Button(self, width=20, text="Volver al menu principal",
                           command=lambda: controller.show_frame(StartPage))
        button.pack()




class PageTwo(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        label = tk.Label(self, text="CALCULO ACTIVIDADES", font=TITLE_FONT)
        label.pack(side="top", fill="x", pady=10)
        button = tk.Button(self, width=20, text="Volver al menu principal",
                           command=lambda: controller.show_frame(StartPage))
        button.pack()


if __name__ == "__main__":
    app = SampleApp()
    app.mainloop()

【问题讨论】:

    标签: python class user-interface variables tkinter


    【解决方案1】:

    由于您创建的每个窗口都是具有对控制器的引用的类的实例,因此可以通过在控制器上设置值来在窗口之间传递变量。

    例如,在从PageOne 创建的窗口中,您可以像这样在控制器上设置一个值: 在init 中,确保在PageOnePageTwo 两个类中存储对控制器的引用:

    self.controller = controller
    

    当你想要传递一个变量时,你可以在控制器对象上设置它:

    self.controller.value = "value"
    

    在从PageTwo 创建的窗口中,您可以像这样访问这个值:

    value_from_other_window = self.controller.value
    

    要回答您的其他问题,要从 spinbox 访问值,您需要有 spinbox 对象的引用。我建议您将这些保留为 PageOnePageTwo 类的实例变量:

    self.test1 = tk.Spinbox(self, values=(1, 2, 4, 8))
    

    当需要访问值时,可以调用:

    self.test1.get()
    

    您可能不应该有两个类PageOnePageTwo,因为它们中的每一个似乎都有完全相同的代码,但对于标签文本。您可以考虑在 init 中添加另一个参数,即标签文本。

    【讨论】:

      【解决方案2】:

      我已修改您的代码,以使用旋转框小部件的特性检索 StartPage 类中旋转框的选定值,并在按钮回调中打印 PageOne 和 PageTwo 类中的当前值:

      import tkinter as tk
      TITLE_FONT = ("Helvetica", 18, "bold")
      class SampleApp(tk.Tk):
          def __init__(self, *args, **kwargs):
              tk.Tk.__init__(self, *args, **kwargs)
              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.varSpin1=1
              self.varSpin2=1
      
              self.frames = {}
              for F in (StartPage, PageOne, PageTwo):
                  frame = F(container, self)
                  self.frames[F] = frame
                  frame.grid(row=0, column=0, sticky="nsew")
              self.show_frame(StartPage)
      
          def show_frame(self, c):
              '''Show a frame for the given class'''
              frame = self.frames[c]
              frame.tkraise()
              #print("spinbox values: %d %d"%(self.varSpin1,self.varSpin2))
      
      class StartPage(tk.Frame):
          def setVarSpin1(self,v):
              self.controller.varSpin1=v
          def setVarSpin2(self,v):
              self.controller.varSpin2=v
          def __init__(self, parent, controller):
              tk.Frame.__init__(self, parent)
              label = tk.Label(self, text="CALCULO DE PRECIOS", font=TITLE_FONT)
              label.pack(side="top", fill="x", pady=10)
              self.controller=controller
              val1 = tk.IntVar()
              val2 = tk.IntVar()
              self.test1 = tk.Spinbox(self, values=(1,2,4,8), textvariable=val1,
                                      command=lambda:self.setVarSpin1(val1.get())).pack()
              self.test2 = tk.Spinbox(self, values=(1,2,4,8), textvariable=val2,
                                      command=lambda:self.setVarSpin2(val2.get())).pack()
              button1 = tk.Button(self, width=20, text="Calculo Final",
                                  command=lambda: controller.show_frame(PageOne)).pack()
              button2 = tk.Button(self, width=20, text="Calculo Actividades",
                                  command=lambda: controller.show_frame(PageTwo)).pack()
      
      class PageOne(tk.Frame):
          def callback(self):
              print("PageOne: spinbox values: %d %d"%(self.controller.varSpin1,self.controller.varSpin2))
              self.controller.show_frame(StartPage)
          def __init__(self, parent, controller):
              tk.Frame.__init__(self, parent)
              label = tk.Label(self, text="CALCULO FINAL", font=TITLE_FONT)
              label.pack(side="top", fill="x", pady=10)
              button = tk.Button(self, width=20, text="Volver al menu principal",
                                 command=lambda:self.callback()).pack()
              self.controller=controller        
      
      class PageTwo(tk.Frame):
          def callback(self):
              print("PageTwo: spinbox values: %d %d"%(self.controller.varSpin1,self.controller.varSpin2))
              self.controller.show_frame(StartPage)   
          def __init__(self, parent, controller):
              tk.Frame.__init__(self, parent)
              label = tk.Label(self, text="CALCULO ACTIVIDADES", font=TITLE_FONT)
              label.pack(side="top", fill="x", pady=10)
              button = tk.Button(self, width=20, text="Volver al menu principal",
                                 command=lambda:self.callback()).pack()
              self.controller=controller
      
      if __name__ == "__main__":
          app = SampleApp()
          app.mainloop()
      

      【讨论】:

        猜你喜欢
        • 2021-05-19
        • 2016-10-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-05-18
        相关资源
        最近更新 更多