Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: irus4 от Октябрь 11, 2012, 17:29



Название: Неблокирующее всплывающее окно
Отправлено: irus4 от Октябрь 11, 2012, 17:29
Дайте совет...

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

Заранее большое спасибо...


Название: Re: Неблокирующее всплывающее окно
Отправлено: GreatSnake от Октябрь 11, 2012, 17:31
Вместо exec() используй show().


Название: Re: Неблокирующее всплывающее окно
Отправлено: irus4 от Октябрь 11, 2012, 17:34
Так ведь если я вызову show() окно не отобразиться...

    QDialog dial;
    dial.setWindowTitle("Test");
    dial.show(); // окно не появилось, а нужно чтобы появилось

    QDialog dial2;
    dial2.setWindowTitle("Test");
    dial2.exec(); // окно появилось и все заблокировалось


Название: Re: Неблокирующее всплывающее окно
Отправлено: GreatSnake от Октябрь 11, 2012, 17:45
    dial.show(); // окно не появилось, а нужно чтобы появилось
Должно появиться.
Какая платформа, WindowManager?


Название: Re: Неблокирующее всплывающее окно
Отправлено: mutineer от Октябрь 11, 2012, 17:47
Так ведь если я вызову show() окно не отобразиться...

    QDialog dial;
    dial.setWindowTitle("Test");
    dial.show(); // окно не появилось, а нужно чтобы появилось

    QDialog dial2;
    dial2.setWindowTitle("Test");
    dial2.exec(); // окно появилось и все заблокировалось


dial, случаем, не уничтожается после вызова show?


Название: Re: Неблокирующее всплывающее окно
Отправлено: irus4 от Октябрь 11, 2012, 17:50
Тестирую в ubuntu

int main(int argc, char** argv)
{
    QApplication app(argc, argv);

    QDialog dial;
    dial.setWindowTitle("Test");
    dial.show();
  
    //тут некий код. к этому моменту диалог уже должен появиться(но не появляется). обращаю внимания что цикл обработки "exec()" я еще не вызвал, т.к. он блокирующей, а мне это не нужно

}


Название: Re: Неблокирующее всплывающее окно
Отправлено: GreatSnake от Октябрь 11, 2012, 17:51
dial, случаем, не уничтожается после вызова show?
Точно, наверняка на стеке всё создано. А я тут про WM...


Название: Re: Неблокирующее всплывающее окно
Отправлено: mutineer от Октябрь 11, 2012, 17:52
Тестирую в ubuntu

int main(int argc, char** argv)
{
    QApplication app(argc, argv);

    QDialog dial;
    dial.setWindowTitle("Test");
    dial.show();
  
    //тут некий код. к этому моменту диалог уже должен появиться(но не появляется). обращаю внимания что цикл обработки "exec()" я еще не вызвал, т.к. он блокирующей, а мне это не нужно

}

Не появится диалог к этому моменту, так как появится он только при попадании управления в exec()


Название: Re: Неблокирующее всплывающее окно
Отправлено: GreatSnake от Октябрь 11, 2012, 17:53
2 irus4
Где на выходе
Код
C++ (Qt)
return app.exec();


Название: Re: Неблокирующее всплывающее окно
Отправлено: irus4 от Октябрь 11, 2012, 17:55
Exec блокирует. мне нужно без него... Т.к. между app.exec() и dial.show() есть код, который долго выполняется... Мб есть какой нить метод, который показывает окно и отдает управление в главный поток?


Название: Re: Неблокирующее всплывающее окно
Отправлено: irus4 от Октябрь 11, 2012, 17:56
Пытался сделать через QApplication::processEvents, но он не полностью прорисовывает окно, а только рамку(без кнопок и т.д.)


Название: Re: Неблокирующее всплывающее окно
Отправлено: mutineer от Октябрь 11, 2012, 17:58
Чтобы показать окно нужен exec(). Полюбому. Переделывай логику, перемещай свой долгий код в другое место


Название: Re: Неблокирующее всплывающее окно
Отправлено: irus4 от Октябрь 11, 2012, 17:59
Да тут задача так стоит... Есть код под arm на железяку, раньше использовалась другая gui либа, решили перейти на qt малой кровью а тут такое... Если будет идея, дайте знать.. Всем еще раз спасибо!


Название: Re: Неблокирующее всплывающее окно
Отправлено: mutineer от Октябрь 11, 2012, 18:00
Да тут задача так стоит... Есть код под arm на железяку, раньше использовалась другая gui либа, решили перейти на qt малой кровью а тут такое... Если будет идея, дайте знать.. Всем еще раз спасибо!

Какая еще идея? Непонятно что тебе надо сделать же


Название: Re: Неблокирующее всплывающее окно
Отправлено: irus4 от Октябрь 11, 2012, 18:12
Окай)

