Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: andi от Ноябрь 02, 2007, 09:46



Название: Действия при выполнении формы.
Отправлено: andi от Ноябрь 02, 2007, 09:46
Есть экземпляр типа QDialog.
На экран мы его вызываем так:
int rez = testform1->exec(); // исполнить форму
Она нормально отрисовывается и все такое.
Теперь вопрос:
Очень хочется что бы после этого вызова, в форме запустилась моя функция (метод, не важно приватный или публичный), которая выполнила какие либо действия. Желательно после полной отрисовки формы.
Перерыл асистент, но ничего простого и понятного не нашел.
Буду благодарен за любые подсказки.


Название: Re: Действия при выполнении формы.
Отправлено: Sergey B. от Ноябрь 02, 2007, 09:53
А что думает конструктор класса?


Название: Re: Действия при выполнении формы.
Отправлено: Kainit от Ноябрь 02, 2007, 09:57
В принципе, люди говорят что ООП - здорово.

Код:
QMyDialog : public QDialog
{
    public:
        QMyDialog ( QWidget * parent = 0, Qt::WindowFlags f = 0 ) :  QDialog ( parent,  f )        {}


        virtual void showEvent ( QShowEvent * event )
        {
        // выполняй всё что хочешь
        }
};

void main(void)
{
    QMyDialog *myDialog = new QMyDialog();
    myDialog->exec();
}


Название: Re: Действия при выполнении формы.
Отправлено: ритт от Ноябрь 02, 2007, 09:57
Очень хочется что бы после этого вызова, в форме запустилась моя функция

значит, "форма" - наследник кудиалога? ну и перегрузи экзек и запускай метод из экзека...


Название: Re: Действия при выполнении формы.
Отправлено: andi от Ноябрь 02, 2007, 10:03
Не совсем понял вопрос.
Причем тут конструктор класса?
Конструктор вызывает где-то однажды. И после этого форма спокойно сидит в памяти.
А когда мне надо (точней когда юзеру взбредет ткнуть в кнопку) я вызываю форму и она тут как тут.
Но после того как она уже выскочила, мне нужно на глазах ошарашенного появлением формы пользователя, сделать красивое изменение размеров элементов формы (в зависимости от неких скрытых параметров).
Чтобы юзер слюнями залил место на котором должна стоять клавиатура (ее там нет конечно, сенсорные панели рулят!).

Пока писал, народ уже ответил.
Уже есть 2 варианта: перегруз exec и showEvent.
Вариант с перегрузом exec промелькивал в голове, но не уверен, что к моменту выполнения мой функции, все отрисуется.
Тоже самое с showEvent... он вызывается, после всей отрисовки или в момент появления желания отрисоваться?


Название: Re: Действия при выполнении формы.
Отправлено: Kainit от Ноябрь 02, 2007, 10:12
andi, вы прекрасно понимаете что всё работает на ивентах. Никто вам не скажет точно когда всё отрисовалось, а когда нет. Можете попробовать сделать QTimer::singleShot(200, this, SLOT(doSomething()));, но всё равно, никогда вы не подберёте значение задержки, которое будет достаточным для отрисовки всего на произвольной машине.

Лично мой выбор - showEvent


Название: Re: Действия при выполнении формы.
Отправлено: Barmaglodd от Ноябрь 02, 2007, 11:32
Если хочется извращений:
testform1->show();
testform1->DoSomething(); ///Тут мы делаем наши магические пассы с формой
testform1->setModal(true);
Можно это методом класса вашего диалога сделать.

А вообще перегрузка showEvent намного более правильный вариант. Перегрузка exec() полумера, т.к. надо будет еще setVisible() перегружать.

А вообще help рулит:
If you need to change some settings before a widget is shown, use showEvent() instead. If you need to do some delayed initialization use the Polish event delivered to the event() function.
Вкратце: либо перегрузка showEvent, либо обрабатываем событие Polish в функции event().


