gpt4 book ai didi

python - 如何将子进程文本输出发送到 Tkinter 文本小部件?

转载 作者:行者123 更新时间:2023-12-01 08:20:11 25 4
gpt4 key购买 nike

import subprocess
import os
import time
from tkinter import *
root=Tk()
textbox=Text(root)
textbox.pack()


def redirector(inputStr):
textbox.insert(INSERT, inputStr)

def address_ping():
'''
DOCSTRING -> Ip addresses in servers.txt are
192.168.0.1 192.168.0.26
'''
while True:
with open('servers.txt', 'r') as f:
for ip in f:
result=subprocess.Popen(["ping", "-c", "7", "-n", "-W", "2", ip],stdout=f, stderr=f).wait()
if result:
print("ip address " + ip, "is inactive")
sys.stdout.write = redirector

else:
print("ip address " + ip, "is active")
sys.stdout.write = redirector
pass

address_ping()

root.mainloop()

我在这里编写一段代码,它将向 IP 地址发送 ping 并返回结果。它在 CLI 上运行良好,但我希望使用 Tkinter 将其“打印”到 Text 小部件。我现在处于将其发送到 Text 小部件 GUI 的位置,但它仅在我中断程序后才使其自身可见。我希望随着 ping 循环的进行,滚动输出到 GUI 文本区域。

最佳答案

这是使用多线程的东西,似乎可以做你想做的事情。主程序分为处理 QUI 的部分和单独的 workerthread管理 ping subprocess ,从中收集结果并将其放入 Queue 中其内容定期传输到 GUI。

它使用 time.sleep()因为它是在一个单独的线程中完成的,使用 tkinter,所以没关系。

请注意,您可能希望向 GUI 添加垂直滚动条。

import subprocess
import queue
import threading
import time
import tkinter as tk


class GuiPart:
def __init__(self, master, queue, end_command):
self.queue = queue
self.master = master
self.textbox = tk.Text(root)
self.textbox.pack()
btn = tk.Button(master, text='Quit', command=end_command)
btn.pack(expand=True)

def process_incoming(self):
""" Handle all messages currently in the queue. """
while self.queue.qsize():
try:
info = self.queue.get_nowait()
self.textbox.insert(tk.INSERT, info)
except queue.Empty: # Shouldn't happen.
pass


class ThreadedClient:
""" Launch the main part of the GUI and the worker thread.
periodic_call() and end_application() could reside in the GUI part, but
putting them here keeps all the thread controls in a single place.
"""
def __init__(self, master):
self.master = master
self.queue = queue.Queue()

# Set up the GUI part.
self.gui = GuiPart(master, self.queue, self.end_application)

# Set up the background processing thread.
self.running = True
self.thread = threading.Thread(target=self.workerthread)
self.thread.start()

# Start periodic checking of the queue.
self.periodic_call(200)

def periodic_call(self, delay):
""" Every delay ms process everything new in the queue. """
self.gui.process_incoming()
if not self.running:
sys.exit(1)
self.master.after(delay, self.periodic_call, delay)

# Runs in separate thread - NO tkinter calls allowed.
def workerthread(self):
while self.running:
with open('servers.txt', 'r') as file:
for ip in file:
rc = subprocess.Popen(["ping", "-c", "7", "-n", "-W", "2", ip]).wait()
if rc:
self.queue.put('ip address {} is inactive\n'.format(ip))
time.sleep(1)

def end_application(self):
self.running = False # Stop queue checking.
self.master.quit()


if __name__ == '__main__':
root = tk.Tk()
root.title('Pinger')
client = ThreadedClient(root)
root.mainloop() # Display application window and start tkinter event loop.

关于python - 如何将子进程文本输出发送到 Tkinter 文本小部件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54697290/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com