Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум на CrossPlatform.RU _ Qt GUI _ Как запретить модальному диалогу растягиваться ?

Автор: flankerr 27.2.2009, 18:47

Как запретить диалогу изменять вертикальный размер но оставить возмоджность менять горизонтальный размер ???
Код создания диалога:

QDialog* pDlg = new QDialog(this);
pDlg->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed);

    QLabel* pLabel = new QLabel;
    QLineEdit* pLineEdit = new QLineEdit;
    
    QHBoxLayout* pHBL1 = new QHBoxLayout();
    pHBL1->addWidget(pLabel);
    pHBL1->addWidget(pLineEdit);

    QPushButton* pButtonCreate = new QPushButton();
    pButtonCreate->setText(tr("1"));
    QPushButton* pButtonExit = new QPushButton();
    pButtonExit->setText(tr("2"));

    QHBoxLayout* pHBL2 = new QHBoxLayout();
    pHBL2->addWidget(pButtonCreate);
    pHBL2->addWidget(pButtonExit);

    QVBoxLayout* pVBL = new QVBoxLayout();
    pVBL->addLayout(pHBL1);
    pVBL->addLayout(pHBL2);

    pDlg->setLayout(pVBL);
    pDlg->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed);

Автор: Litkevich Yuriy 27.2.2009, 19:34

Нужно задать два размера максимальный и минимальный, например для высоты = 500:

    pDlg->setMinimumSize(QSize(0, 500));
    pDlg->setMaximumSize(QSize(16777215, 500));


Цитата(flankerr @ 27.2.2009, 21:47) *
pDlg->setSizePolicy
зачем ты два раза вызываешь этот метод?

Автор: lucifer_vrn 28.2.2009, 10:17

согласен, что sizePolicy тут нафиг не нужен.
а вот метод установки фиксированного размера, не айс.
куда проще заюзать
void QWidget::setFixedWidth ( int w )
если прям в конструкторе диалога или после создания, но до отображения, чтоб он сам прочситал свой оптимальный размер и зафиксил его, то можно так:

QDialog* pDlg = new QDialog(this);
pDlg->show()
pDlg->setFixedWidth( pDlg->width )

Автор: flankerr 28.2.2009, 11:05

Цитата(Litkevich Yuriy @ 27.2.2009, 19:34) *
Нужно задать два размера максимальный и минимальный, например для высоты = 500:
    pDlg->setMinimumSize(QSize(0, 500));
pDlg->setMaximumSize(QSize(16777215, 500));
Размер диалога НЕ известен и должен автоматом ставиться в зависимости от содеожания.
Цитата
Цитата(flankerr @ 27.2.2009, 21:47) *
pDlg->setSizePolicy
зачем ты два раза вызываешь этот метод?
это я уже в "бубны" стучал :rolleyes:
Цитата(lucifer_vrn @ 28.2.2009, 10:17) *
QDialog* pDlg = new QDialog(this);
pDlg->show()
pDlg->setFixedWidth( pDlg->width )
Это всё конечно замечатльно, только вот мне нужен не show() а exec() ;)

пока сделал так:
pDlg->show();
pDlg->setFixedHeight(pDlg->height());
pDlg->close();
pDlg->exec();
для маленького диалога сгодиться, а вот на большом возможно будет заметно что диалог открылся закрылся и снова открылся...

Автор: kwisp 28.2.2009, 11:18

Цитата(flankerr @ 28.2.2009, 11:05) *
pDlg->show();
pDlg->setFixedHeight(pDlg->height());
pDlg->close();
pDlg->exec();

как то некрасиво.

Цитата(flankerr @ 28.2.2009, 11:05) *
Это всё конечно замечатльно, только вот мне нужен не show() а exec() ;)


1. это чем же exec() настолько лучше show()?
2. попробуй переопределить QDialog::showevent() и там устанавливать размер, раз тебе так необходим exec().

на худой конец тут тема на форуме была что то типа "определение размеров окна до его показа"....

Автор: flankerr 28.2.2009, 11:36

Цитата(kwisp @ 28.2.2009, 11:18) *
Цитата(flankerr @ 28.2.2009, 11:05) *
pDlg->show();
pDlg->setFixedHeight(pDlg->height());
pDlg->close();
pDlg->exec();

как то некрасиво.

согласен и готов выслушать более удачные варианты.

Цитата
Цитата(flankerr @ 28.2.2009, 11:05) *
Это всё конечно замечатльно, только вот мне нужен не show() а exec() ;)

1. это чем же exec() настолько лучше show()?

Не лучше и не хуже просто РАЗНЫЙ способ вывода диалога.
Если на пальцах то в случае exec() выполнение функции прерывается до закрытия диалога (т.е. диалог модальный) в случае show() выполение функции в которой был вызван диалог продолжается т.е диалог не модальный.


Цитата
2. попробуй переопределить QDialog::showevent() и там устанавливать размер, раз тебе так необходим exec().

