如何在一个python脚本中控制/调用另一个python脚本? (脚本之间的沟通) [英] How to control/call another python script within one python script? (Communicate between scripts)
问题描述
我建议您查看线程模块。通过对 Thread
类进行子类化,您可以为时间密集型作业创建新线程。
然后,线程之间的通信可以使用 pubsub 或 pydispatcher ,我没有尝试过后者,所以我不能评论它,但我会推荐pubsub的易用性,以及它的wxpython的分配是一个奖金。
这里是一个关于运行长任务的wxpython维基页面,如果您想要最简单的线程使用示例,请跳过到最后。
是一个简单(可运行)的例子,说明如何使用 pubsub
将消息从您的workerThread发送到您的 GUI
。
import时间
导入wx
从线程导入线程
从wx.lib.pubsub import Publisher
class WorkerThread(Thread):
def __init __(self):
Thread .__ init __(self)
#A可以设置的标志
#告诉线程结束
self.stop_flag = False
#这个调用run()来启动新线程
self.start()
def run(self):
超级跑跑()
#在这里的所有东西
#你想在你的新线程中运行
#eg ..
for x in range(20):
if self.stop_flag:
break
time.sleep(1)
#Broadcast一条消息给谁收听
Publisher.sendMessage(your_topic_name,x)
Publisher.sendMessage(your_topic_name,finished)
def stop(self )
调用此方法告诉线程停止
self.stop_flag = True
class GUI(wx.Frame):
def __init __(self,parent,id = -1,title =):
wx.Frame .__ init __(self, parent,id,title,size =(140,180))
self.SetMinSize((140,180))
panel = wx.Panel(id = wx.ID_ANY,name = u'mainPanel',parent = self )
#订阅来自workerThread的消息
Publisher()。subscribe(self.your_message_handler,your_topic_name)
#A按钮启动workerThread
self.startButton = wx.Button(panel,wx.ID_ANY,'Start thread')
self.Bind(wx.EVT_BUTTON,self.onStart,self.startButton)
#A按钮停止工作线程
self.stopButton = wx.Button(panel,wx.ID_ANY,'Stop thread')
self.Bind(wx.EVT_BUTTON,self.onStop,self.stopButton)
#A文本控件显示来自工作线程的消息
self.threadMessage = wx.TextCtrl(panel,wx.ID_ANY,'',size =(75,20))
#Do布局
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.startButton,0,wx.ALL,10)
sizer.Add(self.stopButton ,0,wx.ALL,10)
sizer.Add(self.threadMessage,0,wx.ALL,10)
panel.SetSizerAndFit(sizer)
def onStart(self,event):
#启动工作线程
self.worker = WorkerThread()
#Disable任何可能影响你的线程的小部件
self.startButton.Disable()
def onStop(self,message):
self.worker.stop()
def your_message_handler(self,message):
message_data = message.data
如果message_data =='finished':
self.startButton.Enable()
self.threadMessage.SetLabel(str(message_data))
else:
self.threadMessage.SetLabel(str(message_data))
如果__name__ ==__main__:
app = wx.PySimpleApp()
框架= GUI(无,wx.ID_ANY,'线程示例')
frame.Show()
app.MainLoop()
I'm working on one GUI program, and was gonna add a long running task into one event, but I found this would make the whole program freeze a lot, so considering other people's advice I would make the GUI only responsible for starting, stopping and monitoring and make the long running task run as a separate script. The only way I know to run another script in one script is by import, is there any other methods to communicate with another script, I mean such as reading another's stdout and terminating it at any time you want?
I suggest you look at the threading module. By subclassing the Thread
class you can create new threads for time intensive jobs.
Then for communication between the the threads you can use either pubsub or pydispatcher, I haven't tried the latter so I can't comment on it but I would recommend pubsub for its ease of use and the fact that its apart of wxpython is a bonus.
Here is a wxpython wiki page on running long tasks, skip to the end if you want the simplest example usage of threading.
Heres a simple (runnable) example of how you could use pubsub
to send messages from your workerThread to your GUI
.
import time
import wx
from threading import Thread
from wx.lib.pubsub import Publisher
class WorkerThread(Thread):
def __init__(self):
Thread.__init__(self)
#A flag that can be set
#to tell the thread to end
self.stop_flag = False
#This calls the run() to start the new thread
self.start()
def run(self):
""" Over-rides the super-classes run()"""
#Put everything in here that
#you want to run in your new thread
#e.g...
for x in range(20):
if self.stop_flag:
break
time.sleep(1)
#Broadcast a message to who ever's listening
Publisher.sendMessage("your_topic_name", x)
Publisher.sendMessage("your_topic_name", "finished")
def stop(self):
"""
Call this method to tell the thread to stop
"""
self.stop_flag = True
class GUI(wx.Frame):
def __init__(self, parent, id=-1,title=""):
wx.Frame.__init__(self, parent, id, title, size=(140,180))
self.SetMinSize((140,180))
panel = wx.Panel(id=wx.ID_ANY, name=u'mainPanel', parent=self)
#Subscribe to messages from the workerThread
Publisher().subscribe(self.your_message_handler, "your_topic_name")
#A button to start the workerThread
self.startButton = wx.Button(panel, wx.ID_ANY, 'Start thread')
self.Bind(wx.EVT_BUTTON, self.onStart, self.startButton)
#A button to stop the workerThread
self.stopButton = wx.Button(panel, wx.ID_ANY, 'Stop thread')
self.Bind(wx.EVT_BUTTON, self.onStop, self.stopButton)
#A text control to display messages from the worker thread
self.threadMessage = wx.TextCtrl(panel, wx.ID_ANY, '', size=(75, 20))
#Do the layout
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.startButton, 0, wx.ALL, 10)
sizer.Add(self.stopButton, 0, wx.ALL, 10)
sizer.Add(self.threadMessage, 0, wx.ALL, 10)
panel.SetSizerAndFit(sizer)
def onStart(self, event):
#Start the worker thread
self.worker = WorkerThread()
#Disable any widgets which could affect your thread
self.startButton.Disable()
def onStop(self, message):
self.worker.stop()
def your_message_handler(self, message):
message_data = message.data
if message_data == 'finished':
self.startButton.Enable()
self.threadMessage.SetLabel(str(message_data))
else:
self.threadMessage.SetLabel(str(message_data))
if __name__ == "__main__":
app = wx.PySimpleApp()
frame = GUI(None, wx.ID_ANY, 'Threading Example')
frame.Show()
app.MainLoop()
这篇关于如何在一个python脚本中控制/调用另一个python脚本? (脚本之间的沟通)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!