2016-03-30 18 views
1

Ich versuche, ein Qlabel als Nachrichtenzentrale für die Weiterleitung von Nachrichten an Benutzer der Anwendung zu verwenden. Einige Nachrichten sind möglicherweise länger als für das Qlabel zulässig, und ich möchte, dass sie nur bis zum Ende des Textes horizontal scrollt. Wie kann ich das in einem Qlabel machen? Ich kann anscheinend nichts im Designer finden und möchte keine Art von Kürzungs-Methode im Code ausarbeiten, die nur Stücke von der Vorderseite der Saite entfernt, was albern erscheint.Smooth Scroll-Text in Qlabel

+0

Wollen Sie es automatisch blättern, wie einer dieser beleuchteten Anzeigen? Oder möchten Sie nur, dass der Benutzer es scrollen kann? –

+0

Beleuchtete Schilder. Bestimmt. Ich will nicht, dass jemand es bewegen kann. – electrometro

Antwort

0

Es gibt nichts in Qt, das das standardmäßig tut. Sie müssen in der Tat eine Animation erstellen, die den Text ändert.

Sie können QFontMetrics (label.fontMetrics()) verwenden, um festzustellen, ob der Beschriftungstext größer als dann ist QLabel (um zu wissen, ob Sie es scrollen müssen oder nicht). Sie müssen die QLabel jede halbe Sekunde neu streichen, um das Scrollen zu animieren. Der einfachste Weg ist wahrscheinlich ein QTimer. Die einfachste Methode wäre wahrscheinlich, die Unterklasse QLabel zu entfernen und zu überprüfen, ob sie selbst scrollen muss und den Text jede halbe Sekunde zurücksetzen muss, um das Scrollen zu simulieren.

Wenn Sie möchten, dass das Scrollen noch glatter ist (auf einer Unterzeichenebene), müssen Sie die Malmethode überschreiben und den Text selbst zeichnen, indem Sie ihn bei Bedarf übersetzen und beschneiden.

+0

Das klingt genau wie das, was ich wirklich vermeiden wollte. Danke, ich werde versuchen, einen Weg zu finden, um die erlaubte Textgröße intelligent einzuschränken. – electrometro

+0

Qlabels erlauben Wordwrap Sie wissen. –

+0

Ja, aber wir wollen große Schrift in einem relativ kleinen Raum, glaube nicht, Word-Wrapping wird funktionieren. – electrometro

0

Worauf Sie hinaus wollen, wird allgemein als Marquee-Widget bezeichnet. Hier ist eine sehr einfache und rostige Implementierung, die eine QLabel verwenden, aber es kann auch mit einer QWidget getan werden. Ich überschrieb die setText-Methode, von der ich eine QTextDocument, mit Eltern die QLabel selbst, die den Text enthält. Wenn der Text größer als die Größe des QLabel einer QTimer löst eine Umrechnungsmethode, die den Text bewegt:

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_())