Совершенно верно и это отлично сработает. Только вот городить класс-наследник ради диалога в одну строчку это ещё более не красиво чем предложенное мной решение ;)

Цитата
на худой конец тут тема на форуме была что то типа "определение размеров окна до его показа"....

там вроде как раз и обсуждалось переопределение QDialog::showevent()

Автор: kwisp 28.2.2009, 11:46

Цитата(flankerr @ 28.2.2009, 11:36) *
Не лучше и не хуже просто РАЗНЫЙ способ вывода диалога.
Если на пальцах то в случае exec() выполнение функции прерывается до закрытия диалога (т.е. диалог модальный) в случае show() выполение функции в которой был вызван диалог продолжается т.е диалог не модальный.

:)
модальный это если пока не закроешь не получишь фокус другого окна(и вообще оно(другое окно) события принимать от пользовател не должно) а не то что написано выше(что мол ехес() модальный а show() не модальный). для модальности флаги специальный любому виджету имеющему окно можно модальность назанчить...вполне возможно диалог модален по умолчанию.
и потом даже если ты не хочешь городить класс наследник(что помоему нормально целиком и полностью) и хочешь к примеру чтоб программа ожидала результата диалога можешь использовать ожидание в конце концов...но это вопрос задачи уже - неизвестно для чего тебе это.
show()
setFixedHeight()
ожидание закрытия диалога.

Автор: flankerr 28.2.2009, 11:54

Цитата(kwisp @ 28.2.2009, 11:46) *
Цитата(flankerr @ 28.2.2009, 11:36) *
Не лучше и не хуже просто РАЗНЫЙ способ вывода диалога.
Если на пальцах то в случае exec() выполнение функции прерывается до закрытия диалога (т.е. диалог модальный) в случае show() выполение функции в которой был вызван диалог продолжается т.е диалог не модальный.

:)
show()
setFixedHeight()
ожидание закрытия диалога.

читай доки

Автор: kwisp 28.2.2009, 12:00

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

Автор: flankerr 28.2.2009, 12:08

Цитата(kwisp @ 28.2.2009, 12:00) *
flankerr, удостойте меня пожалуйста более развернутым ответом, а то доки большие все не прочесть и за неделю, может где то я не прав так поправьте смелее...

Так я сразу написал подробно. Вот выдержка из Qt Assistant
Цитата
int QDialog::exec () [slot]
Shows the dialog as a modal dialog, blocking until the user closes it. The function returns a DialogCode result.

Автор: kwisp 28.2.2009, 12:16

flankerr,
если посмотреть свойство modal в доке по диалогу.

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

dialog->setModal(true);
dialog->show();
dialog->setFixedHeight(100);
while(dialog->isVisible()) qWait(250);

Автор: Litkevich Yuriy 28.2.2009, 12:32

kwisp, flankerr, правильно говорит, насчет модальности не модальности.

Автор: kwisp 28.2.2009, 12:37

Цитата(Litkevich Yuriy @ 28.2.2009, 12:32) *
kwisp, flankerr, правильно говорит, насчет модальности не модальности.

т.е. exec() - модальный
show() - не модальный
???

Автор: Litkevich Yuriy 28.2.2009, 12:41

flankerr, еслиб тебе полностью надобыло сделать фиксированный размер (и ширину и высоту), то достаточно было бы сделать так:

pVBL->setSizeConstraint(QLayout::SetFixedSize);
т.е. для главного компоновщика
покопайся в этом направлении, может только один размер можно задать

Цитата(kwisp @ 28.2.2009, 15:37) *
т.е. exec() - модальный
show() - не модальный
???
да и только для QDialog, не QWidget

Автор: kwisp 28.2.2009, 12:51

Litkevich Yuriy,
я всегда думал что за это отвечает
void setModal ( bool modal );

господа разъясните пожалуйста что мешает сделать диалог модальным и воспользоваться show()???

Автор: flankerr 28.2.2009, 12:56

kwisp,

while(dialog->isVisible()) qWait(250);

это называется "красивым" решением ? :blink:

Цитата(Litkevich Yuriy @ 28.2.2009, 12:41) *
flankerr, еслиб тебе полностью надобыло сделать фиксированный размер (и ширину и высоту), то достаточно было бы сделать так:
pVBL->setSizeConstraint(QLayout::SetFixedSize);
т.е. для главного компоновщика
покопайся в этом направлении, может только один размер можно задать

да я сразу начал копать в сторону QLayout тока пока не нашёл как сделать фиксированнм только одно направление.

кстати еслибы не QLayout то решение было бы простым
вызов hide() просчитал бы все размеры элементов без вывода диалога на экран.

Автор: kwisp 28.2.2009, 12:59

flankerr,
я же написал

Цитата(kwisp @ 28.2.2009, 12:16) *
если не хочешь наследоваться по своим причинам и тебе важно свойство модальности и что бы функция прерывалась на время показа диалога то можешь попробовать сделать так.


если не хочешь чтобы функция прерывалась не пиши последнюю строчку...

