在应用程序中,一个界面的布局基本都是固定的。
在这个实例中,我们把管理布局的代码放在槽中。这样点击一次按钮,触发槽。布局改变一次。这样就成为一个动态布局。
(一) 水平和竖直布局改变
横向:
纵向:
明显我们改变combobox中的选项。整个布局的界面就会变化。明显信号就是combobox中的
currentIndexChanged(int index),我们设计槽处理这个信号。
if(index == 0) { buttonLayout->addWidget(button1, 0, 0); buttonLayout->addWidget(button2, 0, 1); buttonLayout->addWidget(button3, 0, 2); mainLayout->removeWidget(buttonGroupBox); mainLayout->addWidget(buttonGroupBox, 2, 0); setLayout(mainLayout); return ; } if(index == 1) { buttonLayout->addWidget(button1, 0, 0); buttonLayout->addWidget(button2, 1, 0); buttonLayout->addWidget(button3, 2, 0); mainLayout->removeWidget(buttonGroupBox); mainLayout->addWidget(buttonGroupBox, 0, 1); setLayout(mainLayout); return; }
需要重新布局的控件。先调用QLayout中的removeWidget方法。然后再添加进来。
不过此时要改变在QGridLayout中的行列,实现水平和竖直布局。
(二)旋转控件。
初始状态:
旋转:
思路和上一个例子一样。先做好初始的布局。
然后再槽中 removeWidget()删除所有的控件。重新布局。
void Dialog::create() { widgetGroupBox = new QGroupBox(tr("Rotate Widgets")); rotateButton = new QPushButton(tr("Rotate Widget")); queue.enqueue(new QSpinBox()); queue.enqueue(new QProgressBar()); queue.enqueue(new QSlider()); queue.enqueue(new QDial()); int n = queue.count(); for(int i=0; i<n; i++) { connect(queue[i], SIGNAL(valueChanged(int)), queue[(i+1)%n], SLOT(setValue(int))); } boxLayout = new QGridLayout; widgetGroupBox->setLayout(boxLayout); rotateWidget(); }
void Dialog::rotateWidget() { Q_ASSERT(queue.count() % 2 == 0); foreach (QWidget * w, queue) { boxLayout->removeWidget(w); } queue.enqueue(queue.dequeue()); int n = queue.count(); for(int i=0; i<n/2; i++) { boxLayout->addWidget(queue[n-1-i], 0, i); boxLayout->addWidget(queue[i], 1, i); } }
第一次的布局也是调用rotateWidget函数实现的。可见,当布局为空。里面没有控件时,调用removeWidget函数也不会使程序报错。
完整代码:https://github.com/Satius/qt5/tree/master/qtbase/examples/widgets/layouts/dynamiclayouts