初接觸Qt,使用的教程是陸文周編寫的《Qt5開發及實例》一書。
其中有關於QDockWidget、QStackedWidget這些類的介紹和使用實例。
要首先說明的是書上講的非常的清楚,代碼也附得非常明白,這本書還是非常值得看看的。
由於是初學,在新建工程的時候,我沒有注意到基類的這個細節,沒有按照教程上說的新建一個基於QDailog的類的項目,而是新建了一個基於QMainWindow的。
這就給我后面留下了一個問題,在使用布局的時候始終不起作用。
我先附上代碼(Ps:代碼沒有問題,只是基類不是QDailog)Layout.cpp的構造函數中的代碼
#include "layout.h" Layout::Layout(QWidget *parent, Qt::WFlags flags) : QMainWindow(parent, flags) { //ui.setupUi(this); /* ---- QDockWidget 停靠窗口類 setWindowTitle(tr("DockWin")); QDockWidget *dock = new QDockWidget(tr("DockWin-1"),this);//停靠窗口1,可移動 dock->setFeatures(QDockWidget::DockWidgetMovable); dock->setAllowedAreas(Qt::LeftDockWidgetArea|Qt::RightDockWidgetArea); addDockWidget(Qt::RightDockWidgetArea,dock); dock = new QDockWidget("DockWin-2",this);//停靠窗口2,可浮動,可關閉 dock->setFeatures(QDockWidget::DockWidgetClosable|QDockWidget::DockWidgetFloatable); addDockWidget(Qt::RightDockWidgetArea,dock); dock = new QDockWidget("DockWin-3",this);//停靠窗口3,可浮動,可關閉 dock->setFeatures(QDockWidget::AllDockWidgetFeatures); addDockWidget(Qt::RightDockWidgetArea,dock); ----- */ //setWindowTitle(tr("StackedWidget"));//QStackedWidget堆棧窗體類 setGeometry(200,200,500,500); //堆棧窗口類 QListWidget *list; QStackedWidget *stack; QLabel *label1; QLabel *label2; QLabel *label3; QWidget *widget1; QWidget *widget2; QWidget *widget3; //QWidget *newWidget = new QWidget(this); //QDockWidget *Widget = new QDockWidget(this); //QWidget *newWidget = new QWidget; //Widget->setWidget(newWidget); //Widget->setTitleBarWidget(newWidget); //->setCentralWidget(newWidget); list = new QListWidget(this); //newWidget->setMinimumWidth(200); //newWidget->setMinimumHeight(80); //Widget->setMinimumWidth(200); //Widget->setMinimumHeight(80); list->insertItem(0,tr("label-1")); list->insertItem(1,tr("label-2")); list->insertItem(2,tr("label-3")); label1 = new QLabel(tr("label - text - 1")); label2 = new QLabel(tr("label - text - 2")); label3 = new QLabel(tr("label - text - 3")); stack = new QStackedWidget(this); stack->addWidget(label1); stack->addWidget(label2); stack->addWidget(label3); QHBoxLayout *mainlayout = new QHBoxLayout(this); mainlayout->setMargin(5); mainlayout->setSpacing(5); mainlayout->addWidget(list); mainlayout->addWidget(stack,0,Qt::AlignHCenter); mainlayout->setStretchFactor(list,1); mainlayout->setStretchFactor(stack,3); connect(list,SIGNAL(currentRowChanged(int)),stack,SLOT(setCurrentIndex(int))); this->setLayout(mainlayout); } Layout::~Layout() { }
運行效果是這樣的:

可以很明顯的看出來,布局是沒有效果的。QLabel全都堆在了一起。
首先,已經說過了,只要新建項目的時候基於QDailog便不會有這個問題了
其次,由於我使用的是VS2008+Qt addin所以編譯的時候並沒有報錯,如果使用的Qt Creater其實編譯會提示一個這樣的錯誤的:
QWidget::setLayout: Attempting to set QLayout "" on MainWindow "", which already has a layout
這句話的意思是說,你已經給MainWindow設置過一個布局了,再設置一個就會出錯。
或者你就是想要建基於QMainWindow的項目,那么解決方法是什么呢?
可以借助一個QWidget來解決這個問題,請看修改(1),(2)代碼后的運行效果:

