【问题标题】:How do I store the information of checkboxes? And how do i use the info in another variable?如何存储复选框的信息?我如何使用另一个变量中的信息?
【发布时间】:2012-08-01 20:48:42
【问题描述】:

我希望您能帮助我编写以下代码并告诉我哪里出错了。我在python方面没有那么有经验,所以帮助会很棒!这是我的代码:

from Tkinter import *

import math
from math import *

import tkFont
import tkMessageBox

numberOfIngredients = {}
diameter = {}

class Application(Frame):
    """ GUI application that creates a story based on user input. """
    def __init__(self, master):
        """ Initialize Frame. """
        #Make size later master.geometry("485x280+5+10")
        Frame.__init__(self, master)
        self.grid()
        self.create_widgets()
        self.config(bg = "#a6b6cb")

    def create_widgets(self):
        """ Define the widgets and positioning within the frame. """
        #Display the Title
        Label(self, text = "Hamburger Calculator", font = ("Calibri", "25"), bg = "#a6b6cb", fg = "#17375e").grid(row = 0, column = 1, sticky = W)

        #Instructions For Selecting Box
        Label(self, text ="Select your extra ingredients:",
              bg = "#a6b6cb").grid(row = 1, column =1, sticky = W)

        #Button To Calculate
        Button(self, text = "Calculate Cost",  bg = "#92d050",
               command = self.calculate,
               font = ("Calibri", "12")).grid(row = 6, column = 1, sticky = SE)

        #Button To Quit
        Button(self, text = "Quit", bg = "#913c3a",
               command = self.quit,
               font = ("Calibri", "12")).grid(row = 7, column = 1,
                                              sticky = SE)

        #Radio Box For Patty Size
        Label(self, text ="Hamburger Size:",
              bg = "#a6b6cb").grid(row = 1, column = 0, sticky = W)

        diameter = IntVar()

        Radiobutton(self,
                    text = "10 cm",
                    bg = "#a6b6cb",
                    variable = diameter,
                    value = 10,
                    ).grid(row = 3, column = 0, sticky =W)

        Radiobutton(self,
                    text = "20 cm",
                    bg = "#a6b6cb",
                    variable = diameter,
                    value = 20,
                    ).grid(row = 4, column = 0, sticky =W)

        Radiobutton(self,
                    text = "35 cm",
                    bg = "#a6b6cb",
                    variable = diameter,
                    value = 35,
                    ).grid(row = 5, column = 0, sticky =W) 


        #Check Box for Cheese
        self.cheese = BooleanVar()
        Checkbutton(self,
                    text="Cheese",
                    bg = "#a6b6cb",
                    variable = self.cheese,
                    onvalue="yes", offvalue="no"
                    ).grid(row =3,
                    column = 1, sticky =W)
        #Check Box for Mushrooms
        self.mushroom = BooleanVar()
        Checkbutton(self,
                    text="Mushrooms",
                    bg = "#a6b6cb",
                    variable = self.mushroom,
                    onvalue="yes", offvalue="no"
                    ).grid(row =4,
                    column = 1, sticky =W)
        #Check Box for Onions
        self.onion = BooleanVar()
        Checkbutton(self,
                    text="Onions",
                    bg = "#a6b6cb",
                    variable = self.onion,
                    onvalue="yes", offvalue="no"
                    ).grid(row =5,
                    column = 1, sticky =W)
        #Check Box for Extra Beefburger
        self.beefburger = BooleanVar()
        Checkbutton(self,
                    text="Extra Burger Patty",
                    bg = "#a6b6cb",
                    variable = self.beefburger,
                    onvalue="yes", offvalue="no"
                    ).grid(row =6,
                    column = 1, sticky =W)

        numberOfIngredients = 0

        if self.cheese.get() == "yes":
            numberOfIngredients + 1
        if self.mushroom.get() == "yes":
            numberOfIngredients + 1
        if self.onion.get() == "yes":
            numberOfIngredients + 1
        if self.beefburger.get() == "yes":
            numberOfIngredients + 1


    def calculate(self):
        #Constants and Variables
        fixedCost = 3.75
        baseCost = 1.55
        extraCost = 1.25

        global numberOfIngredients
        global diameter

        #Formulas
        area = (pi * sqrt(int(diameter) / 100) ) / 4
        cost = fixedCost + (baseCost * area) + (numberOfIngredients * extraCost)
        totalCost = 1.5 * cost

        #Message Box
        tkMessageBox.showinfo(
            title="Total Cost",
            message="The total cost of the hamburger is $" + str(diameter))


