Название: Изменить значение прогрессбара диалогового окна из дочернего потока Отправлено: neosapient от Июль 22, 2008, 19:04 Здравствуйте.
Пишу следующую программку: - есть главное диалоговое окно, для ввода переменных - есть дочерний поток (класс-наследник QThread), который запускается при нажатии на кнопку и крутиться в цикле пока всё не посчитается Расчет долгий, и я хотел бы отобразить в прогресс баре пройденый этап расчета. Сначала попробовал вызывать методы ProgressBar::setMinimum, ProgressBar::setMaximum и ProgressBar::setValue из дочернего потока. Но в ответ получал крах программы, так как надо рисовать в главном (GUI) потоке. Тогда я попробовал создать сигналы у класса-наследника QThread, но компилятор ругается: "Error: Signals cannot have access specifier" Как решить такой "типовой" пример? Может есть готовый пример - хотел бы изучить, а не изобретать велосипед. Название: Re: Изменить значение прогрессбара диалогового окна из дочернего потока Отправлено: pastor от Июль 22, 2008, 19:30 Вариантов решиния два:
1) Как вы и делали, через сигналы. Все должно работать. Код в студию. 2) Посредством событий. Посылаете событие из дочернего потока и ловите его в главном потоке. ЗЫ: Подобные темы уже нераз подымались на форуме Название: Re: Изменить значение прогрессбара диалого Отправлено: spirit от Июль 22, 2008, 19:50 Код: class AnotherThread: public QThread Название: Re: Изменить значение прогрессбара диалогового окна из дочернего потока Отправлено: ритт от Июль 23, 2008, 00:15 мля...я читаю код и них не могу врубиться что там могло не работать и материться на сигнал...
а это, по-ходу, код-как-делать-надо :) жук ты, спирит, хоть бы строчку чиркнул ) Название: Re: Изменить значение прогрессбара диалогового окна из дочернего потока Отправлено: Alex03 от Июль 23, 2008, 06:50 Надеюсь Qt 4.x.x?
Во первых Ваш код компилируется и даже как-то работает, НО... С завидным постоянством на форуме возникают вопросы связнные с QThread. Народ не хочет читать документацию и постоянно наступает на грабли. В Qt 4.x.x у каждого объекта есть принадлежность к потоку. В Вашем случае и m_at и m_pbProgress "принадлежат" к главному потоку. Соответственно Код: connect(m_at, SIGNAL(valueChanged(int)), m_pbProgress, SLOT(setValue(int))); Используйте Qt::QueuedConnection. Код: connect(m_at, SIGNAL(valueChanged(int)), m_pbProgress, SLOT(setValue(int)), Qt::QueuedConnection); Ну а чтобы понять что у Вас там не компилится нужен весь код с "распределением по файлам". PS Если Qt 3.x.x то может пригодится void QApplication::postEvent ( QObject * receiver, QEvent * event ) [static] Название: Re: Изменить значение прогрессбара диалогового окна из дочернего потока Отправлено: ритт от Июль 23, 2008, 07:05 ыы...алекс тоже обманулся
я не обратил внимания, но алекс совершенно прав - Цитировать Используйте Qt::QueuedConnection. Название: Re: Изменить значение прогрессбара диалогового окна из дочернего потока Отправлено: spirit от Июль 23, 2008, 08:35 ладно, понял, буду в селед.раз каммент писать, что бы не вводить в заблуждение. :)
Название: Re: Изменить значение прогрессбара диалогового окна из дочернего потока Отправлено: pastor от Июль 23, 2008, 11:56 Alex03, Константин вы неправы насчет коннекта. По умолчанию стоит параметр Qt::AutoConnection. Открываем ассистант и смотрим что это значит:
Цитировать If the signal is emitted from the thread in which the receiving object lives, the slot is invoked directly, as with Qt::DirectConnection; otherwise the signal is queued, as with Qt::QueuedConnection. Укажите в коннекте явно Qt::DirectConnection и вы получите assert вида: Цитировать ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread a19768. Receiver '' (of type 'MainWindow') was created in thread 3d7a40", file kernel qcoreapplication.cpp, line 279 Так что курим ассистант внимательнее. Название: Re: Изменить значение прогрессбара диалогового окна из дочернего потока Отправлено: neosapient от Июль 23, 2008, 12:11 Спасибо.
Вроде заработало. Сегодня заново пересобрал проект и ошибка ушла. Примерчик тоже показательный - spirit, отдельное спасибо Название: Re: Изменить значение прогрессбара диалогового окна из дочернего потока Отправлено: Alex03 от Июль 23, 2008, 12:53 Alex03, Константин вы неправы насчет коннекта.... Действительно гдето я глюканул, считая что Qt::AutoConnection меняется на Qt::DirectConnection или Qt::QueuedConnection в момент вызова connect(), а не в момент "испускания" сигнала.Посыпаю голову пеплом и приношу извинениея тем кого ввёл в заблуждение. Цитировать If the signal is emitted from the thread in which the receiving object lives, the slot is invoked directly, as with Qt::DirectConnection; otherwise the signal is queued, as with Qt::QueuedConnection. Судя по исходникам для Qt::DirectConnection не только receiving object, но и sender должны жить в emit-потоке.Код: if ((c->type == Qt::AutoConnection Цитировать Так что курим ассистант внимательнее. Угу!Название: Re: Изменить значение прогрессбара диалогового окна из дочернего потока Отправлено: ритт от Июль 23, 2008, 23:07 2Пастор
ну, не так уж и неправы. такие вещи желательно связывать ивентами вместо блокирующих вызовов - хоть в разных потоках, хоть в одном. поэтому я обычно в подобных местах явно указываю Qt::QueuedConnection...вот и спириту так же советую. а про курение доков - это прямо обидно как-то... Название: Re: Изменить значение прогрессбара диалогового окна из дочернего потока Отправлено: pastor от Июль 23, 2008, 23:48 2Пастор ну, не так уж и неправы. такие вещи желательно связывать ивентами вместо блокирующих вызовов - хоть в разных потоках, хоть в одном. поэтому я обычно в подобных местах явно указываю Qt::QueuedConnection...вот и спириту так же советую. а про курение доков - это прямо обидно как-то... В основном ответ адресовался Alex03. Но ты полностью подписался под постом Alex03, поэтому в свой ответ добавил и обращение к тебе. Так что необижайсо, не со зла же ;) Название: Re: Изменить значение прогрессбара диалогового окна из дочернего потока Отправлено: fightcat от Июль 31, 2008, 17:19 На тему исходной ошибки - Error: Signals cannot have access specifier - сигнал не может иметь спецификатор доступа. Т.е. у Вас, видимо, было написано public signals: или private signals:. В то время как может быть только signals: и все - тролли считают, что приватные сигналы не имеют смысла.
Название: Re: Изменить значение прогрессбара диалогового окна из дочернего потока Отправлено: ритт от Июль 31, 2008, 21:03 signals == protected
public protected == бред вот и ошибка |