tkinter画布颜色不变
我有一个两个tkinter画布,需要根据我从其他模块收到的数据更改颜色。基本上为0,1 例如:如果接收到1,则将canvas1设置为黑色,将canvas2设置为绿色,如果接收到0,则反之亦然。tkinter画布颜色不变
我已经使用多处理队列技术来接收数据,但是当我尝试应用更改时,它并未更新?我假设有self
。
这里是我的代码片段: main.py
import multiprocessing from udpsocket import *
from ui import *
if __name__ == "__main__":
queue = multiprocessing.Queue()
ui = multiprocessing.Process(target=uiMain, args=(queue,))
ui.daemon = True
ui.start()
udpMain(queue)
udpsocket.py:
import time import struct
import socket
import ui
MYPORT = 51506
MYGROUP_4 = '225.0.0.1'
MYTTL = 1 # Increase to reach other networks
def udpMain(queue):
app = udpsocket(queue)
class udpsocket():
def __init__(self,queue):
print('UDP Socket started')
group = MYGROUP_4
self.receiver('225.0.0.1',queue)
def receiver(self,group,queue):
print('Receiver')
addrinfo = socket.getaddrinfo(group, None)[0]
# Create a socket
s = socket.socket(addrinfo[0], socket.SOCK_DGRAM)
#.... reuse address, binding, add membership
# loop, send data to ui
while True:
data, sender = s.recvfrom(1500)
while data[-1:] == '\0': data = data[:-1] # Strip trailing \0's
print (str(sender) + ' ' + str(ord(data)))
queue.put(ord(data))
ui.do_something(queue)
ui.py:
from tkinter import * from tkinter import ttk
import multiprocessing
def uiMain(queue):
app = MainWindow()
app.mainloop()
class MainWindow(Frame):
def __init__(self):
Frame.__init__(self)
self.master.title("Test")
self.master.minsize(330, 400)
self.grid(sticky=E+W+N+S)
modeFrame = Frame(self)
modeFrame.pack(side="top", fill="x")
self.canvas1 = Canvas(modeFrame, height=25, width=25)
self.canvas1.create_oval(5, 5, 20, 20, fill="black", tags="SetupLight")
self.canvas1.pack(side="left")
self.canvas2 = Canvas(modeFrame, height=25, width=25)
self.canvas2.create_oval(5, 5, 20, 20, fill="black", tags="RunLight")
self.canvas2.pack(side="left")
def changeLight(self,value):
print('change light ' + str(value))
if(value):
self.canvas1.itemconfig("SetupLight", fill="black")
self.canvas2.itemconfig("RunLight", fill="green")
else:
self.canvas1.itemconfig("SetupLight", fill="green")
self.canvas2.itemconfig("RunLight", fill="black")
def do_something(queue):
t = MainWindow()
MainWindow.changeLight(t,queue.get()) #is this way of calling is correct??
注:我试图修改modeFrame
到self
wh ile创建Canvas
,但没有什么可能发生
我明白从下面的链接tkinter canvas not updating color我一次又一次地创建MainWindow(),这是帆布没有改变颜色的原因。我需要一个实现,它可以帮助我通过用例改变颜色
回答:
正如您已经提到过自己,您正在do_something
中创建MainWindow
类的实例。
其次,do_something
函数调用对我来说有点奇怪。 我宁愿
def do_something(queue): t = MainWindow()
t.changeLight(queue.get())
,如果这是一个更Python的方式或没有,但我认为,在几乎所有的教程,怎么对的和示例代码,你会看到它就像我提到这可能是值得商榷的。
上次我实现了这样的东西,我采取了不同的方法。
我从GUI启动了线程,向它传递了一个队列,让线程处理流量。
GUI更新了循环(每100ms)检查项目的队列,并基于它更新GUI中的队列内的内容。
每次更新完成后再次启动的线程。 (应用程序本身就是一个会话看门狗为包括线程内的用户的本地化服务器)
所以一些实施意见,我会开始像下面这样:
import Tkinter as tk import Queue
class MainWindow(tk.Frame):
""" This is the GUI
It starts threads and updates the GUI
this is needed as tkinter GUI updates inside the Main Thread
"""
def __init__(self, *args, **kwargs):
# Here some initial action takes place
# ...
self.queue = Queue()
self.start_threads()
self.__running = True
self.update_gui()
def start_threads(self):
""" Here we start the threads
for ease of reading only one right now
thread_handler_class is a class performing
tasks and appending results to a queue
"""
thread = thread_handler_class(self.queue)
def update_gui(self):
""" Update the UI with Information from the queue """
if not self.queue.empty():
# we need to check for emptiness first
# otherwise we get exceptions if empty
while self.queue.qsize() > 0:
# handle the data
# self.queue.get() automatically reduces
# qsize return value next round so if no
# new elements are added to the queue,
# it will go to zero
data = self.queue.get()
# do stuff here
# ...
# Set up the cyclic task
if self.__running:
self.after(100, self.update_gui)
# if neccessary we can also restart the threads
# if they have a determined runtime
# self.after(100, self.start_threads)
if __name__ == "__main__":
APP = MainWindow()
APP.mainloop()
以上是 tkinter画布颜色不变 的全部内容, 来源链接: utcz.com/qa/259235.html