【问题标题】:Enum signal parameter枚举信号参数
【发布时间】:2012-11-03 19:59:18
【问题描述】:

我正在尝试将 Qt 的信号槽机制与自定义枚举类型一起使用。

我已阅读以下所有内容,但没有任何帮助:

DetectorEngineThread.h:

class DetectorEngineThread : public QThread
{
    Q_OBJECT
    Q_ENUMS(ErrorCode)
    Q_ENUMS(Status)

public:
    enum ErrorCode
    {
        ...
    };

    enum Status
    {
        ...
    };
...

signals:
    void statusChanged(Status newStatus);
    void processingError(ErrorCode code);
};

Q_DECLARE_METATYPE(DetectorEngineThread::ErrorCode)
Q_DECLARE_METATYPE(DetectorEngineThread::Status)

MainWindow.h:

...
#include "DetectorEngineThread.h"
...

class MainWindow : public QMainWindow
{
    Q_OBJECT
    ...

private:
    DetectorEngineThread* m_detEng;
    ...

private slots:
    void on_detEng_statusChanged(DetectorEngineThread::Status newStatus);
    void on_detEng_processingError(DetectorEngineThread::ErrorCode errorCode);
    ...
};

MainWindow.cpp:

...
#include "MainWindow.h"
...

MainWindow::MainWindow(...) : ...
{
    ...
    qRegisterMetaType<DetectorEngineThread::Status>("DetectorEngineThread::Status");
    qRegisterMetaType<DetectorEngineThread::ErrorCode>("DetectorEngineThread::ErrorCode");
    ...

    m_detEng = new DetectorEngineThread(...);

    connect(m_detEng, SIGNAL(statusChanged(DetectorEngineThread::Status)),
            this, SLOT(on_detEng_statusChanged(DetectorEngineThread::Status)), Qt::QueuedConnection);

    connect(m_detEng, SIGNAL(processingError(DetectorEngineThread::ErrorCode)),
            this, SLOT(on_detEng_processingError(DetectorEngineThread::ErrorCode)), Qt::QueuedConnection);
    ...
}
...

void MainWindow::on_detEng_statusChanged(DetectorEngineThread::Status newStatus)
{
    ...
}

void MainWindow::on_detEng_processingError(DetectorEngineThread::ErrorCode errorCode)
{
    ...
}
...

在运行时,我收到以下消息(在 Qt Creator 的应用程序输出面板中):

Object::connect: 没有这样的信号
DetectorEngineThread::statusChanged(DetectorEngineThread::Status) 在 ...
Object::connect: 没有这样的信号
DetectorEngineThread::processingError(DetectorEngineThread::ErrorCode) in ...

很明显,插槽的代码永远不会运行,尽管会发出匹配的信号。

我试过了:

  • 将枚举移动到全局范围内,但问题仍然存在。
  • 通过 QMetaObject::connectSlotsByName 自动连接信号和槽,但遇到了同样的问题。
  • 在 qRegisterMetaType 和 Q_DECLARE_METATYPE 中使用本地名称(例如,Status 而不是 DetectorEngineThread::Status),并且还尝试在 SIGNAL 和 SLOT 宏中使用这些名称。

【问题讨论】:

    标签: c++ qt signals-slots


    【解决方案1】:

    在信号和槽中声明的枚举应该是完全限定的:

    void statusChanged(Status newStatus);
    void processingError(ErrorCode code);
    

    应该是:

    void statusChanged(DetectorEngineThread::Status newStatus);
    void processingError(DetectorEngineThread::ErrorCode code);
    

    【讨论】:

    • 该死,我没想到。谢谢!
    • 我遇到了同样的问题,只是它甚至没有显示运行时错误消息!在我的信号声明中限定枚举类型解决了这个问题。
    • 此解决方案有效。但是,它的一个问题是,Qt 应用程序通常可以在没有完全限定的枚举作为信号参数类型的情况下正常工作,尤其是在应用程序不涉及多线程的情况下。当涉及多线程时,我经常使用 Qt 5.4 收到以下 Qt 错误消息: QObject::connect: Cannot queue arguments of type 'ErrorType' (确保 'ErrorType' 是使用 qRegisterMetaType() 注册的。)所以我的关注 -问题是: Qt 可以增强以接受非完全限定的枚举类型作为信号函数参数吗?会有什么困难?
    • @jonathanz 您的问题与 OP 问题无关(类型必须通过 qRegisterMetaType() 注册才能添加到线程中的事件队列中)。以新问题的形式提出您的问题。
    • @cmannett85 实际上我确实使用了 qRegisterMetaType() 但仍然偶尔会收到上述 Qt 错误消息,这是误导性的。您的解决方案解决了我的问题。所以我添加了一条可能对其他开发人员有帮助的评论。我不确定向 stackoverflow 提出新问题是否会有所帮助,因为这看起来更像是对 Qt 开发团队的增强请求。
    猜你喜欢
    • 1970-01-01
    • 2010-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多