我正在尝试使用Qlabel作为消息中心,以便将消息转发给应用程序的用户。有些消息可能比Qlabel允许的更长,我希望它只是水平滚动直到文本结束。我怎么能在Qlabel中做到这一点?我似乎无法在设计器中找到任何东西,也不想在代码中找到某种截断方法,只是从字符串的前面取下碎片,这看起来很傻。
答案 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中没有任何内容。您确实需要创建一个更改文本的动画。
您可以使用QFontMetrics
(label.fontMetrics()
)来确定标签文本是否大于QLabel
(以了解是否需要滚动标签文本)。您需要一种方法每半秒左右重新绘制QLabel
以设置滚动动画。最简单的方法可能是QTimer
。最简单的方法可能是子类QLabel
并让它检查是否需要滚动自己并每隔半秒左右重置文本以模拟滚动。
如果您希望滚动更平滑(在子角色级别),您必须覆盖绘制方法并自行绘制文本并根据需要剪切它。