Название: Re: Действия при выполнении формы.
Отправлено: Dodge от Ноябрь 02, 2007, 14:19
andi, вы прекрасно понимаете что всё работает на ивентах. Никто вам не скажет точно когда всё отрисовалось, а когда нет. Можете попробовать сделать QTimer::singleShot(200, this, SLOT(doSomething()));, но всё равно, никогда вы не подберёте значение задержки, которое будет достаточным для отрисовки всего на произвольной машине.

Лично мой выбор - showEvent
Да ладна?
перегружаем paintEvent, в нем вызываем родительский paintEvent а после него пишем свой "полезный" код:
Код:
class MyDialog : public QDialog {
    void paintEvent( QPaintEvent * event ) {
        QDialog::paintEvent( event );
        ....
    }
};
Если хотим чтобы изображение формы из буферо попало на экран(перед выполнением своего кода), можно поставить QApplication::processEvents() после отрисовки, но это не совсем грамотно, так как это может привести к рекурсии. Впринципе и это можно обойти, при помощи небольшого костыля состоящего из статика и мутекса.
Вопросы?


З.Ы.
то Аффтар:
1. В Qt все что видно на дисплее принято называть - Widget( виджет ). Не надо вспоминать си++ билдер.
2. "Форма" не может быть выполнена(жуткая фраза - "выполненная форма").
3. Функции могут быть в классе, в глобл спайсе... но не как не в "Форме" и тем более на ней ;D

Давайте хотябы вопрсы формулировать правильно.


Название: Re: Действия при выполнении формы.
Отправлено: QCasper от Ноябрь 02, 2007, 14:57
В данном случае paintEvent не уместный, на мой взгляд, вариант, ибо doSomething будет выполняться при каждом чихе на это окно, и пользователь будет уже не "заливать слюнями то место, где должна быть клавиатура", а просто плеваться на эту программу, высказывая в адрес разработчика на редкость разнообразные фразы, в основном не литературного характера.


Название: Re: Действия при выполнении формы.
Отправлено: ритт от Ноябрь 02, 2007, 15:28
додж, +1

я плакаю :)


Название: Re: Действия при выполнении формы.
Отправлено: Dodge от Ноябрь 02, 2007, 15:43
В данном случае paintEvent не уместный, на мой взгляд, вариант, ибо doSomething будет выполняться при каждом чихе на это окно, и пользователь будет уже не "заливать слюнями то место, где должна быть клавиатура", а просто плеваться на эту программу, высказывая в адрес разработчика на редкость разнообразные фразы, в основном не литературного характера.
Ну если программу пишет действительно программист, то он догадается внести в exec флаг, который будет проверятццо в паинт эвенте, яж не буду за человека весь алгоритм продумывать, нада самому тож думать... я просто предложил вариант решения проблемы. А как он там будет это реализовывать, это уже его велосипед  ;D


Название: Re: Действия при выполнении формы.
Отправлено: Dodge от Ноябрь 02, 2007, 16:03
Перерыл асистент, но ничего простого и понятного не нашел.
Буду благодарен за любые подсказки.

Асистент на англицком... так на всякий случай.

Вообще, можно поинтересоваццо, зачем такая барикада нужна?... зачем вызывать функцию именно после отрисовки диалога?

Вот не потеме щас напишу:
На мой взгляд, самая простая для понимания и удобная архитектура приложения(покрайнеймере с точки зрения разработчика) - микромодульная.
Если правильно следовать принципам данной архитектуры, то вот таких ситуаций как у аффтора быть не должно впринципе. Это не пустые слова, есть яркий пример ГРАМОТНОГО использования данной архитектуры - ядро линукс.
Я это к чему, перед тем как что-то писать, нужно сначало продумать структуру приложения, учесть все тонкие места, постораццо предусмотреть возможные последующие изменения, может даже воткнуть коегде "пустышки"(пустые функции, например в интерфейсных классах). Возможно конечный код будет не так быстро работать как хочется, возможно это займет больше времени и сил, но результат поверьте, оправдывает жертвы. Когда к вам придет заказчик и скажет, мол - "А можно вот сюда кнопку воткнуть... Красивую!", вы с уверенностью и гордостью скажите - "Да без проблем начальнег, щаз усе арганизуим"...

