我对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()
我认为从这里继承
Tk
类和Toplevel
类会使您受益匪浅。 这样可以简化在类之间传递数据的方式。我重写了你的代码来展示如何在两个类之间传递数据。在这个例子中,我创建了一个名为do_somthing_with_data
的方法,它将打印self.data
的结果。我添加了一个名为self.data
的主类的class属性,并通过引用master从顶级类操作这个类属性。从这里开始,您只需使用self.data
来进行数据操作,就像您使用其他选项一样。在老实说,我没有阅读所有代码,但是要将输入从“ChildWindow”类传递到“MainGUI”,只需执行以下操作:
在MainGUI类中,用您想要的输入在init函数之前或init函数中定义一个变量(不要忘记声明self.your_变量). 在
因为您在“Main()”函数中初始化了MainGUI,所以在ChildWindow函数中,您可以更改变量:
^{pr2}$只需在类中使用main变量进行计算
相关问题 更多 >
编程相关推荐