将用户输入从子窗口传递到父窗口python tkin

2024-04-26 20:52:58 发布

您现在位置:Python中文网/ 问答频道 /正文

我对Python很陌生,对tkinter更是新手。我一直在寻找这个问题的答案,得到了一些看起来很接近的东西,但没有一件是我能够成功实现的。在

基本上,我要做的是创建一个主窗口,其中有一个下拉列表供用户从中选择一个项目。当用户进行选择时,会进行简单的计算并将结果打印到屏幕上。其中一个选项是“用户定义”。当进行此选择时,我想使用Toplevel创建一个子窗口,允许用户进行一些输入并单击“确定”,此时将完成相同的计算,并在主窗口上显示相同的数据,就像他们选择了一个预定义的选项一样。在

我可以让窗口随意打开和关闭,但是当用户定义了一个新项时,我无法将他们的输入传递回主程序以进行必要的计算(这样就很容易显示)。如何将用户输入传递回主窗口?在

在下面的示例代码中,对于下拉列表中的前3个项目,一切都正常,但是对于用户定义的,它什么也不做,因为我不知道如何返回用户输入的值来执行计算。在

提前感谢您的任何帮助/建议。在

import tkinter as tk
from tkinter import ttk
import numpy as np


class MainGUI:
    def __init__(self, master):
        self.master = master
        master.title('Bolted Joint Analysis')
        master.geometry('500x500')

        # Adds tabs to main window
        self.nb = ttk.Notebook(master)
        self.nb.grid(row=1, column=0, columnspan=50, rowspan=49, sticky='NESW')
        self.tab1 = ttk.Frame(self.nb)
        self.nb.add(self.tab1, text='Tab1')
        self.tab2 = ttk.Frame(self.nb)
        self.nb.add(self.tab2, text='Tab2')

        # defines a grid 50 x 50 cells in the main window & tabs
        rows = 0
        while rows < 50:
            master.rowconfigure(rows, weight=1)
            master.columnconfigure(rows, weight=1)

            self.tab1.rowconfigure(rows, weight=1)
            self.tab1.columnconfigure(rows, weight=1)

            self.tab2.rowconfigure(rows, weight=1)
            self.tab2.columnconfigure(rows, weight=1)

            rows += 1

        # Add Tab1 Labels
        self.boltLabel = tk.Label(self.tab1, text="Select A Bolt:")
        self.boltLabel.grid(column=0, row=1, sticky='SW')
        self.labelMajD = tk.Label(self.tab1, text="Bolt Major Dia. [in]:")
        self.labelMajD.grid(column=0, row=4, sticky='W')
        self.labelMinD = tk.Label(self.tab1, text="Bolt Minor Dia. [in]:")
        self.labelMinD.grid(column=0, row=5, sticky='W')
        self.labelPitchD = tk.Label(self.tab1, text="Bolt Pitch Dia. [in]:")
        self.labelPitchD.grid(column=0, row=6, sticky='W')

        # Add Tab1 Dropdown List - Bolt Choices
        self.boltValue = tk.StringVar()
        self.BoltList = ttk.Combobox(self.tab1, textvariable=self.boltValue, state='readonly')
        self.BoltList['values'] = ('',
                                   '#2-56 (UNC)',
                                   '1-1/2"-12 (UNF)',
                                   'User Defined')

        self.BoltList.grid(column=0, row=2, sticky='NS')
        self.BoltList.current(0)
        self.BoltList.bind("<<ComboboxSelected>>", self.boltSelectFunc)

        # Add Tab1 Entry boxes to display values
        self.majDiaBox = tk.Entry(self.tab1)
        self.majDiaBox.insert(0, '0.0000')
        self.majDiaBox.configure(state='disabled')
        self.majDiaBox.grid(column=1, row=4, sticky='NS')

        self.minDiaBox = tk.Entry(self.tab1)
        self.minDiaBox.insert(0, '0.0000')
        self.minDiaBox.configure(state='disabled')
        self.minDiaBox.grid(column=1, row=5, sticky='NS')

        self.pitchDiaBox = tk.Entry(self.tab1)
        self.pitchDiaBox.insert(0, '0.0000')
        self.pitchDiaBox.configure(state='disabled')
        self.pitchDiaBox.grid(column=1, row=6, sticky='NS')

    def UsrDefBolt(self):
        self.newWindow = tk.Toplevel(self.master)
        self.app = ChildWindow(self.newWindow)

    def boltSelectFunc(self, event):
        self.bolt = self.boltValue.get()
        print(self.bolt)

        if (self.bolt == ''):
            self.majDiaBox.configure(state='normal')
            self.majDiaBox.delete(0, 'end')
            self.majDiaBox.insert(0, '0.0000')
            self.majDiaBox.configure(state='disabled')
            self.minDiaBox.configure(state='normal')
            self.minDiaBox.delete(0, 'end')
            self.minDiaBox.insert(0, '0.0000')
            self.minDiaBox.configure(state='disabled')
            self.pitchDiaBox.configure(state='normal')
            self.pitchDiaBox.delete(0, 'end')
            self.pitchDiaBox.insert(0, '0.0000')
            self.pitchDiaBox.configure(state='disabled')

        elif (self.bolt == 'User Defined'):
            self.newBoltData = None
            self.UsrDefBolt()
            # self.boltSpecs = self.boltBasics(d, n)    # need to return d, n from child window to run this calculation

        else:
            if (self.bolt[0] == '#'):
                lhs, rhs = self.bolt.split("-")
                d = float(lhs[1:]) * 0.013 + .060
                n = float(rhs.split(" ")[0])
                self.boltSpecs = self.boltBasics(d, n)

                self.majDiaBox.configure(state='normal')
                self.majDiaBox.delete(0, 'end')
                self.majDiaBox.insert(0, format(self.boltSpecs['d'], '.4f'))
                self.majDiaBox.configure(state='disabled')
                self.minDiaBox.configure(state='normal')
                self.minDiaBox.delete(0, 'end')
                self.minDiaBox.insert(0, format(self.boltSpecs['dm'], '.4f'))
                self.minDiaBox.configure(state='disabled')
                self.pitchDiaBox.configure(state='normal')
                self.pitchDiaBox.delete(0, 'end')
                self.pitchDiaBox.insert(0, format(self.boltSpecs['dp'], '.4f'))
                self.pitchDiaBox.configure(state='disabled')

            else:
                lhs, rhs = self.bolt.split("\"-")
                n = float(rhs.split(" ")[0])

                if ("-" in lhs):
                    d = float(eval(lhs.replace("-", "+")))
                    self.boltSpecs = self.boltBasics(d, n)

                    self.majDiaBox.configure(state='normal')
                    self.majDiaBox.delete(0, 'end')
                    self.majDiaBox.insert(0, format(self.boltSpecs['d'], '.4f'))
                    self.majDiaBox.configure(state='disabled')
                    self.minDiaBox.configure(state='normal')
                    self.minDiaBox.delete(0, 'end')
                    self.minDiaBox.insert(0, format(self.boltSpecs['dm'], '.4f'))
                    self.minDiaBox.configure(state='disabled')
                    self.pitchDiaBox.configure(state='normal')
                    self.pitchDiaBox.delete(0, 'end')
                    self.pitchDiaBox.insert(0, format(self.boltSpecs['dp'], '.4f'))
                    self.pitchDiaBox.configure(state='disabled')

                else:
                    d = float(eval(lhs))
                    self.boltSpecs = self.boltBasics(d, n)

                    self.majDiaBox.configure(state='normal')
                    self.majDiaBox.delete(0, 'end')
                    self.majDiaBox.insert(0, format(self.boltSpecs['d'], '.4f'))
                    self.majDiaBox.configure(state='disabled')
                    self.minDiaBox.configure(state='normal')
                    self.minDiaBox.delete(0, 'end')
                    self.minDiaBox.insert(0, format(self.boltSpecs['dm'], '.4f'))
                    self.minDiaBox.configure(state='disabled')
                    self.pitchDiaBox.configure(state='normal')
                    self.pitchDiaBox.delete(0, 'end')
                    self.pitchDiaBox.insert(0, format(self.boltSpecs['dp'], '.4f'))
                    self.pitchDiaBox.configure(state='disabled')

    def boltBasics(self, d, n):
        P = 1.0 / n           # in - thread pitch
        dm = d - (1.299038 * P)  # in - external thread minor diameter
        dp = d - (0.649519 * P)  # in - bolt pitch Diameter
        return{'d': d, 'dm': dm, 'dp': dp}


