我的HMI由2个按钮组成:启动和停止,还有一个字段QStatusBar,用于将信息从线程打印到GUI。当我做" start"时,我启动了一个可以用Stop按钮中断的线程。 我想要做的是在线程中的某个点打开一个弹出窗口,以便在线程暂停时为用户提供选择。
from PyQt4 import QtCore, QtGui
import sys
import os
import time
from PyQt4.QtGui import QApplication, QDialog, QListWidgetItem, QListWidget, QIcon
from test_bench_tool2 import Ui_MainWindow
from popup import Ui_popup
"""Class poppup window(continue/quit)"""
class MyPopup(QtGui.QDialog):
def __init__(self,type):
super(MyPopup, self).__init__()
self.res = 0
self.type=type
self.ui = Ui_popup()
self.ui.setupUi(self)
QtCore.QObject.connect(self.ui.Quit,QtCore.SIGNAL("clicked()"),self.showDialogstop)
QtCore.QObject.connect(self.ui.Continue,QtCore.SIGNAL("clicked()"),self.showDialogcontinue)
def showDialogcontinue(self):
self.res=1
self.close()
def showDialogstop(self):
self.res=0
self.close()
class MyThread(QtCore.QThread):
Statuschanged = QtCore.pyqtSignal(str)
popupmodechanged = QtCore.pyqtSignal(str)
def __init__(self, parent=None):
super(MyThread, self).__init__(parent=parent)
self.Status_auto = ''
self.dialog = MyPopup('toto')
self.Status_auto +=''
self.popup=''
self.answer=''
def run(self):
result = self.get_result()
def get_result(self, ):
empty_result = []
self.popup='Vn'
self.popupmodechanged.emit((self.popup))
self.Status_auto +='\n\nMeasures finished!!'
self.Statuschanged.emit((self.Status_auto))
results=[]
#do things to calculate results
return(results)
class Main(QtGui.QDialog):
def __init__(self):
QtGui.QMainWindow.__init__(self)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
# Connect the Buttons
QtCore.QObject.connect(self.ui.Start,QtCore.SIGNAL("clicked()"),self.Start)
QtCore.QObject.connect(self.ui.Stop,QtCore.SIGNAL("clicked()"),self.Stop)
self.__thread = MyThread(self)
self.__thread.Statuschanged.connect(self.ui.report_auto.setText)
self.__thread.popupmodechanged.connect(self.open_popup)
def open_popup(self):
self.__thread.dialog.__init__(self.__thread.dialog.type)
self.__thread.dialog.exec_()
def Start(self):
global tableRx, tableTx
self.ui.report_auto.setText('test in process...')
self.__thread.start()
def Stop(self):
self.ui.report_auto.setText('test canceled')
if self.__thread.isRunning():
self.__thread.terminate()
def main():
app = QtGui.QApplication(sys.argv)
window = Main()
window.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
如何从弹出窗口中获取选择结果以继续线程?我试图将get_result()函数放入像这样的测试
if self.dialog.res == 1:
print "continue"
self.dialog.close()
#do things
else:
self.dialog.close()
但是我无法从GUI获得结果到线程。如何从GUI获取信息到我的线程?我有tu使用队列?
答案 0 :(得分:5)
根据我的经验,队列是最好的解决方案。这是一种在线程之间共享信息的线程安全方法。 您应该在Main类中实例化队列,并将其作为init参数传递给线程:
#MyThread init
def __init__(self, queue, parent=None):
#the input queue
self.in_queue = queue
#flag indicating if the thread's run function should actually run
self.running = True
super(MyThread, self).__init__(parent=parent)
self.Status_auto = ''
self.dialog = MyPopup('toto')
self.Status_auto +=''
self.popup=''
self.answer=''
使用队列,您的线程工作者函数应如下所示:
def run(self)
while self.running: #to keep the thread running
if not self.in_queue.empty():
msg = self.in_queue.get()
#do something according to the message
else:
#do regular operation
这也允许您在消息队列中放置(使用self.queue.put(value)
)'STOP'
消息。
请注意,在这种情况下,队列的get方法会阻塞线程,直到它实际上可以从队列中获取某些内容(因此if)。您可以更改此行为:
msg = self.in_queue.get(block = False)
这样,如果队列是empy,则会引发Empty
异常。
访问Queue类:
from queue import Queue
queue = Queue()
除了上面的解决方案,您可以将对话框中的信号连接到线程中的事件处理程序,但我没有尝试过这种方式,也不确定它是否能正常工作。
我希望这能解决你的问题。
干杯, Mátyás酒店