2016-04-23 73 views
1
import time 
import sys, threading 
from PyQt4 import QtGui, QtCore 
from PyQt4.QtGui import QApplication 


class Global: 
    def __init__(self): 
     for c in MyClass, MainWindow: 
      cl = c() 
      setattr(self, c.__name__, cl) 
      setattr(cl, 'global_', self) 


class MyClass: 
    def work(self): 
     for r in range(100): 
      if r == 2: 
       self.global_.MainWindow.SignalBox.emit('MyClass NO PAUSE') # need pause !!! 
      else: 
       print(r) 
      time.sleep(1) 


class MainWindow(QtGui.QWidget): 
    Signal = QtCore.pyqtSignal(str) 
    SignalBox = QtCore.pyqtSignal(str) 

    def __init__(self): 
     QtGui.QWidget.__init__(self) 
     self.resize(300, 300) 

     self.lab = QtGui.QLabel() 
     lay = QtGui.QGridLayout() 
     lay.addWidget(self.lab) 
     self.setLayout(lay) 

     self.msgBox = lambda txt: getattr(QtGui.QMessageBox(), 'information')(self, txt, txt) 
     self.Signal.connect(self.lab.setText) 
     self.SignalBox.connect(self.msgBox) 

    def thread_no_wait(self): 
     self.global_.MainWindow.SignalBox.emit('MyClass PAUSE OK') 
     threading.Thread(target=self.global_.MyClass.work).start() 

    def thread_main(self): 
     def my_work(): 
      for r in range(100): 
       self.Signal.emit(str(r)) 
       time.sleep(1) 
     threading.Thread(target=my_work).start() 


if __name__ == '__main__': 
    app = QApplication(sys.argv) 
    g = Global() 
    g.MainWindow.show() 
    g.MainWindow.thread_main() 
    g.MainWindow.thread_no_wait() 
    app.exec_() 

如何从另一个进程运行QMessageBox?在一个单独的线程,但不参加执行QMessageBox在其他线程

MyClass.work必须暂停,如果它导致QMessageBox提示MyClass的。如果我们定义QMessageBox提示是主窗口,错误将被称为

的QObject :: startTimer所:计时器无法启动从另一个线程 QApplication:对象事件过滤器不能在不同的线程中。 而在这个调用QMessageBox在一个单独的线程中调用,并且工作没有被暂停

+1

我不明白你问什么叫在另一个线程块,直到该函数的功能,但不可能在主线程以外的线程中运行任何GUI代码。 –

回答

0

这听起来像你想要暂停执行一个线程,直到主线程中的某些操作完成。有几种方法可以做到这一点。一个简单的方法是使用共享的全局变量。

PAUSE = False 

class MyClass: 
    def work(self): 
     global PAUSE 
     for r in range(100): 
      while PAUSE: 
       time.sleep(1) 
      if r == 2: 
       self.global_.MainWindow.SignalBox.emit('MyClass NO PAUSE') 
       PAUSE = True 
      ... 

class MainWindow(...) 

    def msgBox(self, txt): 
     QtGui.QMessageBox.information(self, txt, txt) 
     global PAUSE 
     PAUSE = False 

如果使用QThreads而不是蟒蛇线程的,你其实可以完成使用QMetaObject.invokeMethod

@QtCore.pyqtSlot(str) 
def msgBox(self, txt): 
    ... 

... 

if r == 2: 
    # This call will block until msgBox() returns 
    QMetaObject.invokeMethod(
     self.global_.MainWindow, 
     'msgBox', 
     QtCore.Qt.BlockingQueuedConnection, 
     QtCore.Q_ARG(str, 'Text to msgBox') 
    ) 
+0

谢谢,这正是我想要的 –