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不住的 ...
随机推荐
- POJ 1743:Musical Theme(后缀数组+二分)
题目链接 题意 有N个音符的序列来表示一首乐曲,每个音符都是1到88范围内的整数,现在要找一个重复的主题."主题"是整个音符序列的一个子串,它需要满足如下条件: 长度至少为5个音符 ...
- mysql复制那点事 - Seconds_behind_Master参数调查笔记
目录 mysql复制那点事 - Seconds_behind_Master参数调查笔记 0. 参考文献 1. 问题背景 2. 调查结论 3. 调查与分析过程 3.1 轮转binlog时的运行逻辑 3. ...
- 利用LDAP操作AD域
LDAP操作代码样例 初始化LDAP 目录服务上下文 该例子中,我们使用uid=linly,ou=People,dc=jsoso,dc=net这个账号,链接位于本机8389端口的LDAP服务器(ld ...
- 2017《java技术预备作业》
2017<java技术预备作业> 1.阅读邹欣老师的博客,谈谈你期望的师生关系是什么样的? 亦师亦友,很多人这样说,确实,倘若师生之间如果中间有些隔阂最终吃亏的始终是学生.我认为师生之间应 ...
- 生产Server遭挖矿程序入侵,暴力占用CPU
区块链的火热,利益驱使必然导致不少PC或Server,被变成肉鸡,执行挖矿程序进行挖矿,进而导致我们正常的程序无法正常. (Centos7 Server)使用top命令查看服务器进程运行情况,发现几个 ...
- nodejs中文乱码问题
node.js暂时不支持GBK或gb2312,所以编程文件(js)需要修改为utf-8格式. 另外如需要返回html代码,在 writeHead 方法中加入 "charset=utf-8&q ...
- springboot与springcloud的关系
1 . 问题描述 随着springboot.springcloud的不断迭代升级,开发效率不断提升,越来越多的开发团队加入到spring的大军中,今天用通俗的语言,介绍下什么是springboot,s ...
- mybatis的example类
1. 场景描述 idea下使用mybatis_generator自动生成mapper文件,默认生成了一大堆的example文件及方法,使用规则类似于Hibernate,给了一大堆参数,感觉没必要,只所 ...
- TCP/IP协议-网络编程
本文转载自公众号“呆呆熊一点通”,作者:呆呆 开篇语 前两年, 就买了<TCP/IP网络编程>这本书, 由于自身基础薄弱, 只是走马观花翻阅了几张. 后来工作了这些年, 越来越感到瓶颈期已 ...
- Jquery serialize()提交多个表单数据
ajax提交多个表单数据: 先把不同的表单分别用serialize()函数,然后把序列化后的数据用+拼接提交给后台,具体例子如下 var data1 = $('#form1).serialize(); ...