2016-11-19 98 views
1

過去一週我一直在解決這個問題,需要一些幫助。我正在嘗試編寫一個GUI來計算所選的所有複選框的總數。這是我到目前爲止的代碼:帶有複選框的Python 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有沒有屬性「得到」。我希望程序計算檢查的所有服務的總數並顯示總數。

+1

問題是你設置了自我。oil_change = tkinter.IntVar()'是一個'IntVar'(這很好),但是稍後你會覆蓋它'self.oil_change = tkinter.Checkbutton(..)'。從那時起,'self.oil_change'將不再是'IntVar',而是對Checkbutton的引用。 Checkbutton本身沒有'get()'方法。解決方案:爲'IntVar'和'Checkbox'對象使用不同的變量名稱。 – ImportanceOfBeingErnest

回答

1

首先創建了一堆IntVar S和它們保存爲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不同於它們相關的IntVars。或者甚至懶得給他們永久的名字,只是做

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) 

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)