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不住的 ...
随机推荐
- 从无到有构建vue实战项目(三)
四.响应式布局的实现 elemnt-ui参考bootatrap提供了响应式布局,附上地址:https://element.eleme.cn/#/zh-CN/component/layout 以下是我的 ...
- HDU 5792:World is Exploding(树状数组求逆序对)
http://acm.hdu.edu.cn/showproblem.php?pid=5792 World is Exploding Problem Description Given a sequ ...
- [golang]golang time.After内存泄露问题分析
无意中看到一篇文章说,当在for循环里使用select + time.After的组合时会产生内存泄露,于是进行了复现和验证,以此记录 内存泄露复现 问题复现测试代码如下所示: package mai ...
- VS2013日常使用若干技巧+快捷键
1.注释的方法 1)sqlserver中,单行注释:— — 多行注释:/* 代码 */ 2)C#中,单行注释:// 多行注释:/* 代码 */ 3)C#中多行注释的快捷方式:先选中你要注 ...
- Java学习笔记之---方法和数组
Java学习笔记之---方法与数组 (一)方法 (1)什么是方法? 方法是解决一类问题的步骤的有序组合 方法包含于类或对象中 方法在程序中被创建,在其他地方被引用 (2)方法的优点 使程序变得更简短而 ...
- 【tf.keras】在 cifar 上训练 AlexNet,数据集过大导致 OOM
cifar-10 每张图片的大小为 32×32,而 AlexNet 要求图片的输入是 224×224(也有说 227×227 的,这是 224×224 的图片进行大小为 2 的 zero paddin ...
- Excel催化剂开源第15波-VSTO开发之DataTable数据导出至单元格区域
上篇提到如何从Excel界面上拿到用户的数据,另外反方向的怎样输出给用户数据,也是关键之处. VSTO最大的优势是,这双向的过程中,全程有用户的交互操作. 而一般IT型的程序,都是脱离用户的操作,只能 ...
- Excel催化剂开源第8波-VSTO开发之异步调用方法
在VSTO开发过程中,因其和普通的Winform开发有点差别,具体细节笔者也说不清楚,大概是VSTO的插件是寄生在Excel中,不属于独立的进程之类的,其异步方法调用时,未能如Winform那样直接用 ...
- python 面向对象编程 - 小游戏
面向对象写的小游戏 欢迎玩耍 class Omnicience: camp = 'Omniscience' def __init__(self, name, atk=100, hp=1000, mp= ...
- Spring Boot从入门到实战(十):异步处理
原文地址:http://blog.jboost.cn/2019/07/22/springboot-async.html 在业务开发中,有时候会遇到一些非核心的附加功能,比如短信或微信模板消息通知,或者 ...