Нужно отображать экран не блокируя само приложение. Например, вызов show() отображает окно и выполняется код, расположенный ниже. Сейчас такое реализовать не могу, т.к. без вызова exec() ничего не появляется...


Название: Re: Неблокирующее всплывающее окно
Отправлено: alex312 от Октябрь 11, 2012, 19:08
Да тут задача так стоит... Есть код под arm на железяку, раньше использовалась другая gui либа, решили перейти на qt малой кровью а тут такое... Если будет идея, дайте знать.. Всем еще раз спасибо!
а мне вот интерестно, какая такая GUI либа может отобразить окошко без попадания в цикл обработки сообщений?
Ну и поделу : вынеси свой долгий код в другой поток.


Название: Re: Неблокирующее всплывающее окно
Отправлено: moskk от Октябрь 11, 2012, 20:01
попробуйте после show ещё repaint вызвать для окна. у меня было что-то похожее.

upd: да, один в один ситуация была. окошко типа "Пожалуйста, подождите", неблокирующее и поверх всех:
Код
C++ (Qt)
void WaitingStateDialog::start()
{
   m_ElapsedTime.restart();
   m_Timer.start();
 
   // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
   setWindowModality(Qt::ApplicationModal);
   show();
   repaint();
 
   // исходный вариант
   //exec();
}


Название: Re: Неблокирующее всплывающее окно
Отправлено: irus4 от Октябрь 11, 2012, 23:42
а мне вот интерестно, какая такая GUI либа может отобразить окошко без попадания в цикл обработки сообщений?
Ну и поделу : вынеси свой долгий код в другой поток.

Либа обрабатывала запросы в дочернем потоке, с qt нельзя такое сделать, т.к. обработка Gui должна находиться в главном потоке...

попробуйте после show ещё repaint вызвать для окна. у меня было что-то похожее.

upd: да, один в один ситуация была. окошко типа "Пожалуйста, подождите", неблокирующее и поверх всех:
Код
C++ (Qt)
void WaitingStateDialog::start()
{
   m_ElapsedTime.restart();
   m_Timer.start();
 
   // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
   setWindowModality(Qt::ApplicationModal);
   show();
   repaint();
 
   // исходный вариант
   //exec();
}

Проверил с repaint() - окно все равно не появляется  :-\
Код:
int main(int argv, char **argc)
{
    QApplication app(argv, argc);

    QDialog le;
    le.show();
    le.repaint();
    sleep(5); // тут окна еще не видно

    return app.exec(); // тут уже видно
}


Название: Re: Неблокирующее всплывающее окно
Отправлено: mutineer от Октябрь 12, 2012, 00:07
а мне вот интерестно, какая такая GUI либа может отобразить окошко без попадания в цикл обработки сообщений?
Ну и поделу : вынеси свой долгий код в другой поток.

Либа обрабатывала запросы в дочернем потоке, с qt нельзя такое сделать, т.к. обработка Gui должна находиться в главном потоке...

Так пусть гуй работает себе в основном потоке, а код рабочий вынеси в отдельный поток


Название: Re: Неблокирующее всплывающее окно
Отправлено: FalconHAM от Октябрь 12, 2012, 09:04
Цитировать
с qt нельзя такое сделать, т.к. обработка Gui должна находиться в главном потоке...
Кто сказал?
Например как то так в трэде:
Код:
void DecThread::sPathArc()
{
QDialog dlg;
Ui::pathArcDialog ui;
ui.setupUi(&dlg);
dlg.setFixedSize(dlg.baseSize());

if(dlg.exec() == QDialog::Accepted) {

}
}
Перед экзеком дать сигнал в другой тред на выполнение нудных вычислений.
В этом случае блокируется только главное окно, а события в главном потоке
продолжают обрабатываться.
Да и вообще тут масса решений.
В конце концов замутить с
Цитировать
QMdiSubWindow

ИМХО :)



Название: Re: Неблокирующее всплывающее окно
Отправлено: alex312 от Октябрь 12, 2012, 09:05
а мне вот интерестно, какая такая GUI либа может отобразить окошко без попадания в цикл обработки сообщений?
Ну и поделу : вынеси свой долгий код в другой поток.

Либа обрабатывала запросы в дочернем потоке, с qt нельзя такое сделать, т.к. обработка Gui должна находиться в главном потоке...
Шо за люди !? Я тебя что спрашивал про возможности Qt ? Я тебя спрашивал какую либу использовали до сих пор !
Учись читать.


Название: Re: Неблокирующее всплывающее окно
Отправлено: Igors от Октябрь 12, 2012, 09:47
Пытался сделать через QApplication::processEvents, но он не полностью прорисовывает окно, а только рамку(без кнопок и т.д.)
Правильно пытались, но  QApplication::processEvents надо вызывать постоянно (а не 1 раз). Как эти вызовы вставить в код = Ваши проблемы. Вызов app.exec() необязателен, но объект QApplication должен быть создан.

