Ping 一个网站并输出到 Tkinter

Ping a website with output to Tkinter

我尝试 ping 一个网站并将输出实时显示到一个标签。问题:该命令进行无限循环 (nom_mp4 = tk.Label(root, text=line) 并且代码在 nom_mp4.pack() 之前停止。 有人有想法让它发挥作用吗? 这是我的代码:

from subprocess import Popen, PIPE, STDOUT
import Tkinter as tk 
from Tkinter import *

def commande():
    cmd = 'ping www.wikipedia.com'
    p = Popen(cmd.split(), stdout=PIPE, stderr=STDOUT)
    for line in iter(p.stdout.readline,''):
        nom_mp4 = tk.Label(root, text=line)
        nom_mp4.pack()

root = Tk()
root.geometry('300x190+400+400')

browsebutton2 = tk.Button(root,text='Ping',command=commande) #le bouton browse
browsebutton2.pack()

root.mainloop()

一种解决方案是使用线程。

from subprocess import Popen, PIPE, STDOUT
import Tkinter as tk
from Tkinter import Tk
from threading import Thread


def create_worker(target):
    return Thread(target=target)


def start_worker(worker):
    worker.start()


def commande():
    cmd = 'ping www.wikipedia.com'
    p = Popen(cmd.split(), stdout=PIPE, stderr=STDOUT)
    for line in iter(p.stdout.readline, ''):
        nom_mp4 = tk.Label(root, text=line)
        nom_mp4.pack()

root = Tk()
root.geometry('300x190+400+400')

worker = create_worker(commande)
tk.Button(root, text='Ping', command=lambda: start_worker(worker)).pack()

root.mainloop()
cmd = 'ping www.wikipedia.com'

这将 运行 无限。您需要定义希望它出现的次数 运行。并且在测试时可能不会对网站执行 ping 操作。例如:

cmd = 'ping -c 10 localhost'

-c 10 告诉 ping 运行 10 次。 localhost 只是对您自己的机器执行 ping 操作,当您的机器按预期工作时,请替换为 URL。

您还应该将 tk.Label 的创建移到 for-loop 之外。不需要每次都新建标签,只需要改变标签的text值即可。如果在tk.Button后创建打包,它会出现在window.

中的按钮下方

要更新 tk.Labeltext,您可以这样做:

nom_mp4.configure(text=new_value_here)

window 不会在 for-loop 运行 时更新,并且会 "locked" 直到循环结束。要更新它,您可以将其放在 for-loop:

的末尾
root.update_idletasks()

window 仍然会被锁定。要解决此问题,我相信您必须研究 threading 或类似的内容。

有效!我已经根据您的建议更改了代码。我没有将 -c 选项放在 ping 命令上,因为我希望 ping 能够独立运行而不阻塞程序。我按照 Oystein-hr 的建议更改了循环外包的位置,并使用配置更新了文本。我还插入了一个以 Josh Leeb-du Toit 为例的线程。 谢谢你们。

from subprocess import Popen, PIPE, STDOUT
import Tkinter as tk
from Tkinter import Tk
from threading import Thread


def create_worker(target):
    return Thread(target=target)


def start_worker(worker):
    worker.start()


def commande():
    cmd = 'ping localhost'
    p = Popen(cmd.split(), stdout=PIPE, stderr=STDOUT)
    for line in iter(p.stdout.readline, ''):
        result.configure(text=line)

root = Tk()
root.geometry('600x80+400+400')

worker = create_worker(commande)
tk.Button(root, text='Ping', command=lambda: start_worker(worker)).pack()

result = tk.Label(root)
result.pack()

root.mainloop()