我正在使用以下代码使用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)
我不知道为什么即使其他部分用户界面仍在运行,滚动消息也会在几个小时后停止。
答案 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_())