я попробую объясниться на счет модальности
Цитата
By default, this property is false and show() pops up the dialog as modeless. Setting his property to true is equivalent to setting QWidget::windowModality to Qt::ApplicationModal.
exec() ignores the value of this property and always pops up the dialog as modal.


видите By default, по-моему здесь ключевое слово.
хочешь модальный диалог ничего не мешает тебе использовать show(); а зацикливаться на том что
Цитата
т.е. exec() - модальный
show() - не модальный

не верно помоему.

далее, елсли flankerr, намерен все равно использовать exec() и не переопределять showEvent() я пока не вижу методов решения задачи...
хотя это я поторопился....

Автор: flankerr 28.2.2009, 13:07

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

Цитата
что мешает сделать диалог модальным и воспользоваться show()???

модальный диалог крутиться в своём отдельном потоке. Для запуска отдельного потока вызввается exec();
на счёт setModel
Диалог может быть не модальным и работаь в отдельном потке, однако он НЕ может быть модальным и работать в потоке который его вызвал.

Автор: kwisp 28.2.2009, 13:24

Цитата(flankerr @ 28.2.2009, 13:07) *
однако он НЕ может быть модальным и работать в потоке который его вызвал


интересно и странно. а откуда такая информация???
а что же тогда делает последовательность
setModal(1);
show();
???

Цитата(flankerr @ 28.2.2009, 13:07) *
модальность в данном случае обязательна т.к. это диалог задаёт вопрос пользователю и даельнейшее выполнеие функции в частности и программы вообще возможно только после получания ответа от пользователя.

не уж то нельзя никак это обойтись без запуска отдельного потока как утверждается....
повесить ответ пользователя на результат диалога ничего не мешает. пользоваться setModal() тоже ....

Автор: flankerr 28.2.2009, 13:32

kwisp,

iResult = pDlg->exec()
if(iResilt)
{
}
else
{
}

1.Как ты себе представляешь выполнение кода без знания значения iResult , тогда как iResult будет известнен ТОЛЬКО после закрытия диалога?
2.Как ты себе представляешь выполнения кода внутри диалога если поток выполнения остановлен (см п.1)

Автор: kwisp 28.2.2009, 13:39

1. можно вынести в отдельную функцию которая будет вызываться по закрытию диалога. можно слот на finished(int) повесить..
2. не понял вопроса извини.

....
connect(dialog,SIGNAL(finished(int)),this,SLOT(dFinished(int)));
dialog->setModal(true);
dialog->show();
dialog->setFixedHeight();
}// выход в основной цикл обработки событий....
//далее обработка результата в слоте dFinished(int)

да вариантов куча. я не пойму зачем именно тебе отдельнгый поток с диалогом? хоть убей не пойму...

Автор: flankerr 28.2.2009, 13:52

kwisp
Кажется теперь я не много погоричился... setModel делает диалог модальным внтури потока который создал диалог
Однако решение с добавлением ещё одной функции и завязки на события мне кажется более сложным и "не красивым" чем моё и чем даже твой вариант с циклом.

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

Автор: kwisp 28.2.2009, 13:54

Цитата(flankerr @ 28.2.2009, 13:52) *
Кажется теперь я не много погоричился... setModel делает диалог модальным внтури потока который создал диалог

ура!!!!!!!!!
ты уверен???
проверь еще раз пожалуйста???
может все таки нет???

;)

Автор: flankerr 28.2.2009, 14:00

kwisp, да на счёт setModal попутал.
но всё равно городиьт огород с событиями и отдельной функцией в данном случае лишние

Автор: kwisp 28.2.2009, 14:09

flankerr,
честно говоря я бы уже переопределил диалог и его showEvent() и не мучался бы ....

если бы был сигнал о появлении окна на переднем плане можно было бы отследить его(появление) и повесить на слот владельца диалога в котором написать setFixedHeight()....

Автор: flankerr 28.2.2009, 14:16

kwisp, так я сразу сделал как написал с открытием\закрытием меня это устраивает но на будущие интересно найти решение, если оно вообще есть.
Хотя дл маленьикх диалогов сойдёт моё решение а для больших как правило всё ранво создаёться класс-наследник и там уже всё просто.

Автор: Litkevich Yuriy 28.2.2009, 14:22

Давайте модальность QDialog в отдельной теме обсуждать.

Автор: kwisp 28.2.2009, 14:22

Litkevich Yuriy,
с позднячком:). обсудили уже, просто разделить надо.

Автор: Litkevich Yuriy 28.2.2009, 14:34

Цитата(kwisp @ 28.2.2009, 17:22) *
просто разделить надо.
просто нечем, пост начасти поделить нельзя (инструмента такого нет). А пользователей плохая привычка все в кучу смешать.

Автор: kwisp 28.2.2009, 14:36

Цитата
А пользователей плохая привычка все в кучу смешать.

Litkevich Yuriy,
простите уважаемый...
а название темы можно сменить??? или изменить
"Как запретить модальному диалогу растягиваться ?"

Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)