2016-04-27 86 views
0

這是一個小例子來解釋我的問題。我想要在gui類中接收所有線程信號,並且線程A和線程B中的信號應以線程C打印。下一步,我要將信號寫入Excel表單。PYQT - 共享QThread之間的信號

  1. 問題:我如何可以共享的信號
  2. 問題:是否有可能像設置X =信號

感謝您迴應variabel。

import sys,time 
from PyQt4 import QtGui, uic 
from PyQt4.QtCore import QThread, SIGNAL 

qtCreatorFile = 'ThreadUi.ui' 

Ui_MainWindow, QtBaseClass = uic.loadUiType(qtCreatorFile) 

class MyApp(QtGui.QMainWindow, Ui_MainWindow): 
    def __init__(self,parent=None): 
     super(MyApp, self).__init__(parent) 
     self.setupUi(self) 
     self.Thread() 
     self.Ui() 


    def Ui(self): 
     self.state= False 
     self.pushButtonA.pressed.connect(self.BtnA) 
     self.pushButtonB.pressed.connect(self.BtnB) 
     self.pushButtonC.pressed.connect(self.BtnC) 

    def Thread(self): 
     self.threadA = WorkThreadA(self) 
     self.threadB = WorkThreadB(self) 
     self.threadC = WorkThreadC 

    def BtnA(self): 
     self.state = not self.state 
     if self.state: 
      self.threadA.start() 
      self.pushButtonA.setChecked(False) 
     else: 
      self.threadA.stop() 
      self.pushButtonA.setChecked(True) 

    def BtnB(self): 
     self.state = not self.state 
     if self.state: 
      self.threadB.start() 
      self.pushButtonB.setChecked(False) 
     else: 
      self.threadB.stop() 
      self.pushButtonB.setChecked(True) 

    def BtnC(self): 
     A=self.connect(self.threadA,SIGNAL('Signal_A')) 
     B=self.connect(self.threadA,SIGNAL('Signal_B')) 
     self.threadC(self,A,B) 

     self.state = not self.state 
     if self.state: 
      self.threadC.start() 
      self.pushButtonC.setChecked(False) 
     else: 
      self.threadC.stop() 
      self.pushButtonC.setChecked(True) 

if __name__ == "__main__": 
    app = QtGui.QApplication(sys.argv) 
    window = MyApp() 
    window.show() 
    sys.exit(app.exec_()) 


class WorkThreadA(QThread): 
    def __init__(self ,parent=None): 
     super(WorkThreadA, self).__init__(parent) 
     self.host=host_window 
     self.exiting = False 

    def run(self): 
     self.exiting = False 
     i=0 
     while not self.exiting: 
      self.emit(SIGNAL('Signal_A'),i) 
      print("Thread A:",i) 
      i=i+1 
      time.sleep(1) 

    def stop(self): 
     self.exiting = True 

class WorkThreadB(QThread): 
    def __init__(self,host_window ,parent=None): 
     super(WorkThreadB, self).__init__(parent) 
     self.host=host_window 
     self.exiting = False 

    def run(self): 
     self.exiting = False 
     i=0 
     while not self.exiting: 
      self.emit(SIGNAL('Signal_B'),i) 
      print("Thread B:",i) 
      i=i+1 
      time.sleep(1) 

    def stop(self): 
     self.exiting = True 

class WorkThreadC(QThread): 
    def __init__(self,host_window ,SignalA,SignalB,parent=None): 
     super(WorkThreadC, self).__init__(parent) 
     self.host=host_window 
     self.exiting = False 
     self.signalA=SignalA 
     self.signalB=SignalB 

    def run(self): 
     self.exiting = False 
     while not self.exiting: 
      print("Signal A: ",self.signalA) 
      print("Signal B: ",self.signalB)  

    def stop(self): 
     self.exiting = True 

的UI文件IST這裏:

<?xml version="1.0" encoding="UTF-8"?> 
    <ui version="4.0"> 
    <class>Form</class> 
    <widget class="QWidget" name="Form"> 
    <property name="geometry"> 
     <rect> 
     <x>0</x> 
     <y>0</y> 
     <width>400</width> 
     <height>300</height> 
     </rect> 
    </property> 
    <property name="windowTitle"> 
     <string>TreadUi</string> 
    </property> 
    <widget class="QWidget" name="verticalLayoutWidget"> 
     <property name="geometry"> 
     <rect> 
     <x>-1</x> 
     <y>-1</y> 
     <width>401</width> 
     <height>301</height> 
     </rect> 
     </property> 
     <layout class="QVBoxLayout" name="verticalLayout"> 
     <item> 
     <widget class="QPushButton" name="pushButtonA"> 
     <property name="sizePolicy"> 
      <sizepolicy hsizetype="Minimum" vsizetype="MinimumExpanding"> 
      <horstretch>0</horstretch> 
      <verstretch>0</verstretch> 
      </sizepolicy> 
     </property> 
     <property name="text"> 
      <string>Thread A</string> 
     </property> 
     <property name="checkable"> 
      <bool>true</bool> 
     </property> 
     </widget> 
     </item> 
     <item> 
     <widget class="QPushButton" name="pushButtonB"> 
     <property name="sizePolicy"> 
      <sizepolicy hsizetype="Minimum" vsizetype="MinimumExpanding"> 
      <horstretch>0</horstretch> 
      <verstretch>0</verstretch> 
      </sizepolicy> 
     </property> 
     <property name="text"> 
      <string>Thread B</string> 
     </property> 
     <property name="checkable"> 
      <bool>true</bool> 
     </property> 
     </widget> 
     </item> 
     <item> 
     <widget class="QPushButton" name="pushButtonC"> 
     <property name="sizePolicy"> 
      <sizepolicy hsizetype="Minimum" vsizetype="MinimumExpanding"> 
      <horstretch>0</horstretch> 
      <verstretch>0</verstretch> 
      </sizepolicy> 
     </property> 
     <property name="text"> 
      <string>Thread C</string> 
     </property> 
     <property name="checkable"> 
      <bool>true</bool> 
     </property> 
     </widget> 
     </item> 
     </layout> 
    </widget> 
    </widget> 
    <resources/> 
    <connections/> 
    </ui> 
