是/否在GUI中用于bool属性的checkbutton来管理对象列表

时间:2017-04-21 23:59:35

标签: python user-interface checkbox tkinter boolean

对于这个gui,我有五个对象:全名,联系信息,所需语言,难度级别和语言经验。我的这项任务的设计是它是一个简单的“外语书店请求管理器”,我可以在其中添加,编辑和删除外语书籍的请求。

我希望前四个对象是Entry字段,然后第五个(体验)是一个复选框,对于这个数据属性我想让它成为一个bool,表示是/否状态是否有人有经验的问题他们要求的语言。

从我的教科书和之前的示例中,我能够创建一个基本的y / n复选框,但是它出现在我的窗口顶部,而我仍然坚持如何编写它以便体验数据属性是一个检查按钮bool属性而不是Entry表单,当我使用 str 方法使用ListboxSelect显示每个属性的值时,会出现选择的任何内容(是或否/是真还是假)。

当我尝试将第五个属性与其余属性分开以便它是一个复选框而不是Entry表单时,我无法运行我的程序,并且在尝试创建bool属性时我也遇到了错误并且不确定是否我需要先修复bool属性或复选框,无论它们是否齐头并进等等

我的问题是: 1)我是否使用正确的格式为bool属性创建y / n复选框? 2)如何编写复选框以使其出现在体验标签旁边,而不是当前编写的Entry表单?

我很抱歉,如果这是非常愚蠢的问题,但是我花了7个小时试图解决这些问题并且没有弄清楚我做错了什么以及如何纠正并添加了完善这个程序的必要条件。

与Checkbox按钮无关,使用ListboxSelect小部件,它显示我正在寻找的地址上的对象,但实际上并没有显示我原本认为已编写的内容,该内容将显示: '全名:,联系信息:,语言:,难度:,语言经验:(那么这里是我尚未想到的布尔属性复选框的答案)'在我的书面请求部分程序。我正在包括我的程序和当前问题的图片以及一些代码。 does not display what I had thought I had written

import tkinter
import request

