几个小时后pyqt字幕文本挂起

时间:2018-10-31 17:34:38

标签: python-2.7 pyqt4

我正在使用以下代码使用pyqt创建滚动文本。另外,我正在使用QPainter在UI中创建矩形框。问题是这样的代码可以正常工作,但是在一段时间后挂起。当其他部分UI起作用时,消息停止滚动。我使用了来自较早的堆栈溢出问题的代码来滚动文本Marquee effect。以下是我的代码的一部分

class MarqueeLabel(QtGui.QLabel):
    def __init__(self, parent=None):
        QtGui.QLabel.__init__(self, parent)
        self.px = 0
        self.py = 15
        self._direction = Qt.RightToLeft #Qt.LeftToRight
        self.setWordWrap(True)
        self.timer = QTimer(self)
        self.timer.timeout.connect(self.update)
        self.timer.start(20)
        self._speed = 2
        self.textLength = 0
        self.fontPointSize = 0
        self.setAlignment(Qt.AlignVCenter)
        self.setFixedHeight(self.fontMetrics().height())

    def setFont(self, font, size):
        newfont = QtGui.QFont(font, size, QtGui.QFont.Bold)
        QtGui.QLabel.setFont(self, newfont)
        self.setFixedHeight(self.fontMetrics().height())

    def updateCoordinates(self):
        align = self.alignment()
        if align == Qt.AlignTop:
            self.py = 10
        elif align == Qt.AlignBottom:
            self.py = self.height() - 10
        elif align == Qt.AlignVCenter:
            self.py = self.height() / 2
        self.fontPointSize = self.font().pointSize() / 2
        self.textLength = self.fontMetrics().width(self.text())

    def setAlignment(self, alignment):
        self.updateCoordinates()
        QtGui.QLabel.setAlignment(self, alignment)

    def resizeEvent(self, event):
        self.updateCoordinates()
        QtGui.QLabel.resizeEvent(self, event)

    def paintEvent(self, event):
        painter = QPainter(self)
        if self._direction == Qt.RightToLeft:
            self.px -= self.speed()
            if self.px <= -self.textLength:
                self.px = self.width()
        else:
            self.px += self.speed()
            if self.px >= self.width():
                self.px = -self.textLength
        painter.drawText(self.px, self.py + self.fontPointSize, self.text())
        painter.translate(self.px, 0)

    def speed(self):
        return self._speed

    def setSpeed(self, speed):
        self._speed = speed

    def setDirection(self, direction):
        self._direction = direction
        if self._direction == Qt.RightToLeft:
            self.px = self.width() - self.textLength
        else:
            self.px = 0
        self.update()

    def pause(self):
        self.timer.stop()

    def unpause(self):
        self.timer.start()

class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        self.signalUpdateUI()
    def signalUpdateUI(self):
        updateUIThread = Thread(target=self.updateUI)
        updateUIThread.daemon = True
        updateUIThread.start()
    def updateUI(self):
        while(1==1):
            #update some text color and contents
            #update marquee label contents
            self.update()
            sleep(2)
    def paintEvent(self, event):
        QWidget.paintEvent(self, event)
        painter = QPainter(self)
        pen = QtGui.QPen(QtCore.Qt.black, 2, QtCore.Qt.SolidLine)
        painter.setPen(pen)
        painter.drawLine(0,190, 1920,190)
        painter.drawLine(0,300, 1920,300)
        painter.drawLine(0,840, 1920,840)
        painter.drawLine(0,930, 1920,930)

        # Reactangle Box Settings
        painter.setPen(self._rectBoxLine_color)
        painter.setBrush(self._rectBox_color)
        rect = QRect(1430,300,470,535)

        painter.drawRect(rect)
        painter.setFont(QtGui.QFont('Consolas', 60, QtGui.QFont.Bold))
        painter.setPen(QtGui.QColor(0, 0, 0))      
        painter.drawText(QRect(1430,300,470,535), QtCore.Qt.AlignCenter, self._rect_text)

我不知道为什么即使其他部分用户界面仍在运行,滚动消息也会在几个小时后停止。

1 个答案:

答案 0 :(得分:0)

