将用户输入从子级传递到父窗口python tkinter [英] Pass user input from child to parent window python tkinter
问题描述
我对Python很陌生,对tkinter甚至更多.我一直在寻找这个问题的答案,并获得了一些看似接近的东西,但没有一个我能够成功实现的.
I'm pretty new to Python, and even more new to tkinter. I've searched for an answer to this question and gotten some things that seem close, but none that I have been able to successfully implement.
基本上,我想做的是创建一个带有下拉列表的主窗口,供用户从中选择一个项目.当用户进行选择时,将进行简单的计算并将结果打印到屏幕上.选项之一是用户定义".做出选择后,我想使用Toplevel创建一个子窗口,该窗口允许用户进行一些输入并单击确定",然后执行相同的计算,并在主窗口上显示相同的数据,就像他们选择了预定义的选项.
Basically what I'm trying to do is create a main window with a dropdown list for the user to select an item from. When the user makes a selection, a simple calculation is done and the result printed to the screen. One of the choices is 'User Defined'. When this selection is made, I would like to create a child window using Toplevel that allows the user to make a few inputs and hit 'OK', at which point the same calculations are done and the same data displayed on the main window as if they had selected a pre-defined option.
我可以根据需要打开和关闭窗口,但是当用户定义新项目时,我无法将其输入传递回主程序以进行必要的计算(这样显示起来很简单) .如何将用户输入传递回主窗口?
I can get the windows to open and close as I want, but when the user defines a new item I can't pass their input back to the main program to make the necessary calculations (which would then be trivial to display). How do I pass the user inputs back to the main window?
在下面的示例代码中,所有内容都适用于下拉列表中的前3个项目,但对于用户定义的"则不起作用,因为我不知道如何返回用户输入的值来执行计算.
In the sample code below, everything works for the first 3 items in the dropdown list, but for User Defined it does nothing since I can't figure out how to return the user inputted values to perform the calculations.
在此先感谢您的帮助/建议.
Thanks in advance for any help/advice.
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()
推荐答案
我认为您将从这里的Tk
类和Toplevel
类继承中受益.
这样,您可以简化在类之间传递数据的方式.我已经重写了您的代码,以显示如何在两个类之间传递数据.在此示例中,我创建了一个名为do_somthing_with_data
的方法,该方法将打印self.data
的结果.我向您的主类self.data
添加了一个类属性,并从您的顶级类中通过引用master来操纵该类属性.从这里开始,您只需要使用self.data
进行数据处理,就像使用其他选项一样即可.
I think you would benefit from inheriting from the Tk
class and Toplevel
class here.
This way you can simplify how you pass data between the classes. I have rewritten your code to show how you can pass data between the 2 classes. In this example I created a method called do_somthing_with_data
that will print the results of self.data
. I added a class attribute to your main class called self.data
and from your Toplevel class I manipulate this class attribute by referencing master. From here you simply need to do the data manipulation with self.data
that you would do with your other options.
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()
这篇关于将用户输入从子级传递到父窗口python tkinter的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!