Название: Кнопка прерывания выполнения куска кода под Linux Отправлено: slvno от Январь 15, 2009, 18:00 Привет!
Имеется прога портированная из Windows в которой в главном потоке создается форма (FORM) с кнопкой. При нажатии на кнопку (b_start) запускается длительная операция (on_b_start_clicked()). В этом обработчике on_b_start_clicked показывается форма с отменой операции в виде QDialog с кнопкой QPushButton - b_cancel, которая создается в томже главном потоке при создании FORM. При нажатии на кнопку b_cancel->b_stop устанавливается флаг отмены flag_stop и завершается выполнеие on_b_start_clicked(). Если убрать QCoreApplication::processEvents(QEventLoop::AllEvents ), то b_cancel пререстает реагировать. До этого под Windows b_cance создавалась в отдельном потоке on_b_start_clicked_theread и все работало без вызовов QCoreApplication::processEvents(QEventLoop::AllEvents ). Можно ли обойтись без QCoreApplication::processEvents(QEventLoop::AllEvents ) ? Код: class FORM: public QWidget Название: Re: Кнопка прерывания выполнения куска кода под Linux Отправлено: Winstrol от Январь 15, 2009, 18:31 Можно ли обойтись без QCoreApplication::processEvents(QEventLoop::AllEvents ) ? Да. В последних версиях появился интересный модуль QtConcurrent. В папке examples\qtconcurrent\imagescaling есть пример, где имеет место похожая ситуация. Длительное параллельное вычисление с выводом на экран промежуточных результатов и кнопка отмены. Без явных потоков, мьютексов, длинных пауз в гуевом потоке и прочей ереси.Огорчает только, что реализация MapReduce там позорная до безобразия. Но к данной проблеме это не имеет прямого отношения. Название: Re: Кнопка прерывания выполнения куска кода под Linux Отправлено: pastor от Январь 15, 2009, 19:29 До этого под Windows b_cance создавалась в отдельном потоке on_b_start_clicked_theread и все работало без вызовов QCoreApplication::processEvents(QEventLoop::AllEvents ). Это категорически неправильно! Все гуевые элементы должны быть в главном (гуевом) потоке. Цитировать В этом обработчике on_b_start_clicked показывается форма с отменой операции в виде QDialog с кнопкой QPushButton - b_cancel Взгляните на QProgressDialog Название: Re: Кнопка прерывания выполнения куска кода под Linux Отправлено: slvno от Январь 16, 2009, 16:55 Взгляните на QProgressDialog QProgressDialog виснет без вызова processEvents Код: void FORM::on_exit() Название: Re: Кнопка прерывания выполнения куска кода под Linux Отправлено: pastor от Январь 16, 2009, 17:44 Документацию читать нехотим:
Цитировать void setValue ( int progress ) Warning: If the progress dialog is modal (see QProgressDialog::QProgressDialog()), this function calls QApplication::processEvents(), so take care that this does not cause undesirable re-entrancy in your code. Ненужно использовать никаких влагов выхода, это все уже есть в QProgressDialog. Смотрите пример в ассистанте: Код
Название: Re: Кнопка прерывания выполнения куска кода под Linux Отправлено: slvno от Январь 19, 2009, 13:23 А что делать для случая:
setValue(i); wasCanceled() Тут большой промежуток по времени что-то ожидается и GUI виснет setValue(i); wasCanceled() |