Russian Qt Forum
Ноябрь 26, 2024, 11:45 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2 3 ... 6   Вниз
  Печать  
Автор Тема: Создание/вызов методов в разных потоках.  (Прочитано 45185 раз)
niXman
Гость
« : Ноябрь 28, 2009, 18:48 »

Всем хай!

Есть необходимость, в потоке, создавать GUI объекты. Но программа вываливается с сообщением типа сяго:


Кто-то сталкивался с подобной нуждой? Ну вот позарез нужно создавать объекты в потоке. Вот Улыбающийся
Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #1 : Ноябрь 28, 2009, 18:58 »

GUI можно создавать только в главном потоке. И нужды создавать их в другом потоке, все таки нету.
Записан

Юра.
niXman
Гость
« Ответ #2 : Ноябрь 28, 2009, 19:01 »

Юра, а мне нужно. И это не баловство/игрушки, реальная задача.
Хочу в цикле, создавать объекты типа QWebView. Чтоб страницы вебовские загружать, с поддержкой ява-скрипт.
Как это реализовать?
Записан
serg_hd
Хакер
*****
Offline Offline

Сообщений: 668



Просмотр профиля
« Ответ #3 : Ноябрь 28, 2009, 19:08 »

GUI можно создавать только в главном потоке. И нужды создавать их в другом потоке, все таки нету.
У меня похожая трабла. Нужно использовать QWebView (или QWebPage), загружать в него QUrl - и так во многих параллельных потоках для написания веб-сёрфера. Какие тут ещё альтернативы кроме многопоточности?
Я использую QT Jambi (java-фреймворк над QT), объекты QWebView и QUrl в отдельном потоке создаются (в отличие от сишного qt) и можно легко оперировать их методами, за исключением QWebView.load(QUrl), где выдаёт:
Код:
QObject: Cannot create children for a parent that is in a different thread.
(Parent is QApplication(0x33b4210), parent's thread is QThread(0x33b4068), current thread is QThread(0x39924a8)
Весь инет перерыл в поисках, нашёл даже похожую проблему, но там ответ, думаю, будет не скоро.
« Последнее редактирование: Ноябрь 28, 2009, 19:31 от serg_hd » Записан

kubuntu/Win7/x64/NetBeans
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #4 : Ноябрь 28, 2009, 19:48 »

Юра, а мне нужно.

Нельзя и точка! В ассистанте все написано. Даже в сообщении об ошибке об этом идет речь.
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
BRE
Гость
« Ответ #5 : Ноябрь 28, 2009, 19:53 »

Как это реализовать?
Можно попробовать сам QWebView создавать в главном потоке, а в дочерних потоках работать с объектами классов QWebPage/QWebFrame.
Записан
niXman
Гость
« Ответ #6 : Ноябрь 28, 2009, 19:57 »

Юра, а мне нужно.

Нельзя и точка! В ассистанте все написано. Даже в сообщении об ошибке об этом идет речь.
Ладно, нельзя. Но почему?! Непонимающий

Где можно почитать внятные разъяснения?
В сообщении об ошибке, сообщается ошибка, а не причина невозможности создания ГУИ объектов в потоке.
Записан
spectre71
Гость
« Ответ #7 : Ноябрь 28, 2009, 19:59 »

Юра, а мне нужно.

Нельзя и точка! В ассистанте все написано. Даже в сообщении об ошибке об этом идет речь.
Ладно, нельзя. Но почему?! Непонимающий

Где можно почитать внятные разъяснения?
В сообщении об ошибке, сообщается ошибка, а не причина невозможности создания ГУИ объектов в потоке.

Ну если нельзя, то что тут сделаешь!

Я думаю что QWebView для загрузки сам создает поток в котором и грузит данные.
А создавать QWebView можно отправляя сигнал из второстепенного потока объекту в главном потоке, который его и создаст, так что это не проблема
Записан
niXman
Гость
« Ответ #8 : Ноябрь 28, 2009, 20:06 »

Цитировать
создавать QWebView можно отправляя сигнал из второстепенного потока объекту в главном потоке, который его и создаст
Т.е. в основном потоке, создать слот, который будет создавать QWebView, и испускать сигнал с аргументом типа QWebView*, обратно в поток? А вас правильно понял?

Кажется это реально выполнимая задача Подмигивающий
Записан
spectre71
Гость
« Ответ #9 : Ноябрь 28, 2009, 20:25 »

Цитировать
создавать QWebView можно отправляя сигнал из второстепенного потока объекту в главном потоке, который его и создаст
Т.е. в основном потоке, создать слот, который будет создавать QWebView, и испускать сигнал с аргументом типа QWebView*, обратно в поток? А вас правильно понял?

Кажется это реально выполнимая задача Подмигивающий

Да.
А можно и поизвращаться. У меня была задачка:
При длительной обработке данных(исталляция пакаджа) в другом потоке в определенных случаях создавать дополнительные виджеты. Причем это было в некотором объекте который ничего не знает про то, в каком потоке работает и не должен знать! Мало того создание виджетов делалось где-то в цикле и соответственно даже если бы объект и знал про поток, то сделать посылку и получение сигнала было бы тяжело и сильно все портило бы.
Так что я сделал синхронизирующий вызов метода унаследовав свой QApplication и QThread.
Если интересно, посмотри тему:

http://www.prog.org.ru/index.php?topic=10041.msg59182#msg59182
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #10 : Ноябрь 28, 2009, 20:36 »

Юра, а мне нужно.

Нельзя и точка! В ассистанте все написано. Даже в сообщении об ошибке об этом идет речь.
Ладно, нельзя. Но почему?! Непонимающий
Здесь все достаточно просто - сам OC это не держит (по крайней мере не все ОС). Например если просматривать те же ф-ции базовой графики/рисования то легко можно натолкнуться на "not thread-safe"
Так что это не вина Qt
Записан
niXman
Гость
« Ответ #11 : Ноябрь 28, 2009, 20:38 »

Spectre
Огромное спасибо! По идее это то, что нужно.

Но один вопрос остается без ответа: Почему ГУИ объекты нельзя создавать в потоке? Где об этом можно почитать? Может какой костыль написать? Смеющийся

п.с.
эх...Константина бы сюда...
Записан
niXman
Гость
« Ответ #12 : Ноябрь 28, 2009, 20:40 »

Цитировать
если просматривать те же ф-ции базовой графики/рисования то легко можно натолкнуться на "not thread-safe"
Да, согласен. Но если объекту не указывать parent/paint_device, то он и рисоваться не будет. Что в этом случае мешает?
« Последнее редактирование: Ноябрь 28, 2009, 20:42 от niXman » Записан
spectre71
Гость
« Ответ #13 : Ноябрь 28, 2009, 20:55 »

Spectre
Огромное спасибо! По идее это то, что нужно.

Но один вопрос остается без ответа: Почему ГУИ объекты нельзя создавать в потоке? Где об этом можно почитать? Может какой костыль написать? Смеющийся

п.с.
эх...Константина бы сюда...

Написано в ассистанте, где точно не помню. Почему, никогда специально не разбирался, но в C++ Builder, точно так же.
Вот костыль и написал. Улыбающийся
Если будешь юзать причитай тему до конца, там есть правки.
Там есть еще define для простого вызова viod методов для this:
MyClass::anyMethod(....)  {
...
// вместо
// this->methodforsync();
// вызываем
sb_synchronize_method(MyClass, methodforsync);
...
}
MyClass::methodforsync(void)  {
...
...
}

Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #14 : Ноябрь 28, 2009, 20:56 »

Цитировать
если просматривать те же ф-ции базовой графики/рисования то легко можно натолкнуться на "not thread-safe"
Да, согласен. Но если объекту не указывать parent/paint_device, то он и рисоваться не будет. Что в этом случае мешает?
По идее - ничего, ведь можно же создавать QObject в любой нитке. Но гораздо проще (и лучше) сказать как сказано "GUI только в главном потоке" вместо того чтобы вдаваться в долгие объяснения. А вдруг рисование будет вызвано косвенно чем-то типа grabWidget? А вдруг виджету надо себя закешировать? И.т.д  и.т.п. В конце концов что это за элемент UI который не рисуется?

И вообще, нечего распускать пользователя обилием возможностей, он это не ценит. Не так уж давно ВСЕ обращения к ОС возможны были только в главной нитке - и ничего, работали.  
Записан
Страниц: [1] 2 3 ... 6   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.088 секунд. Запросов: 23.