class ChildWindow():
    def __init__(self, master):
        self.master = master
        self.frame = tk.Frame(self.master)
        master.title('User Defined Bolt Info')
        master.geometry('350x250')
        master.focus_set()

        rows = 0
        while rows < 10:
            master.rowconfigure(rows, weight=1)
            master.columnconfigure(rows, weight=1)
            rows += 1

        self.boltName = tk.Label(master, text="Bolt Name (e.g. NewBolt1):")
        self.boltName.grid(column=5, row=1, sticky='NSEW')
        self.boltDia = tk.Label(master, text="Bolt Major Diameter [in]:")
        self.boltDia.grid(column=5, row=3, sticky='NSEW')
        self.boltTPI = tk.Label(master, text="Bolt Threads per Inch (TPI) [-]:")
        self.boltTPI.grid(column=5, row=5, sticky='NSEW')

        self.bName = tk.StringVar()
        self.bDia = tk.StringVar()
        self.bTPI = tk.StringVar()

        self.nameInput = tk.Entry(master, textvariable=self.bName)
        self.nameInput.insert(0, 'BoltName')
        self.nameInput.grid(column=5, row=2, sticky='NSEW')
        self.diaInput = tk.Entry(master, textvariable=self.bDia)
        self.diaInput.insert(0, '0.0000')
        self.diaInput.grid(column=5, row=4, sticky='NSEW')
        self.tpiInput = tk.Entry(master, textvariable=self.bTPI)
        self.tpiInput.insert(0, '0.0000')
        self.tpiInput.grid(column=5, row=6, sticky='NSEW')

        # Create button to save user defined bolt
        self.saveBoltBtn = tk.Button(master, text='Save Bolt', command=self.saveBolt)
        self.saveBoltBtn.bind('<Return>', self.saveBolt)
        self.saveBoltBtn.grid(column=5, row=8, sticky='NSEW')

    def saveBolt(self, *event):
        self.data = {}
        self.data['name'] = self.bName.get()
        self.data['d'] = float(self.bDia.get())
        self.data['n'] = float(self.bTPI.get())

        # NEED TO RETURN THIS DATA TO PARENT WINDOW

        self.master.destroy()


