Russian Qt Forum

Qt => Общие вопросы => Тема начата: taifun от Май 07, 2010, 09:24



Название: QThread, terminate (), finished ()
Отправлено: taifun от Май 07, 2010, 09:24
Здраствуйте, помогите разобраться. По нажатию кнопки мыши создаю дочерний поток, в котором обрабатываю данные, сделал так:
Код:
void clthreadzip::run()
{  
   .............
   while (intCount < 1000) {
      ................
   }
   // и тут мне надо отослать сигнал, что обработка данных окончена
   // и для этого я вызываю функцию terminate (), которая должна завершить поток и соответственно отсылать сигнал finished ()
   // но этого не происходит. Более того она по моему вообще зависает
   terminate ();
}

Вот точно я что-то не так понимаю, вот только что? Разъясните ситуацию.


Название: Re: QThread, terminate (), finished ()
Отправлено: BRE от Май 07, 2010, 09:27
А как "туда" может управление попасть, если у тебя цикл бесконечный.
Когда расчет окончен, нужно просто выйти из цикла и поток завершиться и сигнал отошлет.


Название: Re: QThread, terminate (), finished ()
Отправлено: taifun от Май 07, 2010, 09:50
А как "туда" может управление попасть, если у тебя цикл бесконечный.
Когда расчет окончен, нужно просто выйти из цикла и поток завершиться и сигнал отошлет.


Извиняюсь, не коректно условие в while () написал (не то имел ввиду). Я так понимаю должен отослаться сигнал finished()? если да, то это не происходит, потому что (в главном потоке):

Код:
clthreadzip ZFileRead;
void MainWindow::init()
{
    QObject::connect(&ZFileRead, SIGNAL(finished()), this, SLOT(FinishThread()));
}
void MainWindow::FinishThread(){

    ui->pgBar->setValue(ui->pgBar->maximum());
    ui->statusBar->showMessage(trUtf8("Обработка данных завершена"));
    qDebug() << trUtf8("Thread Finished!");
}

а у меня получается, что когда поток отработал я не получаю не одного уведомления об этом, следуя из этого я могу сказать, что сигнал finished() не приходит.


Название: Re: QThread, terminate (), finished ()
Отправлено: AlekseyK от Май 07, 2010, 10:34
terminate лучше не пользоваться, они и сами об этом пишут, сам только недавно сталкивался. Если надо поток остановить из вне - есть выход более простой, элегантный и красивый: добавляешь в свой clthreadzip слот, например, setTerminated() и переменную, например, isTerminated и по сигналу из вне меняешь её на true, а цикл твой можно переписать так:

Код
C++ (Qt)
void clthreadzip::run()
{  
  .............
  while (intCount < 1000 && !isTerminated ) {
     ................
  }
}

По окончании run finished() вызовется автоматом, а при использовании terminated() этого почему-то не происходит.


Название: Re: QThread, terminate (), finished ()
Отправлено: taifun от Май 07, 2010, 11:47
ага, идея отличная - управление циклом (потоком) из вне (на данный момент из вне я управляю им как раз c помошью terminate() ), но проблема у меня пока в том что по оканчанию run() сигнал finished() не отсылается - вот в чем вопрос. Я, конечно же, и сам могу его отсылать? но по идеи он должен отсылаться автоматически  ???


Название: Re: QThread, terminate (), finished ()
Отправлено: AlekseyK от Май 07, 2010, 12:20
ага, идея отличная - управление циклом (потоком) из вне (на данный момент из вне я управляю им как раз c помошью terminate() ), но проблема у меня пока в том что по оканчанию run() сигнал finished() не отсылается - вот в чем вопрос. Я, конечно же, и сам могу его отсылать? но по идеи он должен отсылаться автоматически  ???

Повторяю: он и отсылается автоматически по завершении run, но terminate использовать нельзя! :) Иначе сигнал не отсылается.


Название: Re: QThread, terminate (), finished ()
Отправлено: taifun от Май 07, 2010, 13:27
Повторяю: он и отсылается автоматически по завершении run, но terminate использовать нельзя! :) Иначе сигнал не отсылается.

Я вас прекрасно понял, я имел ввиду, что terminate() убрал. но по оканчанию run() сигнал finished() не отсылается все равно.


Название: Re: QThread, terminate (), finished ()
Отправлено: AlekseyK от Май 07, 2010, 14:14
Странно, но у меня waitForFinished() работает. Может явно сигнал отсылать emit finished()?


Название: Re: QThread, terminate (), finished ()
Отправлено: taifun от Май 07, 2010, 14:44
Странно, но у меня waitForFinished() работает. Может явно сигнал отсылать emit finished()?

Можно, пока так и делаю  :) просто хочется разобраться в чем дело  ???


Название: Re: QThread, terminate (), finished ()
Отправлено: AlekseyK от Май 07, 2010, 15:03
Странно, но у меня waitForFinished() работает. Может явно сигнал отсылать emit finished()?

Можно, пока так и делаю  :) просто хочется разобраться в чем дело  ???

Дело как всегда в том, что мы не читаем документацию: ;)

Цитировать
Each QThread can have its own event loop. You can start the event loop by calling exec(); you can stop it by calling exit() or quit(). Having an event loop in a thread makes it possible to connect signals from other threads to slots in this thread, using a mechanism called queued connections. It also makes it possible to use classes that require the event loop, such as QTimer and QTcpSocket, in the thread. Note, however, that it is not possible to use any widget classes in the thread.

int QThread::exec ()   [protected]
Enters the event loop and waits until exit() is called, returning the value that was passed to exit(). The value returned is 0 if exit() is called via quit().

It is necessary to call this function to start event handling.

See also quit() and exit().

Код
C++ (Qt)
class MyThread : public QThread
{
public:
    void run();
};
 
void MyThread::run()
{
    QTcpSocket socket;
    // connect QTcpSocket's signals somewhere meaningful
    ...
    socket.connectToHost(hostName, portNumber);
    exec();
}


Название: Re: QThread, terminate (), finished ()
Отправлено: taifun от Май 07, 2010, 15:36
не то (в моем случаи не нужно постоянно "крутить" run(), while() отработал и все - дело сделано), да и не помогло - проверил.


Название: Re: QThread, terminate (), finished ()
Отправлено: AlekseyK от Май 07, 2010, 16:04
Пиши в багзиллу ;)


Название: Re: QThread, terminate (), finished ()
Отправлено: taifun от Май 12, 2010, 07:45
Вот, накидал простенький примерчик, если кому интересно.