Qt状态机框架连接信号

发布于 2024-12-06 12:23:14 字数 445 浏览 6 评论 0原文

Qt状态机框架文档中有一个如何设置属性的示例状态激活:

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 处于活动状态时才会连接?

In the Qt State Machine Framework documentation there is an example how to set properties on state activation:

s1->assignProperty(label, "text", "In state s1");
s2->assignProperty(label, "text", "In state s2");
s3->assignProperty(label, "text", "In state s3");

Is there a way to connect slots on state activation? like s1_buttonclick will only be connected when s1 is active and s2_buttonclick will only be connected when s2 is active?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

你的背包 2024-12-13 12:23:14

您希望连接根据状态机当前所处的状态而有所不同?

我认为您必须使用其他插槽以及 Entered() 和 Exited() 信号自行管理。只需为各州的每个入口和出口创建一个插槽即可。

QObject::connect(s1, SIGNAL(entered()), connectionManager, SLOT(connectS1()));
QObject::connect(s1, SIGNAL(exited()), connectionManager, SLOT(disconnectS1()));
//continue for each state

You want the connections to be different based on which state the state machine is currently in?

I think you will have to manage this yourself using other slots and the entered() and exited() signals. Just create a slot for the each entrance and exit of the states.

QObject::connect(s1, SIGNAL(entered()), connectionManager, SLOT(connectS1()));
QObject::connect(s1, SIGNAL(exited()), connectionManager, SLOT(disconnectS1()));
//continue for each state
绿萝 2024-12-13 12:23:14

可以使用代表连接并提供连接的活动属性的辅助类来完成过滤信号槽连接。请注意,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);
    }
};

Filtering signal-slot connections can be done using a helper class that represents a connection and provides an active property of the connection. Note that Qt 5's QMetaObject::Connection is not sufficient for this.

#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);
    }
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文