QStateMachine 如何在不同的 QState 中显示和隐藏 QGraphicsView 和 QObject
Posted
技术标签:
【中文标题】QStateMachine 如何在不同的 QState 中显示和隐藏 QGraphicsView 和 QObject【英文标题】:QStateMachine how to show and hide QGraphicsView and QObject in different QState 【发布时间】:2016-06-07 16:10:23 【问题描述】:这是我的简单代码:
我创建了一个新的scene
、view
和QPixmapItem
QGraphicsScene *scena = new QGraphicsScene();
QGraphicsPixmapItem *object1= new QGraphicsPixmapItem();
object1->setPixmap(QPixmap(":/prova/prova.png"));
QGraphicsView *view = new QGraphicsView();
view->setScene(scena);
scena->addItem(object1);
view->show();
接下来我创建了一个新的QStateMachine
和两个QState
QStateMachine *machine = new QStateMachine();
QState *s1 = new QState();
QState *s2 = new QState();
machine -> addState(s1);
machine -> addState(s2);
//mouse click in a void mousePressEvent
s1 -> addTransition(this,SIGNAL(mouseclick()),s2);
machine -> start();
我想在s1
中显示view
并设置object1
可见。
通过在场景上单击鼠标,我添加了到 s2
的过渡。
在s2
我只想隐藏object1
。
我该怎么做?有人可以帮我做一个小教程吗?
我正在使用带有 MinGW 4.9.2 32 位的 Qt 5.6.0。
【问题讨论】:
你读过this answer吗?看起来你一遍又一遍地问非常相似的问题...... 是的,我已经阅读了答案,我意识到我不能将view
分配给QState
。我的问题是我有一个scene
,在那个scene
里面我有QGraphicsPixmapObject
。这是一个纸牌游戏,所以我必须隐藏和显示该对象 20 次,而我不能用 for
来做到这一点,所以你告诉我使用 QStateMachine
。现在我创建了QState
和QStateMachine
,但我无法使用它。我使用signals
添加了从s1
到s2
的转换,现在我要指定要在每个QState
中显示的对象。有可能吗?
"我必须隐藏和显示该对象 20 次" 同一个?你的意思是你希望它闪烁 20 次?或者您希望按顺序显示 20 个不同的对象?
这是一款纸牌游戏,所以我在场景中有 10 个QGraphicsPixmapItem
。要玩我想展示牌的游戏,等待玩家选择,然后将那张牌移到场景中心。之后我想重新加载以前的情况并重复同样的事情20次
您可能并不关心鼠标点击。你关心一张卡片被选中,然后你移动它。图形视图框架已经将鼠标单击项目解释为项目选择。你真的对如此低级的细节很感兴趣,但从不解释你希望你的游戏如何工作。当鼠标在场景中按下时,你永远不想切换状态。您想使用鼠标选择一张卡片,然后对该选择做出反应,或者至少您想对鼠标单击项目做出反应,而不是场景/视图!这是一个很大的不同!
【参考方案1】:
每个QState
都有entered
和exited
信号,您可以将函子连接到它们。这是现代 Qt 5 代码中的常见习语。可以使用 lambda 表达式简洁地给出函子,您可以在其中对非对象调用任意操作,例如在 QPixmapItem
上。如果QPixmapItem
派生自QGraphicsObject
,您可以使用QState::assignProperty
来分配所需的可见性状态,而不是调用show()
和hide()
。
下面是一个完整的例子。
// https://github.com/KubaO/***n/tree/master/questions/scenestate-37684315
#include <QtWidgets>
void addTransition(QState * src, QObject * eventSource, QEvent::Type type, QAbstractState * dst)
auto transition = new QEventTransition(eventSource, type);
transition->setTargetState(dst);
src->addTransition(transition);
struct Window : public QWidget
QHBoxLayout m_layoutthis;
QGraphicsScene m_scene;
QGraphicsPixmapItem m_item;
QGraphicsView m_view&m_scene;
QStateMachine m_mach;
QState s1&m_mach;
QState s2&m_mach;
Window()
m_layout.addWidget(&m_view);
QPixmap pix128, 128;
QPainter p&pix;
p.setBrush(Qt::white);
p.drawRect(pix.rect().adjusted(0,0,-1,-1));
p.drawText(pix.rect(), "Hello");
m_item.setPixmap(pix);
m_scene.addItem(&m_item);
// I want to show the view in s1...
s1.assignProperty(&m_view, "visible", true);
// and set object1 visible.
s1.connect(&s1, &QState::entered, [&] m_item.show(); );
// With a mouse click on the scene I've added a transition to s2.
addTransition(&s1, &m_view, QEvent::MouseButtonPress, &s2);
// In s2 I want to hide only object1.
s2.connect(&s2, &QState::entered, [&] m_item.hide(); );
m_mach.setInitialState(&s1);
m_mach.start();
;
int main(int argc, char ** argv)
QApplication appargc, argv;
Window w;
w.show();
return app.exec();
【讨论】:
以上是关于QStateMachine 如何在不同的 QState 中显示和隐藏 QGraphicsView 和 QObject的主要内容,如果未能解决你的问题,请参考以下文章