【问题标题】:How to pass the 2D array from one class to another in Tkinter?如何在 Tkinter 中将二维数组从一个类传递到另一个类?
【发布时间】:2017-10-16 19:09:49
【问题描述】:

我正在尝试使用 Tkinter 编写我的第一个应用程序。我根本无法理解如何将二维数组(由用户输入)中的变量数据从一个类传递到另一个类。试图改变一些东西,但没有结果。我将非常感谢任何帮助或建议。

from Tkinter import *

date_index = [2017, 2018, 2019, 2020, 2021]
product_name = ['product 1', 'product 2', 'product 3', 'product 4', 'product 5']

class main: 
    def __init__(self, master):
        self.master = master
        self.master.title('revenue calc')

        Button(self.master, text = 'quantity', command=self.q_button).pack()
        Button(self.master, text = 'prices', command=self.p_button).pack()

        self.master.mainloop()

    def q_button(self):
        q_child(self.master)

    def p_button(self):
        p_child(self.master)

class q_child:
    def __init__(self, master):
        self.slave = Toplevel(master)
        self.slave.title('quantity')

        self.corner_frame = Frame(self.slave)
        self.corner_frame.grid(row=0, column=0)

        self.left_frame = Frame(self.slave)
        self.left_frame.grid(row=1, column=0)

        self.head_frame = Frame(self.slave)
        self.head_frame.grid(row=0, column=1)

        self.main_frame = Frame(self.slave)
        self.main_frame.grid(row=1, column=1)

        self.button_frame = Frame(self.slave)
        self.button_frame.grid(row=2, column=1)


        for i in range(len(product_name)):
            self.testlabel = Label(self.left_frame, text = product_name[i])
            self.testlabel.grid(row=i, column=0)

        for j in range(len(date_index)):
            self.testlabel1 = Label(self.head_frame, width = 5, text = date_index[j])
            self.testlabel1.grid(row=0, column=j)

        self.q0 = []

        for j in range(len(date_index)):
            self.q0.append([])
            for i in range(len(product_name)):
                self.q0[j].append(Entry(self.slave, width = 5, text=""))
                self.q0[j][i].grid(row=j, column=i, in_ = self.main_frame)

        self.save_q_button = Button(self.button_frame, text = 'save', command = self.save_q_data)
        self.save_q_button.pack()

    def save_q_data(self):
        self.q = []

        for j in range(len(date_index)):
            self.q.append([])
            for i in range(len(product_name)):  
                self.q[j].append(float(self.q0[j][i].get()))

class p_child:
    def __init__(self, master):
        self.slave = Toplevel(master)
        self.slave.title('prices')

        self.corner_frame = Frame(self.slave)
        self.corner_frame.grid(row=0, column=0)

        self.left_frame = Frame(self.slave)
        self.left_frame.grid(row=1, column=0)

        self.head_frame = Frame(self.slave)
        self.head_frame.grid(row=0, column=1)

        self.main_frame = Frame(self.slave)
        self.main_frame.grid(row=1, column=1)

        self.button_frame = Frame(self.slave)
        self.button_frame.grid(row=2, column=1)


        for i in range(len(product_name)):
            self.testlabel = Label(self.left_frame, text = product_name[i])
            self.testlabel.grid(row=i, column=0)

        for j in range(len(date_index)):
            self.testlabel1 = Label(self.head_frame, width = 5, text = date_index[j])
            self.testlabel1.grid(row=0, column=j)

        self.p0 = []

        for j in range(len(date_index)):
            self.p0.append([])
            for i in range(len(product_name)):
                self.p0[j].append(Entry(self.slave, width = 5, text=""))
                self.p0[j][i].grid(row=j, column=i, in_ = self.main_frame)

        self.save_p_button = Button(self.button_frame, text = 'save', command = self.save_p_data)
        self.save_p_button.pack()

    def save_p_data(self):
        self.rev = []
        self.revall = []
        self.p = []

        for j in range(len(date_index)):
            self.rev.append([])
            self.p.append([])
            self.s = 0
            for i in range(len(product_name)):  
                self.p[j].append(float(self.p0[j][i].get()))
                self.rev[j].append(self.p[j][i]*q[j][i]) # NameError: global name 'q' is not defined
                self.s += self.rev[j][i]
            self.revall.append(self.s)  

root = Tk()
main(root) 

【问题讨论】:

  • 发布您的错误/输出。
  • NameError:未定义全局名称“q”。但是当我尝试在主类中定义它时,它会“破坏”来自子类的所有输入。
  • 我还可以添加以下预期输出。对于 q_child - 2D 数组:q = [[...q1i...][...q2i...]...]。对于 p_child:p = [[...p1i...][...p2i...]...],rev = [[...q1ip1i...][...q2ip2i...] ...]。第一和第二没有问题。最后一个产生错误。

标签: python arrays python-2.7 tkinter


【解决方案1】:

请参阅下面的代码简化版本,它显示了如何将数据(在本例中为单个条目框的文本)从 TopLevel() 窗口传回主窗口。

基本上,在您的q_child 类中,您将要返回的数据存储在一个名为self.data 的属性中,这样当您返回主类时,您可以通过调用@987654324 来访问它@。

您甚至可以将这些数据存储在主窗口的master 属性中,命名为q_data,以便可以在p_child 类中通过master.q_data 访问它

import Tkinter as tk

class main: 
    def __init__(self, master):
        self.master = master
        self.master.q_data = "No data entered"
        tk.Button(self.master, text='quantity', command=self.q_button).pack()
        tk.Button(self.master, text='prices', command=self.p_button).pack()
        self.master.mainloop()

    def q_button(self):
        # Create a TopLevel window to get user input
        q = q_child(self.master)
        # Wait for the user to close the TopLevel window
        self.master.wait_window(q.slave)
        # Store the data input by the user in the main window's "master" attribute
        self.master.q_data = q.data

    def p_button(self):
        # Create a TopLevel window to use the user input data
        p = p_child(self.master)
        # Wait for the user to close the TopLevel window
        self.master.wait_window(p.slave)

class q_child:
    def __init__(self, master):
        # Create a TopLevel window, and grab focus
        self.slave = tk.Toplevel(master)
        self.slave.grab_set()

        # Add an Entry box and a button
        self.q_entry = tk.Entry(self.slave, text="")
        self.q_entry.pack()
        tk.Button(self.slave, text='save', command=self.save_q_data).pack()

        # Initialize the data to be returned
        self.data = "No data entered"

    def save_q_data(self):
        # Update the data to be returned with the Entry box content
        self.data = self.q_entry.get()
        # Close the TopLevel window
        self.slave.destroy()

class p_child:
    def __init__(self, master):
        # Create a TopLevel window, and grab focus
        self.slave = tk.Toplevel(master)
        self.slave.grab_set()

        # Retrieve the user-input data from the "master"
        q_data = master.q_data
        # Show the data on a label
        tk.Label(self.slave, text=q_data).pack()
        # Add a button to go back
        tk.Button(self.slave, text='back', command=self.slave.destroy).pack()

root = tk.Tk()
main(root)

重要提示self.master.wait_window(q.slave) 确保主类在继续运行之前等待 TopLevel 窗口关闭。

【讨论】:

  • 感谢您的回答!但我仍然不明白如何在 p_child 类中使用 q.data 。当我尝试这样做时,会发生同样的错误:“NameError:未定义全局名称'q'”。我怎样才能避免这种情况?
  • 我更新了我的答案,向您展示如何从 p 窗口中的 q 窗口访问数据,方法是将其存储在他们共同的 master 中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-15
  • 2013-04-12
  • 1970-01-01
相关资源
最近更新 更多