+0

什麼是'WorkThread'? –

+0

它只是一個名字,我命名了3個線程類:WorkThreadA,WorkThreadB和WorkThreadC –

回答

0

你不能在一個類實例動態定義的信號。它們必須被定義爲類屬性。你應該使用new-style signals and slot syntax。當使用pyqtSlot裝飾器連接線程中的信號和插槽時,您還需要聲明插槽。

class WorkThreadA(QThread): 
    signal_a = QtCore.pyqtSignal(int) 

    def run(self): 
     ... 
     self.signal_a.emit(10) 


class MyApp(...) 

    def thread(self): 
     self.threadA = WorkThreadA(self) 
     self.threadA.signal_a.connect(self.handle_signal) 

    @QtCore.pyqtSlot(int) 
    def handle_signal(self, value): 
     print 'Thread Value', value 
+0

我試過了,但我沒有工作。 AttributeError:'PyQt4.QtCore.pyqtSignal'對象沒有'連接'屬性 您可以讓我的腳本工作嗎? –

+0

確保在'__init__'方法中將信號添加爲類屬性和連接。 –

0

現在,它的工作原理,但不知道如果這是最好的辦法。 謝謝你的幫助。

import sys,time 
from PyQt4 import QtGui, uic 
from PyQt4.QtCore import QThread , pyqtSignal,pyqtSlot 

qtCreatorFile = 'ThreadUi.ui' 

Ui_MainWindow, QtBaseClass = uic.loadUiType(qtCreatorFile) 

class MyApp(QtGui.QMainWindow, Ui_MainWindow): 

    def __init__(self,parent=None): 
     super(MyApp, self).__init__(parent) 
     self.setupUi(self) 
     self.Thread() 
     self.Ui() 
     self.Signals() 


    def Ui(self): 
     self.state= False 
     self.pushButtonA.pressed.connect(self.BtnA) 
     self.pushButtonB.pressed.connect(self.BtnB) 
     self.pushButtonC.pressed.connect(self.BtnC) 

    def Thread(self): 
     self.threadA = WorkThreadA(self) 
     self.threadB = WorkThreadB(self) 
     self.threadC = WorkThreadC(self) 

    def Signals(self): 
     self.threadA.signal_a.connect(self.threadC.handle_signalA) 
     self.threadB.signal_b.connect(self.threadC.handle_signalB) 

    def BtnA(self): 
     self.state = not self.state 
     if self.state: 
      self.threadA.start() 
      self.pushButtonA.setChecked(False) 
     else: 
      self.threadA.stop() 
      self.pushButtonA.setChecked(True) 

    def BtnB(self): 
     self.state = not self.state 
     if self.state: 
      self.threadB.start() 
      self.pushButtonB.setChecked(False) 
     else: 
      self.threadB.stop() 
      self.pushButtonB.setChecked(True) 

    def BtnC(self): 

     self.state = not self.state 
     if self.state: 
      self.threadC.start() 
      self.pushButtonC.setChecked(False) 
     else: 
      self.threadC.stop() 
      self.pushButtonC.setChecked(True) 



class WorkThreadA(QThread): 
    signal_a = pyqtSignal(int) 

    def __init__(self,host_window,parent=None): 
     super(WorkThreadA, self).__init__(parent) 
     self.host=host_window 
     self.exiting = False 


    def run(self): 
     self.exiting = False 
     i=0 
     while not self.exiting: 
      self.signal_a.emit(i) 
      print("Thread A:",i) 
      i=i+1 
      time.sleep(1) 

    def stop(self): 
     self.exiting = True 

class WorkThreadB(QThread): 
    signal_b = pyqtSignal(int) 

    def __init__(self,host_window,parent=None): 
     super(WorkThreadB, self).__init__(parent) 
     self.host=host_window 
     self.exiting = False 


    def run(self): 
     self.exiting = False 
     i=0 
     while not self.exiting: 
      self.signal_b.emit(i) 
      print("Thread B:",i) 
      i=i+1 
      time.sleep(1) 

    def stop(self): 
     self.exiting = True 



class WorkThreadC(QThread): 
    def __init__(self,host_window,parent=None): 
     super(WorkThreadC, self).__init__(parent) 
     self.host=host_window 
     self.exiting = False 


    def run(self): 
     self.exiting = False 
     while not self.exiting: 
      print("Signal A: ",self.signalA) 
      print("Signal B: ",self.signalB) 
      time.sleep(1) 


    def stop(self): 
     self.exiting = True 

    @pyqtSlot(int) 
    def handle_signalA(self, value): 
     self.signalA=value 

    @pyqtSlot(int) 
    def handle_signalB(self, value): 
     self.signalB=value 

if __name__ == "__main__": 
    app = QtGui.QApplication(sys.argv) 
    window = MyApp() 
    window.show() 
    sys.exit(app.exec_()) 
+0

請注意,ThreadC上的插槽實際上在主線程**中運行**。在單獨的線程中運行的'QThread'的唯一部分是從'run'方法運行的東西。 –