Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: alexei2011 от Сентябрь 10, 2011, 10:21



Название: Не зависающий интерфейс при использовании библиотечной функции Qthread
Отправлено: 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 где задача ровно такая как мне необходимо однако, как там сказано решений предостаточно (которых к сожалению гугл не может найти) и поэтому примеров не приведено. При этом используются сигналы и слоты.

Можете помочь с решением?


Название: Re: Не зависающий интерфейс при использовании библиотечной функции Qthread
Отправлено: brankovic от Сентябрь 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);


Название: Re: Не зависающий интерфейс при использовании библиотечной функции Qthread
Отправлено: alexei2011 от Сентябрь 10, 2011, 12:18
Спасибо