Search code examples
c++qtenumsenum-class

enums and enum classes in Qt Queued Slots


Following advice from Qt documentation and this question's answers, I have code structured like so:

emulator.h:

class Emulator : public QObject
{
        Q_OBJECT

    public:
        enum HaltCause {
            Breakpoint,
            ReadWatch,
            WriteWatch,
            UserHalted,
            Reset,
            SingleStep,
        };

        Q_ENUM(HaltCause)
    ...
    signals:
        void emulationHalted(HaltCause cause);
    ...
};

My MainWindow class has a matching slot:

    private slots:
        ...
        void onEmulationHalted(Emulator::HaltCause cause);

In mainwindow.cpp, the constructor contains:

...
    qRegisterMetaType<Emulator::HaltCause>();
...

and in a method invoked later on in the MainWindow class:

...
connect(m_emulator, &Emulator::emulationHalted, this, &MainWindow::onEmulationHalted);
...

The Emulator class is threaded, so the connection between its signal and MainWindow's slot is queued.

Regardless of seemingly following all the guidelines for getting something into Qt's meta-object system, I still get this debug message when the Emulator's thread emits the signal:

QObject::connect: Cannot queue arguments of type 'HaltCause'
(Make sure 'HaltCause' is registered using qRegisterMetaType().)

I've tried this with Enumeration::HaltCause being both a simple enum and a strongly-typed enum class. Both yield the same results.

What am I missing?


Solution

  • Turns out the unqualified HaltCause used in the declaration of Emulator's slot confused the meta-object system. The resolution was to change

    signals:
        void EmulationHalted(HaltCause cause);
    

    to

    signals:
        void EmulationHalted(Emulator::HaltCause cause);
    

    in the Emulator declaration (emulator.h).