zoukankan      html  css  js  c++  java
  • QT状态机

    首先吐槽下网上各种博主不清不楚的讲解 特别容易让新手迷惑

    总体思想是这样的:首先要有一个状态机对象, 顾名思义,这玩意就是用来容纳状态的。然后调用状态机的start()函数它就会更具你的逻辑去执行相关状态

    下面看代码,精华在注释

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include<QGraphicsScene>
    #include<QGraphicsView>
    #include<QGraphicsWidget>
    #include<QState>
    #include<QStateMachine>
    #include"MyPix.h"
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        this->setGeometry(100,100,400,400);
        QGraphicsView *view=new QGraphicsView(this);
        view->setGeometry(0,0,400,400);
        QGraphicsScene *scene=new QGraphicsScene;
        scene->setSceneRect(-200,-200,400,400);
        view->setScene(scene);
        //item scene 这些位置锚点都在其正中心
        //测试的时候注意要注意每个item本身坐标的体系的创建 否则很难看到效果
        QPixmap pix("1.png");
        MyPix *mypix=new MyPix(pix);
        scene->addItem(mypix);
        mypix->setPos(0,0);
    QStateMachine
    *states=new QStateMachine; QState *sm=new QState(states); QState *state1=new QState(states); #if 1 for(int i=0;i<10;i++){ //将mypix这个item添加到到state1这个状态里来 第一种效果 state1->assignProperty(mypix, "pos", QPointF(-200+i*40, -200+i*40)); } sm->addTransition(mypix,SIGNAL(pressed()),state1); //某一状态触发后 就从sm状态转换到state1状态 然而state1状态包含了Item的状态 故item状态变化 //因为状态state1只添加了item这个状态 所以一个循环执行完 实际上<==>state1->assignProperty(mypix,"pos",QPointF( //200,200)); //我们看下下面的表达方式 第二种效果 # else QList<MyPix*>pixs; for(int i=0;i<10;i++){ MyPix *mypix2=new MyPix(pix); pixs.append(mypix2); scene->addItem(mypix2); //这里的不只一个item的状态添加到了state这个状态里 state1->assignProperty(pixs.at(i), "pos", QPointF(-200+i*40, -200+i*40)); } sm->addTransition(pixs.at(9),SIGNAL(pressed()),state1); #endif states->setInitialState(sm); states->start(); } MainWindow::~MainWindow() { delete ui; }
     
    //这是第item的构建方法 因为本身QGraphicsItem 不支持Q_OBJECT 这意味着信号槽不能用 所以从QGraphicsWidget自行派生定义item是最佳选择 网上也有人从QObjecth和graphicsi
    //item派生的 不建议那么干

    #ifndef MYPIX_H #define MYPIX_H #include<QGraphicsWidget> #include<QPixmap> class MyPix : public QGraphicsWidget { Q_OBJECT public: MyPix(QPixmap &pix); //提供在约定的范围内进行绘图等操作接口 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); //提供整个item画图操作的约定范围接口 当然这是一个君子约定 QRectF boundingRect() const; //提供一个item绘画shape接口 QPainterPath shape() const; void mousePressEvent(QGraphicsSceneMouseEvent *event); private: QPixmap _pix; signals: void pressed(); }; #endif // MYPIX_H
    #include "MyPix.h"
    #include<QPainter>
    #include<QPainterPath>
    #include<QGraphicsSceneMouseEvent>
    MyPix::MyPix(QPixmap &pix):_pix(pix)
    {
    
    
    }
    QPainterPath MyPix::shape() const
    {
        QPainterPath path;
        path.addEllipse(boundingRect());
        return path;
    }
    void MyPix::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *){
        QRectF  p=boundingRect();
        painter->drawEllipse(p);
        painter->drawPixmap(-_pix.width()/2,-_pix.height()/2,_pix);
    
    
    }
    QRectF MyPix::boundingRect() const{
    
    
        return QRectF(-100,-100,200,200);
    }
    void MyPix::mousePressEvent(QGraphicsSceneMouseEvent *event)
    {
        if(event->button()==Qt::LeftButton){
    
    
            emit pressed();
        }
    }
     
    第一种情况点击一下运行效果为:从中间到右下角

    第二种点击一下运行效果:

    
    
  • 相关阅读:
    mysql表结构转hive表结构,字段映射脚本
    kafka 相关命令 偏移重置
    Specified key was too long; max key length is 767 bytes
    java IO 流关系图谱
    jvm 性能监控与linux常用命令
    jupiter的@TempDir 等不生效
    mysql 深度分页
    jedis的ShardedJedisPool链接池的扩容问题
    拜读《三国》看懂男人
    linux 性能优化
  • 原文地址:https://www.cnblogs.com/enjoyall/p/5436539.html
Copyright © 2011-2022 走看看