非阻塞函数调用阻止tkintker GUI启动
问题描述:
该示例显示了我创建非阻塞状态栏的方法,同时积极提高了我的python技能。非阻塞函数调用阻止tkintker GUI启动
问题是,gui不会被创建,并且不会显示任何错误,尽管isEthernetUp()
例如在与LAN断开连接时工作正常。我很惊讶,即使使用pythons异步库,GUI也不会被创建。我能做些什么来不断更新状态?正在使用异步方法解决另一个问题?我是否需要降低级别并在使用线程的同时将其恶化?
我的例子:
import tkinter as tk
import socket
import asyncio
import asyncore
import datetime
import time
class Statusbar():
def __init__(self):
self.root = tk.Tk()
self.root.title("Am I connected?")
self.net_color = "red"
self.connected = False
self.timer = 0
monitor = tk.Frame(self.root)
monitor.grid(row=0, column=0)
monitor_label = tk.Label(monitor, bd=2, relief=tk.SUNKEN,
text="Net",
fg="white",
bg=self.net_color,
padx=3,
font=('courier', 16, 'bold'))
monitor_label.grid(row=0, sticky=tk.E)
time_label = tk.Label(self.root, text=self.timer, font=("courier", 16), relief=tk.SUNKEN)
time_label.grid(row=0, column=1, sticky=tk.NSEW)
self.getInfos()
self.root.mainloop()
def getInfos(self):
try:
n = NetworkIndicate()
t = TimeIndicate()
loop = asyncio.get_event_loop()
loop.run_forever()
while 1:
self.connected = loop.run_until_complete(n.isEthernetUp())
self.timer = loop.run_until_complete(t.whatTimeIsLove())
except KeyboardInterrupt:
# Canceling tasks
asyncio.gather(*asyncio.Task.all_tasks()).cancel()
loop.stop()
loop.close()
class NetworkIndicate(asyncore.dispatcher):
def __init__(self):
pass
@asyncio.coroutine
async def isEthernetUp(self):
"""
Updates the master's background color option if an IPv4 other than localhost was found and returns a boolean value.
:return: boolean
"""
try:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
s.connect(('<broadcast>', 0))
# Referencing Example
e = Statusbar()
# Changes the color of the background color in Statusbar
e.net_color = "green"
return True
except OSError:
return False
class TimeIndicate(asyncore.dispatcher):
def __init__(self):
pass
@asyncio.coroutine
async def whatTimeIsLove(self):
"""
Returns just the current unformatted time
:return: string
"""
return datetime.datetime.now()
if __name__ == '__main__':
Statusbar()
答
我一般都用这个方法来使用内置的Tkinter的事件循环(使用后命令),这将避免阻塞:
import tkinter
from tkinter import *
class Visual(Frame):
def __init__(self, root):
self.root = root
self.root.title("Am I connected?")
self.net_color = "red"
self.connected = False
self.timer = 0
monitor = Frame(self.root)
monitor.grid(row=0, column=0)
monitor_label = Label(monitor, bd=2, relief=SUNKEN,
text="Net",
fg="white",
bg=self.net_color,
padx=3,
font=('courier', 16, 'bold'))
monitor_label.grid()
self.getInfos()
def getInfos(self):
print("Got the info")
self.root.after(1000, self.getInfos)
if __name__ == '__main__':
root = Tk()
v = Visual(root)
root.mainloop()
谢谢非常简单和支持。是的,实际上应该已经使用了已经存在的tkinter循环。尝试异步也许是个不错的主意。 – Semo