QLabel中的文本滚动(字幕) [英] Text scrolling (Marquee) in QLabel

查看:1176
本文介绍了QLabel中的文本滚动(字幕)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习 WidgetMarqueeLabel 类:

#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):

I was wondering if it was possible to make the text reappear before the text that reaches the end of the last letter on the right. I want something like this: for example (white space are 25):

WidgetMarqueeLabel
tMarqueeLabel                         Widge
eLabel                         WidgetMarque
el                          WidgetMarqueeLa
                      WidgetMarqueeLabel
               WidgetMarqueeLabel
       WidgetMarqueeLabel
WidgetMarqueeLabel

这可能吗?

推荐答案

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

For this purpose, I once wrote a class.


示例屏幕快照,显示文本这是示例文本.它将水平滚动.".请注意两边的Alpha混合.


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

代码:

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();
}

这篇关于QLabel中的文本滚动(字幕)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