带有复选框的Python GUI

时间:2016-11-19 13:26:49

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

过去一周我一直在努力解决这个问题,需要一些帮助。我正在尝试编写一个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没有属性' get'。我希望程序计算所有已检查服务的总数并显示总数。

2 个答案:

答案 0 :(得分:1)

首先,您创建一堆public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException, NoSuchMethodException { Class<?> type = new ByteBuddy() .subclass(Object.class) .name("domain") .defineField("id", int.class, Visibility.PRIVATE) .defineMethod("getId", int.class, Visibility.PUBLIC).intercept(FieldAccessor.ofBeanProperty()) .defineMethod("setId", Void.TYPE, Visibility.PUBLIC).intercept(FieldAccessor.ofBeanProperty()) .make() .load(sample.class.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER) .getLoaded(); Object o = type.newInstance(); Field f = o.getClass().getDeclaredField("id"); f.setAccessible(true); System.out.println(o.toString()); Method m = o.getClass().getDeclaredMethod("getId"); System.out.println(m.getName()); Method s = o.getClass().getDeclaredMethod("setId", int.class); System.out.println(s.getName()); } 并将其保存为IntVar实例的属性

Joes_auto

等,但随后用

破坏了这些属性
self.oil_change = tkinter.IntVar()

等。所以现在self.oil_change = tkinter.Checkbutton(self.top_frame, text = 'Oil Change ($30)', \ variable=self.oil_change) 指的是Checkbutton,而不是IntVar。这就是你得到这个错误的原因:IntVar有一个self.oil_change方法,但Checkbutton小部件没有。

因此,您需要为Checkbuttons提供与其关联的IntVar不同的名称。或者甚至不打扰给他们永久的名字,只是做

.get

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

顺便说一句,你可以通过改变

来节省一些打字
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

答案 1 :(得分:1)

当您创建select * from student order by primarykey desc offset 1 row fetch first 1 row only; 个实例时,您将覆盖具有相同名称的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