如何实现QStateMachine状态转换动作?QSignalMapper?

3
我正在构建一个程序,其流程主要是顺序的,但也有一些替代路径。我认为状态机可能是实现这一点最简单的方法,因为Qt提供了这样一个类:QStateMachine(还请参见API)。
然而,我似乎有相当多的状态(20+)。此外,我有许多不同的转换事件(比如说按钮1-10)。例如,按下x按钮会导致从状态13到14的转换。
进入或离开每个状态应该能够执行具有参数的特定函数,虽然每个状态都发出这样的信号,但无法传递参数,因此需要大量的无参数函数。
重新实现QAbstractState对于这个问题似乎也很繁琐,除非它具有类似于assignProperty()的方法,允许在“状态进入”时设置QObject属性。
使用QSignalMapper以及每个状态的转换信号的多个信号槽连接来处理多个操作是否是合适的方法?

顺便提一下:如果您在“相当线性的程序”中有20个状态和10个按钮,每个按钮都会转换到不同的状态,则可能在概念层面上出了问题。 - Zimano
@Zimano 感谢您的建议。但请不要引用我没有写过的内容。另外,您基本上只是在说我做错了,这可能是一个好的提示,但并不真正有帮助。那么 - 我应该如何正确地做呢? - handle
不,我并不是“基本上在说你做错了”。你的作品可能完成得很好。我的意思是,如果状态的数量非常大,并且相当多的按钮会生成唯一的状态转换,而整个程序在“顺序”中具有一些替代路径,那么您的设计中可能存在概念性错误,并且您可能需要重新定义状态及其转换。我不知道您在建模什么或者您的领域是什么,因此无法给您任何方向。我只是注意到这一点。我没有发表任何建议,也没有打算发布回答。 - Zimano
1个回答

2

如果您正在使用C++11,您可以直接连接到一个lambda表达式,然后使用指定的参数调用函数。

否则,请确定哪个对象是您的信号的sender(),并在该对象上设置动态属性。该属性可以在槽中查询,并作为参数传递给函数。

例如(在类内部):

void setup() {
  QState *s2 = new QState();
  s2->assignProperty(myLabel, "text", "state two");
  s2->setProperty("prop", 0);
  connect(s2, SIGNAL(entered()), io, SLOT(testSlot()));
}
Q_SLOT void testSlot() {
  QObject *obj = this->sender();
  QVariant prop = obj->property("prop");
  qDebug() << __FUNCTION__ << prop.toString();
}

我已经为您的答案添加了示例代码,希望不会介意。太好了!我正在寻找的功能几乎是内置的!这似乎比使用QSignalMapper要简单得多,并且可以通过单个信号槽连接执行多个操作,当然,这取决于属性类型及其由Slot的“解释”。 - handle
我试图将QList设置为属性以便能够“传递”更多信息,但最终使用了QVariantList:http://stackoverflow.com/q/19029623/ - handle

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接