Russian Qt Forum

Qt => Общие вопросы => Тема начата: kim от Июнь 18, 2011, 11:47



Название: Узнать компановщик у произвольного QWidget
Отправлено: kim от Июнь 18, 2011, 11:47
Доброго времени суток.

Собственно вопрос:

    QWidget *window = new QWidget;
    QPushButton *button1 = new QPushButton("One");
     
    QHBoxLayout *layout = new QHBoxLayout;
    layout->setObjectName(QString::fromUtf8("curr_layout"));
    layout->addWidget(button1);
   
    window->setLayout(layout);
    window->show();

Как через button1 получить имя компановщика "curr_layout" ?


Название: Re: Узнать компановщик у произвольного QWidget
Отправлено: Пантер от Июнь 18, 2011, 11:48
Чего?


Название: Re: Узнать компановщик у произвольного QWidget
Отправлено: kim от Июнь 18, 2011, 12:03
сейчас поясню:

вот так я могу перебрать все виджеты добавленные в  QHBoxLayout:
         QLayoutItem *child;
          while ((child = layout->takeAt(0)) != 0)
          {
              qDebug()<< child->widget()->objectName();
          }

а мне нужно наоборот, узнать в какой именно layout (на форме их несколько) добавлен button1
т.е. вытащить имя компановщика имея только button1


Название: Re: Узнать компановщик у произвольного QWidget
Отправлено: BRE от Июнь 18, 2011, 12:05
Поискать этот виджет по очереди в каждом layout?


Название: Re: Узнать компановщик у произвольного QWidget
Отправлено: kim от Июнь 18, 2011, 12:10
как вариант, но геморойный... т.к. все намного сложнее, это в разы все усложнит...

мож свойство какое есть...  я нашел только layout();  но оно почемуто всегда = 0.


Название: Re: Узнать компановщик у произвольного QWidget
Отправлено: GreatSnake от Июнь 18, 2011, 12:31
Как-то так:
Код
C++ (Qt)
QLayout* getLayout( QWidget* w )
{
    while( w )
    {
          if( w->layout() )
            return w->layout();
          w = w->parentWidget();
    }
    return 0;
}
Хотя при сложных компоновках могут быть ньюансы.


Название: Re: Узнать компановщик у произвольного QWidget
Отправлено: BRE от Июнь 18, 2011, 12:44
как вариант, но геморойный... т.к. все намного сложнее, это в разы все усложнит...
Тогда можно просто использовать указатель на parent. При помещении виджета в layout последний становиться его parent'ом.
Код
C++ (Qt)
QLayout *layout = qobject_cast<QLayout*>( widget->parent() );
if( !layout )
qDebug() << "Виджет не расположен в layout";
 
qDebug() << layout->objectName();
 

мож свойство какое есть...  я нашел только layout();  но оно почемуто всегда = 0.
Почитай в документации, что он возвращает.


Название: Re: Узнать компановщик у произвольного QWidget
Отправлено: kim от Июнь 19, 2011, 00:02
Читал я про layout()...
Returns the layout manager that is installed on this widget, or 0 if no layout manager is installed.
только не понял логики:  w = w->parentWidget();  return w->layout(); да еще и в цикле...
в ассистанте же ясно написано- возвращает layout manager если он установлен для этого! виджета.
непонимаю.... но работает.

2й Вариант не работает:
Код
C++ (Qt)
   qDebug() << button1->parent()->objectName();        //вывод: "cwidget"
   QLayout *lt = qobject_cast<QLayout*>( button1->parent() );
   if( !lt )
     qDebug() << tr("Виджет не расположен в layout");  //собственно это и имеем
   else
    qDebug() << lt->objectName();
 
всем спасибо, буду дальше разбиратся.


Название: Re: Узнать компановщик у произвольного QWidget
Отправлено: BRE от Июнь 19, 2011, 09:59
Читал я про layout()...
Returns the layout manager that is installed on this widget, or 0 if no layout manager is installed.
только не понял логики:  w = w->parentWidget();  return w->layout(); да еще и в цикле...
в ассистанте же ясно написано- возвращает layout manager если он установлен для этого! виджета.
непонимаю.... но работает.
Так для button1 слой и не устанавливался (возвращает 0), а вот для виджета window слой устанавливался.
Этот виджет window является владельцем виджета button1.

Код
C++ (Qt)
QWidget *parentWidget = button1->parentWidget(); // Пробуем получить вышестоящий виджет-владелец.
QLayout *lt = ( parentWidget )? parentWidget->layout() : 0; // Если он есть, то возвращаем его слой.
 


Название: Re: Узнать компановщик у произвольного QWidget
Отправлено: GreatSnake от Июнь 20, 2011, 10:52
Вот вариант, работающий при компоновке любой сложности:
Код
C++ (Qt)
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 ) )
{
QLayoutIterator it = l->iterator();
QLayoutItem *li;
while( ( li = it.current() ) != 0 )
{
++it;
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 = 0, int* col = 0 )
{
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;
 
if( QGridLayout* l = qobject_cast< QGridLayout* >( lay ) )
{
int index = l->indexOf( w );
if( index >= 0 )
{
int r, c, rs, cs;
l->getItemPosition( index, &r, &c, &rs, &cs );
if( row )
*row = r;
if( col )
*col = c;
return l;
}
}
else if( QBoxLayout* l = qobject_cast< QBoxLayout* >( lay ) )
{
int index = l->findWidget( w );
if( index >= 0 )
{
if( row )
*row = index;
return l;
}
}
 
QLayoutIterator it = lay->iterator();
QLayoutItem *l;
while( ( l = it.current() ) != 0 )
{
++it;
if( l->layout() )
{
lay = l->layout();
goto retry;
}
}
 
return 0;
}
 


Название: Re: Узнать компановщик у произвольного QWidget
Отправлено: kim от Июнь 21, 2011, 13:10
да уже сделал  :)
работает, вот что получилось: 

Код
C++ (Qt)
void getWidgetLayout(QObject* cur_obj, QString WidgetName, QString &lt_name)
{
 
   QLayout *lt = qobject_cast<QLayout*>(cur_obj);
   if(lt)
   {
    QString layout_name = lt->objectName();
    QString ob_name="";
    if((!layout_name.isEmpty()) && (layout_name != "_layout"))
     for (int i=0, lcount=lt->count(); i < lcount; ++i)
     {
      ob_name="";
      if(lt->itemAt(i)->widget()) ob_name = lt->itemAt(i)->widget()->objectName();
      if(ob_name == WidgetName){ lt_name = layout_name;  return; }
     }
   }
 
   QObjectList objch_list = cur_obj->children();
   QObjectList::iterator objch_it = objch_list.begin();
   QObject * chobj;
   while((objch_it != objch_list.end())  &&  (lt_name.isEmpty()))
   {
    chobj = *objch_it;
     getWidgetLayout(chobj, WidgetName, lt_name);
    ++objch_it;
   }
 
}
 


Код
C++ (Qt)
  if(cur_obj->isWidgetType())
  {
      QWidget *topLvWidget = qobject_cast<QWidget*>(cur_obj)->topLevelWidget();
      QString lt_name="";
      getWidgetLayout(qobject_cast<QObject*>(topLvWidget), obj_name, layout_name);
      if(!lt_name.isEmpty())qDebug()<<lt_name;
  }