qt label scrolltext

来源:互联网 发布:淘宝一千零一夜男厨师 编辑:程序博客网 时间:2024/05/20 01:36

enter image description here
Example screenshot showing the text "This is an example text. It will be scrolled horizontally.". Note the alpha blending at both sides.

The code:

scrolltext.h:

#ifndef SCROLLTEXT_H#define SCROLLTEXT_H#include <QWidget>#include <QStaticText>#include <QTimer>class ScrollText : public QWidget{    Q_OBJECT    Q_PROPERTY(QString text READ text WRITE setText)    Q_PROPERTY(QString separator READ separator WRITE setSeparator)public:    explicit ScrollText(QWidget *parent = 0);public slots:    QString text() const;    void setText(QString text);    QString separator() const;    void setSeparator(QString separator);protected:    virtual void paintEvent(QPaintEvent *);    virtual void resizeEvent(QResizeEvent *);private:    void updateText();    QString _text;    QString _separator;    QStaticText staticText;    int singleTextWidth;    QSize wholeTextSize;    int leftMargin;    bool scrollEnabled;    int scrollPos;    QImage alphaChannel;    QImage buffer;    QTimer timer;private slots:    virtual void timer_timeout();};#endif // SCROLLTEXT_H

scrolltext.cpp:

#include "scrolltext.h"#include <QPainter>ScrollText::ScrollText(QWidget *parent) :    QWidget(parent), scrollPos(0){    staticText.setTextFormat(Qt::PlainText);    setFixedHeight(fontMetrics().height());    leftMargin = height() / 3;    setSeparator("   ---   ");    connect(&timer, SIGNAL(timeout()), this, SLOT(timer_timeout()));    timer.setInterval(50);}QString ScrollText::text() const{    return _text;}void ScrollText::setText(QString text){    _text = text;    updateText();    update();}QString ScrollText::separator() const{    return _separator;}void ScrollText::setSeparator(QString separator){    _separator = separator;    updateText();    update();}void ScrollText::updateText(){    timer.stop();    singleTextWidth = fontMetrics().width(_text);    scrollEnabled = (singleTextWidth > width() - leftMargin);    if(scrollEnabled)    {        scrollPos = -64;        staticText.setText(_text + _separator);        timer.start();    }    else        staticText.setText(_text);    staticText.prepare(QTransform(), font());    wholeTextSize = QSize(fontMetrics().width(staticText.text()), fontMetrics().height());}void ScrollText::paintEvent(QPaintEvent*){    QPainter p(this);    if(scrollEnabled)    {        buffer.fill(qRgba(0, 0, 0, 0));        QPainter pb(&buffer);        pb.setPen(p.pen());        pb.setFont(p.font());        int x = qMin(-scrollPos, 0) + leftMargin;        while(x < width())        {            pb.drawStaticText(QPointF(x, (height() - wholeTextSize.height()) / 2) + QPoint(2, 2), staticText);            x += wholeTextSize.width();        }        //Apply Alpha Channel        pb.setCompositionMode(QPainter::CompositionMode_DestinationIn);        pb.setClipRect(width() - 15, 0, 15, height());        pb.drawImage(0, 0, alphaChannel);        pb.setClipRect(0, 0, 15, height());        //initial situation: don't apply alpha channel in the left half of the image at all; apply it more and more until scrollPos gets positive        if(scrollPos < 0)            pb.setOpacity((qreal)(qMax(-8, scrollPos) + 8) / 8.0);        pb.drawImage(0, 0, alphaChannel);        //pb.end();        p.drawImage(0, 0, buffer);    }    else    {        p.drawStaticText(QPointF(leftMargin, (height() - wholeTextSize.height()) / 2), staticText);    }}void ScrollText::resizeEvent(QResizeEvent*){    //When the widget is resized, we need to update the alpha channel.    alphaChannel = QImage(size(), QImage::Format_ARGB32_Premultiplied);    buffer = QImage(size(), QImage::Format_ARGB32_Premultiplied);    //Create Alpha Channel:    if(width() > 64)    {        //create first scanline        QRgb* scanline1 = (QRgb*)alphaChannel.scanLine(0);        for(int x = 1; x < 16; ++x)            scanline1[x - 1] = scanline1[width() - x] = qRgba(0, 0, 0, x << 4);        for(int x = 15; x < width() - 15; ++x)            scanline1[x] = qRgb(0, 0, 0);        //copy scanline to the other ones        for(int y = 1; y < height(); ++y)            memcpy(alphaChannel.scanLine(y), (uchar*)scanline1, width() * 4);    }    else        alphaChannel.fill(qRgb(0, 0, 0));    //Update scrolling state    bool newScrollEnabled = (singleTextWidth > width() - leftMargin);    if(newScrollEnabled != scrollEnabled)        updateText();}void ScrollText::timer_timeout(){    scrollPos = (scrollPos + 2)                % wholeTextSize.width();    update();}

Something like the following should work. The padding is hard-coded at 25, which is what is sounded like you wanted. If you wanted the label to always be a certain size, you could use something likeQString::leftJustified.

class MarqueeLabel : public QLabel { public:  explicit MarqueeLabel(const QString &text) : QLabel(text), pos_(0) {    QString pad(25, ' ');    actual_text_ = text + pad;    startTimer(100);  }protected:  void timerEvent(QTimerEvent *) {    pos_ = ++pos_ % actual_text_.length();    setText(actual_text_.mid(pos_).append(actual_text_.left(pos_)));  }private:  QString actual_text_;  int pos_;};int main(int argc, char *argv[]) {    QApplication a(argc, argv);    MarqueeLabel lbl("WidgetMarqueeLabel");    lbl.show();    return a.exec();}





0 0