Tkinter 标签覆盖:更新还是刷新?

Tkinter label overwrite: update or refresh?

我正在 Python 中使用 Tkinter 使用 GUI 构建调度器。

我基本上遇到了与 this question 相同的问题:时间表 table 上的标签没有被替换;另一个排在最前面。但是由于我动态创建 table 我没有标签的变量名称。

那么我还可以在没有变量名的情况下更新标签小部件的文本值吗? StringVar 有办法做到这一点吗?或者如何正确刷新 table?

from tkinter import *

#DATA
class Staff(object):
    def __init__(self, name, ID):
        self.name = name #this data comes from storage
        self.ID = ID #this is for this instance, starting from 0 (for use with grid)

ID42 = Staff("Joe", 0)
ID25 = Staff("George", 1)
ID84 = Staff("Eva", 2)

stafflist = [ID42, ID25, ID84]
weekdays = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]

scheduleDictionary = {}

for r in range(0,3):
    scheduleDictionary[r] = ['shift','shift','shift','shift','shift','shift','shift','shift','shift','shift','shift','shift','shift','shift']

#Build window
root = Tk()

ScheduleFrame = Frame(root)
ScheduleFrame.pack()

#(Re)Build schedule on screen
def BuildSchedule():

    for r in range(1,4):
        Label(ScheduleFrame, text=stafflist[r-1].name).grid(row=r, column=0)

    for c in range(1,15):
        Label(ScheduleFrame, text=weekdays[(c-1)%7]).grid(row=0, column=c)

    for r in range(1,4):
        for c in range(1,15):
            Label(ScheduleFrame, text=scheduleDictionary[r-1][c-1]).grid(row=r, column=c)

#Mouse events
def mouse(event):
    y = event.widget.grid_info()['row'] - 1
    x = event.widget.grid_info()['column'] - 1
    print(x,y)
    shiftSelection(y,x)

#shiftSelection
def shiftSelection(row, column):
    shifts_window = Tk()
    box = Listbox(shifts_window)
    box.insert(1, "MR")
    box.insert(2, "AR")
    box.insert(3, "ER")
    box.pack()
    button = Button(shifts_window, text="Okay", command = lambda: selectShift(shifts_window, box.get(ACTIVE),row, column))
    button.pack()

def selectShift(shifts_window, shift,row, column):
    scheduleDictionary[row][column] = shift
    BuildSchedule()
    shifts_window.destroy()

root.bind("<Button-1>", mouse)

BuildSchedule()

root.mainloop()

您应该始终为标签分配名称,如果您想更改或更新标签的值,请使用 config()

import tkinter
from tkinter import *

#DATA
class Staff(object):
    def __init__(self, name, ID):
        self.name = name #this data comes from storage
        self.ID = ID #this is for this instance, starting from 0 (for use with grid)

ID42 = Staff("Joe", 0)
ID25 = Staff("George", 1)
ID84 = Staff("Eva", 2)

stafflist = [ID42, ID25, ID84]
weekdays = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]

scheduleDictionary = {}

for r in range(0,3):
    scheduleDictionary[r] = ['shift','shift','shift','shift','shift','shift','shift','shift','shift','shift','shift','shift','shift','shift']

#Build window
root = Tk()

ScheduleFrame = Frame(root)
ScheduleFrame.pack()

#(Re)Build schedule on screen
def BuildSchedule():

    for r in range(1,4):
        abcd = tkinter.Label(ScheduleFrame, text=stafflist[r-1].name).grid(row=r, column=0)

    for c in range(1,15):
        efgh = tkinter.Label(ScheduleFrame, text=weekdays[(c-1)%7]).grid(row=0, column=c)

    for r in range(1,4):
        for c in range(1,15):
            ijkl = tkinter.Label(ScheduleFrame, text=scheduleDictionary[r-1][c-1]).grid(row=r, column=c)

如果您希望更新标签,请使用 config()set() 小改动,只是给每个变量命名,你想改就改。

解决方案是创建一次标签小部件,保存对每个小部件的引用,然后更改小部件而不是创建新的小部件。

由于您似乎在构建类似 table 的结构,因此请使用(行,列)元组将小部件存储在字典中。例如:

#(Re)Build schedule on screen
def BuildSchedule():
    global widgets
    widgets = {}

    for r in range(1,4):
        label = Label(ScheduleFrame, text=stafflist[r-1].name)
        label.grid(row=r, column=0)
        widgets[(r,0)] = label

    for c in range(1,15):
        label = Label(ScheduleFrame, text=weekdays[(c-1)%7])
        label.grid(row=0, column=c)
        widgets[(0,c)] = label

    for r in range(1,4):
        for c in range(1,15):
            label = Label(ScheduleFrame, text=scheduleDictionary[r-1][c-1])
            label.grid(row=r, column=c)
            widgets[(r,c)] = label

稍后,您可以使用 configure 更改标签。例如,要更改第 1 行第 10 列的标签,您可以这样做:

widgets[(1,10)].configure(text="the new text")