![]() |
|
|
![]()
|
|
| 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 не хотелось бы. Месяц работы в пустую. Помогите пожалуйста, укажите что и как изменить. Код маленький и в процессе обсуждения я его почти весь выложил Заранее благодарен за помощь |
|||
|
||||
![]()
|
| Правила форума "С/С++: Кроссплатформенное программирование, 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. |