Вызвать слот асинхронно, не подключаясь к нему, используя чистую строку кода

Я столкнулся с довольно странной ошибкой — QAction::trigger вызвал диалоговое окно блокировки, которое вызвало мой сервер, который вызвал trigger застрять (например, не в состоянии обрабатывать сигналы сокета, пока диалог не был закрыт).

Я нашел обходной путь. Подключаю сигнал void triggerWorkaround() в слот QAction::trigger с помощью Qt::QueuedConnection и я испускаю это:

QObject::connect(this, &HackClass::triggerWorkaround, targetAction_.data(), &QAction::trigger, Qt::QueuedConnection);
emit triggerWorkaround();
QObject::disconnect(this, nullptr, targetAction_.data(), nullptr);

Но это три строки запутанного кода. Есть ли не путающий способ сделать это? я нашел QMetaObject::invokeMethod, но, честно говоря, это в 10 раз более запутанно, чем мое текущее решение. Также, Я не хочу использовать имя метода в качестве строки!

1

Решение

Вы можете разделить это на функцию QueuedInvoke как это:

//overload for methods/slots
//the slot gets invoked in the thread where the QObject lives
template <typename Object, typename T>
void QueuedInvoke(Object* object, T (Object::* f)()){
QObject signalSource;
QObject::connect(&signalSource, &QObject::destroyed,
object, f, Qt::QueuedConnection);
}
//overload for functors
//the functor gets invoked in the thread where the contextObject lives
//or in the current thread if no contextObject is provided
template <typename Func>
void QueuedInvoke(Func&& f, QObject* contextObject = QAbstractEventDispatcher::instance()){
QObject signalSource;
QObject::connect(&signalSource, &QObject::destroyed,
contextObject, std::forward<Func>(f), Qt::QueuedConnection);
}

Это будет использовать destroyed() сигнал испускается из временного QObject отправить событие в очереди в цикл событий. Слот / функтор фактически вызывается, когда цикл обработки событий обрабатывает это событие.

Итак, вместо 3-х строк, которые вы разместили, вы можете использовать вышеописанную функцию следующим образом:

QueuedInvoke(targetAction_.data(), &QAction::trigger);

Мой ответ основан на этот великий ответ о выполнении функтора в данном QThread, Вы можете обратиться к нему для более подробной информации.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]