Russian Qt Forum

Qt => XML => Тема начата: Alur от Январь 12, 2011, 15:48



Название: setContent в отдельном потоке
Отправлено: Alur от Январь 12, 2011, 15:48
Здравствуйте!
Разбираю хml документ при помощи setContent. Документ большой, поэтому setContent работает долго. При этом необходимо, чтобы графический интерфейс основного потока нормально отображался во время разбора xml. Попробовал вынести разбор xml в другой поток. В итоге: поток создаётся, xml парсится, а основной интерфейс по-прежнему "подвисает"...

Может, я что-то делаю неправильно, а, может, так вообще не рекомендуется делать?

Класс потока:
Код:
class setXMLContentThread : public QThread {
public:
void work(QByteArray);
void run();
QDomDocument getQDomDocumentPtr();
QDomDocument ownDomTree;
QByteArray ownArray;
                int ownResultFlag;
};

Методы класса:
Код:
void work(QByteArray newArray)
{
ownArray = newArray;
start();
}

void run()
{
if(ownDomTree.setContent(ownArray))
ownResultFlag = 1;
else
ownResultFlag = -1;
}

Создаю и запускаю поток в своём графическом классе:
Код:
setXMLContentThread setContentThr;
setContentThr.work(arrayXMLContent);

Как уже говорил выше, поток запускается и отрабатывает как надо, но графический интерфейс основного потока всё равно подвисает на время разбора xml.

Где причина?!


Название: Re: setContent в отдельном потоке
Отправлено: Пантер от Январь 12, 2011, 15:53
Нужно вызывать setContentThr->start ()


Название: Re: setContent в отдельном потоке
Отправлено: Alur от Январь 12, 2011, 15:55
Вызываю метод start() в методе work().
Пробовал и напрямую, как Вы указали:
Код:
setContentThr.start();
Результат тот же!


Название: Re: setContent в отдельном потоке
Отправлено: Alur от Январь 14, 2011, 09:10
Неужели никто ничто не может посоветовать вразумительного ?  :-\


Название: Re: setContent в отдельном потоке
Отправлено: BRE от Январь 14, 2011, 09:15
После запуска потока, как происходит ожидание/определение момента его завершения в главном потоке?


Название: Re: setContent в отдельном потоке
Отправлено: Alur от Январь 14, 2011, 11:41
Я пробовал делать несколькими способами.

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

С основным потоком я пробовал поступать разными способами:

1. Делал бесконечный цикл до завершения работы дочернего потока, пытаясь насильно перерисовывать графический интерфейс основного потока. Примерно так:
Код:
...
MyThread thr;
thr.start();
while(!thr.finished()) {
    qApp->processEvents();
}
...

2. Делал дочерний поток глобальным, чтобы он не убивался при выходе из функции основного потока, которая его вызывает.
Код:
void someClass::someFunc()
{
    thr.start();
    /* Всё просто - запустили поток и вышли из функции. Пускай себе там работает наздоровье...
       При этом поток не убивается, а продолжает работать - ведь он определён как глобальный,
       а графический интерфейс должен быть снова доступен пользователю для действий            */
}

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

В первом методе я допускал, что подобное явление возможно из-за цикла, который я насильно вставил в основной поток, чтобы дождаться завершения работы дочернего. Но второй метод отвязан от этого и должен гарантированно работать, чего не происходит...

Может, я что-то делаю неправильно?!