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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Не зависающий интерфейс при использовании библиотечной функции Qthread  (Прочитано 3664 раз)
alexei2011
Гость
« : Сентябрь 10, 2011, 10:21 »

Может быть уже было на форуме, но ответа не нашел.

Помогите решить следующую проблему:
есть функция (класса) в библиотеке, которая долго выполняется, при этом естественно интерфейс зависает.
При этом в классе есть метод который может сказать на каком этапе выполнения функция.
Задача такая: необходми запустить поток с этой функцие через Qthread и ждать пока он не завершиться, при этом опрашивать состояние выполнения функции.
Вот, что получилось:

Класс потока:
Код:
class RunThread : public QThread
{
Q_OBJECT
private:
action_class_t *action_class;
uint64 start;

void run()
{
action_class->do_action(start);
}

public:
RunThread(action_class_t *action_class, uint64 start)
{
this->action_class = action_class;
this->start = start;
}
~RunThread()
{
wait();
}
};

В приложении:
Код:
		RunThread thread(action_class,start);
thread.start();

uint64 pos = 0;
while (thread.isRunning())
{
pos = action_class->get_position();
ui->progressBar->setValue((pos*100)/max_size);
repaint();
sleep(1.0);
}

thread.wait();
В итоге интерфейс обновляется раз в 1 секунду при этом грузятся оба ядра на двух ядерном процессоре.

В http://doc.qt.nokia.com/qq/qq27-responsive-guis.html есть заголовок Using a Worker Thread где задача ровно такая как мне необходимо однако, как там сказано решений предостаточно (которых к сожалению гугл не может найти) и поэтому примеров не приведено. При этом используются сигналы и слоты.

Можете помочь с решением?
Записан
brankovic
Гость
« Ответ #1 : Сентябрь 10, 2011, 11:43 »

в RunThread определите:

signal void pos_changed (size_t pos);

в гуи определите:

slot void progress_update (size_t pos) { ui->progressBar->setValue ((pos * 100) / max_size); }

при вызове треда:

void run_thread ()
{
  RunThread *rt = new RunThread ();
  connect (rt, pos_changed (size_t), this, progress_update (size_t));
  rt->start ();
}

в action_class_t, где меняется pos делаете:

emit pos_changed (pos);
Записан
alexei2011
Гость
« Ответ #2 : Сентябрь 10, 2011, 12:18 »

Спасибо
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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