简体   繁体   中英

QSpacerItem In QFormLayout - Vertical Expand

I would like to force an expanding space in my QFormLayout , but no matter what QFormLayout only uses the QSpaceItem::sizeHint() . Does anyone know a way around this, or the proper way to handle this?


MyWidget::MyWidget(QWidget *parent) : QWidget(parent)
{
   SetupLayout();
}

void MyWidget::SetupLayout()
{
   QFormLayout * layout = new QFormLayout();

   layout->addRow("Something1", new QComboBox());
   layout->addRow("Something2", new QSpinBox());

   //Spacer
   layout->addItem(new QSpacerItem(0,10, QSizePolicy::Expanding, QSizePolicy::Expanding));

   layout->addRow(QPushButton("Something3"));

   setLayout(layout);
}

So there were a few different issues:

  1. QFormLayout do not expand like other layouts. My widgets (a few of them) were being placed into a QFormLayout . This prevented them from expanding. I switched my main parent layout from QFormLayout to QVBoxLayout . This made me have to use QLayout::setAlignment(Qt::AlignTop)
  2. This fixed a few problems with a few of my other widgets not expanding. However these widgets used QVBoxLayout . The widget above uses a QFormLayout . To get this expand, I had to use the following line in my QSpacerItem :

QSpacerItem * my_spacer = new QSpacerItem(0,1000, QSizePolicy::Expanding, QSizePolicy::Expanding);


I am supplying some example code. The goal is to show the hierarchy, and where QFormLayout would cause trouble.

Example code:

//A main Widget class
void SetupLayout()
{
   QHBoxLayout * main_layout = new QHBoxLayout();

   main_layout->addWidget(Some_Widget);

   //Create a control widget
   control_widget = new QWidget();  // IMPORTANT control_widget is a member
   QVBoxLayout * layout = new QVBoxLayout(); //IMPORTANT!!!! - Here it was QFormLayout

   layout->setAlignment(Qt::AlignTop); //IMPORTANT - Needed this after switching to QVBoxLayout

   layout->addWidget(new QComboBox("stuff")); //Some combo box
   control_widget->setLayout(layout);

   main_layout->addWidget(control_widget);
}

//Later on, we have a "Put a new widget in the control area" task
void NewControlArea()
{
   if(current_control)
      control_widget->removeWidget(current_control);  //current_control is a member variable

   current_control = new MyWidget();  //FROM ABOVE
   control_widget->addWidget(current_control);
}

If MyWidget uses a QFormLayout , things are not expanded unless I add spacers with size hints. However, if MyWidget uses a QVBoxLayout , any QWidgets inside it are expanded correctly.

After lot of time with manual as well as lots of tries i guess it's impossible to do what you want using QFormLayout.

This layout is desinged for windows with lot of fields to fill, but only for that.

If you want to add bigger spacing between sections of your form you can use QVBoxLayout with a couple of QFormLayout's inside it separated by spacings. Notice that in this case each section will have own width of first and second column so maybe that is not the best solution.

The other solution (if we are talking about grouping some options) is to use a couple of QGroupBoxes with QFormLayouts in it. The groups will not be separated by growing spacing, but it will be very readable and you can name your groups. If grouping options is what you want to do - this is probably the most common and user friendly way to do this.

If you only want visual effect you pointed - columns with same width in every section and growing spacing between sections, you can use QGridLayout with 2 columns and add spacers in rows between sections. In this case you have to create QLabel to put into first column by yourself.

Just for posterity, I was having a similar problem. I found that having an organization like the following would cause anything in the inner layout (QHBoxLayout) to not expand vertically as they would if I had dropped them into the QFormLayout by themselves:

QFormLayout
-QHBoxLayout
--QListWidget

However, if I added a layer of indirection by putting the HBoxLayout into a QWidget, then sizing worked correctly:

QFormLayout
-QWidget
--QHBoxLayout
---QListWidget

So you might try adding a QWidget in there and putting your spacer inside of it.

What I did is probably a bit of hacking and is not very elegant, yet it did the trick in just one row:

addRow("  ", (QWidget*)nullptr);

This doubles the space between rows added before and after this call.

I suspect that MyWidget has the wrong size. The layout will use the widget's size to work out how best to layout its own items. Just because one of those items is set to an expanding policy does not mean that the layout will force the size of MyWidget to expand. If the size of MyWidget is fixed there is nothing the internal layout can do.

If you make MyWidget bigger you should see the layout working as you hope. Perhaps you need to put MyWidget in a vertical layout with its policy set to expanding? Without knowing how MyWidget gets its size it's hard to be sure.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM