Qt:走马灯代码理解

走马灯是编程学习中常用到的示例代码。在这里把从中学到的知识进行一个汇总。如有不对之处,请各位指正。

一:思路

走马灯首先要考虑是在特定时间点将显示内容向一个方向移动,当显示最后有空位时,循环填写显示内容。

要有一个定时器;处理定时器的事件;显示的文本内容;当显示内容在控件中移动时,需要重绘控件。

当控件隐藏后,停止走马灯。

处理控件隐藏事件。

当控件显示时,开始走马灯。

处理控件显示事件。

二:头文件

#ifndef MAINWIDGET_H#define MAINWIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
class QTimerEvent;
class QShowEvent;
class QHideEvent;
class QPaintEvent;
QT_END_NAMESPACE

namespace Ui {
class MainWidget;
}

class MainWidget : public QWidget
{
    Q_OBJECT
    //属性
    Q_PROPERTY(QString text READ text WRITE setText)

public:
    explicit MainWidget(QWidget *parent = 0);
    ~MainWidget();
    //接收文本
    void setText(const QString &newText);
    //返回保存文本
    QString text() const;
    //返回最合适的控件尺寸大小
    virtual QSize sizeHint() const;
    //重绘控件
    virtual void paintEvent(QPaintEvent* e);

protected:
    //处理定时器事件
    virtual void timerEvent(QTimerEvent* e);
    //处理控件显示事件
    virtual void showEvent(QShowEvent* e);
    //处理控件隐藏事件
    virtual void hideEvent(QHideEvent* e);

private:
    Ui::MainWidget *ui;
    //保存文本变量
    QString myText;
    //保存显示文本偏移量
    int offset;
    //保存定时器id
    int myTimerId;
};

#endif // MAINWIDGET_H

下面是对方法的具体实现及注释。

当控件显示时,每隔30minsec调用定时器。将定时器id赋给myTimerId。

void MainWidget::showEvent(QShowEvent *e){
    myTimerId = startTimer(30);
}

当定时器被激活时,调用控件的定时器处理事件。

触发定时器事件时,首先判断触发此事件的定时器是否是走马灯定时器,如果是则对offset变量自加1,同时对控件面板上的内容左移1pixel。这样相当于控件面板左上角坐标为(0,0);但是面板最左边坐标为(-1,0)。当在paintEvent事件中重绘面板时,总是从最左端开始绘制内容,这样看就好像内容是不断向左边移动的。形成跑马灯效果。在其他情况下,调用父类的定时器事件进行处理。

void MainWidget::timerEvent(QTimerEvent *e){
   if (e->timerId() == myTimerId) {
       ++offset;

       /**
         如果是则对offset变量自加1,同时对控件面板上的内容左移1pixel。这样相当于控件面板左上
         角坐标为(0,0);但是面板最左边坐标为(-1,0)。当在paintEvent事件中重绘面板时,总是
         从最左端开始绘制内容,这样看就好像内容是不断向左边移动的。形成跑马灯效果。
        */
       if (offset >= fontMetrics().width(text())) {
           offset = 0;
       }

       scroll(-1, 0);
   } else {
       //调用父类定时器事件处理。
       QWidget::timerEvent(e);
   }
}

当控件隐藏时,kill定时器。并将定时器id变量置0。

void MainWidget::hideEvent(QHideEvent *e){
    Q_UNUSED(e);

    killTimer(myTimerId);
    myTimerId = 0;
}

当控件变化时(控件挪动,尺寸变化等),对控件面板进行重绘。

void MainWidget::paintEvent(QPaintEvent *e){
    Q_UNUSED(e);

    QPainter painter(this);

    //set the text width and height.
    const int textWidth(fontMetrics().width(text()));
    const int textHeight(fontMetrics().height());

    //no text show.
    if (1 > textWidth) {
        return;
    }

    //set the text begin in (-offset, 0).
    int x(-offset);
    while (width() > x) {
        painter.drawText(x,
                         0,
                         textWidth,
                         textHeight,
                         Qt::AlignLeft | Qt::AlignVCenter,
                         text());
        //
        x += textWidth;
    }
}


转载于:https://my.oschina.net/weiweiqiao/blog/334931

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值