Russian Qt Forum
Ноябрь 22, 2024, 23:26 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Как принудительно пересчитать sizeHint  (Прочитано 5199 раз)
Sasha
Гость
« : Январь 20, 2016, 17:30 »

Здравствуйте,
Есть форма у которой несколько вложенных фреймов и где-то внутри есть QLabel у которого wordWrap=true.
Далее в конструкторе после ui->setupUi(this); я пытаюсь посчитать размер всей формы в 2-х вариантах - когда wordWrap=true и wordWrap=false. Делаю я это кодом:
Код
C++ (Qt)
 
QSize sz1 = ui->frame->sizeHint();
ui->labelInfo->setWordWrap(false);
// ???
QSize sz2 = ui->frame->sizeHint();
 
Но оказывается, что sz1 = sz2. что нужно вставить перед 2-м sizeHint-ом, чтобы sz2 получился неравным sz1? Я пробовал:
Код
C++ (Qt)
ui->frame->update();
ui->frame->layout()->invalidate();
ui->frame->updateGeometry();
 
Ничего не помогло. Дабы убедиться, что они всё-же разные и зависят от wordWrap, я закоментарил получение sz1, т.е. посчитал только sz2 после сброса wordWrap-а и он оказался другим.
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #1 : Январь 20, 2016, 17:57 »

попробуй
Код
C++ (Qt)
ui->frame->adjustSize();
QSize sz2 = ui->frame->sizeHint();
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Sasha
Гость
« Ответ #2 : Январь 20, 2016, 18:24 »

Не помогло

Кстати, если зайти внутрь adjustSize-а, то там почти сразу вызывается sizeHint(), который как раз и нужен. Перед ним только ensurePolished(), но видимо он тоже не инвалидэйтит всё.
« Последнее редактирование: Январь 20, 2016, 18:31 от Sasha » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #3 : Январь 21, 2016, 04:02 »

Да, мутное место, тоже неск раз сталкивался но не нашел четкого решения, каждый раз "методом втыка". Попробуйте
Код
C++ (Qt)
ui->frame->layout()->activate();
Но layout должен быть именно тем где сидит QLabel. Не поможет - выкладывайте тестовый проект (в zip)
Записан
Sasha
Гость
« Ответ #4 : Январь 21, 2016, 12:17 »

Если я Вас правильно понял, то если иерархия такая:
frame
 -> frame2
 --->label
то нужно вызывать frame2->layout()->activate();
Если так, то я так сделал и тоже не помогло. Собственно, я попробовал и для frame и тоже не помогло.

Чуть попозже попробую сделать маленький пример и выложить.
Записан
Sasha
Гость
« Ответ #5 : Январь 21, 2016, 13:47 »

Создал я тестовый проект под VisualStudio2010 - он в прикреплённом файле. Там в файле sizehint.cpp в конструкторе sizeHint::sizeHint() sizeHint берётся 2 раза строчками QSize sz2 = ui.frame->sizeHint(); и QSize sz = ui.frame->sizeHint(); между которыми вначале производятся изменения wordWrap для QLabel-ов и далее разные попытки инвалидэйтить форму с целью добиться чтобы sz не равнялся sz2. Там же есть и рабочий вариант с ф-ей влоб инвалидэйтящую всё дерево - QLayout_invalidateTree().
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Январь 21, 2016, 16:26 »

Вроде так работает (Qt 5.4.2)
Код
C++ (Qt)
void RecalcParentLayouts( QWidget * w )
{
while (w) {
w = w->parentWidget();
if (w && w->layout())
w->layout()->activate();
}
}
...
RecalcParentLayouts(ui.labelInfo1);
RecalcParentLayouts(ui.labelInfo2);
 
Записан
Sasha
Гость
« Ответ #7 : Январь 21, 2016, 17:16 »

Да, работает, спасибо.
На всякий случай приведу здесь и своё решение, которое инвалидэйтит всю иерархию. Может кому-то понадобится
Когда чётко известно, что поменялось и поменялось не много, то Ваше решение конечно будет оптимальнее.

Код
C++ (Qt)
void QLayout_invalidateTree     ( QLayout *pl );
void QWidget_invalidateTree     ( QWidget *p );
void QLayoutItem_invalidateTree ( QLayoutItem *pli );
 
void QLayoutItem_invalidateTree( QLayoutItem *pli )
{
   if( pli==NULL )return;
 
   if( pli->widget()!=NULL )
       QWidget_invalidateTree( pli->widget() );
   else
   if( pli->layout()!=NULL )
       QLayout_invalidateTree( pli->layout() );
}
void QLayout_invalidateTree( QLayout *pl )
{
   if( pl==NULL )return;
 
   pl->invalidate();
   for( int i=0,n=pl->count(); i<n; i++ )
        QLayoutItem_invalidateTree( pl->itemAt(i) );
}
void QWidget_invalidateTree( QWidget *p )
{
   if( p!=NULL )
       p->updateGeometry(), QLayout_invalidateTree( p->layout() );
}
 
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 3.252 секунд. Запросов: 23.