python - tkinter按钮颜色无故闪烁
问题描述
我正在制作一个刷新函数来更改 tkinter 中按钮的颜色,问题是这种颜色必须来自另一个返回字符串的函数,并且每次我更新所有内容时都会闪烁片刻。
我试过使用 StringVar() 并且只更新颜色而不更新整个布局,但它只会卡在循环中并且永远不会显示布局。我还尝试将所有对象转储到一个列表中,然后一次更改整个网格而不是一个一个地更改,但没有取得多大成功。
代码的核心是:
root = Tk()
frame=Frame(root)
root.title("States")
Grid.rowconfigure(root, 0, weight=1)
Grid.columnconfigure(root, 0, weight=1)
frame.grid(row=0, column=0, sticky=N+S+E+W)
grid=Frame(frame)
grid.grid(sticky=N+S+E+W, column=0, row=7, columnspan=2)
Grid.rowconfigure(frame, 7, weight=1)
Grid.columnconfigure(frame, 0, weight=1)
def loop_1():
for x in range(4):
for y in range(3):
btnxy(x,y,frame)
for x in range(4):
Grid.columnconfigure(frame, x, weight=1)
for y in range(3):
Grid.rowconfigure(frame, y, weight=1)
root.after(1000,loop_1)
loop_1()
btnxy 创建一个按钮并将其放置在网格中
def btnxy(x,y,frame):
index=4*y+x+1
if index>8:
message="Relay "+str(index-8)
btn = Button(frame,text=message, command=lambda p=(index-8): Relay(index-8), bg="blue", relief="groove", height=10, width=30)
else:
message="Entrée "+str(index)
color=check_color(index)
btn = Button(frame,text=message, command="", bg=color, relief="groove", height=10, width=30)
btn.grid(column=x, row=y, sticky=N+S+E+W
check_color 是一个函数,它返回一个带有“red”或“green”的字符串
据我了解,这不应该占用太多的处理能力,因此很容易更新,但它会闪烁。
解决方案
我试图对您的代码进行一些修改,但老实说我无法让它工作并且不理解它背后的逻辑。有很多地方不ok:
1)全球进口不好。不要使用from tkinter import *
. 而是使用import tkinter as tk
. 这提高了可读性,使事情变得明确并具有许多其他好处(您可以在 Google 上轻松找到更多信息)
2)您使用该功能loop1
将按钮放置在所需的框架中。这一切都很好,但你不要将框架作为参数传递,同样适用于root
. 如果您确实修改了代码以解决此问题,您将看到闪烁消失,但root.after
由于缺少参数您会遇到问题。
这里的解决方案是更改应用程序的结构,以便按钮和根目录易于访问和使用。让您入门的一种方法可以是以下代码:
import tkinter as tk
from random import shuffle
def get_random_colors():
colors = ["red" for i in range(4)] + ["blue" for i in range(4)] + ["green" for i in range(4)]
shuffle(colors)
return colors
class MyGUI(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.frame = tk.Frame()
self.frame.pack()
self.n_rows = 3
self.n_cols = 4
self.bt_list = []
for x in range(self.n_rows):
for y in range(self.n_cols):
self.bt_list.append(tk.Button(self.frame, text="Button {}.{}".format(x, y)))
self.bt_list[-1].grid(row=x, column=y)
def change_colors(self):
colors = get_random_colors()
for index, button in enumerate(self.bt_list):
button.configure(bg=colors[index])
self.after(5000, self.change_colors)
root = MyGUI()
root.after(5000, root.change_colors)
root.mainloop()
首先,主框架现在是类的一个属性,所以self.frame
只要我需要在类中调用它就足够了,只要将 self 传递给函数。
然后我决定将按钮存储在一个列表中,这样我就可以在课堂上通过self
. 这很有用,因为在 change_colors 函数中,我可以遍历列表并通过.configure(bg=<color here>)
.
最后一点是.after
。我在定义之后在类构造函数外部调用它一次root
,然后在change_colors
函数内部使用self
. 最终代码应该每 5 秒随机更改一次按钮的颜色。
希望能帮助到你!
推荐阅读
- node.js - 如何为 socket.io 中的每个房间生成自定义链接
- javascript - Javascript/React 如何从 Promise 中返回数据?
- selenium - 在 XPath 中,我如何在两个元素之间寻找一些东西?
- php - 从 php laravel 中的 url 下载文件
- c++ - 当我在参数中使用类似技术的类型特征时无法推断模板
- cluster-computing - Slurm:一些工作卡在状态运行但资源可用
- node.js - Postgress 查询返回对象而不是字符串
- python - 将 STATA 4 文件 (.DTA) 转换为 CSV/EXCEL
- c++ - 配置虚拟U盘,快速复制虚拟U盘/驱动器中由被动设备保存的图像/文件
- java - JRCsvExporter 生成第一行空白的 csv