使用Qthread时Signal-Slot的问题

时间:2016-09-26 15:30:00

标签: python multithreading pyqt4 signals-slots

我为我的问题写了一个示例代码。此代码应生成两个给定数字的总和,并在文本浏览器中显示结果,然后用sum替换第一个数字,并将其添加到第二个数字并再次在文本浏览器中显示结果。此过程应继续。问题是:

1 - 为什么信号无法正常工作?

2 - 如何使用sum-number发出信号以显示在文本浏览器上?

import sys
import time

from PyQt4.QtCore import *
from PyQt4.QtGui import *


class AreaThread(QThread):
    signal = pyqtSignal()

    def __init__(self, no1, no2, parent):
        QThread.__init__(self)

        self.no1 = no1
        self.no2 = no2

    def area(self):
        for i in range(10):
            self.sum = self.no1 + self.no2
            self.no1 = self.no2
            self.no2 = self.sum
            self.signalemit()
            time.sleep(1)

    def signalemit(self):
        self.signal.emit()

    def run(self):
        self.area()


class GeneralizedRun (QMainWindow):

    def __init__(self, no1, no2):

        QMainWindow.__init__(self)
        self.no1 = no1
        self.no2 = no2

    def initUi(self, mainwindow):

        mainwindow.centralWidget = QWidget(mainwindow)

        self.runflow = QTextBrowser()
        self.runflow.isReadOnly()
        self.runflow.setText('running:')
        self.runflow.moveCursor(QTextCursor.End)

        self.runflow.show()
        mainwindow.centralWidget = self.runflow
        self.threadruning()

    def threadruning(self):
        self.area = AreaThread(self.no1, self.no2, self)
        self.area.start()
        self.area.signal.connect(self.updatetexteditor)

    def updatetexteditor(self):

        self.runflow.insertPlainText('\n\n' + 'sum')
        self.runflow.moveCursor(QTextCursor.End)


class MainApplication(QMainWindow):

    def __init__(self):

        QMainWindow.__init__(self)
        self.setWindowTitle('Home')
        self.setGeometry(50, 50, 500, 500)

        #Main widget
        self.mainwidget = QWidget()
        self.mainlayout = QVBoxLayout()

        #Widgets
        #Form line edits
        self.no1 = QLineEdit()
        self.no2 = QLineEdit()

        self.run = QPushButton('Run')
        self.exit = QPushButton('Exit')

        self.form = QFormLayout()
        self.form.addRow('First number', self.no1)
        self.form.addRow('Second number', self.no2)

        self.mainlayout.addLayout(self.form)
        self.mainlayout.addWidget(self.run)
        self.mainlayout.addWidget(self.exit)

        self.exit.clicked.connect(self.exitapplication)
        self.run.clicked.connect(self.mainprogramrun)

        self.mainwidget.setLayout(self.mainlayout)
        self.mainwidget.show()

    def exitapplication(self):
        sys.exit()

    def mainprogramrun(self):

        number1 = float(self.no1.text())
        number2 = float(self.no2.text())

        run = GeneralizedRun(number1, number2)
        run.initUi(self)


def main():

    application = QApplication(sys.argv)
    application_window = MainApplication()
    application.exec_() 

if __name__ == '__main__':
    main()

1 个答案:

答案 0 :(得分:1)

示例代码无法正常工作,因为您没有保留对GeneralizedRun窗口的引用。所以要解决的第一件事是:

class MainApplication(QMainWindow):
    ...

    def mainprogramrun(self):

        number1 = float(self.no1.text())
        number2 = float(self.no2.text())

        # keep a reference to the window
        self.runner = GeneralizedRun(number1, number2)
        self.runner.initUi(self)

要将总和传递给gui,线程类应如下所示:

class AreaThread(QThread):
    # re-define the signal to send a value
    signal = pyqtSignal(float)

    def __init__(self, no1, no2, parent):
        QThread.__init__(self)

        self.no1 = no1
        self.no2 = no2

    def area(self):
        for i in range(10):
            self.sum = self.no1 + self.no2
            self.no1 = self.no2
            self.no2 = self.sum
            # pass the value
            self.signalemit(self.sum)
            time.sleep(1)

    def signalemit(self, value):
        # send the value
        self.signal.emit(value)

    def run(self):
        self.area()

并且信号处理程序应如下所示:

class GeneralizedRun (QMainWindow):
    ...

    def updatetexteditor(self, value):
        # show the value
        self.runflow.insertPlainText('\n\nsum: %s' % value)
        self.runflow.moveCursor(QTextCursor.End)