可以看到布局已經生效了,但是由於尺寸問題,newWidget並沒有充滿整個窗口。此時我們只需要加入代碼(3)即可:
1 #include "layout.h" 2 3 Layout::Layout(QWidget *parent, Qt::WFlags flags) 4 : QMainWindow(parent, flags) 5 { 6 //ui.setupUi(this); 7 /* ---- QDockWidget 停靠窗口類 8 setWindowTitle(tr("DockWin")); 9 QDockWidget *dock = new QDockWidget(tr("DockWin-1"),this);//停靠窗口1,可移動 10 dock->setFeatures(QDockWidget::DockWidgetMovable); 11 dock->setAllowedAreas(Qt::LeftDockWidgetArea|Qt::RightDockWidgetArea); 12 13 addDockWidget(Qt::RightDockWidgetArea,dock); 14 dock = new QDockWidget("DockWin-2",this);//停靠窗口2,可浮動,可關閉 15 dock->setFeatures(QDockWidget::DockWidgetClosable|QDockWidget::DockWidgetFloatable); 16 addDockWidget(Qt::RightDockWidgetArea,dock); 17 18 dock = new QDockWidget("DockWin-3",this);//停靠窗口3,可浮動,可關閉 19 dock->setFeatures(QDockWidget::AllDockWidgetFeatures); 20 addDockWidget(Qt::RightDockWidgetArea,dock); 21 ----- */ 22 //setWindowTitle(tr("StackedWidget"));//QStackedWidget堆棧窗體類 23 setGeometry(200,200,500,500); 24 //堆棧窗口類 25 QListWidget *list; 26 QStackedWidget *stack; 27 QLabel *label1; 28 QLabel *label2; 29 QLabel *label3; 30 QWidget *widget1; 31 QWidget *widget2; 32 QWidget *widget3; 33 //QWidget *newWidget = new QWidget(this); 34 //QDockWidget *Widget = new QDockWidget(this); 35 QWidget *newWidget = new QWidget(this);//!!!!!添加代碼(1) 36 setCentralWidget(newWidget);//!!!!添加代碼(3) 37 //Widget->setWidget(newWidget); 38 //Widget->setTitleBarWidget(newWidget); 39 //->setCentralWidget(newWidget); 40 list = new QListWidget(this); 41 //newWidget->setMinimumWidth(200); 42 //newWidget->setMinimumHeight(80); 43 //Widget->setMinimumWidth(200); 44 //Widget->setMinimumHeight(80); 45 list->insertItem(0,tr("label-1")); 46 list->insertItem(1,tr("label-2")); 47 list->insertItem(2,tr("label-3")); 48 49 label1 = new QLabel(tr("label - text - 1")); 50 label2 = new QLabel(tr("label - text - 2")); 51 label3 = new QLabel(tr("label - text - 3")); 52 53 stack = new QStackedWidget(this); 54 stack->addWidget(label1); 55 stack->addWidget(label2); 56 stack->addWidget(label3); 57 58 QHBoxLayout *mainlayout = new QHBoxLayout(this); 59 mainlayout->setMargin(5); 60 mainlayout->setSpacing(5); 61 mainlayout->addWidget(list); 62 mainlayout->addWidget(stack,0,Qt::AlignHCenter); 63 mainlayout->setStretchFactor(list,1); 64 mainlayout->setStretchFactor(stack,3); 65 connect(list,SIGNAL(currentRowChanged(int)),stack,SLOT(setCurrentIndex(int))); 66 newWidget->setLayout(mainlayout);//this->setLayout(mainlayout);!!!!修改代碼(2) 67 } 68 Layout::~Layout(){ 69 }
運行效果:

