【问题标题】:Python GUI with Checkboxes带有复选框的 Python GUI
【发布时间】:2017-04-03 06:29:12
【问题描述】:

过去一周我一直在努力解决这个问题,需要一些帮助。我正在尝试编写一个 GUI 来计算所有选中的复选框的总数。到目前为止,这是我的代码:

import tkinter
import tkinter.messagebox

class Joes_auto:

    def __init__(self):

        # Create the main window.
        self.main_window = tkinter.Tk()

        # Create the frames.  One for the checkbuttons,
        # one for the total frame, and one for the buttons
        self.top_frame = tkinter.Frame(self.main_window)
        self.mid_frame = tkinter.Frame(self.main_window)
        self.bottom_frame = tkinter.Frame(self.main_window)

        #Create the IntVar objects to use with the checkbuttons
        self.oil_change = tkinter.IntVar()
        self.lube_job = tkinter.IntVar()
        self.radiator_flush = tkinter.IntVar()
        self.transmission_flush = tkinter.IntVar()
        self.inspection = tkinter.IntVar()
        self.muffler_replacement = tkinter.IntVar()
        self.tire_rotation = tkinter.IntVar()

        # Set the IntVar objects to 0
        self.oil_change.set(0)
        self.lube_job.set(0)
        self.radiator_flush.set(0)
        self.transmission_flush.set(0)
        self.inspection.set(0)
        self.muffler_replacement.set(0)
        self.tire_rotation.set(0)

        # Create the Checkbutton widgets in the top_frame
        self.oil_change = tkinter.Checkbutton(self.top_frame, text = 'Oil Change ($30)', \
                                                variable=self.oil_change)
        self.lube_job = tkinter.Checkbutton(self.top_frame, text = 'Lube Job ($20)', \
                                            variable=self.lube_job)
        self.radiator_flush = tkinter.Checkbutton(self.top_frame, text = 'Radiator Flush ($40)', \
                                          variable=self.radiator_flush)
        self.transmission_flush = tkinter.Checkbutton(self.top_frame, text = 'Transmission Flush ($100)', \
                                              variable=self.transmission_flush)
        self.inspection = tkinter.Checkbutton(self.top_frame, text = 'Inspection ($35)', \
                                      variable=self.inspection)
        self.muffler_replacement = tkinter.Checkbutton(self.top_frame, text = 'Muffler Replacement ($200)', \
                                               variable=self.muffler_replacement)
        self.tire_rotation = tkinter.Checkbutton(self.top_frame, text = 'Tire Rotation ($20)', \
                                         variable=self.tire_rotation)

        # Pack the Checkbuttons
        self.oil_change.pack()
        self.lube_job.pack()
        self.radiator_flush.pack()
        self.transmission_flush.pack()
        self.inspection.pack()
        self.muffler_replacement.pack()
        self.tire_rotation.pack()

        # Create a total and quit button
        self.total_button = tkinter.Button(self.bottom_frame, text = 'Calculate Total', \
                                           command = self.total)
        self.quit_button = tkinter.Button(self.bottom_frame, text = 'Quit', \
                                           command = self.main_window.destroy)

        # Pack the buttons
        self.total_button.pack(side = 'left')
        self.quit_button.pack(side = 'left')

        # Pack the frames
        self.top_frame.pack()
        self.mid_frame.pack()
        self.bottom_frame.pack()

        # Start the mainloop
        tkinter.mainloop()

    def total(self):

        self.total = 0

        if self.oil_change.get() == 1:
            self.total += 30
        if self.lube_job.get() == 1:
            self.total += 20
        if self.radiator_flush.get() == 1:
            self.total += 40
        if self.transmission_flush.get() == 1:
            self.total += 100
        if self.inspection.get() == 1:
            self.total += 35
        if self.muffler_replacement.get() == 1:
            self.total += 200
        if self.tire_rotation.get() == 1:
            self.total += 20

        tkinter.messagebox.showinfo("Your total is", self.total)

joes_auto = Joes_auto()

每次我运行程序时都会收到 AttributeError: Checkbutton has no attribute 'get'。我希望程序计算检查的所有服务的总数并显示总数。

