PyQt5:如何在QThread和某些子类之间进行“通信”?

时间:2018-01-22 04:00:08

标签: python pyqt pyqt4 pyqt5

对于这个问题,我指的是PyQt5: How to scroll text in QTextEdit automatically (animational effect)?

中来自@eyllanesc的答案

@eyllanesc显示了如何使用'Same data 'If condition met, copy cells j = 2 For i = 2 To OLast_row IsEqual = False For j = 2 To NLast_row If OWS.Cells(i, 1).Value = NWS.Cells(j, 1).Value Then For Z = 2 To OLast_clmn If OWS.Cells(i, Z).Value = NWS.Cells(j, Z).Value Then IsEqual = True Else IsEqual = False End If Next If IsEqual = True Then cnt = cnt + 1 CompareWS.Cells(cnt, 1).Value = same For D = 1 To OLast_clmn OWS.Cells(i, D).Copy CompareWS.Cells(cnt, D + 1) Next End If Else Next Next 使文本自动滚动。它很棒。

对于这个问题,我添加了一些额外的行,以使用verticalScrollBar()来获取文本。

我想在此处实现:QThreadQThread class进行“沟通”,以便滚动时间可以通过文字长度来确定。当滚动过程结束时,程序停止。

我必须说这对我来说非常棘手。我想首先展示程序流程,正如我想象的那样。

enter image description here

更新:我的代码如下。它有效,但是......

代码问题:当文字停止滚动时,AnimationTextEdit class仍然有效。应用程序在那里等待time.sleep()停止。

我想要的内容:当文本停止滚动时,time.sleep()会运行到其结束值。

time.sleep()

感谢您的帮助和提示。我做错了什么?

1 个答案:

答案 0 :(得分:2)

虽然在动画中持续时间已经建立,但有必要了解这并不准确,这可能因多种原因而有所不同,因此使用睡眠计算等待它在特定时间内结束并且只是关闭应用程序可能失败。

如果您的主要目标是当动画完成时程序执行完成,那么您必须使用完成的QVariantAnimation信号来完成线程的执行,此信号在完成执行时会被激活。

class AnimationTextEdit(QTextEdit):
    def __init__(self, *args, **kwargs):
        QTextEdit.__init__(self, *args, **kwargs)
        self.animation = QVariantAnimation(self)
        self.animation.valueChanged.connect(self.moveToLine)

    @pyqtSlot()
    def startAnimation(self):
        self.animation.stop()
        self.animation.setStartValue(0)
        self.textLength = self.verticalScrollBar().maximum()
        self.animation.setEndValue(self.textLength)
        self.animation.setDuration(self.animation.endValue()*4)
        self.animation.start()

    @pyqtSlot(QVariant)
    def moveToLine(self, i):
        self.verticalScrollBar().setValue(i)


class Worker(QObject):
    textSignal = pyqtSignal(str)
    @pyqtSlot()
    def getText(self):
        longText = "\n".join(["{}: long text - auto scrolling ".format(i) for i in range(100)])
        self.textSignal.emit(longText)


class MyApp(QWidget):
    def __init__(self):
        super(MyApp, self).__init__()
        self.setFixedSize(600, 400)
        self.initUI()
        self.startThread()

    def initUI(self):
        self.txt = AnimationTextEdit(self)
        self.btn = QPushButton("Start", self)

        self.layout = QHBoxLayout(self)
        self.layout.addWidget(self.txt)
        self.layout.addWidget(self.btn)

        self.btn.clicked.connect(self.txt.startAnimation)

    def startThread(self):
        self.obj = Worker()
        self.thread = QThread()

        self.obj.textSignal.connect(self.textUpdate)
        self.obj.moveToThread(self.thread)
        self.txt.animation.finished.connect(self.thread.quit)
        self.thread.started.connect(self.obj.getText)
        self.thread.finished.connect(app.exit)
        self.thread.start()

    def textUpdate(self, longText):
        self.txt.append(longText)
        self.txt.moveToLine(0)


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