QT中使用絕對定位的佈局方式沒法自適應窗口的變化。ide
QT中提供了對界面組件進行佈局管理的類,用於對界面組件進行管理,可以自動排列窗口中的界面組件,窗口大小變化後自動更新界面組件的大小。函數
QLayout是QT中佈局管理器的抽象基類,經過對QLayout的繼承,實現了功能各異且互補的佈局管理器。佈局
佈局管理器不是界面組件,而是界面組件的定位策略。ui
任意容器類型的組件均可以指定佈局管理器。this
同一個佈局管理器管理中的組件擁有相同的父組件,在設置佈局管理器的同時已經隱式指定了父子關係。spa
QBoxLayout以垂直或水平的方式管理界面組件。設計
QBoxLayout有兩個子類:QHBoxLayout和QVBoxLayput。orm
A、QVBoxLayout使用對象
void Widget::VBoxLayout() { QVBoxLayout *vLayout = new QVBoxLayout(); //設置組件間隔 vLayout->setSpacing(20); //設置組件的標籤 button1.setText("button1"); button2.setText("button2"); button3.setText("button3"); button4.setText("button4"); //設置每一個組件的尺寸策略 button1.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); button2.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); button3.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); button4.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); //設置組件的最小尺寸 button1.setMinimumSize(60,30); button2.setMinimumSize(60,30); button3.setMinimumSize(60,30); button4.setMinimumSize(60,30); //添加組件到佈局管理器 vLayout->addWidget(&button1); vLayout->addWidget(&button2); vLayout->addWidget(&button3); vLayout->addWidget(&button4); //設置窗口的佈局管理器 setLayout(vLayout); }
B、QHBoxLayout使用blog
void Widget::HBoxLayout() { QHBoxLayout *hLayout = new QHBoxLayout(); //設置組件間隔 hLayout->setSpacing(20); //設置組件的標籤 button1.setText("button1"); button2.setText("button2"); button3.setText("button3"); button4.setText("button4"); //設置每一個組件的尺寸策略 button1.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); button2.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); button3.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); button4.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); //設置組件的最小尺寸 button1.setMinimumSize(60,30); button2.setMinimumSize(60,30); button3.setMinimumSize(60,30); button4.setMinimumSize(60,30); //添加組件到佈局管理器 hLayout->addWidget(&button1); hLayout->addWidget(&button2); hLayout->addWidget(&button3); hLayout->addWidget(&button4); //設置窗口的佈局管理器 setLayout(hLayout); }
佈局管理器能夠相互嵌套,造成複雜的佈局管理方式。
QBoxLayout佈局管理器的嵌套使用實例以下:
void Widget::HVBoxLayout() { QHBoxLayout *hLayout1 = new QHBoxLayout(); QHBoxLayout *hLayout2 = new QHBoxLayout(); //button一、buuton2使用水平佈局管理器hLayout1管理 hLayout1->setSpacing(20); button1.setText("button1"); button2.setText("button2"); button1.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); button2.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); button1.setMinimumSize(60,30); button2.setMinimumSize(60,30); hLayout1->addWidget(&button1); hLayout1->addWidget(&button2); //button三、buuton4使用水平佈局管理器hLayout2管理 hLayout2->setSpacing(20); button3.setText("button3"); button4.setText("button4"); button3.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); button4.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); button3.setMinimumSize(60,30); button4.setMinimumSize(60,30); hLayout2->addWidget(&button3); hLayout2->addWidget(&button4); //水平佈局管理器hLayout一、hLayout2使用垂直佈局管理器vLayout管理 QVBoxLayout *vLayout = new QVBoxLayout(); vLayout->setSpacing(20); vLayout->addLayout(hLayout1); vLayout->addLayout(hLayout2); //設置窗口的佈局管理器爲vLayout setLayout(vLayout); }
QBoxLayout中比例係數的設置:
void setStretch(int index, int stretch)
bool setStretchFactor(QWidget * widget, int stretch)
bool setStretchFactor(QLayout * layout, int stretch)
vLayout->setStretch(0,1);
vLayout->setStretch(1,0.5);
vLayout->setStretch(2,1);
vLayout->setStretch(3,2);
vLayout->setStretchFactor(&button1, 1);
vLayout->setStretchFactor(&button2, 1);
vLayout->setStretchFactor(hLayout1, 1);
vLayout->setStretchFactor(hLayout2, 2);
界面組件的初始大小是獨立於佈局管理器設置的,比例係數只有在窗口變化的時候纔會生效。
QGridLayout佈局管理器以網格的方式管理界面組件。
QGridLayout佈局管理器比例係數設置函數:
void setColumnStretch(int column, int stretch)
void setRowStretch(int row, int stretch)
void Widget::GridLayout() { QGridLayout *gLayout = new QGridLayout(); //設置組件間隔 gLayout->setSpacing(20); //設置組件的標籤 button1.setText("button1"); button2.setText("button2"); button3.setText("button3"); button4.setText("button4"); //設置每一個組件的尺寸策略 button1.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); button2.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); button3.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); button4.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); //設置組件的最小尺寸 button1.setMinimumSize(60,30); button2.setMinimumSize(60,30); button3.setMinimumSize(60,30); button4.setMinimumSize(60,30); //添加組件到網格佈局管理器 gLayout->addWidget(&button1, 0, 0); gLayout->addWidget(&button2, 0, 1); gLayout->addWidget(&button3, 1, 0); gLayout->addWidget(&button4, 1, 1); //設置行和列的比例係數 gLayout->setColumnStretch(0, 1); gLayout->setColumnStretch(1, 2); gLayout->setRowStretch(0, 1); gLayout->setRowStretch(1, 2); //設置窗口的佈局管理器 setLayout(gLayout); }
void Widget::HVGridLayout() { QGridLayout *gLayout = new QGridLayout(); //設置組件間隔 gLayout->setSpacing(20); //設置組件的標籤 button1.setText("button1"); button2.setText("button2"); button3.setText("button3"); button4.setText("button4"); //設置每一個組件的尺寸策略 button1.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); button2.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); button3.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); button4.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); //設置組件的最小尺寸 button1.setMinimumSize(60,30); button2.setMinimumSize(60,30); button3.setMinimumSize(60,30); button4.setMinimumSize(60,30); //添加組件到網格佈局管理器,放置的位置,佔用的行和列 gLayout->addWidget(&button1, 0, 0, 1, 1); gLayout->addWidget(&button2, 0, 1, 1, 1); gLayout->addWidget(&button3, 1, 0, 1, 2); gLayout->addWidget(&button4, 2, 0, 3, 1); //設置窗口的佈局管理器 setLayout(gLayout); }
QGridLayout佈局管理器支持嵌套使用。
QFormLayout佈局管理器使用表單的方式管理界面組件,表單中的標籤和組件是相互對應的關係,支持嵌套使用。
void addRow(QWidget * label, QWidget * field)
void addRow(QWidget * label, QLayout * field)
void addRow(const QString & labelText, QWidget * field)
void addRow(const QString & labelText, QLayout * field)
void Widget::FormLayout() { //建立組件和表單佈局管理器 QLineEdit *nameEdit = new QLineEdit(); QLineEdit *mailEdit = new QLineEdit(); QLineEdit *addrEdit = new QLineEdit(); QFormLayout *fLayout = new QFormLayout(); fLayout->setSpacing(20); fLayout->setLabelAlignment(Qt::AlignRight); //添加組件到表單佈局管理器 fLayout->addRow("name:", nameEdit); fLayout->addRow("mail:", mailEdit); fLayout->addRow("addr:", addrEdit); //設置窗口標題 setWindowTitle("FTP"); //設置表單佈局管理器到窗口 setLayout(fLayout); }
void Widget::FormLayout() { //建立組件和表單佈局管理器 QLineEdit *nameEdit = new QLineEdit(); QLineEdit *mailEdit = new QLineEdit(); QLineEdit *addrEdit1 = new QLineEdit(); QLineEdit *addrEdit2 = new QLineEdit(); QFormLayout *fLayout = new QFormLayout(); //添加addrEdit一、addrEdit2到QVBoxLayout QVBoxLayout *vLayout = new QVBoxLayout(); vLayout->addWidget(addrEdit1); vLayout->addWidget(addrEdit2); vLayout->setSpacing(6); fLayout->setSpacing(20); //添加組件到表單佈局管理器 fLayout->addRow("name:", nameEdit); fLayout->addRow("mail:", mailEdit); fLayout->addRow("address:", vLayout); //設置對齊 fLayout->setLabelAlignment(Qt::AlignRight); fLayout->setFormAlignment(Qt::AlignLeft); //設置窗口標題 setWindowTitle("FTP"); //設置表單佈局管理器到窗口 setLayout(fLayout); }
void setRowWrapPolicy(RowWrapPolicy policy)
void setLabelAlignment(Qt::Alignment alignment)
QStackedLayout棧式佈局管理器管理的全部組件在垂直於屏幕的方向上,每次只有一個界面組件會顯示在屏幕上,只要最頂層的界面組件會被顯示。
QStackedLayout棧式佈局管理器的特色以下:
A、組件大小一致,且充滿父組件的顯示區
B、不能直接嵌套其它佈局管理器
C、可以自由切換須要顯示的組件
D、每次僅能顯示一個界面組件
void Widget::StackedLayout() { //建立組件並設置顯示標籤 QPushButton *button1 = new QPushButton(); QPushButton *button2 = new QPushButton(); QPushButton *button3 = new QPushButton(); QPushButton *button4 = new QPushButton(); button1->setText("1st"); button2->setText("2rd"); button3->setText("3th"); button4->setText("4th"); //建立棧式佈局管理器並添加組件 QStackedLayout *sLayout = new QStackedLayout(); sLayout->addWidget(button1); sLayout->addWidget(button2); sLayout->addWidget(button3); sLayout->addWidget(button4); //設置當前棧頂顯示的組件 sLayout->setCurrentIndex(0); //設置棧式佈局管理器到窗口 setLayout(sLayout); }
QStackedLayout棧式佈局管理器不能直接嵌套其餘佈局管理器,但能夠間接嵌套使用其餘佈局管理器。
void Widget::StackedLayout() { //建立組件並設置顯示標籤 QPushButton *button1 = new QPushButton(); QPushButton *button2 = new QPushButton(); QPushButton *button3 = new QPushButton(); QPushButton *button4 = new QPushButton(); button1->setText("1st"); button2->setText("2rd"); button3->setText("3th"); button4->setText("4th"); //建立要嵌套的QVBoxLayout佈局管理器 QVBoxLayout * vbLayout = new QVBoxLayout(); //建立中間對象並將須要嵌套佈局管理管理的組件的父組件設置爲中間對象 QWidget * qwidget = new QWidget(); button2->setParent(qwidget); button3->setParent(qwidget); //設置組件的QVBoxLayout佈局管理器 vbLayout->addWidget(button2); vbLayout->addWidget(button3); //設置中間對象的佈局管理器爲要嵌套的QVBoxLayout佈局管理器 qwidget->setLayout(vbLayout); //建立棧式佈局管理器並添加組件 QStackedLayout *sLayout = new QStackedLayout(); sLayout->addWidget(button1); sLayout->addWidget(qwidget); sLayout->addWidget(button4); //設置當前棧頂顯示的組件 sLayout->setCurrentIndex(1); //設置棧式佈局管理器到窗口 setLayout(sLayout); }
int addWidget(QWidget * widget)
QWidget *currentWidget() const
void setCurrentIndex(int index)
int currentIndex() const
QT中提供了預約義的定時器類QTimer,用於每隔必定時間觸發一個消息,觸發的計時器消息會被轉化爲函數調用。
QTimer的使用以下:
A、編寫計時器消息處理函數
B、建立計時器對象
C、鏈接計時器消息和消息處理函數
D、設置計時器計時間隔並啓動計時器
void Widget::StackedLayout() { //建立組件並設置顯示標籤 QPushButton *button1 = new QPushButton(); QPushButton *button2 = new QPushButton(); QPushButton *button3 = new QPushButton(); QPushButton *button4 = new QPushButton(); button1->setText("1st"); button2->setText("2rd"); button3->setText("3th"); button4->setText("4th"); //建立要嵌套的QVBoxLayout佈局管理器 QVBoxLayout * vbLayout = new QVBoxLayout(); //建立中間對象並將須要嵌套佈局管理管理的組件的父組件設置爲中間對象 QWidget * qwidget = new QWidget(); button2->setParent(qwidget); button3->setParent(qwidget); //設置組件的QVBoxLayout佈局管理器 vbLayout->addWidget(button2); vbLayout->addWidget(button3); //設置中間對象的佈局管理器爲要嵌套的QVBoxLayout佈局管理器 qwidget->setLayout(vbLayout); //建立棧式佈局管理器並添加組件 QStackedLayout *sLayout = new QStackedLayout(); sLayout->addWidget(button1); sLayout->addWidget(qwidget); sLayout->addWidget(button4); //設置當前棧頂顯示的組件 sLayout->setCurrentIndex(1); //設置棧式佈局管理器到窗口 setLayout(sLayout); //建立QTimer對象 QTimer *timer = new QTimer(this); //綁定定時器消息到消息處理函數 connect(timer, SIGNAL(timeout()), this, SLOT(timer())); //啓動定時器,設定間隔 timer->start(2000); } //定時器消息處理函數 void Widget::timer() { //獲取當前窗口布局管理器並轉換爲棧式佈局管理器 QStackedLayout *sLayout = dynamic_cast<QStackedLayout *>(layout()); if(sLayout != NULL) { int index = (sLayout->currentIndex() + 1) % sLayout->count(); //設置棧頂顯示的組件 sLayout->setCurrentIndex(index); } }
用戶嚮導界面開發需求:
A、在同一個界面顯示不一樣的嚮導頁面
B、經過上一步和下一步按鈕進行頁面切換
界面設計:
棧式佈局管理器顯示不一樣頁面
Widget.h源碼:
#ifndef WIDGET_H #define WIDGET_H #include <QPushButton> #include <QtGui/QWidget> #include <QLineEdit> #include <QLabel> #include <QStackedLayout> class Widget : public QWidget { Q_OBJECT private: QPushButton preButton; QPushButton nextButton; QStackedLayout sLayout; //第一頁組件 private: QLabel label1; QLabel label2; QLabel label3; QLabel label4; //第二頁組件 private: QLineEdit edit; //第三頁組件 private: QPushButton button1; QPushButton button2; QPushButton button3; QPushButton button4; private: QWidget * get1stPage(); QWidget * get2ndPage(); QWidget * get3rdPage(); private slots: void pre(); void next(); public: Widget(QWidget *parent = 0); ~Widget(); }; #endif // WIDGET_H
Widget.cpp源碼:
#include "Widget.h" #include <QFormLayout> #include <QGridLayout> #include <QHBoxLayout> #include <QVBoxLayout> Widget::Widget(QWidget *parent) : QWidget(parent) { QVBoxLayout* vbLayout = new QVBoxLayout(); QHBoxLayout* hbLayout = new QHBoxLayout(); preButton.setText("Pre"); preButton.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); preButton.setMinimumSize(80, 30); nextButton.setText("Next"); nextButton.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); nextButton.setMinimumSize(80, 30); connect(&preButton, SIGNAL(clicked()), this, SLOT(pre())); connect(&nextButton, SIGNAL(clicked()), this, SLOT(next())); hbLayout->addWidget(&preButton); hbLayout->addWidget(&nextButton); sLayout.addWidget(get1stPage()); sLayout.addWidget(get2ndPage()); sLayout.addWidget(get3rdPage()); vbLayout->addLayout(&sLayout); vbLayout->addLayout(hbLayout); setLayout(vbLayout); } Widget::~Widget() { } QWidget * Widget::get1stPage() { QWidget * ret = new QWidget(); QGridLayout *gLayout = new QGridLayout(); label1.setText("Hello"); label2.setText("word"); label3.setText("This is"); label4.setText("1st page"); gLayout->addWidget(&label1, 0, 0); gLayout->addWidget(&label2, 0, 1); gLayout->addWidget(&label3, 1, 0, 1, 2); gLayout->addWidget(&label4, 2, 0, 1, 2); ret->setLayout(gLayout); return ret; } QWidget * Widget::get2ndPage() { QWidget * ret = new QWidget(); QFormLayout *fLayout = new QFormLayout(); fLayout->addRow("username:", &edit); edit.setText("hello world"); ret->setLayout(fLayout); return ret; } QWidget * Widget::get3rdPage() { QWidget * ret = new QWidget(); QVBoxLayout *vbLayout = new QVBoxLayout(); button1.setText("hello"); button2.setText("world"); button3.setText("3rd"); button4.setText("page"); vbLayout->addWidget(&button1); vbLayout->addWidget(&button2); vbLayout->addWidget(&button3); vbLayout->addWidget(&button4); ret->setLayout(vbLayout); return ret; } void Widget::pre() { int index = ((sLayout.currentIndex() - 1) + 3) % 3; sLayout.setCurrentIndex(index); } void Widget::next() { int index = (sLayout.currentIndex() + 1) % 3; sLayout.setCurrentIndex(index); }