def main():
    root = tk.Tk()
    app = MainGUI(root)
    root.mainloop()


if __name__ == '__main__':
    main()

Tags: selfmasterconfigurecolumntkgridrowsrow
2条回答

我认为从这里继承Tk类和Toplevel类会使您受益匪浅。 这样可以简化在类之间传递数据的方式。我重写了你的代码来展示如何在两个类之间传递数据。在这个例子中,我创建了一个名为do_somthing_with_data的方法,它将打印self.data的结果。我添加了一个名为self.data的主类的class属性,并通过引用master从顶级类操作这个类属性。从这里开始,您只需使用self.data来进行数据操作,就像您使用其他选项一样。在

import tkinter as tk
from tkinter import ttk

class MainGUI(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        self.title('Bolted Joint Analysis')
        self.geometry('500x500')
        # Adds tabs to main window
        self.nb = ttk.Notebook(self)
        self.nb.grid(row=1, column=0, columnspan=50, rowspan=49, sticky='NESW')
        self.tab1 = ttk.Frame(self.nb)
        self.nb.add(self.tab1, text='Tab1')
        self.tab2 = ttk.Frame(self.nb)
        self.nb.add(self.tab2, text='Tab2')
        self.data = {}
        # defines a grid 50 x 50 cells in the main window & tabs
        rows = 0
        while rows < 50:
            self.rowconfigure(rows, weight=1)
            self.columnconfigure(rows, weight=1)
            self.tab1.rowconfigure(rows, weight=1)
            self.tab1.columnconfigure(rows, weight=1)
            self.tab2.rowconfigure(rows, weight=1)
            self.tab2.columnconfigure(rows, weight=1)
            rows += 1
        # Add Tab1 Labels
        self.boltLabel = tk.Label(self.tab1, text="Select A Bolt:")
        self.boltLabel.grid(column=0, row=1, sticky='SW')
        self.labelMajD = tk.Label(self.tab1, text="Bolt Major Dia. [in]:")
        self.labelMajD.grid(column=0, row=4, sticky='W')
        self.labelMinD = tk.Label(self.tab1, text="Bolt Minor Dia. [in]:")
        self.labelMinD.grid(column=0, row=5, sticky='W')
        self.labelPitchD = tk.Label(self.tab1, text="Bolt Pitch Dia. [in]:")
        self.labelPitchD.grid(column=0, row=6, sticky='W')
        # Add Tab1 Dropdown List - Bolt Choices
        self.boltValue = tk.StringVar()
        self.BoltList = ttk.Combobox(self.tab1, textvariable=self.boltValue, state='readonly')
        self.BoltList['values'] = ('', '#2-56 (UNC)', '1-1/2"-12 (UNF)', 'User Defined')
        self.BoltList.grid(column=0, row=2, sticky='NS')
        self.BoltList.current(0)
        self.BoltList.bind("<<ComboboxSelected>>", self.boltSelectFunc)
        # Add Tab1 Entry boxes to display values
        self.majDiaBox = tk.Entry(self.tab1)
        self.majDiaBox.insert(0, '0.0000')
        self.majDiaBox.configure(state='disabled')
        self.majDiaBox.grid(column=1, row=4, sticky='NS')
        self.minDiaBox = tk.Entry(self.tab1)
        self.minDiaBox.insert(0, '0.0000')
        self.minDiaBox.configure(state='disabled')
        self.minDiaBox.grid(column=1, row=5, sticky='NS')
        self.pitchDiaBox = tk.Entry(self.tab1)
        self.pitchDiaBox.insert(0, '0.0000')
        self.pitchDiaBox.configure(state='disabled')
        self.pitchDiaBox.grid(column=1, row=6, sticky='NS')

    def do_somthing_with_data(self):
        print(self.data)

    def boltSelectFunc(self, event):
        self.bolt = self.boltValue.get()
        print(self.bolt)

        if (self.bolt == ''):
            self.majDiaBox.configure(state='normal')
            self.majDiaBox.delete(0, 'end')
            self.majDiaBox.insert(0, '0.0000')
            self.majDiaBox.configure(state='disabled')
            self.minDiaBox.configure(state='normal')
            self.minDiaBox.delete(0, 'end')
            self.minDiaBox.insert(0, '0.0000')
            self.minDiaBox.configure(state='disabled')
            self.pitchDiaBox.configure(state='normal')
            self.pitchDiaBox.delete(0, 'end')
            self.pitchDiaBox.insert(0, '0.0000')
            self.pitchDiaBox.configure(state='disabled')

        elif (self.bolt == 'User Defined'):
            self.newBoltData = None
            ChildWindow(self)


            # self.boltSpecs = self.boltBasics(d, n)    # need to return d, n from child window to run this calculation

        else:
            if (self.bolt[0] == '#'):
                lhs, rhs = self.bolt.split("-")
                d = float(lhs[1:]) * 0.013 + .060
                n = float(rhs.split(" ")[0])
                self.boltSpecs = self.boltBasics(d, n)
                self.majDiaBox.configure(state='normal')
                self.majDiaBox.delete(0, 'end')
                self.majDiaBox.insert(0, format(self.boltSpecs['d'], '.4f'))
                self.majDiaBox.configure(state='disabled')
                self.minDiaBox.configure(state='normal')
                self.minDiaBox.delete(0, 'end')
                self.minDiaBox.insert(0, format(self.boltSpecs['dm'], '.4f'))
                self.minDiaBox.configure(state='disabled')
                self.pitchDiaBox.configure(state='normal')
                self.pitchDiaBox.delete(0, 'end')
                self.pitchDiaBox.insert(0, format(self.boltSpecs['dp'], '.4f'))
                self.pitchDiaBox.configure(state='disabled')
            else:
                lhs, rhs = self.bolt.split("\"-")
                n = float(rhs.split(" ")[0])
                if ("-" in lhs):
                    d = float(eval(lhs.replace("-", "+")))
                    self.boltSpecs = self.boltBasics(d, n)
                    self.majDiaBox.configure(state='normal')
                    self.majDiaBox.delete(0, 'end')
                    self.majDiaBox.insert(0, format(self.boltSpecs['d'], '.4f'))
                    self.majDiaBox.configure(state='disabled')
                    self.minDiaBox.configure(state='normal')
                    self.minDiaBox.delete(0, 'end')
                    self.minDiaBox.insert(0, format(self.boltSpecs['dm'], '.4f'))
                    self.minDiaBox.configure(state='disabled')
                    self.pitchDiaBox.configure(state='normal')
                    self.pitchDiaBox.delete(0, 'end')
                    self.pitchDiaBox.insert(0, format(self.boltSpecs['dp'], '.4f'))
                    self.pitchDiaBox.configure(state='disabled')
                else:
                    d = float(eval(lhs))
                    self.boltSpecs = self.boltBasics(d, n)
                    self.majDiaBox.configure(state='normal')
                    self.majDiaBox.delete(0, 'end')
                    self.majDiaBox.insert(0, format(self.boltSpecs['d'], '.4f'))
                    self.majDiaBox.configure(state='disabled')
                    self.minDiaBox.configure(state='normal')
                    self.minDiaBox.delete(0, 'end')
                    self.minDiaBox.insert(0, format(self.boltSpecs['dm'], '.4f'))
                    self.minDiaBox.configure(state='disabled')
                    self.pitchDiaBox.configure(state='normal')
                    self.pitchDiaBox.delete(0, 'end')
                    self.pitchDiaBox.insert(0, format(self.boltSpecs['dp'], '.4f'))
                    self.pitchDiaBox.configure(state='disabled')

    def boltBasics(self, d, n):
        P = 1.0 / n           # in - thread pitch
        dm = d - (1.299038 * P)  # in - external thread minor diameter
        dp = d - (0.649519 * P)  # in - bolt pitch Diameter
        return{'d': d, 'dm': dm, 'dp': dp}


class ChildWindow(tk.Toplevel):
    def __init__(self, master):
        tk.Toplevel.__init__(self, master)
        self.frame = tk.Frame(self)
        self.title('User Defined Bolt Info')
        self.geometry('350x250')
        self.focus_set()
        rows = 0
        while rows < 10:
            self.rowconfigure(rows, weight=1)
            self.columnconfigure(rows, weight=1)
            rows += 1

        self.boltName = tk.Label(self, text="Bolt Name (e.g. NewBolt1):")
        self.boltName.grid(column=5, row=1, sticky='NSEW')
        self.boltDia = tk.Label(self, text="Bolt Major Diameter [in]:")
        self.boltDia.grid(column=5, row=3, sticky='NSEW')
        self.boltTPI = tk.Label(self, text="Bolt Threads per Inch (TPI) [-]:")
        self.boltTPI.grid(column=5, row=5, sticky='NSEW')
        self.bName = tk.StringVar()
        self.bDia = tk.StringVar()
        self.bTPI = tk.StringVar()
        self.nameInput = tk.Entry(self, textvariable=self.bName)
        self.nameInput.insert(0, 'BoltName')
        self.nameInput.grid(column=5, row=2, sticky='NSEW')
        self.diaInput = tk.Entry(self, textvariable=self.bDia)
        self.diaInput.insert(0, '0.0000')
        self.diaInput.grid(column=5, row=4, sticky='NSEW')
        self.tpiInput = tk.Entry(self, textvariable=self.bTPI)
        self.tpiInput.insert(0, '0.0000')
        self.tpiInput.grid(column=5, row=6, sticky='NSEW')
        # Create button to save user defined bolt
        self.saveBoltBtn = tk.Button(self, text='Save Bolt', command=self.saveBolt)
        self.saveBoltBtn.bind('<Return>', self.saveBolt)
        self.saveBoltBtn.grid(column=5, row=8, sticky='NSEW')

    def saveBolt(self, *event):
        self.master.data = {}
        self.master.data['name'] = self.bName.get()
        self.master.data['d'] = float(self.bDia.get())
        self.master.data['n'] = float(self.bTPI.get())
        self.master.do_somthing_with_data()
        # NEED TO RETURN THIS DATA TO PARENT WINDOW
        self.destroy()


def main():
    MainGUI().mainloop()

if __name__ == '__main__':
    main()

老实说,我没有阅读所有代码,但是要将输入从“ChildWindow”类传递到“MainGUI”,只需执行以下操作:

在MainGUI类中,用您想要的输入在init函数之前或init函数中定义一个变量(不要忘记声明self.your_变量). 在

def __init__(self):
   self.input_from_child = None

因为您在“Main()”函数中初始化了MainGUI,所以在ChildWindow函数中,您可以更改变量:

^{pr2}$

只需在类中使用main变量进行计算

相关问题 更多 >