marqueLabel的实现是高效的,因此我不认为这是导致错误的原因,另一方面,显示的代码也不可执行,但是显示的内容可以引起您注意线程在定期任务中的滥用,在禁止使用GUI的情况下,直接从另一个线程修改GUI,除了执行的任务不繁重之外,还必须使用QTimer。

from PyQt4 import QtCore, QtGui

class MarqueeLabel(QtGui.QLabel):
    def __init__(self, parent=None):
        super(MarqueeLabel, self).__init__(parent)
        self.px = 0
        self.py = 15
        self._direction = QtCore.Qt.RightToLeft #Qt.LeftToRight
        self.setWordWrap(True)
        self.timer = QtCore.QTimer(self, interval=20)
        self.timer.timeout.connect(self.update)
        self.timer.start()
        self._speed = 2
        self.textLength = 0
        self.fontPointSize = 0
        self.setAlignment(QtCore.Qt.AlignVCenter)
        self.setFixedHeight(self.fontMetrics().height())

    def setFont(self, font, size):
        newfont = QtGui.QFont(font, size, QtGui.QFont.Bold)
        QtGui.QLabel.setFont(self, newfont)
        self.setFixedHeight(self.fontMetrics().height())

    def updateCoordinates(self):
        align = self.alignment()
        if align == QtCore.Qt.AlignTop:
            self.py = 10
        elif align == QtCore.Qt.AlignBottom:
            self.py = self.height() - 10
        elif align == QtCore.Qt.AlignVCenter:
            self.py = self.height() / 2
        self.fontPointSize = self.font().pointSize() / 2
        self.textLength = self.fontMetrics().width(self.text())

    def setAlignment(self, alignment):
        self.updateCoordinates()
        QtGui.QLabel.setAlignment(self, alignment)

    def resizeEvent(self, event):
        self.updateCoordinates()
        QtGui.QLabel.resizeEvent(self, event)

    def paintEvent(self, event):
        painter = QtGui.QPainter(self)
        if self._direction == QtCore.Qt.RightToLeft:
            self.px -= self.speed()
            if self.px <= -self.textLength:
                self.px = self.width()
        else:
            self.px += self.speed()
            if self.px >= self.width():
                self.px = -self.textLength
        painter.drawText(self.px, self.py + self.fontPointSize, self.text())
        painter.translate(self.px, 0)

    def speed(self):
        return self._speed

    def setSpeed(self, speed):
        self._speed = speed

    def setDirection(self, direction):
        self._direction = direction
        if self._direction == Qt.RightToLeft:
            self.px = self.width() - self.textLength
        else:
            self.px = 0
        self.update()

    def pause(self):
        self.timer.stop()

    def unpause(self):
        self.timer.start()

class MainWindow(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self._rectBoxLine_color = QtGui.QColor(QtCore.Qt.green)
        self._rectBox_color = QtGui.QBrush(QtCore.Qt.blue)
        self._rect_text = "_rect_text"

        self.marquee = MarqueeLabel(self)
        self.signalUpdateUI()

    def signalUpdateUI(self):
        timer = QtCore.QTimer(self, interval=2000)
        timer.timeout.connect(self.updateUI)
        timer.start()
        self.updateUI()

    def updateUI(self):
            #update some text color and contents
            #update marquee label contents
            self.marquee.setText(QtCore.QDateTime.currentDateTime().toString())
            self.update()

    def paintEvent(self, event):
        super(MainWindow, self).paintEvent(event)
        painter = QtGui.QPainter(self)
        pen = QtGui.QPen(QtCore.Qt.black, 2, QtCore.Qt.SolidLine)
        painter.setPen(pen)
        painter.drawLine(0,190, 1920,190)
        painter.drawLine(0,300, 1920,300)
        painter.drawLine(0,840, 1920,840)
        painter.drawLine(0,930, 1920,930)

        # Reactangle Box Settings
        painter.setPen(self._rectBoxLine_color)
        painter.setBrush(self._rectBox_color)
        rect = QtCore.QRect(1430,300,470,535)

        painter.drawRect(rect)
        painter.setFont(QtGui.QFont('Consolas', 60, QtGui.QFont.Bold))
        painter.setPen(QtGui.QColor(0, 0, 0))      
        painter.drawText(QtCore.QRect(1430,300,470,535), QtCore.Qt.AlignCenter, self._rect_text)


if __name__ == '__main__':
    import sys
    app = QtGui.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())