【问题讨论】:

  • 问题是您将self.oil_change = tkinter.IntVar() 设置为IntVar(这很好)但后来您将其覆盖self.oil_change = tkinter.Checkbutton(..)。从那时起,self.oil_change 将不再是 IntVar,而是对 Checkbutton 的引用。 Checkbutton 本身没有get() 方法。解决方案:IntVarCheckbox对象使用不同的变量名。

标签: python user-interface checkbox tkinter python-3.5


【解决方案1】:

当您创建 Checkbutton 实例时,您将覆盖具有相同名称的 IntVar 变量。

self.oil_change = tkinter.Checkbutton(self.top_frame, text = 'Oil Change ($30)',
                                      variable=self.oil_change)

通过为Checkbutton 实例选择其他名称来避免这种情况。实际上,没有复选框实例引用的用例;您可以立即打包而无需保存到变量:

# Create the Checkbutton widgets in the top_frame
tkinter.Checkbutton(self.top_frame, text='Oil Change ($30)',
                    variable=self.oil_change).pack()
tkinter.Checkbutton(self.top_frame, text='Lube Job ($20)',
                    variable=self.lube_job).pack()
tkinter.Checkbutton(self.top_frame, text='Radiator Flush ($40)',
                    variable=self.radiator_flush).pack()
tkinter.Checkbutton(self.top_frame, text='Transmission Flush ($100)',
                    variable=self.transmission_flush).pack()
tkinter.Checkbutton(self.top_frame, text='Inspection ($35)',
                    variable=self.inspection).pack()
tkinter.Checkbutton(self.top_frame, text='Muffler Replacement ($200)',
                    variable=self.muffler_replacement).pack()
tkinter.Checkbutton(self.top_frame, text='Tire Rotation ($20)',
                    variable=self.tire_rotation).pack()

还有另一个属性覆盖问题,在total 方法中:该方法正在覆盖self.total;方法将被替换为 int 对象。因为方法是绑定的,不会在外面使用;因此,除非您在其他地方访问total 方法,否则不会出现任何症状,但仍然无效。

我建议把self.total = 0改成total = 0,因为total只用在方法中。

def total(self):
    total = 0

    if self.oil_change.get() == 1:
        total += 30
    if self.lube_job.get() == 1:
        total += 20
    if self.radiator_flush.get() == 1:
        total += 40
    if self.transmission_flush.get() == 1:
        total += 100
    if self.inspection.get() == 1:
        total += 35
    if self.muffler_replacement.get() == 1:
        total += 200
    if self.tire_rotation.get() == 1:
        total += 20

    tkinter.messagebox.showinfo("Your total is", total)

【讨论】:

    【解决方案2】:

    首先你创建一堆IntVars 并将它们保存为Joes_auto 实例的属性

    self.oil_change = tkinter.IntVar()
    

    等等,但是你用

    破坏了这些属性
    self.oil_change = tkinter.Checkbutton(self.top_frame, text = 'Oil Change ($30)', \
                                                    variable=self.oil_change)
    

    等等。所以现在self.oil_change 指的是 Checkbutton,而不是 IntVar。这就是您收到该错误的原因:IntVar 有一个 .get 方法,但 Checkbutton 小部件没有。

    因此,您需要为 Checkbuttons 指定与其关联的 IntVar 不同的名称。或者甚至不用给他们永久的名字,就这样做

    b = tkinter.Checkbutton(self.top_frame, text = 'Oil Change ($30)',
                                            variable=self.oil_change)
    b.pack()
    b = tkinter.Checkbutton(self.top_frame, text = 'Lube Job ($20)',
                                        variable=self.lube_job)
    b.pack()
    

    等等。 (我去掉了那些反斜杠 - 你不需要它们,因为你在括号内继续一行。这也适用于括号和大括号)。


    顺便说一句,您可以通过更改来节省一些打字时间

    import tkinter
    

    import tkinter as tk
    

    那你就可以了

    b = tk.Checkbutton(self.top_frame, text = 'Oil Change ($30)', variable=self.oil_change)
    

    等等

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-06-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-19
      • 2014-07-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多