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(,,,);
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状态机的更多相关文章
- Qt 状态机框架学习(没学会)
Qt状态机框架是基于状态图XML(SCXML) 实现的.从Qt4.6开始,它已经是QtCore模块的一部分.尽管它本身是蛮复杂的一套东西,但经过和Qt的事件系统(event system).信号槽(s ...
- Qt状态机框架(状态机就开始异步的运行了,也就是说,它成为了我们应用程序事件循环的一部分了)
状态机框架 Qt中的状态机框架为我们提供了很多的API和类,使我们能更容易的在自己的应用程序中集成状态动画.这个框架是和Qt的元对象系统机密结合在一起的.比如,各个状态之间的转换是通过信号触发的,状态 ...
- 如何保证Qt状态机的最佳性能
如何保证Qt状态机的最佳性能 How to ensure the best Qt state machine performance 如果您使用Qt进行应用程序开发,并且使用状态机,那么很可能您正在使 ...
- Qt状态机框架
The State Machine Framework 状态机框架提供了用于创建和执行状态图的类.概念和符号是基于Harel的Statecharts: A visual formalism for c ...
- Qt之动画框架
简述 Qt动画框架旨在为创建动画和平滑的GUI提供了一种简单的方法.通过Qt动画属性,该框架为部件和其它QObject对象的动画操作提供了非常大的自由性,框架也可以被用于图形视图框架中,动画框架中许多 ...
- Qt事件循环与状态机事件循环的思考
写下这个给自己备忘,关于事件循环以及多线程方面的东西我还需要多多学习.首先我们都知道程序有一个主线程,在GUI程序中这个主线程也叫GUI线程,图形和绘图相关的函数都是由主线程来提供.主线程有个事件循环 ...
- Qt 事件系统浅析 (用 Windows API 描述,分析了QCoreApplication::exec()和QEventLoop::exec的源码)(比起新号槽,事件机制是更高级的抽象,拥有更多特性,比如 accept/ignore,filter,还是实现状态机等高级 API 的基础)
事件系统在 Qt 中扮演了十分重要的角色,不仅 GUI 的方方面面需要使用到事件系统,Signals/Slots 技术也离不开事件系统(多线程间).我们本文中暂且不描述 GUI 中的一些特殊情况,来说 ...
- Qt 动画框架
最近一个项目中的需要做动画效果,很自然就想起来用qt animation framework .这个框架真的很强大.支持多个动画组合,线性动画,并行动画等.在此总结一下使用该框架一些需要注意的地方: ...
- 《Qt 实战一二三》
简介 "我们来自Qt分享&&交流,我们来自Qt Quick分享&&交流",不管你是笑了,还是笑了,反正我们是认真的.我们就是要找寻一种Hold不住的 ...
随机推荐
- OC CollectionView和TableView自身高度的隐式递归计算,改变父试图布局
CollectionView和TableView自身高度的隐式递归计算 1.前沿:我们一般会碰到这样的需求,一个tableview或者一个colletionview放在一个scrollview上边,而 ...
- 使用java的MultipartFile实现layui官网文件上传实现全部示例,java文件上传
layui(谐音:类UI) 是一款采用自身模块规范编写的前端 UI 框架,遵循原生 HTML/CSS/JS 的书写与组织形式,门槛极低,拿来即用. layui文件上传示例地址:https://www. ...
- python PEP8常用规范
python 常用PEP8规范 一 代码编排 1 缩进.4个空格的缩进(编辑器都可以完成此功能),不使用Tap,更不能混合使用Tap和空格.2 每行最大长度79,换行可以使用反斜杠,最好使用圆括号 ...
- .Net Core 学习使用Session、和Cookie验证身份
一.使用Session 1.1 Status.cs 中配置 public void ConfigureServices(IServiceCollection services) { services. ...
- 基于go语言结合微信小程序开发的微商城系统
最近在慕课网上录制了一门<Golang微信小程序微商城系统原型>,这门免费课程特别适合在校大学生或者刚毕业的大学生,go语言初学者以及想要从事微商城开发项目入门的小伙伴们来学习.在课程当中 ...
- Dom4J的基本使用
初始化数据 <?xml version="1.0" encoding="UTF-8"?> <RESULT> <VALUE> ...
- Spring MVC源码(四) ----- 统一异常处理原理解析
SpringMVC除了对请求URL的路由处理特别方便外,还支持对异常的统一处理机制,可以对业务操作时抛出的异常,unchecked异常以及状态码的异常进行统一处理.SpringMVC既提供简单的配置类 ...
- 【分治】黑白棋子的移动-C++
题目描述 有2n个棋子(n≥4)排成一行,开始为位置白子全部在左边,黑子全部在右边,如下图为n=5的情况: ○○○○○●●●●● 移动棋子的规则是:每次必须同时移动相邻的两个棋子,颜色不限,可以左移也 ...
- UVA1103 古代象形符号 Ancient Messages 题解
题目链接: https://www.luogu.org/problemnew/show/UVA1103 题目分析: 我们可以先进行矩阵的还原 for(int k=1;k<=4;k++) { a[ ...
- Excel催化剂开源第39波-json字符串解释的超能类库
对一般VBA开发群体来说,处理json.xml结构的数据源,在VB6的世界里,是一件非常不容易的事情,隐约记得当年自己从哪里找到了一个使用字典实现的json解释的函数,实在非常稀有. 在.Net的世界 ...