#Main
root = Tk()
root.title("Hamburger Calculator")
app = Application(root)
root.mainloop()
root.destroy()

这是我目前遇到的错误:

Tkinter 回调异常 回溯(最近一次通话最后): 调用中的文件“C:\Python27\lib\lib-tk\Tkinter.py”,第 1410 行 返回 self.func(*args) 文件“C:\Users\Matt Sharp\Desktop\Assessment For Hamburgers v2tester.py”,第 131 行,在计算中 面积 = (pi * sqrt(int(直径) / 100) ) / 4 TypeError: int() 参数必须是字符串或数字,而不是 'dict'

除了这个错误,我知道我的直径和 numberOfIngredients 不起作用。

【问题讨论】:

    标签: tkinter python-2.7


    【解决方案1】:

    这是一个很好的例子,说明了为什么你应该避免使用全局变量来存储你的状态......

    在模块的顶部,您将 diameter 创建为字典:

    diameter = {}
    

    然后在您的 create_widgets() 方法中,您创建一个局部变量 diameter 以在您的小部件中使用(尽管您从不保留对它的引用):

    diameter = IntVar() 
    

    但是在您的 calculate() 方法中,您引用全局 diameter(这是一个 dict)并在数学表达式中使用它,就好像它是一个 int:

    area = (pi * sqrt(int(diameter) / 100) ) / 4
    

    您也对numberOfIngredients 做了类似的事情。它被创建为全局 dict,但用作本地 int 且未保存,然后在数学表达式中再次称为全局。

    # global numberOfIngredients is {}
    cost = fixedCost + (baseCost * area) + (numberOfIngredients * extraCost)
    

    全局变量很容易使您的应用程序混乱,因为您不能总是根据当前范围识别变量的来源。

    我不确定您希望如何使用全局 dict 与本地 int,但最终应该将变量作为实例属性保留在类上:

    class Application(Frame):
        def __init__(self, master): 
            ...
            self.diameter = IntVar()
            self.numberOfIngredients = 0
    
        def create_widgets(self):
            ...
            Radiobutton(self,
                        text = "10 cm",
                        bg = "#a6b6cb",
                        variable = self.diameter,
                        value = 10,
                        ).grid(row = 3, column = 0, sticky =W)
            ...
            if self.cheese.get() == "yes":
                self.numberOfIngredients += 1
    
        def calculate(self):
            ...
            area = (pi * sqrt(int(self.diameter) / 100) ) / 4
            cost = fixedCost + (baseCost * area) + \
                        (self.numberOfIngredients * extraCost)
    

    【讨论】:

    • 不错的分析。但是,我认为如果您将布局 (.grid(...)) 与小部件创建 (Button(...)) 分开,这个答案会更好。我知道原始示例是这样做的,但一般来说这是一种不好的做法。最终,一些代码将需要对小部件的引用,或者想要重做布局,这变得更加困难。
    • @BryanOakley:你可能。老实说,我不使用 tkinter,所以我并没有过多关注 tk 特定的设计问题。就在耀眼的一般蟒蛇设计。随意编辑。
    • 非常感谢您的意见。我现在已经整理了很多代码:)
    • 如果此答案解决了您的问题,请不要忘记点击绿色复选标记!谢谢!
    猜你喜欢
    • 1970-01-01
    • 2015-05-03
    • 1970-01-01
    • 1970-01-01
    • 2021-05-04
    • 1970-01-01
    • 2023-02-04
    • 2010-10-14
    • 2011-07-10
    相关资源
    最近更新 更多