在Qlabel中平滑滚动文本

时间:2016-03-30 00:16:48

标签: python-2.7 pyqt pyqt4 qwidget qlabel

我正在尝试使用Qlabel作为消息中心,以便将消息转发给应用程序的用户。有些消息可能比Qlabel允许的更长,我希望它只是水平滚动直到文本结束。我怎么能在Qlabel中做到这一点?我似乎无法在设计器中找到任何东西,也不想在代码中找到某种截断方法,只是从字符串的前面取下碎片,这看起来很傻。

2 个答案:

答案 0 :(得分:1)

你所追求的通常被称为Marquee小部件。这是一个使用QLabel的非常简单和生锈的实现,但也可以使用QWidget来完成。我重写了使用QTextDocument的setText方法,其中父项QLabel本身保存文本。如果文字大于QLabel的大小,QTimer会触发移动文字的翻译方法:

import sys

from PyQt5.QtCore import QEvent, QTimer, pyqtSlot
from PyQt5.QtGui import QTextDocument, QPainter, QFontMetrics
from PyQt5.QtWidgets import QLabel, QApplication


class Marquee(QLabel):

    x = 0

    paused = False
    document = None
    speed = 50
    timer = None

    def __init__(self, parent=None):
        super().__init__(parent)
        self.fm = QFontMetrics(self.font())
        self.setFixedSize(200, 20)

    def setText(self, value):
        self.x = 0

        self.document = QTextDocument(self)
        self.document.setPlainText(value)
        # I multiplied by 1.06 because otherwise the text goes on 2 lines
        self.document.setTextWidth(self.fm.width(value) * 1.06)
        self.document.setUseDesignMetrics(True)

        if self.document.textWidth() > self.width():
            self.timer = QTimer(self)
            self.timer.timeout.connect(self.translate)
            self.timer.start((1 / self.speed) * 1000)

    @pyqtSlot()
    def translate(self):
        if not self.paused:
            if self.width() - self.x < self.document.textWidth():
                self.x -= 1
            else:
                self.timer.stop()
        self.repaint()

    def event(self, event):
        if event.type() == QEvent.Enter:
            self.paused = True
        elif event.type() == QEvent.Leave:
            self.paused = False
        return super().event(event)

    def paintEvent(self, event):
        if self.document:
            p = QPainter(self)
            p.translate(self.x, 0)
            self.document.drawContents(p)
        return super().paintEvent(event)


if __name__ == '__main__':

    app = QApplication(sys.argv)
    w = Marquee()
    w.setText('Lorem ipsum dolor sit amet, consectetur adipiscing elit...')
    w.show()
    sys.exit(app.exec_())

答案 1 :(得分:0)

默认情况下,Qt中没有任何内容。您确实需要创建一个更改文本的动画。

您可以使用QFontMetricslabel.fontMetrics())来确定标签文本是否大于QLabel(以了解是否需要滚动标签文本)。您需要一种方法每半秒左右重新绘制QLabel以设置滚动动画。最简单的方法可能是QTimer。最简单的方法可能是子类QLabel并让它检查是否需要滚动自己并每隔半秒左右重置文本以模拟滚动。

如果您希望滚动更平滑(在子角色级别),您必须覆盖绘制方法并自行绘制文本并根据需要剪切它。