2016-03-30 63 views
1

我正在嘗試使用Qlabel作爲消息中心將消息轉發給應用程序的用戶。一些消息可能比Qlabel允許的更長,我希望它只是水平滾動直到文本結束。我怎樣才能在Qlabel中做到這一點?我似乎無法在設計器中找到任何東西,也不想在代碼中找到某種截斷方法,只是從字符串的前面取下一些片斷,看起來很愚蠢。Qlabel中的平滑滾動文本

+0

你希望它自動滾動,像那些點燃的跡象嗎?或者你只是想讓用戶能夠滾動它? –

+0

發光的跡象。當然。不希望任何人能夠移動它。 – electrometro

回答

0

在默認情況下,Qt並沒有這樣做。您確實需要創建一個改變文本的動畫。

您可以使用QFontMetricslabel.fontMetrics())來確定標籤文本是否大於QLabel(要知道是否需要滾動它)。您需要每半秒重新繪製一次QLabel的方法來爲滾動設置動畫。最簡單的方法可能是QTimer。最簡單的方法可能是QLabel的子類,並檢查它是否需要滾動自己並每隔半秒左右重置文本以模擬滾動。

如果您希望滾動更平滑(在子字符級別),您必須重寫paint方法,並根據需要自行繪製文本並進行剪裁。

+0

這聽起來完全像我真正想避免的。謝謝,我只是試圖找到一種方法來巧妙地限制文本的大小。 – electrometro

+0

Qlabels允許你知道wordwrap。 –

+0

是的,但我們希望在一個相當小的空間中使用大字體,不要以爲換行就行。 – electrometro

0

你所追求的是俗稱的選框部件。這是一個非常簡單和生鏽的實現,它使用了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_())