Python 如何使用多线程执行子流程
此程序在一个小画布上工作并显示服务器延迟,但由于ping服务器和显示pingPython 如何使用多线程执行子流程,python,python-3.x,tkinter,Python,Python 3.x,Tkinter,此程序在一个小画布上工作并显示服务器延迟,但由于ping服务器和显示pingdef display():需要程序时间,因此在子进程完成之前,无法拖动窗口类WindowDragable():,因此拖动窗口时存在延迟。是否可以通过多线程解决此延迟,以便平滑拖动窗口 from tkinter import * from PIL import ImageTk, Image import subprocess import _thread host = "141.101.115.212" #host I
def display():
需要程序时间,因此在子进程完成之前,无法拖动窗口类WindowDragable():
,因此拖动窗口时存在延迟。是否可以通过多线程解决此延迟,以便平滑拖动窗口
from tkinter import *
from PIL import ImageTk, Image
import subprocess
import _thread
host = "141.101.115.212" #host IP address
root = Tk()
root.overrideredirect(1)
im = Image.open("image.png")
width, height = im.size
canvas = Canvas(root, width=width, height=height)
canvas.pack()
image = ImageTk.PhotoImage(file="image.png")
canvas.create_image(0, 0, image=image, anchor=NW)
text = canvas.create_text(125, 75, anchor=CENTER)
def display():
global text
#Launches 'command' windowless and waits until finished; finds ping
suinfo = subprocess.STARTUPINFO()
suinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
x = subprocess.Popen(["ping.exe", "141.101.115.212"], stdout=subprocess.PIPE, startupinfo=suinfo)
#find latency with regex
x = str(x.communicate()[0])
lhs, rhs = x.split("Average = ")
lhs, rhs = rhs.split("\\", 1)
lhs, rhs = lhs.split("m")
if int(lhs) > 999:
lhs = "999" + "ms"
latency = lhs
canvas.itemconfig(text, text=latency, width=width)
canvas.itemconfig(text, font=("courier", 25, "bold"))
canvas.itemconfig(text, fill="white")
root.after(1000, display)
class WindowDraggable():
def __init__(self, label):
self.label = label
label.bind('<ButtonPress-1>', self.StartMove)
label.bind('<ButtonRelease-1>', self.StopMove)
label.bind('<B1-Motion>', self.OnMotion)
def StartMove(self, event):
self.x = event.x
self.y = event.y
def StopMove(self, event):
self.x = None
self.y = None
def OnMotion(self,event):
x = (event.x_root - self.x - self.label.winfo_rootx() + self.label.winfo_rootx())
y = (event.y_root - self.y - self.label.winfo_rooty() + self.label.winfo_rooty())
root.geometry("+%s+%s" % (x, y))
label = Label(root, text='drag me')
WindowDraggable(label)
label.pack()
#_thread.start_new_thread( print_time, ("Thread-2", 4, ) )
root.after(0, display())
root.mainloop()
从tkinter导入*
从PIL导入ImageTk,图像
导入子流程
导入线程
host=“141.101.115.212”#主机IP地址
root=Tk()
root.overrideredirect(1)
im=Image.open(“Image.png”)
宽度、高度=im尺寸
画布=画布(根,宽度=宽度,高度=高度)
canvas.pack()
image=ImageTk.PhotoImage(file=“image.png”)
canvas.create_image(0,0,image=image,anchor=NW)
文本=画布。创建文本(125,75,锚定=中心)
def display():
全局文本
#无窗口启动“命令”并等待完成;找到平
suinfo=subprocess.STARTUPINFO()
suinfo.dwFlags |=subprocess.STARTF_USESHOWWINDOW
x=subprocess.Popen([“ping.exe”,“141.101.115.212”],stdout=subprocess.PIPE,startupinfo=suinfo)
#使用正则表达式查找延迟
x=str(x.communicate()[0])
lhs,rhs=x.split(“Average=”)
lhs,rhs=rhs.split(“\\”,1)
左侧,右侧=左侧拆分(“m”)
如果int(lhs)>999:
lhs=“999”+“ms”
延迟=lhs
canvas.itemconfig(text,text=latency,width=width)
canvas.itemconfig(文本,字体=(“courier”,25,“粗体”))
canvas.itemconfig(text,fill=“white”)
root.after(1000,显示)
类WindowDraggable():
定义初始化(自我,标签):
self.label=标签
label.bind(“”,self.StartMove)
label.bind(“”,self.StopMove)
label.bind(“”,self.OnMotion)
def StartMove(自身、事件):
self.x=event.x
self.y=event.y
def停止移动(自身、事件):
self.x=无
self.y=None
def OnMotion(自身、事件):
x=(event.x_root-self.x-self.label.winfo_rootx()+self.label.winfo_rootx())
y=(event.y_root-self.y-self.label.winfo_rooty()+self.label.winfo_rooty())
根几何体(“++%s++%s”%(x,y))
label=label(根,text='drag me')
WindowDragable(标签)
label.pack()
#_线程。启动新线程(打印时间,(“线程2”,4,))
root.after(0,display())
root.mainloop()
与其尝试对抗Tkinter的内置循环/线程,不如使用它:
def wait_for_it(proc):
proc.poll()
if proc.returncode is None: # subprocess hasn't finished yet
root.after(100, lambda: wait_for_it(proc)) # register a callback for 100ms
else:
display(proc.communicate()[0])
def display(x):
lhs, rhs = x.split("Average = ")
# the rest of your code goes here...
# instead of root.after(0, display)
wait_for_it(subprocess.Popen(['ping', 'google.com']))
顺便说一句,我强烈建议您将代码粘贴到堆栈交换上,以获得一些样式指针并帮助简化它。为什么不等到过程实际完成后再尝试与它通信?@WayneWerner我对Python(以及一般编程)还是有点陌生,我不确定您的意思。你能解释一下你的建议吗?@WayneWerner我还是迷路了……谢谢,这两个网站到底有什么区别?前者的目的是帮助整个程序,而不是故障代码片段吗?这个网站最初更具包容性。随着我们的规模越来越大,我们需要不断缩小和完善范围。所以现在有些东西可能是准主题的,要么是较少的,要么是完全脱离主题的。因此,这是一个错误驱动的网站-有些东西不工作,但我不知道为什么。CR确实适用于那些具有功能性的代码,但可以以计算机不关心的方式进行改进的代码,但其他程序员会。更多的事实检查也是如此,CR更多的是编辑。至少这是我的理解!