Russian Qt Forum
Май 03, 2024, 12:40 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Потоки и диалоговые окна  (Прочитано 6353 раз)
ElderOrb
Гость
« : Февраль 02, 2006, 20:13 »

Есть задача сделать программу для тестирования всякого харда. Каждый тест у меня оформляется в виде потока, который работает, а по окончанию испускает сигнал с результатом. Некоторые тесты будут требовать вмешательства пользователи, то есть во время тестов будут открываться диалоговые окна. Но в QThread нельзя создавать виджэты. Как быть?

До сих пор я выходил из положения следующим образом.
у меня в потоке была функция примерно такого содержания:
Код:
void InitTask::errorMsg(const QString& str, InitStates retryState)
{
mutex.lock();

QApplication::postEvent(eventReceiver,
new mayBeRetryInitEvent(QString(str),this, retryState));

condition.wait(&mutex);
mutex.unlock();
}

а в гуи потоке приходилось делать следующее
Код:
void Pls1Widget::customEvent ( QEvent * event )
{
if(event->type() == RETRY_INIT) {

mayBeRetryInitEvent* e = (mayBeRetryInitEvent*) event;

int ret = QMessageBox::warning(this, appName,
e->message, tr("Повторить"), tr("Прервать"), "", 0, 1);

if(ret == 0)
{
e->initTask->initState = e->retryState;
e->initTask->setCompleted(false);
} else {
e->initTask->initState = InitTask::INIT_FINISHED_ERROR;
e->initTask->setCompleted(true);
}

e->initTask->condition.wakeAll();

}


Всё работает, но возникает ужасное чувство кривого очередного велосипеда с квадратными колёсами. Может быть кто-нибудь придумал решение получше?
Записан
Gop-Stop
Гость
« Ответ #1 : Февраль 02, 2006, 21:33 »

действительно виджет показать нельзя, тогда создавай виджеты с диалогами заранее (в главном потоке) а в дочерний поток передавай указатель и ОК .
Записан
Dendy
Гость
« Ответ #2 : Февраль 02, 2006, 21:41 »

Йопт, а в чём проблема? Испускаешь асинхронньІй сигнал из потока в гуи поток, смотришь ответ, возвращаешь результат в поток, работаешь дальше. Не-гуи поток не может юзать блокирующие диалоговьІе окна, енто нормально. Прделагаю закрутить во втором потоке неглавньІй цикл обработки собьІтий, которьІй и будет отправлять/принимать сигнальІ.

добавлено спустя 1 минуту:

 2 Gop-Stop
Так делать нельзя.
Записан
Gop-Stop
Гость
« Ответ #3 : Февраль 02, 2006, 22:22 »

это почему же
вот пример такого потока (аналогично и совсем остальным)

class MyThread : public QThread {
 QProgressBar *m_prog;

public:
 MyThread(QProgressBar* prog) : QThread(), m_prog(prog)
 {
 }

 void run();

};
Записан
ElderOrb
Гость
« Ответ #4 : Февраль 03, 2006, 09:18 »

Проблема в том, что поток должен на это время вывода диалога останавливаться, а после вывода снова запускаться. Пока что я добился этого с помощью мутексов и вэйт кондишенов.

Цитировать
Прделагаю закрутить во втором потоке неглавньІй цикл обработки собьІтий, которьІй и будет отправлять/принимать сигнальІ.


А можно насчёт этого поподробнее? Отправлять/принимать сигналы потоки могут и без циклов обработки событий, или я чего-то не понимаю?.
Записан
Dendy
Гость
« Ответ #5 : Февраль 03, 2006, 10:11 »

Работа потока слитная, у него есть просто начало и конец, куда вставить получение собьІтия внутрь ентого непрерьІвного процесса никто не знает. Именно поетому поток без QEventLoop может максимум отправить сигнал когда он завершится. Для реализации собьІтий внутри потока необходимьІ некие маркёрьІ итераций главного цикла. Именно етим и занимается QEventLoop. Реализация потока с циклом обработки собьІтий будет работать по той же асинхронной модели, как, например, по сети: К нам приходит сигнал, мьІработаем, нужно спросить - испускаем сигнал, ждём сигнал-ответ. Для такой работьІ обязательно нужен стек состояний, что именно мьІ делаем и на какой вопрос ждём ответ.

добавлено спустя 2 минуты:

 Ещё.
Испускать сигнальІ поток без цикла может за счёт неявного постирования асинхронньІх собьІтий в главньІй цикл, которьІе обрабатьІваются на следующей его итерации.
Принимать же без главного цикла он не может.
Записан
Sergeich
Гость
« Ответ #6 : Февраль 03, 2006, 18:56 »

Я бы посоветовал делать каждый тест в виде отдельного процесса, к-ый общается с программой тестирования по сокету. Во-первых, не будет проблем с диалогами, во-вторых это намного надежней, в-третьих можно делать тестирование по сетке.
Записан
ElderOrb
Гость
« Ответ #7 : Февраль 03, 2006, 22:28 »

2Dendy: Спасибо за информацию, наконец-то я понял что именно добавляет потоку exec() ж). Вот только вопрос, каким образом теперь реализовывать алгоритмы?.. Если раньше весь алгоритм находился в функции run() и выполнялся последовательно, то после использования exec() алгоритм как бы размажется по сигналам и слотам?.. То есть к примеру хочу я чтобы
1. поток открывал устройство
2. что-то проверял, и в зависимости от результата слал гуи-потоку запрос на открытие диалога.
3. Пользователь определяет как поступить в этой ситуации, что то выбирает, тем самым инициируя сигнал, который испустит гуи-поток и поймает воркер.

Пока я вижу что при использовании exec() у воркер - потока придётся ввести отдельные слоты для открытия устройства, проверки, сигнал для запроса гуи-потока на создание диалога, слот куда придёт сигнал от гуи-потока после выбора пользователем чего-то в диалоге. Если делать надо именно так - то это слегка непривычно после органазации алгоритма в одной функции ж). Если же я так ничего и не понял - можно примерчик, иллюстрирующий взаимодействие гуи-потока и потока с циклом сообщений?

2Sergeich: Интересная мысль. И сразу интересные (хотя наверняка тупые) вопросы:
Каким образом в новом процессе создаются виджеты?..
Засчёт чего это надёжнее чем поток?
Да, чуть не забыл, каким образом будет осуществляться взаимодействие между процессами? (будут ли работать прямые вызовы функций находящихся в просецце 1 из процесса 2? будут ли работать соденинения сигнал-слот?)

Дело в том что я ещё ни разу не использовал в Qt QProcess и сокеты соответстенно, поэтому хотелось бы знать какие там могут быть подводные камни?.. Или может быть небольшой туториал ж)

Dendy, Sergeich - отзовитесь пожалуйста!.. Не лишайте меня призрачной надежды наконец-то узнать КАК НАДО ж)...
Записан
FrankS
Гость
« Ответ #8 : Февраль 04, 2006, 21:58 »

Цитировать

Засчёт чего это надёжнее чем поток?

За счёт того, что если произойдёт какой-то сбой (что вполне вероятно при работе с глючным железом, упадёт именно процесс с тестом, а не вся тестирующаяя прога
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.153 секунд. Запросов: 20.