2017-05-30 83 views
1

该示例显示了我创建非阻塞状态栏的方法,同时积极提高了我的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() 

回答

2

我一般都用这个方法来使用内置的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() 
+0

谢谢非常简单和支持。是的,实际上应该已经使用了已经存在的tkinter循环。尝试异步也许是个不错的主意。 – Semo