Russian Qt Forum

Qt => Общие вопросы => Тема начата: uriel от Сентябрь 26, 2008, 06:52



Название: И снова GUI и потоки...
Отправлено: uriel от Сентябрь 26, 2008, 06:52
Уже второй день не могу понять, что не так с этим кодом.
Код:
#include <QApplication>
#include <QThread>
#include <QEvent>
#include <QPushButton>
#include <QDebug>
//
class Thread: public QThread
{
protected:
void customEvent(QEvent*)
{
qDebug() << currentThread() << QApplication::instance()->thread();

QPushButton *pb = new QPushButton("!");
connect(pb, SIGNAL(clicked()), pb, SLOT(close()));
pb->show();
}
};
//
int main(int argc, char *argv[])
{
QApplication app(argc, argv);

Thread *thrd = new Thread();
thrd->start();
QApplication::postEvent(thrd, new QEvent(QEvent::User));

return app.exec();
}
Судя по отладочной информации, customEvent(), как и подсказывает логика, вызывается из GUI потока. Но как только я нажимаю на кнопку - приложение тихо падает, ни сегфолта, ни исключения. Причём виджет может быть абсолютно любым.
Может быть, я просто не замечаю чего-то очевидного? :)


Название: Re: И снова GUI и потоки...
Отправлено: lit-uriy от Сентябрь 26, 2008, 07:19
виджеты можно создавать только в главном, ГУЁвом потоке


Название: Re: И снова GUI и потоки...
Отправлено: uriel от Сентябрь 26, 2008, 07:34
Ну это-то понятно. В том и дело, что этот виджет создаётся как раз в GUI потоке, если верить отладочной информации. Если бы я его создавал, скажем, в функции run(), то он бы прямо выругался, что виджет создаётся не там, где надо. Сам объект потока тоже живёт в гуёвом. Так что не вижу здесь проблем.


Название: Re: И снова GUI и потоки...
Отправлено: Tonal от Сентябрь 26, 2008, 07:57
Странная какая-то логика. Попробуй в отладчике посмотреть.

А зачем такое вообще может понадобиться?


Название: Re: И снова GUI и потоки...
Отправлено: lit-uriy от Сентябрь 26, 2008, 09:48
что-то я не понял, у тебя кнопка создается в объекте типа Thread, а он и есть другой (не ГУЁвый поток) разве нет?


Название: Re: И снова GUI и потоки...
Отправлено: denka от Сентябрь 26, 2008, 09:59
Твое приложение не падает. В 4-ке по закрытию главного окна приложения QApplication завершает свою работу.
Используй метод setQuitOnLastWindowClosed ( bool quit ) класса QApplication и не будет проблемы.


Название: Re: И снова GUI и потоки...
Отправлено: developer от Сентябрь 26, 2008, 10:10
Мне кажеться что с кодом все нормально, и что с тем что виджет тихо закрывается тоже нормально, а иначе и не может быть
Код:
connect(pb, SIGNAL(clicked()), pb, SLOT(close()));
. Ты ведь сам подсоединил его к слоту который закривает в данном случае кнопку.


Название: Re: И снова GUI и потоки...
Отправлено: kirill от Сентябрь 26, 2008, 10:53
Вот так новость, оказывается создавать в thread gui объекты можно, лишь бы это был не метод run.


Название: Re: И снова GUI и потоки...
Отправлено: pastor от Сентябрь 26, 2008, 12:27
что-то я не понял, у тебя кнопка создается в объекте типа Thread, а он и есть другой (не ГУЁвый поток) разве нет?

Нет


Вопрос к автору: А что вы своим кодом хотите добиться? Мулитипотоковости?

ЗЫ: Код весьма странный и непонятный!


Название: Re: И снова GUI и потоки...
Отправлено: pastor от Сентябрь 26, 2008, 12:36
Вот так новость, оказывается создавать в thread gui объекты можно, лишь бы это был не метод run.

Совершенно верно. Можите ознакомиться вот с этим Thread Support in Qt (http://doc.trolltech.com/4.4/threads.html). Там все подробно описано.


Название: Re: И снова GUI и потоки...
Отправлено: uriel от Сентябрь 26, 2008, 13:57
Благодарю, den'ka оказался прав. Я почему-то считал, что по умолчанию это свойство имеет значение false и всегда ставил его в true руками. :)
Этот код - просто минимальный набор для воспроизведения подобного поведения. А глобальная проблема такая: есть дополнительный не-гуи поток, который выполняет свою работу и может в процессе запросить какие-то данные у пользователя. Создавать экземпляры дилогов для запроса заранее и потом кидаться сигналами не получится, ибо основной поток может и не знать о том, что именно требуется создать (если использовать плагины, скажем).


Название: Re: И снова GUI и потоки...
Отправлено: SASA от Сентябрь 26, 2008, 14:11
http://crossplatform.ru/documentation/qtdoc4.3/threads.php (http://crossplatform.ru/documentation/qtdoc4.3/threads.php)
Любые гуи-объекты должны создаваться в гуи-потоке! Но негуи-поток может вызывать функции и в гуи-потоке. Либо sendEvent либо QMetaObject::invokeMethod объекту, созданному гуи-потоке. Можно ещё сигнал/слот с Qt::QueuedConnection.


Название: Re: И снова GUI и потоки...
Отправлено: pastor от Сентябрь 26, 2008, 14:36
Но негуи-поток может вызывать функции и в гуи-потоке.

А здесь попрошу подробнее :)

Либо sendEvent либо QMetaObject::invokeMethod объекту, созданному гуи-потоке.

Это пояснение к предыдущему предложению (т.е. каким образом работать с гуем с негуевого потока)?


Название: Re: И снова GUI и потоки...
Отправлено: SASA от Сентябрь 26, 2008, 19:50
Цитировать
Это пояснение к предыдущему предложению (т.е. каким образом работать с гуем с негуевого потока)?
Да, а что не так-то?


Название: Re: И снова GUI и потоки...
Отправлено: pastor от Сентябрь 28, 2008, 14:42
Цитировать
Это пояснение к предыдущему предложению (т.е. каким образом работать с гуем с негуевого потока)?
Да, а что не так-то?

Да все так. Прсто несовсем понятна была фраза:

Цитировать
Но негуи-поток может вызывать функции и в гуи-потоке.

и то этому попросил вас уточнить насчет следующего предложения: пояснение это или нет.