如何清除循环中的 tkinter 标签以及如何在单击另一个按钮时终止循环

How to clear the tkinter label in loop and how to terminate the loop upon clicking another button

我是 python Tkinter 的初学者,我试图在单击相应按钮时打印不同列表中的字符。单击按钮后,只要用户按下键盘上的任意键,列表中的项目就会继续显示。按 Enter 键后,它应该停止从当前列表中显示。 1. canvas 不会在下一次迭代中清除。新标签创建并放置在旧标签的顶部。我正在分享我得到的输出的图片。

我知道 w.delete('all') 方法,但是,在使用它之后,我的 python 崩溃了。有人可以建议我如何修改它以完全擦除吗?

  1. 如何在按钮1循环时按按钮2切换到按钮2的方法。我使用了 or 运算符,但是我的 python 崩溃了。现在,我只能在按下回车键时退出。如果我按下另一个按钮,python 就会崩溃。 我可以知道我的 python 崩溃的原因吗?

我的代码是:

import tkinter as tk
import msvcrt
import random


root= tk.Tk()
myCanvas = tk.Canvas(root, width = 500, height = 200)
myCanvas.pack()

w = tk.Canvas(root, width = 500, height = 200)
w.place(relx= 0.5, rely=0.1)



def printing_2():
    flag2=1
    name_list=['Mia Jennete Moi' , 'cara', 'juili', 'meera', 'ed']
    input1 = msvcrt.getwch()
    label2 = tk.Label(root, font=('Courier', 15))
    w.create_window(60, 40, window=label2)
    if flag1!=1 or input1!='\r':
        label2.config(text=random.choice(name_list))
        root.after(10, printing_2)

def printing_1():
    flag1=1
    name_list=['Rui Sagar' , 'Nana Kana', 'Mike', 'Bob', 'Drake']
    input1 = msvcrt.getwch()
    if flag2!=1 or input1!='\r':
        label2 = tk.Label(root, text=random.choice(name_list), font=('Courier', 15))
        w.create_window(60, 40, window=label2)
        root.after(10, printing_1)

flag1=0
flag2=0
B1 = tk.Button(root, text ="Option 1", font=('Courier', 12), command= printing_1)
myCanvas.create_window(40, 30, window=B1)
B2 = tk.Button(root, text ="Option 2", font=('Courier', 12), command= printing_2)
myCanvas.create_window(40, 80, window=B2)

root.mainloop()

您应该在开始时创建空标签,之后只更改现有标签中的文本

 label2.config(text=random.choice(name_list))

 label2["text"] = random.choice(name_list))

当你按下按钮时,你可以 运行 改变值 flag1flag2 的功能(一组 True 和另一组 False)然后 运行 函数将 运行 使用 after()

循环

而且你必须使用global来设置外部变量。如果没有 global,您将创建局部变量。

您可以使用更易读的名称 running_1running_2 代替 flag1flag2 并使用值 True/False 代替 0/1

而不是 msvcrt 你可以使用 root.bind("<Return>", stop) 到 运行 函数 stop() 这将设置 running_1 = Falserunning_2 = False 停止所有loop.s


最少的工作代码

顺便说一句:我在 after() 中使用 500 来降低它的速度并查看它显示的值。

import tkinter as tk
import random

# --- functions

def printing_1():
    global running_1
    global running_2
    global name_list

    running_1 = True
    running_2 = False  # stop other list
    name_list = ['Rui Sagar' , 'Nana Kana', 'Mike', 'Bob', 'Drake']

    print("start list 1")
    update_1()

def update_1():
    if running_1:
        label["text"] = random.choice(name_list)
        root.after(500, update_1)

def printing_2():
    global running_1
    global running_2
    global name_list

    running_1 = False  # stop other list
    running_2 = True
    name_list = ['Mia Jennete Moi' , 'cara', 'juili', 'meera', 'ed']

    print("start list 2")
    update_2()

def update_2():
    if running_2:
        label["text"] = random.choice(name_list)
        root.after(500, update_2)

def stop(event):
    global running_1
    global running_2

    running_1 = False
    running_2 = False

    print('stoped')

# --- main ---

running_1 = False
running_2 = False
name_list = None

root = tk.Tk()

root.bind('<Return>', stop)

canvas = tk.Canvas(root, width=500, height=200)
canvas.pack()

w = tk.Canvas(root, width=500, height=200)
w.place(relx=0.5, rely=0.1)

label = tk.Label(root)
w.create_window(60, 40, window=label)

button1 = tk.Button(root, text="Option 1", command=printing_1)
canvas.create_window(40, 30, window=button1)

button2 = tk.Button(root, text="Option 2", command=printing_2)
canvas.create_window(40, 80, window=button2)

root.mainloop()

编辑:

您也可以减少使用一个 running 和一个函数 update_label()

我检查 running 是否是 True 然后我不 运行 新循环但是它会自动使用已经 运行ning 循环但是新的 name_list

import tkinter as tk
import random

# --- functions

def printing_1():
    global name_list
    global running

    name_list = ['Rui Sagar' , 'Nana Kana', 'Mike', 'Bob', 'Drake']

    if not running:
        running = True
        update_label()

def printing_2():
    global name_list
    global running

    name_list = ['Mia Jennete Moi' , 'cara', 'juili', 'meera', 'ed']

    if not running:
        running = True
        update_label()

def update_label():

    if running:
        label["text"] = random.choice(name_list)
        root.after(500, update_label)

def stop(event):
    global running

    running = False

    print('stoped')

# --- main ---

name_list = None
running = False

root = tk.Tk()

root.bind('<Return>', stop)

canvas = tk.Canvas(root, width=500, height=200)
canvas.pack()

w = tk.Canvas(root, width=500, height=200)
w.place(relx=0.5, rely=0.1)

label = tk.Label(root)
w.create_window(60, 40, window=label)

button1 = tk.Button(root, text="Option 1", command=printing_1)
canvas.create_window(40, 30, window=button1)

button2 = tk.Button(root, text="Option 2", command=printing_2)
canvas.create_window(40, 80, window=button2)

root.mainloop()

编辑:

如果您只想在按下按键时更新标签,那么您不需要 msvcrtafter,而只需要 bind('<Key>', function_name)

import tkinter as tk
import random

# --- functions

def printing_1():
    """Assign new list and update label"""
    global name_list

    name_list = ['Rui Sagar' , 'Nana Kana', 'Mike', 'Bob', 'Drake']

    # set value at start
    update_label()

def printing_2():
    """Assign new list and update label"""
    global name_list

    name_list = ['Mia Jennete Moi' , 'cara', 'juili', 'meera', 'ed']

    # set value at start
    update_label()

def on_key(event):
    """Update label if list is assigned to `name_list`
       and pressed key is different then `Return`"""
    if name_list and event.keysym != 'Return':
        update_label()

def update_label():
    label["text"] = random.choice(name_list)

# --- main ---

name_list = None

root = tk.Tk()
root.bind('<Key>', on_key) # run function when pressed any key

canvas = tk.Canvas(root, width=500, height=200)
canvas.pack()

w = tk.Canvas(root, width=500, height=200)
w.place(relx=0.5, rely=0.1)

label = tk.Label(root)
w.create_window(60, 40, window=label)

button1 = tk.Button(root, text="Option 1", command=printing_1)
canvas.create_window(40, 30, window=button1)

button2 = tk.Button(root, text="Option 2", command=printing_2)
canvas.create_window(40, 80, window=button2)

root.mainloop()