Название: Вызов слота из стороннего потока, используя указатель на владельца слота Отправлено: neosapient от Январь 09, 2009, 15:40 Есть окно MyMainWindow, производное от QMainWindow.
Код
У окна есть слот, вида Код
Есть второй поток, в который передается указатель на существующий экземпляр окна. Как в этом потоке выполнить вызов слота. Код Такой вариант не подходит, так как отрисовка окон происходит в GUI потоке, о чем свидетельствует екцепшин с красным крестиком в верхнем левом угле. :) "Widgets must be created in GUI thread" Сейчас пошел по второму варианту: объявил дополнительный сигнал и метод приема Код
Собственно, хочется более элегантного решения чем я описал в последнем случае, а то много вторичного кода получается. Хочется, зная указатель на QT-объект, передать в GUI-поток, о том что был emit (вызов). Название: Re: Вызов слота из стороннего потока, используя указатель на владельца слота Отправлено: Rcus от Январь 09, 2009, 16:05 bool QMetaObject::invokeMethod ( QObject * obj, const char * member, Qt::ConnectionType type, ...)
Название: Re: Вызов слота из стороннего потока, используя указатель на владельца слота Отправлено: neosapient от Январь 09, 2009, 16:39 Так оно конечно лучше ;)
Но всё ещё "не айс". Строчка вызова выглядит громоздко, QMetaObject::invokeMethod ( pWindow, "sltGet", Qt::QueuedConnection, Q_ARG(QString, "Hello World")); по сравнению с pWindow->get("Hello World"); Можно её облегчить? ---------- Приложение. Текущий вариант Код
Название: Re: Вызов слота из стороннего потока, используя указатель на владельца слота Отправлено: Rcus от Январь 09, 2009, 16:54 Тут уж либо вы пишете обвязку, либо миритесь с громоздкими выражениями при вызове. Я бы объявил в одном из классов, используемых в дополнительном потоке сигнал типа
Код и связал его со слотом в основном окне через Qt::QueuedConnection или Qt::BlockingQueuedConnection в зависимости от ситуации. В таком случае вызов сводится к строчке Код
Название: Re: Вызов слота из стороннего потока, используя указатель на владельца слота Отправлено: neosapient от Январь 09, 2009, 17:12 Второй поток, который не GUI, был создан виндозной функцией _beginthreadex, а не классом QThread.
Далее, для требуется связать методом connect(источник,сигнал,приемник,слот) указатель pWindow и указатель на вспомогательный объект, наследующий QObject. Но они глобальными не являются (во всяком случае у меня). По этому, потребуется синхронизированная передача указателей. Тут, собственно, возвращаемся к тому от чего хотелось уйти - дополнительный код на синхронизацию, который перегружает читабельность листингов. Может есть какой-нибудь макрос ? Название: Re: Вызов слота из стороннего потока, используя указатель на владельца слота Отправлено: Dendy от Январь 09, 2009, 18:01 А вам в любом случае прийдётся обвязать код синхронизацией, если пользуетесь голыми указателями, чтобы убедиться в том что окно всё ещё живое.
Далее. Элегантного решения в одну строчку вроде: Код: pWindow->get("Hello World"); быть не может, так как тело должно выполниться в другом потоке. Так или иначе вызов прийдётся разорвать делая функцию потокобезопастной (разрыв внутри MyMainWindow::get()) или нет (разрыв во втором потоке). Разрыв будет в виде вспомагательного вызова, вроде invokeMethod() или postEvent(), то-есть неочевидным. Кстати, всё зависит от задачи. Должен ли второй поток ждать, когда пользователь закроет MessageBox, чтобы обработать результат или нет? |