а мне вот интерестно, какая такая GUI либа может отобразить окошко без попадания в цикл обработки сообщений?
Ну и поделу : вынеси свой долгий код в другой поток.
Это нормальное решение, но оно не единственное. Крутить вторичный eventLoop (с помощью processEvents)  также неплохо, а иногда и лучше


Название: Re: Неблокирующее всплывающее окно
Отправлено: irus4 от Октябрь 12, 2012, 13:37
Пытался сделать через QApplication::processEvents, но он не полностью прорисовывает окно, а только рамку(без кнопок и т.д.)
Правильно пытались, но  QApplication::processEvents надо вызывать постоянно (а не 1 раз). Как эти вызовы вставить в код = Ваши проблемы. Вызов app.exec() необязателен, но объект QApplication должен быть создан.

а мне вот интерестно, какая такая GUI либа может отобразить окошко без попадания в цикл обработки сообщений?
Ну и поделу : вынеси свой долгий код в другой поток.
Это нормальное решение, но оно не единственное. Крутить вторичный eventLoop (с помощью processEvents)  также неплохо, а иногда и лучше

Вызываю processEvents в другом потоке:

Код:
class Thread: public QThread
{
Q_OBJECT

protected:
    void run()
    {
        while(true)
        {
            std::cout<<"process events"<<std::endl;
            QApplication::processEvents();
        }
    }
};

В main запускаю поток и создаю экран:

Код:
int main(int argc, char** argv)
{
    QApplication app(argc, argv);

    Thread thread;
    thread.start();

    QDialog dial;
    dial.setWindowTitle("Test");
    dial.show();
    sleep(15);
}

Жду 15 секунд, экран так и не появился...


Название: Re: Неблокирующее всплывающее окно
Отправлено: GreatSnake от Октябрь 12, 2012, 13:40
Жду 15 секунд, экран так и не появился...
Мде...
А что, разве не видно что после sleep(15); приложение закроется ???
Может стоит чем-нибудь другим заняться?


Название: Re: Неблокирующее всплывающее окно
Отправлено: Igors от Октябрь 12, 2012, 13:46
Вызываю processEvents в другом потоке:
...
Жду 15 секунд, экран так и не появился...
QApplication::processEvents работает "для текущего потока", поэтому конечно не появится  :) Вы сделали "2 техники вместе", это не работает, выберите одну, напр

Код
C++ (Qt)
#include <QtGUI>
 
int main( int argc, char **argv )
{
QApplication app(argc, argv);
QDialog dlg;
QLabel * lab = new QLabel("Test", &dlg);
dlg.show();
 
while (true) {
DoSomething();
QApplication::processEvents();
}
return 0;
}
 
Это ничем не хуже чем "с потоком" (что так усиленно рекомендуют  :))  


Название: Re: Неблокирующее всплывающее окно
Отправлено: irus4 от Октябрь 12, 2012, 13:50
Igors, спасибо большое. Только вот логика не совсем мне подходит, т.к. в DoSomething может выполняться долго и до processEvents код может так и не дойти, а в DoSomething должны создавать различные экраны и т.д.


Название: Re: Неблокирующее всплывающее окно
Отправлено: GreatSnake от Октябрь 12, 2012, 13:51
Мне кажется, что мы здесь все отвечающие просто зря теряем время, ибо ТС понятия не имеет что такое
Событийно-ориентированное программирование (http://ru.wikipedia.org/wiki/%D0%A1%D0%BE%D0%B1%D1%8B%D1%82%D0%B8%D0%B9%D0%BD%D0%BE-%D0%BE%D1%80%D0%B8%D0%B5%D0%BD%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5) :(


Название: Re: Неблокирующее всплывающее окно
Отправлено: Igors от Октябрь 12, 2012, 14:07
Igors, спасибо большое. Только вот логика не совсем мне подходит, т.к. в DoSomething может выполняться долго и до processEvents код может так и не дойти, а в DoSomething должны создавать различные экраны и т.д.
Вы можете заменить весь цикл на 1 вызов DoSomething - тогда Вам надо натыкать processEvents внутрь этой ф-ции так чтобы оно вызывалось достаточно часто (UI не замерзало). Если (наверняка) у Вас больше ф-ций - ну натыкать во все. Ничего страшного в этом нет, все равно отображать "прогресс" придется.

В варианте с потоком этих проблем нет, но зато есть другие - напр Вы не сможете создавать там окна, придется городить сигналы для каждого действия с UI. Смотрите что Вам выгоднее по задаче, ну и теорию почитывайте (иногда  :))