Qt状态机框架连接信号

时间:2011-09-22 16:51:38

标签: qt state-machine

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处于有效状态时才会被连接?

2 个答案:

答案 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);
    }
};