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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: как узнать в каком лаяуте лежит виджет  (Прочитано 5420 раз)
shender
Гость
« : Октябрь 20, 2010, 10:37 »

Собственно вопрос:
Есть маинвиндой с кучай разных лаяутов, в лаяутах виджеты,
есть ли возможность узнать в каком лаяуте лежит виджет?
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #1 : Октябрь 20, 2010, 10:48 »

QLayout * QWidget::layout () const
« Последнее редактирование: Октябрь 20, 2010, 10:51 от GreatSnake » Записан

Qt 5.11/4.8.7 (X11/Win)
shender
Гость
« Ответ #2 : Октябрь 20, 2010, 10:57 »

QLayout * QWidget::layout () const
возвращает лаяут установленный у вызываемого объекта, а необходимо, то в котором вызываемый объект лежит
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #3 : Октябрь 20, 2010, 11:04 »

Цитировать
возвращает лаяут установленный у вызываемого объекта, а необходимо, то в котором вызываемый объект лежит
И в чём разница?
Записан

Qt 5.11/4.8.7 (X11/Win)
Kolobok
Гость
« Ответ #4 : Октябрь 20, 2010, 11:40 »

Вызови layout() у родительского виджета. В чем проблема то?
Записан
shender
Гость
« Ответ #5 : Октябрь 20, 2010, 12:17 »

Вызови layout() у родительского виджета. В чем проблема то?

в том, что layout() у парента возвращает указатель на лаяут установленный через setParent(QLayout*);
А ситуация такая, что в этот самый парент лаяут накидано куча лаяутов, и в те лаяуты виджеты.
-> если я у виджета вызову parentWidhget()->layout(), то он вернет не верный указатель.
paretn->setLayout(l1);
l1->addLayout(l2);
l2->addLayout(l3);
l3->addWidget(w1);
w1->parentWidget()->layoy(); == l1;
а мне необходим указатель на l3;
Записан
Kolobok
Гость
« Ответ #6 : Октябрь 20, 2010, 12:58 »

Тогда можно так

Код:
QWidget *parent = childWidget->parentWidget();
if( parent )
    {
        QList<QLayout *> layoutList = parent->findChildren<QLayout *>();
        foreach( QLayout *l, layoutList )
            if( l->indexOf( childWidget ) > -1 )
                return l;
    }
return 0;
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #7 : Октябрь 20, 2010, 13:15 »

Да, с этим у троллей сложно. Особенно сложно, если пытаешься найти лейаут для виджета из формы созданной в дизайнере.
Я тоже бился и пришлось написать следующее:

Код
C++ (Qt)
#include <QBoxLayout>
#include <QGridLayout>
 
static bool qu_find_widget_layout_( QLayout* li, QWidget* w, QLayout** lay )
{
   if( !li )
       return false;
   if( li->widget() == w )
       return true;
 
   if( QLayout* l = qobject_cast< QLayout* >( li ) )
   {
       int i = 0;
       QLayoutItem *li;
       while( ( li = l->itemAt( i ) ) != 0 )
       {
           ++i;
           if( li->widget() == w || qu_find_widget_layout_( li->layout(), w, lay ) )
           {
               if( *lay == 0 )
                   *lay = l;
               return true;
           }
       }
   }
   return false;
}
 
QLayoutItem* QUFindWidgetLayout( QWidget* w, int* row, int* col )
{
   if( row )
       *row = -1;
   if( col )
       *col = -1;
 
   if( !w )
       return 0;
 
   QWidget* pw = w->parentWidget();
   QLayout* lay = pw->layout();
   if( !lay )
   {
       QList< QLayout* > l = pw->findChildren< QLayout* >();
       if( !l.isEmpty() )
           lay = l.at( 0 );
   }
 
retry:
   if( !lay || !qu_find_widget_layout_( lay, w, &lay ) )
       return 0;
 
   int index = lay->indexOf( w );
   if( index >= 0 )
   {
       if( QGridLayout* l = qobject_cast< QGridLayout* >( lay ) )
       {
           int r, c, d;
           l->getItemPosition( index, &r, &c, &d, &d );        
           if( row )
               *row = r;
           if( col )
               *col = c;
           return l;
       }
       else if( QBoxLayout* l = qobject_cast< QBoxLayout* >( lay ) )
       {
           if( row )
               *row = index;
           return l;
       }
   }
 
   int i = 0;
   QLayoutItem *l;
   while( ( l = lay->itemAt( i ) ) != 0 )
   {
       ++i;
       if( l->layout() )
       {
           lay = l->layout();
           goto retry;
       }
   }
 
   return 0;
}
 
« Последнее редактирование: Октябрь 20, 2010, 13:31 от GreatSnake » Записан

Qt 5.11/4.8.7 (X11/Win)
shirushizo
Гость
« Ответ #8 : Октябрь 20, 2010, 13:15 »

Тогда можно так

Код:
QWidget *parent = childWidget->parentWidget();
if( parent )
    {
        QList<QLayout *> layoutList = parent->findChildren<QLayout *>();
        foreach( QLayout *l, layoutList )
            if( l->indexOf( childWidget ) > -1 )
                return l;
    }
return 0;

Скорее всего не будет работать, т.к. родитель будет устоновлен только у одного лейаута.
« Последнее редактирование: Октябрь 20, 2010, 17:41 от shirushizo » Записан
Kolobok
Гость
« Ответ #9 : Октябрь 20, 2010, 13:31 »

Скорее всего не будет работать, т.к. радотель будет устоновлен только у одного лейаута.

Ну если тебе даже проверить лень...
Записан
ufna
Гость
« Ответ #10 : Октябрь 20, 2010, 14:11 »

да, единственный способ в данном случае - брать лейаут родителя, и далее спускаться по дитям и искать.
Записан
offitserov
Гость
« Ответ #11 : Октябрь 21, 2010, 19:20 »

Можно так, работает, проверено -
Код:
static QLayout* findParentLayout(QLayout *parentWidgetLayout, QWidget *widget)
{
Q_ASSERT(widget);

if (!parentWidgetLayout)
return 0;

QLayoutItem *item(0);
int counter(-1);
do {
item = parentWidgetLayout->itemAt(++counter);
if (!item)
break;
QWidget *itemWidget = item->widget();
if (itemWidget && itemWidget == widget)
return parentWidgetLayout;
QLayout *itemLayout = findParentLayout(item->layout(), widget);
if (itemLayout)
return itemLayout;
} while (item);
return 0;
}
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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