QLabel 中的文本滚动(字幕)

2024-01-06

我正在学习小部件选框标签 https://www.linux-apps.com/p/1132075/ class:

#include "WidgetMarqueeLabel.h"
#include <QPainter>
#include <QWidget>

WidgetMarqueeLabel::WidgetMarqueeLabel(QWidget *parent)//*parent)
{   
        px = 0;
        py = 10;
        speed = 1;
        direction = RightToLeft;
        connect(&timer3, SIGNAL(timeout()), this, SLOT(refreshLabel()));
        timer3.start(10);
}

void WidgetMarqueeLabel::refreshLabel()
{
    repaint();  
}

WidgetMarqueeLabel::~WidgetMarqueeLabel()
{}

void WidgetMarqueeLabel::show()
{   
    QLabel::show();
}

void WidgetMarqueeLabel::setAlignment(Qt::Alignment al)
{
    m_align = al;
    updateCoordinates();
    QLabel::setAlignment(al);
}

void WidgetMarqueeLabel::paintEvent(QPaintEvent *evt)
{
    QPainter p(this);
    if(direction==RightToLeft)
    {
        px -= speed;
        if(px <= (-textLength))
            px = width();
    }
    else
    {
        px += speed;
        if(px >= width())
            px = - textLength;
    }
        p.drawText(px, py+fontPointSize, text());
    p.translate(px,0);
}

void WidgetMarqueeLabel::resizeEvent(QResizeEvent *evt)
{   
    updateCoordinates();
    QLabel::resizeEvent(evt);
}

void WidgetMarqueeLabel::updateCoordinates()
{
    switch(m_align)
    {
        case Qt::AlignTop:
            py = 10;
            break;
        case Qt::AlignBottom:
                        py = height()-10;
            break;
        case Qt::AlignVCenter:
            py = height()/2;
            break;
    }
    fontPointSize = font().pointSize()/2;
    textLength = fontMetrics().width(text());
}

void WidgetMarqueeLabel::setSpeed(int s)
{
    speed = s;
}

int WidgetMarqueeLabel::getSpeed()
{
    return speed;
}

void WidgetMarqueeLabel::setDirection(int d)
{
    direction = d;
    if (direction==RightToLeft)
        px = width() - textLength;
    else
        px = 0;
    refreshLabel();
}

void WidgetMarqueeLabel::close()
{
        QLabel::close();
}

我想知道是否可以使文本重新出现在到达右侧最后一个字母末尾的文本之前。我想要这样的东西:例如(空白是 25):

WidgetMarqueeLabel
tMarqueeLabel                         Widge
eLabel                         WidgetMarque
el                          WidgetMarqueeLa
                      WidgetMarqueeLabel
               WidgetMarqueeLabel
       WidgetMarqueeLabel
WidgetMarqueeLabel

这可能吗?


为此,我曾经写过一个类。

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.

代码:

滚动文本.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

滚动文本.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();
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

QLabel 中的文本滚动(字幕) 的相关文章