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

总体思想是这样的:首先要有一个状态机对象, 顾名思义,这玩意就是用来容纳状态的。然后调用状态机的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(,,,);
QGraphicsView *view=new QGraphicsView(this);
view->setGeometry(,,,);
QGraphicsScene *scene=new QGraphicsScene;
scene->setSceneRect(-,-,,);
view->setScene(scene);
//item scene 这些位置锚点都在其正中心
//测试的时候注意要注意每个item本身坐标的体系的创建 否则很难看到效果
QPixmap pix("1.png");
MyPix *mypix=new MyPix(pix);
scene->addItem(mypix);
mypix->setPos(,);
QStateMachine *states=new QStateMachine;
QState *sm=new QState(states);
QState *state1=new QState(states);
#if 1
for(int i=;i<;i++){
//将mypix这个item添加到到state1这个状态里来 第一种效果
state1->assignProperty(mypix, "pos",
QPointF(-+i*,
-+i*));
}
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=;i<;i++){
MyPix *mypix2=new MyPix(pix);
pixs.append(mypix2);
scene->addItem(mypix2);
//这里的不只一个item的状态添加到了state这个状态里
state1->assignProperty(pixs.at(i), "pos",
QPointF(-+i*,
-+i*));
}
sm->addTransition(pixs.at(),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();
    }
}
 
第一种情况点击一下运行效果为:从中间到右下角

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

												

QT状态机的更多相关文章

  1. Qt 状态机框架学习(没学会)

    Qt状态机框架是基于状态图XML(SCXML) 实现的.从Qt4.6开始,它已经是QtCore模块的一部分.尽管它本身是蛮复杂的一套东西,但经过和Qt的事件系统(event system).信号槽(s ...

  2. Qt状态机框架(状态机就开始异步的运行了,也就是说,它成为了我们应用程序事件循环的一部分了)

    状态机框架 Qt中的状态机框架为我们提供了很多的API和类,使我们能更容易的在自己的应用程序中集成状态动画.这个框架是和Qt的元对象系统机密结合在一起的.比如,各个状态之间的转换是通过信号触发的,状态 ...

  3. 如何保证Qt状态机的最佳性能

    如何保证Qt状态机的最佳性能 How to ensure the best Qt state machine performance 如果您使用Qt进行应用程序开发,并且使用状态机,那么很可能您正在使 ...

  4. Qt状态机框架

    The State Machine Framework 状态机框架提供了用于创建和执行状态图的类.概念和符号是基于Harel的Statecharts: A visual formalism for c ...

  5. Qt之动画框架

    简述 Qt动画框架旨在为创建动画和平滑的GUI提供了一种简单的方法.通过Qt动画属性,该框架为部件和其它QObject对象的动画操作提供了非常大的自由性,框架也可以被用于图形视图框架中,动画框架中许多 ...

  6. Qt事件循环与状态机事件循环的思考

    写下这个给自己备忘,关于事件循环以及多线程方面的东西我还需要多多学习.首先我们都知道程序有一个主线程,在GUI程序中这个主线程也叫GUI线程,图形和绘图相关的函数都是由主线程来提供.主线程有个事件循环 ...

  7. Qt 事件系统浅析 (用 Windows API 描述,分析了QCoreApplication::exec()和QEventLoop::exec的源码)(比起新号槽,事件机制是更高级的抽象,拥有更多特性,比如 accept/ignore,filter,还是实现状态机等高级 API 的基础)

    事件系统在 Qt 中扮演了十分重要的角色,不仅 GUI 的方方面面需要使用到事件系统,Signals/Slots 技术也离不开事件系统(多线程间).我们本文中暂且不描述 GUI 中的一些特殊情况,来说 ...

  8. Qt 动画框架

    最近一个项目中的需要做动画效果,很自然就想起来用qt animation framework .这个框架真的很强大.支持多个动画组合,线性动画,并行动画等.在此总结一下使用该框架一些需要注意的地方: ...

  9. 《Qt 实战一二三》

    简介 "我们来自Qt分享&&交流,我们来自Qt Quick分享&&交流",不管你是笑了,还是笑了,反正我们是认真的.我们就是要找寻一种Hold不住的 ...

随机推荐

  1. Effective Java - 静态方法与构造器

    目录 用静态工厂方法替代构造器? 静态工厂有名称 静态工厂不必重新创建一个对象 静态工厂可以返回任何子类型对象 静态工厂返回的类可以动态变化 静态工厂返回的类可以不存在 静态工厂方法的缺点 静态工厂方 ...

  2. 嵊州D1T1 总统先生,一路走好!

    嵊州D1T1 总统先生,一路走好! 在总统先生的所有财产就是 n 杯黑咖啡,咖啡店可以用 m 个空杯子换一杯黑咖啡. 因为总统的特殊身份,心地善良而心生怜悯的咖啡店店长决定先借给总统一杯黑咖啡,只要他 ...

  3. 基于lua-nginx-module(openresty)的WEB应用防火墙

    独乐乐,不如众乐乐,分享给大家一篇WEB应用防火墙的文章,基于Lua+ Nginx实现.以下是ngx_lua_waf的作者全文输出. Github地址:https://github.com/loves ...

  4. 微信小程序 键盘显示短信验证码

    1.场景描述: IOS系统 一些APP或者微信小程序在收到短信验证码的时候会在键盘上自动保存验证码信息,当用户点击的时候,会自动赋值到当前所点击的输入框中 2.案例: 2.实现: TIPS:这个功能是 ...

  5. Bzoj 2318 Spoj4060 game with probability Problem

    2318: Spoj4060 game with probability Problem Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 524  Sol ...

  6. shell的用处到底大不大

    我曾在智联招聘等网站上搜寻有关shell脚本员的职位,与C++.JAVA等热门语言相比,冷清很多.看上去似乎招shell程序员的公司比较少.是不是公司不重视或者是很少用到shell这个东东呢?     ...

  7. 算法与数据结构基础 - 堆(Heap)和优先级队列(Priority queue)

    堆基础 堆(Heap)是具有这样性质的数据结构:1/完全二叉树 2/所有节点的值大于等于(或小于等于)子节点的值: 图片来源:这里 堆可以用数组存储,插入.删除会触发节点shift_down.shif ...

  8. Ubuntu中目录右下角的锁标志

    在ubuntu中如果是用root权限创建的目录,在普通权限下展示时则会出现一个锁的标志,表明该目录是一个受保护的目录(只读,不能写入和删除),普通权限无法对其进行操作.如用命令sudo mkdir d ...

  9. C#3.0新增功能10 表达式树 04 执行表达式

    连载目录    [已更新最新开发文章,点击查看详细] 表达式树 是表示一些代码的数据结构. 它不是已编译且可执行的代码. 如果想要执行由表达式树表示的 .NET 代码,则必须将其转换为可执行的 IL ...

  10. python基础练习 dict切片

    利用切片操作,实现一个trim()函数,去除字符串首尾的空格 def trim(s): if s[:1] != ' ' and s[-1:] != ' ': return s elif s[:1] = ...