class Application:
    def __init__(self):
        self.__requests = []
        self.__selected_index = 0
        self.__selected_request = None

        self.__window = tkinter.Tk()
        self.__window.title('Foreign Language Bookstore Request Manager')

        self.__full_name = tkinter.StringVar()
        self.__contact_info = tkinter.StringVar()
        self.__language = tkinter.StringVar()
        self.__difficulty = tkinter.StringVar()
        self.__experience = tkinter.StringVar()

        self.cb_var1 = tkinter.IntVar()
        self.cb_var2 = tkinter.IntVar()

        self.cb_var1.set(0)
        self.cb_var2.set(0)

        self.cb1 = tkinter.Checkbutton(self.__window, \
                                       text='Yes', variable=self.cb_var1)
        self.cb2 = tkinter.Checkbutton(self.__window, \
                                       text='No', variable=self.cb_var2)

        self.cb1.pack()
        self.cb2.pack()



        self.build_input_frame('Full Name: ', self.__full_name)
        self.build_input_frame('Contact info (phone, email): ', self.__contact_info)
        self.build_input_frame('Desired language: ', self.__language)
        self.build_input_frame('Difficulty level 1- beginner, 2- intermediate, 3- advanced: ', self.__difficulty)
        self.build_input_frame('Experience with language? ', self.__experience)

        frame = tkinter.Frame(self.__window)
        self.__add_button = tkinter.Button(frame, text='Add Request',
            anchor=tkinter.W, command=self.add_request)
        self.__add_button.pack(side='left')
        self.__save_button = tkinter.Button(frame, text='Save Request',
            anchor=tkinter.W, command=self.save_request, state=tkinter.DISABLED)
        self.__save_button.pack(side='left')
        self.__delete_button = tkinter.Button(frame, text='Delete Request',
            anchor=tkinter.W,
            command=self.delete_request, state=tkinter.DISABLED)
        self.__delete_button.pack()
        frame.pack()

        frame = tkinter.Frame(self.__window)
        label = tkinter.Label(frame, text='Book Requests')
        self.__requests_list = tkinter.Listbox(frame, width=80,
            selectmode=tkinter.SINGLE)

        self.__requests_list.bind('<<ListboxSelect>>', self.select_request)
        label.pack()
        self.__requests_list.pack()
        frame.pack()

    def build_input_frame(self, label, textvariable):
        """Build the top frames of the window for being able to enter data."""
        frame = tkinter.Frame(self.__window)
        label = tkinter.Label(frame, text=label, width=50, anchor=tkinter.W)
        entry = tkinter.Entry(frame, textvariable=textvariable, width=30)
        label.pack(side='left')
        entry.pack(side='right')
        frame.pack()

    def add_request(self):
        """Get the values from the bound variables and create a new Request."""
        r = request.Request(self.__full_name.get(), self.__contact_info.get(),
            self.__language.get(), self.__difficulty.get(),
                            self.__experience.get())
        self.__requests.append(r)

        self.__requests_list.insert(tkinter.END, str(r))

    def select_request(self, event):
        """Get the Request at the index selected, and set the Entry fields
           with its values."""
        # Get the current selection from the Listbox. curselection() returns
        # a tuple and we want the first item
        # Get the current selection from the Listbox. curselection() returns
        # a tuple and we want the first item
        current_selection = self.__requests_list.curselection()
        if current_selection:
            self.__selected_index = current_selection[0]

            # Grab the Request object from self.__request at that index
            self.__selected_request = self.__requests[self.__selected_index]

            # Use it's values to set the StringVars
            self.__full_name.set(self.__selected_request.get_full_name())
            self.__contact_info.set(self.__selected_request.get_contact_info())
            self.__language.set(self.__selected_request.get_language())
            self.__difficulty.set(self.__selected_request.get_difficulty())
            self.__experience.set(self.__selected_request.get_experience())

            # Make sure the Save button is enabled
            self.__save_button.config(state=tkinter.NORMAL)
            self.__delete_button.config(state=tkinter.NORMAL)


    def delete_request(self):
        """Remov the Request at the index selected then set the Entry fields
           to empty values."""
        if 0 <= self.__selected_index < len(self.__requests):
            del self.__requests[self.__selected_index]
            self.__requests_list.delete(self.__selected_index)

            # Call the method to deselect the item, clear Entry fields, and
            # disable buttons.
            self.after_selected_operation()

    def save_request(self):
        """Set the selected Request's fields and then persist its __str__
           representation to the Listbox."""
        self.__selected_request.set_full_name(self.__full_name.get())
        self.__selected_request.set_contact_info(self.__contact_info.get())
        self.__selected_request.set_language(self.__language.get())
        self.__selected_request.set_difficulty(self.__difficulty.get())
        self.__selected_request.set_experience(self.__experience.get())

        # Listbox widgets don't have a way of updating an item in place. So
        # We'll delete the item at a particular index and then add it
        self.__requests_list.delete(self.__selected_index)
        self.__requests_list.insert(self.__selected_index,
            str(self.__selected_request))

        # Call the method to deselect the item, clear Entry fields, and
        # disable buttons.
        self.after_selected_operation()

    def after_selected_operation(self):
        """Clear the selected index, request, and disable buttons."""
        self.__selected_index = -1
        self.__selected_request = None

        self.__full_name.set('')
        self.__contact_info.set('')
        self.__language.set('')
        self.__difficulty.set('')
        self.__experience.set('')

        # Make sure the Save and Delete buttons are disabled
        self.__save_button.config(state=tkinter.DISABLED)
        self.__delete_button.config(state=tkinter.DISABLED)

1 个答案:

答案 0 :(得分:0)

不要使用Checkbutton,最好在此处使用Radiobutton,因为您提供了yes / no选项。你可以使用Checkbutton,但在这种情况下只提供一个更有效率。然后,您还可以实现所需的程序结构。

try:
    import Tkinter as tk
except ImportError:
    import tkinter as tk


class Window(tk.Tk):
    def __init__(self):
        # This is better practice when using Tkinter windows 
        # as this is a true OOP GUI implementation
        tk.Tk.__init__(self)
        self.boolean_var = tk.BooleanVar()
        self.option_yes = tk.Radiobutton(self, text="Yes", variable=self.boolean_var,
                                         value=True, command=self.callback)
        self.option_no = tk.Radiobutton(self, text="No", variable=self.boolean_var,
                                        value=False, command=self.callback)
        self.option_yes.grid(row=0, column=0)
        self.option_no.grid(row=0, column=1)

    def callback(self):
        print self.boolean_var.get()


Window().mainloop()

此方法还可以防止同时选择“是”和“否”,并且由于您只需要使用单个BooleanVar对象,因此可以提高内存效率。至于您的布局问题,使用您提供的代码进行故障排除非常困难。但是,如果您需要创建一个包含十个以上小部件的更复杂的布局,我建议使用grid几何管理器,因为它可以更轻松地管理您的布局并在以后添加更多小部件。可以找到这个几何管理器的一个很好的解释和参考here。我发现它在过去非常有用。