在Qt State Machine Framework documentation中,有一个示例如何设置状态激活的属性:
s1->assignProperty(label, "text", "In state s1");
s2->assignProperty(label, "text", "In state s2");
s3->assignProperty(label, "text", "In state s3");
有没有办法在状态激活时连接插槽?仅s1_buttonclick
仅在s1
处于活动状态时才会被关联,s2_buttonclick
只会在s2
处于有效状态时才会被连接?
答案 0 :(得分:2)
根据状态机当前所处的状态,您希望连接不同吗?
我认为您必须使用其他插槽以及输入的()和退出()信号来自行管理。只需为州的每个入口和出口创建一个插槽。
QObject::connect(s1, SIGNAL(entered()), connectionManager, SLOT(connectS1()));
QObject::connect(s1, SIGNAL(exited()), connectionManager, SLOT(disconnectS1()));
//continue for each state
答案 1 :(得分:0)
可以使用表示连接的辅助类来完成过滤信号槽连接,并提供连接的活动属性。请注意,Qt 5的QMetaObject::Connection
是不够的。
#include <QMetaMethod>
#include <QPointer>
class Connection : public QObject
{
Q_OBJECT
Q_PROPERTY(bool active READ isActive WRITE setActive NOTIFY activeChanged USER true)
Q_PROPERTY(bool valid READ isValid)
QMetaMethod m_signal, m_slot;
QPointer<QObject> m_source, m_target;
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
QMetaObject::Connection m_connection;
#else
bool m_connection;
#endif
bool m_active;
void release() {
if (!m_source || !m_target) return;
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
disconnect(m_connection);
#else
disconnect(m_source, m_signal, m_target, m_slot);
#endif
}
public:
Connection(QObject * source, const char * signal, QObject * target, const char * slot, QObject * parent = 0) :
QObject(parent),
m_signal(source->metaObject()->method(source->metaObject()->indexOfSignal(signal))),
m_slot(target->metaObject()->method(target->metaObject()->indexOfSlot(slot))),
m_source(source), m_target(target),
m_connection(connect(m_source, m_signal, m_target, m_slot)),
m_active(m_connection)
{}
~Connection() { release(); }
QObject* source() const { return m_source; }
QObject* target() const { return m_target; }
QMetaMethod signal() const { return m_signal; }
QMetaMethod slot() const { return m_slot; }
bool isActive() const { return m_active && m_source && m_target; }
bool isValid() const { return m_connection && m_source && m_target; }
Q_SIGNAL void activeChanged(bool);
Q_SLOT void setActive(bool active) {
if (active == m_active || !m_source || !m_target) return;
m_active = active;
if (m_active) {
m_connection = connect(m_source, m_signal, m_target, m_slot);
} else {
release();
}
emit activeChanged(m_active);
}
};