перечисления и классы перечислений в Qt Queued Slots

Следуя советам документации Qt и ответы на этот вопрос, у меня есть код, структурированный так:

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);
    ...
};

У моего класса MainWindow есть соответствующий слот:

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

В mainwindow.cpp конструктор содержит:

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

и в методе, вызываемом позже в классе MainWindow:

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

Класс Emulator является многопоточным, поэтому соединение между его сигналом и слотом MainWindow ставится в очередь.

Несмотря на кажущееся соблюдение всех рекомендаций по добавлению чего-либо в мета-объектную систему Qt, я все равно получаю это сообщение отладки, когда поток эмулятора emit получает сигнал:

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

Я пробовал это, когда Enumeration::HaltCause одновременно был простым enum и строго типизированным enum class. Оба дают одинаковые результаты.

Что мне не хватает?


person Brian A. Henning    schedule 20.06.2019    source источник


Ответы (1)


Оказывается, неквалифицированный HaltCause, использованный в объявлении слота Emulator, запутал систему метаобъектов. Решение было изменить

signals:
    void EmulationHalted(HaltCause cause);

to

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

в объявлении эмулятора (emulator.h).

person Brian A. Henning    schedule 20.06.2019
comment
Похоже, вам стоит сообщить об ошибке на bugreports.qt.io - person Allan Jensen; 21.06.2019