【问题标题】:ttk tkinter multiple frames/windowsttk tkinter 多帧/窗口
【发布时间】:2011-08-27 11:10:23
【问题描述】:

我创建的以下应用程序用于在 tkinter 中演示多个窗口。主要问题是,无论是在 bmi 计算器还是转换器中,Entry 控件都不接受输入框中的值 - 当我进行计算时,它们会得到 ValueError

from tkinter import *
from tkinter import ttk
from tkinter import messagebox

class App1(ttk.Frame):
    def createWidgets(self):
        #text variables
        self.i_height = StringVar()
        self.i_weight = StringVar()
        self.o_bmi = StringVar()

        #labels
        self.label1 = ttk.Label(self, text="Enter your weight:").grid(row=0, column=0, sticky=W)
        self.label2 = ttk.Label(self, text="Enter your height:").grid(row=1, column=0, sticky=W)
        self.label3 = ttk.Label(self, text="Your BMI is:").grid(row=2, column=0, sticky=W)

        #text boxes
        self.textbox1 = ttk.Entry(self, textvariable=self.i_weight).grid(row=0, column=1, sticky=E)
        self.textbox2 = ttk.Entry(self, textvariable=self.i_height).grid(row=1, column=1, sticky=E)
        self.textbox3 = ttk.Entry(self, textvariable=self.o_bmi).grid(row=2, column=1, sticky=E)

        #buttons
        self.button1 = ttk.Button(self, text="Cancel/Quit", command=self.quit).grid(row=3, column=1, sticky=E)
        self.button1 = ttk.Button(self, text="Ok", command=self.calculateBmi).grid(row=3, column=2, sticky=E)

    def calculateBmi(self):
        try:
            self.weight = float(self.i_weight.get())
            self.height = float(self.i_height.get())
            self.bmi = self.weight / self.height ** 2.0
            self.o_bmi.set(self.bmi)
        except ValueError:
            messagebox.showinfo("Error", "You can only use numbers.")
        finally:
            self.i_weight.set("")
            self.i_height.set("")

    def __init__(self, master=None):
        ttk.Frame.__init__(self, master)
        self.grid()
        self.createWidgets()

class App2(ttk.Frame):
    def create_widgets(self):
        """Create the widgets for the GUI"""
        #1 textbox (stringvar)
        self.entry= StringVar()
        self.textBox1= ttk.Entry(self, textvariable=self.entry).grid(row=0, column=1)

        #5 labels (3 static, 1 stringvar)
        self.displayLabel1 = ttk.Label(self, text="feet").grid(row=0, column=2, sticky=W)
        self.displayLabel2 = ttk.Label(self, text="is equivalent to:").grid(row=1, column=0)
        self.result= StringVar()
        self.displayLabel3 = ttk.Label(self, textvariable=self.result).grid(row=1, column=1)
        self.displayLabel4 = ttk.Label(self, text="meters").grid(row=1, column=2, sticky=W)

        #2 buttons
        self.quitButton = ttk.Button(self, text="Quit", command=self.quit).grid(row=2, column=1, sticky=(S,E))
        self.calculateButton = ttk.Button(self, text="Calculate", command=self.convert_feet_to_meters).grid(row=2, column=2, sticky=(S,E))

    def convert_feet_to_meters(self):
        """Converts feet to meters, uses string vars and converts them to floats"""
        self.measurement = float(self.entry.get())
        self.meters = self.measurement * 0.3048
        self.result.set(self.meters)

    def __init__(self, master=None):
        ttk.Frame.__init__(self, master)
        self.grid()
        self.create_widgets()

def button1_click():
    root = Tk()
    app = App1(master=root)
    app.mainloop()

def button2_click():
    root = Tk()
    app = App2(master=root)
    app.mainloop()

def main():
    window = Tk()
    button1 = ttk.Button(window, text="bmi calc", command=button1_click).grid(row=0, column=1)
    button2 = ttk.Button(window, text="feet conv", command=button2_click).grid(row=1, column=1)
    window.mainloop()

if __name__ == '__main__':
    main()

我该如何解决这个问题,但仍然保持类结构和 python3 的使用?顺便说一句 - 任何类似于 C# 的form1.Show()

【问题讨论】:

    标签: python user-interface python-3.x tkinter ttk


    【解决方案1】:

    您必须将StringVar() 转换为整数/浮点数或使用IntVar()DoubleVar()

    还有其他问题。像下面这样的语句返回“None”,因为它是 grid() 对象而不是 Label() 对象:

    self.label1 = ttk.Label(self, text="Enter your weight:").grid(row=0, column=0, sticky=W)   
    

    我想你也会遇到同时打开两个Tk() 窗口的问题。请改用Toplevel() 或单独的框架。

    【讨论】:

    • grid 不是对象,也不会返回对象。这只是一个功能。但是你是正确的 Label(...).grid(...) 没有返回任何有用的东西。
    • 它仅用于布局,它在函数 create_widgets 中设置框架中的小部件。我将它用作一个类,因为它有助于将所有小部件设置在一个地方,而且我喜欢单衬里:)
    • @py_tk_coder:如果是这种情况,请不要将结果分配给实例变量。这很有意义,令人困惑,并且会使您的“单行”超出必要的时间。
    【解决方案2】:

    谢谢乔,你帮了很多忙,我偶然发现了答案......使用 ttk 你可以使用笔记本,因为我的两个类都是派生框架,所以我可以将它们添加到笔记本的框架中。 ..

    def main():
    #Setup Tk()
    window = Tk()
    
    #Setup the notebook (tabs)
    notebook = ttk.Notebook(window)
    frame1 = ttk.Frame(notebook)
    frame2 = ttk.Frame(notebook)
    notebook.add(frame1, text="BMI Calc")
    notebook.add(frame2, text="Feet to Meters")
    notebook.grid()
    
    #Create tab frames
    app1 = App1(master=frame1)
    app1.grid()
    app2 = App2(master=frame2)
    app2.grid()
    
    #Main loop
    window.mainloop()
    

    这解决了问题:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-07-03
      • 1970-01-01
      • 2018-12-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-07
      • 1970-01-01
      相关资源
      最近更新 更多