Python - tkinter - 动态复选框

时间:2016-10-06 16:08:18

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

我的一门课程对tkinter进行了传递,并且它超出了入门课程的范围。它激起了我的好奇心,我想深入挖掘它。

我有基础知识 - 我可以让复选框显示在我想要的位置,但我想让它更具动态性/ pythonic。

第1列 - 应始终显示所有复选框。这按预期工作。 第2列 - 仅显示第一个复选框,如果单击该复选框,则应显示其他4个复选框。单击这4个复选框中的任何一个时,它应该在UI底部的文本框中显示一条消息。

当我单击第二列中焦点课程的复选框时,它们什么都不做。此外,当选择核心课程的复选框时,通常隐藏的ABC 702复选框似乎随机出现。我无法弄清楚原因。

    from tkinter import *

    class Application(Frame):
        def __init__(self, master):
            Frame.__init__(self, master)
            self.grid()
            self.create_widgets()
            # self.grid()
            # self.create_widgets()

        def create_widgets(self):
            Label(self, text="How many of the core courses have you completed so far?"
                  ).grid(row=1, column=0, sticky=W)

            self.checkBoxA = BooleanVar()
            Checkbutton(self,
                        text="ABC 501",
                        variable=self.checkBoxA,
                        command=self.update_text
                        ).grid(row=2, column=0, sticky=W)

            self.checkBoxB = BooleanVar()
            Checkbutton(self,
                        text="ABC 502",
                        variable=self.checkBoxB,
                        command=self.update_text
                        ).grid(row=3, column=0, sticky=W)

            self.checkBoxC = BooleanVar()
            Checkbutton(self,
                        text="ABC 601",
                        variable=self.checkBoxC,
                        command=self.update_text
                        ).grid(row=4, column=0, sticky=W)
            self.checkBoxD = BooleanVar()
            Checkbutton(self,
                        text="ABC 602",
                        variable=self.checkBoxD,
                        command=self.update_text
                        ).grid(row=5, column=0, sticky=W)
            self.checkBoxE = BooleanVar()
            Checkbutton(self,
                        text="ABC 603",
                        variable=self.checkBoxE,
                        command=self.update_text
                        ).grid(row=6, column=0, sticky=W)
            self.checkBoxF = BooleanVar()
            Checkbutton(self,
                        text="ABC 701",
                        variable=self.checkBoxF,
                        command=self.update_text
                        ).grid(row=7, column=0, sticky=W)

            self.results_txt = Text(self, width=80, height=10, wrap=WORD)
            self.results_txt.grid(row=8, column=0, columnspan=3)

            Label(self, text="Which focus are you enrolled in?"
                  ).grid(row=1, column=1, sticky=W)

            self.checkBoxF1 = BooleanVar()
            Checkbutton(self,
                        text="Focus #1",
                        variable=self.checkBoxF1,
                        command=self.update_text
                        ).grid(row=2, column=1, sticky=W)

            # if self.checkBoxF1.get():
            #     self.checkBoxF1A = BooleanVar()
            #     Checkbutton(self,
            #                 text="ABC 503",
            #                 variable=self.checkBoxF1A,
            #                 command=self.update_text
            #                 ).grid(row=3, column=1, sticky=W)


        def update_text(self):
            courses = ""
            counter = 0
            focusCounter = 0

        ##The checkboxes for the focus courses do not display text at the bottom
            ##The ABC 702 checkbox randomly appears when clicking core courses
            ##Is this related to reusing self vs creating another attribute?
            if self.checkBoxF1.get():
                self.checkBoxF1A = BooleanVar()
                Checkbutton(self,
                            text="ABC 503",
                            variable=self.checkBoxF1A,
                            command=self.update_text
                            ).grid(row=3, column=1, sticky=W)

                self.checkBoxF1B = BooleanVar()
                Checkbutton(self,
                            text="ABC 504",
                            variable=self.checkBoxF1B,
                            command=self.update_text
                            ).grid(row=4, column=1, sticky=W)

                self.checkBoxF1C = BooleanVar()
                Checkbutton(self,
                            text="ABC 505",
                            variable=self.checkBoxF1C,
                            command=self.update_text
                            ).grid(row=5, column=1, sticky=W)

            self.checkBoxF1D = BooleanVar()
            Checkbutton(self,
                        text="ABC 702",
                        variable=self.checkBoxF1D,
                        command=self.update_text
                        ).grid(row=6, column=1, sticky=W)

            if self.checkBoxA.get():
                courses += "Introductory class \n"
                counter += 1

            if self.checkBoxB.get():
                courses += "Next level class description \n"
                counter += 1

            if self.checkBoxC.get():
                courses += "Core class #3 \n"
                counter += 1

            if self.checkBoxD.get():
                courses += "Another core class \n"
                counter += 1

            if self.checkBoxE.get():
                courses += "A higher level class \n"
                counter += 1

            if self.checkBoxF.get():
                courses += "An advanced class \n"
                counter += 1

            if self.checkBoxF1A.get():
                specialty = "Focused class #1"
                focusCounter += 1

            if self.checkBoxF1B.get():
                specialty = "Focused class #2"
                focusCounter += 1

            if self.checkBoxF1C.get():
                specialty = "Focused class #3"
                focusCounter += 1

            if self.checkBoxF1D.get():
                specialty = "Focused class #4"
                focusCounter += 1

            self.results_txt.delete(0.0, END)
            self.results_txt.insert(0.0, courses)
            if focusCounter > 0:    #this means the user selected at least 1 focus course
                self.results_txt.insert(0.0, specialty)
            if counter == 6:
                congrats = ("\n Congratulations on completing all of your core courses! \n \n")
                self.results_txt.insert(0.0, congrats)
            # print(focusCounter)

    root = Tk()
    root.title("This is where the title goes")
    app = Application(root)
    root.mainloop()

1 个答案:

答案 0 :(得分:0)

如果您首先点击复选框Focus #1,则会显示新的复选框,并且它们按预期工作

但如果您先单击其他复选框,则会收到错误消息

  

AttributeError:'应用程序'对象没有属性' checkBoxF1A'

问题是因为update_text() checkBoxF1A使用了checkBoxF1Bif self.checkBoxF1A.get(): specialty = "Focused class #1" focusCounter += 1 等等,即使它们还不存在。

self.checkBoxF1A = BooleanVar()

create_widgets()中创建if self.checkBoxF1.get() - 不在grid()中,您就不会有问题。

您甚至可以在create_widgets()

中创建没有 self.checkbutton_F1 = Checkbuttons(...) 的复选框
if self.checkBoxF1A.get():

并在self.checkbutton_F1.grid(...)中使用else:来显示小部件和(在self.checkbutton_F1.grid_forget()Key中隐藏它。