那么在QDockWidget中出現這個問題應該如何處理呢?我們知道QDockWidget中並沒有
setCentralWidget()這個方法。答案是SetWidget()
請看代碼:
1 #include "layout.h" 2 3 Layout::Layout(QWidget *parent, Qt::WFlags flags) 4 : QMainWindow(parent, flags) 5 { 6 //ui.setupUi(this); 7 /* ---- QDockWidget 停靠窗口類 8 setWindowTitle(tr("DockWin")); 9 QDockWidget *dock = new QDockWidget(tr("DockWin-1"),this);//停靠窗口1,可移動 10 dock->setFeatures(QDockWidget::DockWidgetMovable); 11 dock->setAllowedAreas(Qt::LeftDockWidgetArea|Qt::RightDockWidgetArea); 12 13 addDockWidget(Qt::RightDockWidgetArea,dock); 14 dock = new QDockWidget("DockWin-2",this);//停靠窗口2,可浮動,可關閉 15 dock->setFeatures(QDockWidget::DockWidgetClosable|QDockWidget::DockWidgetFloatable); 16 addDockWidget(Qt::RightDockWidgetArea,dock); 17 18 dock = new QDockWidget("DockWin-3",this);//停靠窗口3,可浮動,可關閉 19 dock->setFeatures(QDockWidget::AllDockWidgetFeatures); 20 addDockWidget(Qt::RightDockWidgetArea,dock); 21 ----- */ 22 //setWindowTitle(tr("StackedWidget"));//QStackedWidget堆棧窗體類 23 setGeometry(200,200,500,500); 24 //堆棧窗口類 25 QListWidget *list; 26 QStackedWidget *stack; 27 QLabel *label1; 28 QLabel *label2; 29 QLabel *label3; 30 QWidget *widget1; 31 QWidget *widget2; 32 QWidget *widget3; 33 //QWidget *newWidget = new QWidget(this); 34 QDockWidget *Widget = new QDockWidget(this);//!!添加代碼(4) 35 QWidget *newWidget = new QWidget(this);//!!!!!添加代碼(1) 36 //setCentralWidget(newWidget);//!!!!添加代碼(3) 37 Widget->setWidget(newWidget);//添加代碼(5) 38 //Widget->setTitleBarWidget(newWidget); 39 //->setCentralWidget(newWidget); 40 list = new QListWidget(this); 41 //newWidget->setMinimumWidth(200); 42 //newWidget->setMinimumHeight(80); 43 //Widget->setMinimumWidth(200); 44 //Widget->setMinimumHeight(80); 45 list->insertItem(0,tr("label-1")); 46 list->insertItem(1,tr("label-2")); 47 list->insertItem(2,tr("label-3")); 48 49 label1 = new QLabel(tr("label - text - 1")); 50 label2 = new QLabel(tr("label - text - 2")); 51 label3 = new QLabel(tr("label - text - 3")); 52 53 stack = new QStackedWidget(this); 54 stack->addWidget(label1); 55 stack->addWidget(label2); 56 stack->addWidget(label3); 57 58 QHBoxLayout *mainlayout = new QHBoxLayout(this); 59 mainlayout->setMargin(5); 60 mainlayout->setSpacing(5); 61 mainlayout->addWidget(list); 62 mainlayout->addWidget(stack,0,Qt::AlignHCenter); 63 mainlayout->setStretchFactor(list,1); 64 mainlayout->setStretchFactor(stack,3); 65 connect(list,SIGNAL(currentRowChanged(int)),stack,SLOT(setCurrentIndex(int))); 66 newWidget->setLayout(mainlayout);//this->setLayout(mainlayout);!!!!修改代碼(2) 67 } 68 Layout::~Layout(){ 69 }
運行效果:

PS:
其實QMainWindow和QDailog的基類都是QWidget,真的搞不懂為何在QDailog派生的類中可以直接使用布局類,而在QMainWindow的派生類中卻不可以。
知其然而不知其所以然的感受不太好,望知道的大神解疑。