Есть над чем задумаццо правда? ;D


Название: Re: Действия при выполнении формы.
Отправлено: QCasper от Ноябрь 02, 2007, 16:06
Ну если программу пишет действительно программист, то он догадается внести в exec флаг, который будет проверятццо в паинт эвенте

Это уже костыль, showEvent здесь наиболее приемлемый вариант.


Название: Re: Действия при выполнении формы.
Отправлено: Dodge от Ноябрь 02, 2007, 16:18
Ну если программу пишет действительно программист, то он догадается внести в exec флаг, который будет проверятццо в паинт эвенте

Это уже костыль, showEvent здесь наиболее приемлемый вариант.
Ух... я не настаиваю на своем варианте, но могу точно сказать что мой костыль не более костыльный вашего, т.к. этот самый showEvent вызывается еще и при ресторинге окна, и как вы писали выше,  юзверь чтото зальет слюнями... или както так... короче без флагов тут тоже не обойтись...
Вопрос на засыпку: у кого костыль костыльнее? :)


Название: Re: Действия при выполнении формы.
Отправлено: QCasper от Ноябрь 02, 2007, 16:36
Вопрос на засыпку: у кого костыль костыльнее? :)

Да тут и нечего засыпать, showEvent вызывается гораздо реже paintEvent'a (а именно при показе и, как Вы сами заметили, при ресторинге), стало быть слюновыделяющие навороты будут выполняться тоже гораздо реже, и соответственно раздражать пользователя тоже гораздо реже.


Название: Re: Действия при выполнении формы.
Отправлено: Alex03 от Ноябрь 02, 2007, 16:42
Автору вопроса топика - ИМХО в конструкторе диалога:
QTimer::singleShot(0, this, SLOT(doSomething()))
или
QApplication::postEvent(this,.....)

Первый вариант намного проще.
A QTimer with a timeout interval of 0 will time out as soon as all the events in the window system's event queue have been processed.


Название: Re: Действия при выполнении формы.
Отправлено: ритт от Ноябрь 02, 2007, 17:19
а если слюни нужны вообще только один раз - в самые первые секунды/минуты отображения диалога? например, строим кэш...

чего вы прям баталию устроили? какой ивент ни выбери, всё-равно должен быть флажок (например, "уже отработали - иди дальше")

и, если слюноотделяющий метод должен вызываться лишь единожды, я бы перегрузил экзек вместо ивентлистнера :)


Название: Re: Действия при выполнении формы.
Отправлено: ритт от Ноябрь 02, 2007, 17:20
б**дь...я - птица говорун :(


Название: Re: Действия при выполнении формы.
Отправлено: Dodge от Ноябрь 03, 2007, 00:31
Вопрос на засыпку: у кого костыль костыльнее? :)

Да тут и нечего засыпать, showEvent вызывается гораздо реже paintEvent'a (а именно при показе и, как Вы сами заметили, при ресторинге), стало быть слюновыделяющие навороты будут выполняться тоже гораздо реже, и соответственно раздражать пользователя тоже гораздо реже.
Это бесспорно, но у меня еще есть аргументы... если делать doSomething сразу после отрисовки, то это гарантирует что "форма"(прости меня Линус Торвальд) уже отрисована и ничего больше не произошло, в showEvent "форма" тоже уже отрисована, но эвент происходит не сразу после отрисовки...
Вообще спор не о чем, тк ситуация простите идиоццкая, если надо чтото сграбить с "формы"(мне это слово уже начинает нравиццо), то на мой взгляд следить за ее показом совсем не обязательно, а если надо чтото сделать после отображения, то это:
Код:
class MyWidget : public QDialog {
    void exec(...) {
        QDialog::exec(...);
        doSomething();
    }
я прав?


Название: Re: Действия при выполнении формы.
Отправлено: Racheengel от Ноябрь 06, 2007, 01:58
А может, устроим конкурс - кто придумает самый извращенный способ?
Типа там - стартануть второй процесс, отловить момент появления формы, захватить гуй-поток, выполнить отрисовку, застрелиться...