【问题标题】:tkinter does not properly display data with check buttonstkinter 无法使用复选按钮正确显示数据
【发布时间】:2021-07-28 21:51:05
【问题描述】:

我正在制作类似于“待办事项列表”的内容,其中包含指示任务状态的检查按钮(doneto-do)。检查按钮进行回调和更改状态。我认为与“后院”有关的一切都有效。当我单击按钮时,对象中的状态会发生变化,但无法正常显示。

当我第一次显示任务列表时,它会正确显示所有内容,但是当我将另一个任务添加到现有列表并显示它时,就会出现问题。我发现它可能会以某种方式覆盖现有对象上的任务,但老实说,我不知道如何解决这个问题......

代码如下:

c_body(带有类的文件):

import datetime

class CalendarObj:
    def __init__(self, task, date, time, stat = False):
        self.task = task
        self.stat = stat
        self.date = date
        self.time = time
    def displayObj(self):
        return self.task + ' ' +  self.date  + ' ' + self.time
    def nowDate():
        date = datetime.datetime.today().strftime("%d %B")
        return date
    def nowTime():
        time = datetime.datetime.today().strftime("%H:%M")
        return time

c_view:

import c_body
from tkinter import *

calendar = []
status = []
checkbuttons = []
textlist = []

def config():
    global listback, main_root, button_display_list, button_add_task, button_delete_task, button_delete_all_done, button_exit_app
    main_root = Tk()
    main_root.title('Lista zadan')
    main_root.geometry("500x500")
    button_display_list = Button(main_root, text='Display Tasks', width=12, command=display)
    button_display_list.grid(column=0, row=4)
    button_add_task = Button(main_root, text='Add Task', width=12, command=add)
    button_add_task.grid(column=0, row=0)
    button_delete_task = Button(main_root, text='Delete Task', width=12)
    button_delete_task.grid(column=0, row=1)
    button_delete_all_done = Button(main_root, text='Delete All Done', width=12)
    button_delete_all_done.grid(column=0, row=2)
    button_exit_app = Button(main_root, text='EXIT', width=12, command=exit_window)
    button_exit_app.grid(column=0, row=3)

def exit_window():
    main_root.destroy()

def add():
    global task, button_add
    insert_root = Tk()
    insert_root.title('Dodaj zadanie:')
    task = Entry(insert_root, width=80)
    task.grid(column=0, row=0, padx=20, pady=20)

    def add_task():
        global task_obj, calendar
        date = c_body.CalendarObj.nowDate()
        time = c_body.CalendarObj.nowTime()
        task_obj = c_body.CalendarObj(task.get(), date, time)
        calendar.append(task_obj)
        insert_root.destroy()

    button_add = Button(insert_root, text='dodaj zadanie', command=add_task)
    button_add.grid(column=0, row=1, sticky=E, padx=20, pady=20)
    insert_root.mainloop()

def callback_on_checkbutton_click():
    print("One of the Checkbuttons clicked!")
    for i in range(len(calendar)):
        print('\tOld calendar[' + str(i) + '] state: ' + calendar[i].displayObj())
        calendar[i].stat = status[i].get()
        print('\t\tNew calendar[' + str(i) + '] state: ' + calendar[i].displayObj())

def display():
    for i in range(len(calendar)):
        lp = i + 1
        print("status dla:", lp, calendar[i].stat)
        x = (str(lp) + '. ' + calendar[i].displayObj())
        textlist.append(x)
        status.append(BooleanVar())
        if calendar[i].stat == False:
            print("display() called. For index i: ", i, ' setting checkbutton value to checked (onvalue=0)')
            status[i].set(False)
        elif calendar[i].stat == True:
            print("display() called. For index i: ", i, ' setting checkbutton value to unchecked (offvalue=1)')
            status[i].set(True)
        checkbuttons.append(
            Checkbutton(
                master=main_root,
                text=textlist[i],
                variable=status[i],
                onvalue=True,
                offvalue=False,
                command=callback_on_checkbutton_click
            )
        )
        checkbuttons[i].grid(column=1, row=i, sticky=W)

if __name__ == '__main__':
    config()
    main_root.mainloop()

【问题讨论】:

  • 什么是“后院”?怎么显示不正常?
  • 多次调用Tk() 会导致 Tk Vars 无法工作(无需付出很多额外的努力)。请改用Toplevel() 创建其他窗口。
  • master=main_root 添加到BooleanVar()
  • 那么清除显示的任务(过期数据)并显示更新数据的最佳方法是什么?

标签: python python-3.x tkinter


【解决方案1】:

问题解决了。

  1. 首先,textlist.appendstatus.append 需要移动到函数`add()。因为每次我显示数据时,它都会在我的列表中添加不必要的额外位置。
  2. 在使用display()函数之前,需要清除checkbuttons的列表。在该函数的先前版本中,每次调用迭代时,它都会将checkbuttons 添加到现有数据中。简而言之:在显示新数据之前,必须清除带有数据的容器。

这是我的修复和更改的代码:

def add():
    global task, button_add
    insert_root = Toplevel()
    insert_root.title('Dodaj zadanie:')
    task = Entry(insert_root, width=80)
    task.grid(column=0, row=0, padx=20, pady=20)
    def add_task():
        global task_obj, calendar
        date = c_body.CalendarObj.nowDate()
        time = c_body.CalendarObj.nowTime()
        task_obj = c_body.CalendarObj(task.get(), date, time)
        calendar.append(task_obj)
        textlist.append(StringVar())
        status.append(BooleanVar())
        insert_root.destroy()
    button_add = Button(insert_root, text='dodaj zadanie', command=add_task)
    button_add.grid(column=0, row=1, sticky=E, padx=20, pady=20)
    insert_root.mainloop()

def display():
    global calendar, textlist, status, checkbuttons
    checkbuttons.clear()
    for i in range(len(calendar)):
        lp = i + 1
        print("status dla:", lp, calendar[i].stat)
        x = (str(lp) + '. ' + calendar[i].displayObj())
        textlist[i].set(x)
        if calendar[i].stat == False:
            print("display() called. For index i: ", i, ' setting checkbutton value to checked (onvalue=0)')
            status[i].set(False)
        elif calendar[i].stat == True:
            print("display() called. For index i: ", i, ' setting checkbutton value to unchecked (offvalue=1)')
            status[i].set(True)
        checkbuttons.append(
            Checkbutton(
                master=main_root,
                textvariable=textlist[i],
                variable=status[i],
                onvalue=True,
                offvalue=False,
                command=callback_on_checkbutton_click
            )
        )
        checkbuttons[i].grid(column=1, row=i+1, sticky=W)

【讨论】:

    猜你喜欢
    • 2014-03-01
    • 2016-10-23
    • 2016-12-25
    • 2017-01-06
    • 1970-01-01
    • 2018-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多