1. Qt属性系统

Qt属性系统,使用Q_PROPERTY(....)宏完成自定义属性到元对象系统的属性注册,对于属性系统,也有不用注册的属性值,称之为Qt弱属性,属性系统要求类必须继承至QObject或其子类,注册方式如下

Q_PROPERTY(type name
            (READ getFunction [WRITE setFunction] |
             MEMBER memberName [(READ getFunction | WRITE setFunction)])
            [RESET resetFunction]
            [NOTIFY notifySignal]
            [REVISION int]
            [DESIGNABLE bool]
            [SCRIPTABLE bool]
            [STORED bool]
            [USER bool]
            [CONSTANT]
            [FINAL])

属性名字和READ方法一般是有必要提供的,属性的类型是任何QVariant支持的属性类型,对于非内置的新类型需要注册才可以使用,WRITE表示写方法,一般用来修改属性值,NOTIFY标志属性变化时需要发送的信号,大多情况下完成以上几个函数即可。

2. Qt属性系统的使用

本文以仪表举例,在仪表类中注册一个angle属性并增加其属性动画,以下为注册语句

//在类中注册angle属性,并提供属性set/get方法
Q_PROPERTY(int angle READ angle WRITE setAngle);
    int angle(){
        return mAngle;
    }
    void setAngle(int angle){
        mAngle = angle;
    }

通过以上的注册语句,使得该类就含有了angle属性,对于属性值的访问,可以使用angle()函数获取,也可以使用对象名,例如 object->Property("angle").toInt()的方式访问。

3. 给自定义的属性增加属性动画,完成仪表的非线性自检扫描

使用Qt属性动画,给当前自定义属性增加动画的过程如下

3.1 注册属性并提供set/get方法

class DashBoard : public QWidget
{
    Q_OBJECT
public:
    explicit DashBoard(QWidget *parent = nullptr);
    void paintScale(QPainter &paint);
    void paintPointer(QPainter &paint);
    Q_PROPERTY(int angle READ angle WRITE setAngle);
    int angle(){
        return mAngle;
    }
    void setAngle(int angle){
        mAngle = angle;
    }
signals:
protected:
    void paintEvent(QPaintEvent *event) override;
private:
    int mAngle = 0;
    QPropertyAnimation mAnimationGo;
    QPropertyAnimation mAnimationBack;
};

3.2 设置指针的往复动画

表盘指针在模拟自检时,需要往复运动,因此需要两组渐变动画,代码如下

    mAnimationGo.setPropertyName("angle");
    mAnimationGo.setTargetObject(this);
    mAnimationGo.setDuration(2000);
    mAnimationGo.setStartValue(0);
    mAnimationGo.setEndValue(220);
    mAnimationGo.setEasingCurve(QEasingCurve::InCirc);
    mAnimationGo.start();
    QTimer *timer = new QTimer(this);
    connect(timer,&QTimer::timeout,this,[=](){
        update();
    });
    mAnimationBack.setPropertyName("angle");
    mAnimationBack.setTargetObject(this);
    mAnimationBack.setDuration(1500);
    mAnimationBack.setStartValue(220);
    mAnimationBack.setEndValue(0);
    mAnimationBack.setEasingCurve(QEasingCurve::InCirc);

3.3 属性动画结果如下

navar