• [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的派生类中却不可以。

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

    
    
  • 相关阅读:
    java相关
    cmd批处理命令及powershell
    火狐浏览器调试模式
    windows 配置java环境变量
    Acwing-279-自然数拆分(背包)
    Acwing-278-数字组合(背包)
    Acwing-277-饼干(DP)
    Acwing-274-移动服务(DP)
    Acwing-275-传纸条(DP)
    Acwing-121-赶牛入圈(二分, 二维前缀和,离散化)
  • 原文地址:https://www.cnblogs.com/meime7/p/6491604.html
Copyright © 2020-2023  润新知