2017-05-30 82 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