繁体   English   中英

这是子类化python线程以接受变量更新的有效方法吗?

[英]Is this a valid way to subclass a python thread to accept a variable update?

我正在查看Python(版本3.4.3)中的线程模块,并且很难找到一种方法来更新所调用的目标函数中的变量。 我想我可以创建一个全局变量以在主程序和正在启动的线程之间共享,但是发现自己却创建了以下子类。 这似乎可以达到我的目的,但是我很好奇这仅仅是一个hack还是有效。

这里的目标是创建一个单独的线程,该线程定期(安静地)ping服务器,然后使用更新状态更新指定的小部件:

from tkinter import *
import threading

class ipthread(threading.Thread):
    def __init__(self, ip=None, labelobj=None):
        self.ip = ip
        threading.Thread.__init__(self, target=self.checkconnection, args=(labelobj,))

    def newip(self, ip):
        self.ip = ip

    def checkconnection(self, widget):
        while True:
            self.response = os.system("ping -c 1 -W 10 " + self.ip + " > /dev/null 2> /dev/null")
            if self.response==0:
                widget.config(text="connected", bg='green')
            else:
                widget.config(text="no connection", bg='red')
            time.sleep(1)

if __name__=="__main__":
    win = Tk()
    status = Label(win, text='')
    status.pack()
    ipchecker = ipthread(ip='192.168.1.1',widget=status)
    time.sleep(10)
    ipchecker.newip('192.168.1.2')

虽然我在这里放置了一个简单的例程,该例程在10秒钟的延迟后调用更新,但是在我的程序中,当我创建tkinter Frame控制面板时,线程被初始化。 面板上有一个按钮,该按钮然后调用newip方法来更新线程。 它起作用了,所以我感觉自己已经完成了一些事情,但这是矫kill过正还是不必要的? 我找不到另一种方法来将“ checkconnection”例程初始化为单独的线程,然后能够更新其使用的ip地址。

您问了几个问题,我希望能全部回答。

这是将参数传递给线程的有效方法吗?

有两种方法可以将参数传递给线程:

  • 子类Thread,重新定义函数运行并从那里访问新变量,如

     class ipthread(threading.Thread): def __init__(self, ip=None, labelobj=None): self.ip = ip self.labelobj = labelobj def newip(self, ip): self.ip = ip def run(self): while True: self.response = os.system("ping -c 1 -W 10 " + self.ip + " > /dev/null 2> /dev/null") if self.response==0: self.labelobj.config(text="connected", bg='green') else: self.labelobj.config(text="no connection", bg='red') time.sleep(1) 
  • 或者您可以指定要呼叫的目标

     def checkconnection(widget, ip): while True: self.response = os.system("ping -c 1 -W 10 " + self.ip + " > /dev/null 2> /dev/null") if self.response==0: widget.config(text="connected", bg='green') else: widget.config(text="no connection", bg='red') time.sleep(1) th = threading.Thread(target=checkconnection, args=(labelobj, ip)) th.start() 

这是此问题的正确解决方案吗?

不它不是!

窗口小部件库通常不喜欢第二个线程来切入其窗口小部件。 您可以使用TKInter 计时器而不是线程,也可以使用自定义事件让线程告诉小部件文本已更改。

使用计时器时,在处理刻度线时,GUI变得无响应。 在您的情况下,ping具有无限延迟,因此我将保留线程并让其发送自定义事件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM