Название: Изменение текущего индекса QStackedWidget из потока pthread Отправлено: alexlogvinenkoit от Ноябрь 15, 2011, 11:53 Здравствуйте!
Такая вот проблема: есть класс, наследующийся от QStackedWidget, в нем много классов, наследующихся от QWidget... Есть поток, который запускается из QStackedWidget (pthread). Так вот, в этом потоке мне нужно менять текущий индекс QStackedWidget (QStackedWidget::setCurrentIndex(int index)); Прога на этом моменте вылетает, вот, что пишет: Цитировать <unknown>: Fatal IO error 11 (Ресурс временно недоступен) on X server :0.0. Код: class WidgetStacked : public QStackedWidget При чем, если просто поменять текст лейбы или еще какие-то действия с дочерними виджетами - то работает... Подскажите, пожалуйста, в чем может быть дело и как можно решить данную проблему. Спасибо! Название: Re: Изменение текущего индекса QStackedWidget из потока pthread Отправлено: alexlogvinenkoit от Ноябрь 15, 2011, 12:41 Есть идея, только не знаю как реализовать (и вообще возможно ли)...
Если программировать на C# - такая проблема всплывает очень часто. Ее решают очень просто - создают делегат. Есть ли в Qt (или даже лучше в C++) делегаты или хотя бы что-то отдоленно похожее? Просто никогда не сталкивался с токого рода проблемой с C++ Название: Re: Изменение текущего индекса QStackedWidget из потока pthread Отправлено: BRE от Ноябрь 15, 2011, 12:58 Почитай про QThread и систему сигнал-слот (есть специальный режим для передачи сигналов между потоками).
Изменять GUI можно только из главного потока! Название: Re: Изменение текущего индекса QStackedWidget из потока pthread Отправлено: alexlogvinenkoit от Ноябрь 15, 2011, 13:07 Повторюсь: из отдельного потока можно делать определенные действия с GUI (я менял текст лейбы (удачно)).
Вылетает только при вызове функции setCurrentIndex(int index). P.S. Пробовал сделать public-функцию SetIndex(int index), в ней уже вызвать setCurrentIndex(index), а ьиз потока вызывать SetIndex(int index). Тоже не помогает. Пробовал еще послать сигнал (emit) - тоже ничего :) Да и еще, поток не QThread, а pthread_t... Название: Re: Изменение текущего индекса QStackedWidget из потока pthread Отправлено: GreatSnake от Ноябрь 15, 2011, 13:24 Повторюсь: из отдельного потока можно делать определенные действия с GUI (я менял текст лейбы (удачно)). Можешь повторяться сколько угодно, ноВылетает только при вызове функции setCurrentIndex(int index). Изменять GUI можно только из главного потока! Вся перерисовка в Qt делается асинхронно, поэтому при изменении текста ничего не упало.Изменение stacking-order и не только его на X11 делается синхронно (со стороны Qt, вернее Xlib) поэтому и падает. Цитировать P.S. Пробовал сделать public-функцию SetIndex(int index), в ней уже вызвать setCurrentIndex(index), а ьиз потока вызывать SetIndex(int index). Тоже не помогает. От перестановки слогаемых сумма не меняется...Цитировать Пробовал еще послать сигнал (emit) - тоже ничего Кому и как слал?Цитировать Да и еще, поток не QThread, а pthread_t... Тем более...Название: Re: Изменение текущего индекса QStackedWidget из потока pthread Отправлено: alexlogvinenkoit от Ноябрь 15, 2011, 13:29 Спасибо, проблему понял.
Вот только решения не понял... Решение какое-нибудь найти можно? Название: Re: Изменение текущего индекса QStackedWidget из потока pthread Отправлено: GreatSnake от Ноябрь 15, 2011, 13:34 Спасибо, проблему понял. Всё зависит от того как быстро ты сможешь перейти от pthreads к QThread.Вот только решения не понял... Решение какое-нибудь найти можно? Название: Re: Изменение текущего индекса QStackedWidget из потока pthread Отправлено: alexlogvinenkoit от Ноябрь 15, 2011, 13:44 Дело в том, что изначально-то и был QThread, но это поток читает из COM-порта, а при использовании QThread - на моменте чтения прога вылетает. Уже даже не помню что писал, но точно какая-то ошибка была.
А если из потока pthread вызвать поток QThread? И в потоке QThread просто вызвать функцию setCurrentIndex(int index)? Т.е. так же, как в дочерних виджетах вызываю ((QStackedWidget *)->parent())->setCurrentIndex(int index)? Название: Re: Изменение текущего индекса QStackedWidget из потока pthread Отправлено: BRE от Ноябрь 15, 2011, 13:55 Для переключения нужно будет посылать сигнал через очередь сообщений, это можно сделать еще и с помощью invokeMethod.
Название: Re: Изменение текущего индекса QStackedWidget из потока pthread Отправлено: thechicho от Ноябрь 15, 2011, 14:58 //Вся перерисовка в Qt делается асинхронно, поэтому при изменении текста ничего не упало.
Изменение stacking-order и не только его на X11 делается синхронно (со стороны Qt, вернее Xlib) поэтому и падает. а я то думал, почему у меня прога в убунту падает. итс факин щит. придется все переделывать. таскать указатель на гуишный элемент, сначала в поток, потом обратно в гуи, через сигналы и слоты. ну чо бл за маразм :-\ Название: Re: Изменение текущего индекса QStackedWidget из потока pthread Отправлено: GreatSnake от Ноябрь 15, 2011, 15:03 таскать указатель на гуишный элемент, сначала в поток, потом обратно в гуи, через сигналы и слоты. ну чо бл за маразм :-\ Действительно маразм. А зачем так делать ???Название: Re: Изменение текущего индекса QStackedWidget из потока pthread Отправлено: alexlogvinenkoit от Ноябрь 15, 2011, 15:22 Маразм, согласен!
Я бы посмотрел в сторону Java, но проект уже написан, остается пару вещей сделать. И вот эта проблема - одна них. Если кто знает, каким образом можно ренить проблему, отпишитесь, please, очень надо! Название: Re: Изменение текущего индекса QStackedWidget из потока pthread Отправлено: GreatSnake от Ноябрь 15, 2011, 16:30 Если кто знает, каким образом можно ренить проблему, отпишитесь, please, очень надо! Дык решение очевидно - не "таскать указатель на гуишный элемент, сначала в поток, потом обратно в гуи".Название: Re: Изменение текущего индекса QStackedWidget из потока pthread Отправлено: thechicho от Ноябрь 15, 2011, 16:34 допустим запускается 100 потоков. как тогда сделать синхронизацию каждого потока с гуи? (QLineEdit, QLabel)
Название: Re: Изменение текущего индекса QStackedWidget из потока pthread Отправлено: alexlogvinenkoit от Ноябрь 15, 2011, 16:35 Цитировать Дык решение очевидно - не "таскать указатель на гуишный элемент, сначала в поток, потом обратно в гуи". Немного не понял... Покажите на примере, please... Название: Re: Изменение текущего индекса QStackedWidget из потока pthread Отправлено: BRE от Ноябрь 15, 2011, 16:42 Немного не понял... Покажите на примере, please... Нельзя дергать слот виджета из другого потока напрямую:Код
но можно его дернуть через очередь сообщений, в этом случае он выполниться в контексте главной (GUI) нитки. Код
Название: Re: Изменение текущего индекса QStackedWidget из потока pthread Отправлено: GreatSnake от Ноябрь 15, 2011, 16:46 допустим запускается 100 потоков. как тогда сделать синхронизацию каждого потока с гуи? (QLineEdit, QLabel)
Название: Re: Изменение текущего индекса QStackedWidget из потока pthread Отправлено: alexlogvinenkoit от Ноябрь 15, 2011, 16:57 Цитировать но можно его дернуть через очередь сообщений, в этом случае он выполниться в контексте главной (GUI) нитки. Я попробовал, но метод возвращает false... Вопрос на засыпку: метод нужно вызывать только из QThread или из pthread тоже можно? P.S. Спасибо за код! Название: Re: Изменение текущего индекса QStackedWidget из потока pthread Отправлено: BRE от Ноябрь 15, 2011, 17:03 Я попробовал, но метод возвращает false... В консоль что нибудь пишет?Название: Re: Изменение текущего индекса QStackedWidget из потока pthread Отправлено: thechicho от Ноябрь 15, 2011, 17:05 // Связать этот сигнал с QLineEdit::setText( const QString& ).
пример кода, плиз? для каждого потока свой QLineEdit я не догоняю как такую связь (без слота) осуществить :-\ Название: Re: Изменение текущего индекса QStackedWidget из потока pthread Отправлено: alexlogvinenkoit от Ноябрь 15, 2011, 17:05 В консоль пишет только то, что я сам говорю писать... Т.е. если вернет true я пишу в консоль тру, если false - то false...
В остальном - никаких ошибок, warnings и т.д. Даже прога не вылетает :) Название: Re: Изменение текущего индекса QStackedWidget из потока pthread Отправлено: GreatSnake от Ноябрь 15, 2011, 17:07 // Связать этот сигнал с QLineEdit::setText( const QString& ). Дык QLineEdit::setText() и есть слот ???пример кода, плиз? для каждого потока свой QLineEdit я не догоняю как такую связь (без слота) осуществить :-\ Название: Re: Изменение текущего индекса QStackedWidget из потока pthread Отправлено: BRE от Ноябрь 15, 2011, 17:11 Попробуй так:
Код
Название: Re: Изменение текущего индекса QStackedWidget из потока pthread Отправлено: GreatSnake от Ноябрь 15, 2011, 17:16 Попробуй так: Скорее всего тоже не прокатит. QGenericReturnArgument() не нужен:Код
Код
Название: Re: Изменение текущего индекса QStackedWidget из потока pthread Отправлено: thechicho от Ноябрь 15, 2011, 17:19 // Дык QLineEdit::setText() и есть слот
пример кода, плиз. QLineEdit для каждого потока свой. 10 потоков. Название: Re: Изменение текущего индекса QStackedWidget из потока pthread Отправлено: BRE от Ноябрь 15, 2011, 17:26 Скорее всего тоже не прокатит. Должен прокатить. :)Название: Re: Изменение текущего индекса QStackedWidget из потока pthread Отправлено: alexlogvinenkoit от Ноябрь 15, 2011, 17:28 Заработало!!!
Всем огромное спасибо!!! Прямо выручили! Код: QMetaObject::invokeMethod( stackWidget, "setCurrentIndex", Qt::QueuedConnection, Q_ARG( int, 0 ) ); Название: Re: Изменение текущего индекса QStackedWidget из потока pthread Отправлено: GreatSnake от Ноябрь 15, 2011, 17:33 // Дык QLineEdit::setText() и есть слот пример кода, плиз. QLineEdit для каждого потока свой. 10 потоков. Как-то так: Код
Название: Re: Изменение текущего индекса QStackedWidget из потока pthread Отправлено: thechicho от Ноябрь 15, 2011, 18:08 а все допер) я ставил this, SLOT() поэтому понять не мог, почему не прокатывает :D
биг сенкс :) |