[Qt初級] 解決 中QMainWindow和QDockWidget添加布局失敗問題


初接觸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的派生類中卻不可以。

  知其然而不知其所以然的感受不太好,望知道的大神解疑。

 
       


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM