![]() |
|
|
![]()
|
|
| RobRoj7779 |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 28 Регистрация: 13.7.2009 Репутация: нет Всего: нет |
Здравствуйте, помогите новичку разобраться с главным потоком.
Просмотрел предыдущие темы по подобным вопросам, но к сожалению не понял. Помогите. пытаюсь писать на QT4. В диалоговой форме код отработал нормально, но мне его нужно перенести на главную форму приложения. Суть проблемы: во вторичном потоке создаю строку. Ее нужно отобразить на главной форме. В главном потоке динамически. При переносе кода от QDialog. Строка отображается только при старте потока, и чтобы увидеть новую строку, снова стартую поток. Необходимо увидеть динамику, как в Таймере. Таймер для задачи не подошел, поэтому пытаюсь понять работу потоков. При использовании Mutex, PostEvent программа висит *.h class MyPotok : public QThread { Q_OBJECT signals: void currentValueV(QString); void currentValueA(QString); public: MyPotok(); void stop(); QString StrA, StrVal, StrPak; protected: void run(); private: volatile bool stopped; QMutex mutex; }; *.c void MyPotok::run() { ---------- try{ mutex.lock(); while(!stopped){ формирую строку StrA ; emit currentValueA(StrA); if(!myValue) { формирую строку StrVal ; emit currentValueV(StrVal); } usleep(120000); } stopped = false; mutex.unlock(); } catch(...){ ----------------------------- } } int main(int argc, char ** argv) { QApplication app( argc, argv ); MainWindowImpl win; MyPotok threadA; win.show(); win.connect(&threadA, SIGNAL(currentValueA(QString)), &win, SLOT(startThread())); win.connect(&threadA, SIGNAL(currentValueV(QString)), &win, SLOT(startThread())); win.connect(&win, SIGNAL(getSendPak(bool)), &threadA, SLOT(run())); app.connect( &app, SIGNAL( lastWindowClosed() ), &app, SLOT( quit() ) ); return app.exec(); } void MainWindowImpl::startThread() { QString Ln; threadA.start(); Ln = threadA.StrA; if(!threadA.myValue) Ln = threadA.StrVal; } void MainWindowImpl::stopThread() { QString Ln; threadA.stop(); } void MainWindowImpl::getSendPak() { threadA.StrPak = EdSendPak->text(); emit setSendPak(threadA.myValue = false); } void MainWindowImpl::closeEvent(QCloseEvent *event) { threadA.stop(); threadA.wait(); event->accept(); } Заранее благодарен за помощь. |
|||
|
||||
| andrew_121 |
|
|||
![]() Кодофей ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3448 Регистрация: 3.1.2008 Репутация: 11 Всего: 33 |
Два раза прочел, и не понял
Опишите пожалуйста последовательно. И код поместите в тэги "" -------------------- Удалил аккаунт. Прощайте! |
|||
|
||||
| null56 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 721 Регистрация: 19.3.2008 Репутация: 6 Всего: 12 |
ваще жесть... я тоже не догнал )))) |
|||
|
||||
| RobRoj7779 |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 28 Регистрация: 13.7.2009 Репутация: нет Всего: нет |
В диалоговой форме 3 кнопки "Старт", "Стоп" и "Переслать" При "Старт" стартует поток и создается строка Ln += номер. номер++
Строка обновляется через 120 мс. и передается на форму Edit1. При "Переслать" подобным образом создается другая строка и также передается на форму, но другому Edit2. При "Стоп" поток останавливается и Edit очищается. Так я вижу на форме изменяющиеся строки по счетчику через 120 мс. Такое можно реализовать в Timer но для задачи нужен поток. Поэтому пытаюсь его освоить. Код работает при QDialog, когда я создал диалоговое приложение. Нужно подобное написать для главного приложения. При переносе кода строки на главной форме обновляются только при постоянном нажатии кнопки "Старт". Если нажал "Старт" один раз Edit1 пустой. Нужно нажать "Старт" (run() потока) и видеть изменяющие строки, до нажатия "Стоп"(stop() потока). Что я не понял или делаю не так?????? Помогите пожалуйста.
|
|||
|
||||
| andrew_121 |
|
|||
![]() Кодофей ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3448 Регистрация: 3.1.2008 Репутация: 11 Всего: 33 |
RobRoj7779, Приблизительно, что-то понял, не уверен. Ты очень тяжело объясняешь.
Выложи весь проект на какой-нить файлообменник, а ссылку сюда. Так скорее придет понимание. Добавлено через 1 минуту и 25 секунд Этого делать не надо! Добавлено через 3 минуты и 49 секунд По моему начал понимать. Тебе нужно чтоб при нажатии кнопок в диалоге, запускался некий поток, что-то выполнял. И, при этом, по ходу выполнения, что-то отображалось в главном окне? Так? -------------------- Удалил аккаунт. Прощайте! |
|||
|
||||
| null56 |
|
||||||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 721 Регистрация: 19.3.2008 Репутация: 6 Всего: 12 |
Ну что бросается в глаза...
1) Функция run: Мьютекс стоит не там и где обращение к мьютексу со стороы класса MainWindowImpl? а) если поток работает постоянно, то как же мьютекс будет разблокироваться, если ты постоянно в цикле, а разблокируешь его только после выхода из цикла б) если ты используешь мьютекс для синхронизации доступа к разделяемым ресурсам, то и на принимающей стороне должен его контроллировать доступ к твоим публичным переменным
Но я смотрю ты решился на такое
то получается, что у тебя после генерации сигнала внутри работающего потока, поток стартует опять незавершаясь, и ты нарываешься на свой же заблокированный мьютекс... И почему бы тогда не передать значение прямиком в слот и за синхронизацию межпоточного взаимодействия будет отвечать уже механизм сигналов и слотов Но вообще говоря, алгоритм ВООБЩЕ не понятен, чего ты хочешь таким образом добиться ЗЫ: если тебе нужны миллисекунды, то есть аналог
ЗЫ2: try->catch не нужен... на сколько мне известно Qt нигде не генерит исключения, всюду пользуются assert и ко... 2) Слота run нет у класса Qthread и в твоём наследнике + новый поток создавать можно только методом start, а в run реализация
есть start
Это сообщение отредактировал(а) null56 - 30.8.2009, 06:05 |
||||||||||
|
|||||||||||
| RobRoj7779 |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 28 Регистрация: 13.7.2009 Репутация: нет Всего: нет |
Здравствуйте,
По моему начал понимать. Тебе нужно чтоб при нажатии кнопок в диалоге, запускался некий поток, что-то выполнял. И, при этом, по ходу выполнения, что-то отображалось в главном окне? Так? Да именно, так. Но как это сделать???????????? Добавлено через 2 минуты и 34 секунды почему бы тогда не передать значение прямиком в слот и за синхронизацию межпоточного взаимодействия будет отвечать уже механизм сигналов и слотов Как это сделать?????? |
|||
|
||||
| RobRoj7779 |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 28 Регистрация: 13.7.2009 Репутация: нет Всего: нет |
Разве таким образом не передается строка в SLOT главной формы???????? |
|||
|
||||
| andrew_121 |
|
|||
![]() Кодофей ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3448 Регистрация: 3.1.2008 Репутация: 11 Всего: 33 |
Нет. Потому что сигнал передает строку, а слот не принимает аргументы. -------------------- Удалил аккаунт. Прощайте! |
|||
|
||||
| RobRoj7779 |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 28 Регистрация: 13.7.2009 Репутация: нет Всего: нет |
т.е. мне нужно в startThread() написать startThread(QString str) и str передавать из алоговое currentValueV(QString). Так????????
Но почему эта тестовая программа работала, когда использовал диалоговое окно. Перенес код в приложение с главным окном и ни чего не увидел?????????????? |
|||
|
||||
| RobRoj7779 |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 28 Регистрация: 13.7.2009 Репутация: нет Всего: нет |
Это у меня тестовая прога, для понятия работы с потоком и взаимодействие с главным потоком приложения.
Файлообменниками не пользовался, может перекину на мыло. Уже парюсь 2-й день и понять не могу в что делаю не так. Помогите. Когда был класс QDialog все работало. Теперь не вижу строк, которые должен был получать из потока, через 120 мс
|
|||
|
||||
| null56 |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 721 Регистрация: 19.3.2008 Репутация: 6 Всего: 12 |
можно, если у тебя будет соответствующий слот с аргументов QString со стороны главного приложения
нет не переданная, а просто обращаешься к разделяемому ресурсу, хоть и в слоте, заметь без использования мьютекса!!!!.... Переданную ты можешь поличить только в слоте, а здесь другому потоку ничто не будет мешать его изменять, что уже подразумевает рассинхронизацию ЗЫ: у тебя хоть какая = нибудь книжка есть по Qt? или в ассистенте ты примеры нашел? |
||||
|
|||||
| RobRoj7779 |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 28 Регистрация: 13.7.2009 Репутация: нет Всего: нет |
Правильно ли я понял. Для того чтобы передать приложению из потока строку, я должен написать подобное
void MainWindowImpl::startThread(const QString&). Но этот SLOT на кнопке "Старт" и при этом такая ошибка:
Укажите мне пожалуйста, что мне нужно поменять, для того, чтобы увидеть изменяющие строки на главной форме. Книга есть. Этот пример, но для QDialog, писал по книге. Пример работает. В книге указывалось на асинхронный режим работы Сигнал-Слот для случая Главного потока. Я пишу прогу для работы с COM портом. С использованием QTimer приложение работает. Но требования инженера по железу переписать часть приема/передачи с использованием параллельного потока. Что и пытаюсь понять. Пока с трудом. |
|||
|
||||
| andrew_121 |
|
|||
![]() Кодофей ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3448 Регистрация: 3.1.2008 Репутация: 11 Всего: 33 |
RobRoj7779, Примитивнейший пример:
Повторяю, это примитивнейший пример! Добавлено через 1 минуту и 49 секунд Ты абсолютно не правильно понимаешь работу с потоками, и с QThread в частности. Почитай документацию! -------------------- Удалил аккаунт. Прощайте! |
|||
|
||||
| RobRoj7779 |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 28 Регистрация: 13.7.2009 Репутация: нет Всего: нет |
Мой код для случая class Form: public QDialog { отработал так как мне надо. Я не могу понять, что надо изменить что бы то же самое заработало для приложения созданного как MainWindows Сейчас я вижу на главной форме обновленные строки, в том случае, если постоянно нажимаю кнопку "Старт" Мой пример тестовый, переписывать почти готовое приложение (MainWindows) под QDialog не хотелось бы. Месяц работы в пустую. Помогите пожалуйста, укажите что и как изменить. Код маленький и в процессе обсуждения я его почти весь выложил Заранее благодарен за помощь |
|||
|
||||
| andrew_121 |
|
|||
![]() Кодофей ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3448 Регистрация: 3.1.2008 Репутация: 11 Всего: 33 |
Заархивируй проект и выложи на http://rghost.ru/
-------------------- Удалил аккаунт. Прощайте! |
|||
|
||||
| RobRoj7779 |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 28 Регистрация: 13.7.2009 Репутация: нет Всего: нет |
Теперь я ничего не вижу |
|||
|
||||
| andrew_121 |
|
|||
![]() Кодофей ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3448 Регистрация: 3.1.2008 Репутация: 11 Всего: 33 |
Где ты инициализируешь эти переменные? п.с. рано тебе программировать. -------------------- Удалил аккаунт. Прощайте! |
|||
|
||||
| RobRoj7779 |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 28 Регистрация: 13.7.2009 Репутация: нет Всего: нет |
Выложил http://rghost.ru/429772
В архиве бинарник, Так должно быть. Писал как QDialog. А так же папка с проектом, который нужно исправить по подобию бинарника. Прога создает в корне лог, в нем процесс правильный, строки динамически изменяются, но их я не вижу на форме. Добавлено через 5 минут и 47 секунд п.с. рано тебе программировать. Все так безнадежно................ Учусь. По этому и обратился за помощью. Не привык опускать весла. Может быть выплыву с Вашей помощью. Помогите пожалуйста. Добавлено через 12 минут и 15 секунд А где нужно объявить??? В class MainWindowImpl. При компиляции не находил соединения. Пишу в Mandriva 2009 |
|||
|
||||
| RobRoj7779 |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 28 Регистрация: 13.7.2009 Репутация: нет Всего: нет |
Здравствуйте,
Задачу решил. Ошибка тупая, но стоила мне 2-х дней. Большое спасибо. Еще раз извиняюсь за глупые вопросы. Но я учусь, а спецов по QT найти тяжело для того, чтобы пообщаться в живую. Большое спасибо. И Еще раз извиняюсь. |
|||
|
||||
| andrew_121 |
|
|||
![]() Кодофей ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3448 Регистрация: 3.1.2008 Репутация: 11 Всего: 33 |
RobRoj7779, Расскажи как решил.
-------------------- Удалил аккаунт. Прощайте! |
|||
|
||||
| RobRoj7779 |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 28 Регистрация: 13.7.2009 Репутация: нет Всего: нет |
MyPotok *threadA;
QLabel *lbInfo_masAHex; QLabel *lbInfo_masBHex; Глупо, но переменные были определены не в том месте. Сравнил с проектом QDialog. Понял что не прав. Исправил. Заработало. Спасибо за помощь. |
|||
|
||||
| null56 |
|
||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 721 Регистрация: 19.3.2008 Репутация: 6 Всего: 12 |
не хочу тебя огорчать... может и я невнимательный в коде... .но мне кажется, что дочерний поток у тебя не создается, а просто идет вызов функции run(), что само по себе подразумевает выполнение в текущем потоке....
Вопрос: ты где - нибудь вызываешь функцию start() или нет? (может я слепой?)
или я не прав? на сколько мне было известно, новый поток создается ТОЛЬКО после вызова функции start(), которая запускает новый поток с кодом, который описан в функции run()...
|
||||||
|
|||||||
| RobRoj7779 |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 28 Регистрация: 13.7.2009 Репутация: нет Всего: нет |
Здравствуйте, вызов start() в кнопке "Старт"
|
|||
|
||||
| null56 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 721 Регистрация: 19.3.2008 Репутация: 6 Всего: 12 |
RobRoj7779, да проспал... но тогда мне непонятно... зачем это
|
|||
|
||||
| RobRoj7779 |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 28 Регистрация: 13.7.2009 Репутация: нет Всего: нет |
Программка была тестовой. Хотел научиться работать с потоком. В частности возможность пересылки другой строки, в тот момент, когда поток запущен и обрабатывает основную строку. SIGNAL(getSendPak(bool)) формирует другую строку и передает ее потоку, который в этот момент уже запущен. А в целом все эти тестовые задачи подчинены одной. Написать что-то на подобии своего униикального программатора для Устройства через COM порт. Программатор должен иметь графическую оболочку, работать в среде Linux. Ранее задавал вопросы по интерфейсу и с помощью Форума его своял. Теперь команды. Работа с буфером COM порта почти отлажена. Если споткнусь, то надеюсь на помощь форума. Ранее писал на Delphi. Пришлось переквалифицироваться, т.е. учиться по новой. Поэтому еще раз СПАСИБО и надеюсь на Вашу поддержку. |
|||
|
||||
![]()
|
| Правила форума "С/С++: Кроссплатформенное программирование, QT/Gtk+/wxWidgets" | |
|
|
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, Любитель. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |