PyQt:从GUI向线程发送信息



我的HMI由2个按钮组成:开始和停止,还有一个字段QStatusBar,用于从线程打印信息到GUI。当我"开始"时,我启动一个线程,我可以用停止按钮打断它。我想做的是在线程的某一点打开一个弹出窗口,给用户一个选择,而线程暂停。

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 +='nnMeasures 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到我的线程获取信息??我必须使用队列吗??

根据我的经验,队列是最好的解决方案。这是一种在线程间共享信息的线程安全方式。您应该在Main类中实例化队列,并将其作为初始化参数传递给线程:

#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)

这样,如果队列为空,则会引发Empty异常。

访问Queue类:

from queue import Queue
queue = Queue()

而不是上面的解决方案,你可能会连接信号从对话框到事件处理程序在线程中,但我没有尝试过这种方式,不确定它是否会正常工作。

我希望这能解决你的问题。

欢呼,地主选手

相关内容

  • 没有找到相关文章

最新更新