Qt fails using the QVBoxLayout layouter

Qt series article directory

foreword

My need is: this will create a vertical layout and add three headers and three QTreeWidgets to the layout, the order from top to bottom is: header1, tree1, header2, tree2, header3, tree 3. You can adjust the layout and widget settings according to your needs.
m_tabWidget, m_picTree, m_tabWidgetPara, m_paraTree, m_tabWidgetNavi are laid out vertically in your main layout m_mainLayout, but you didn't add any content to these widgets, so they may not be displayed.

Before adding to the main layout, you need to add some content to your QTabWidget and QTreeWidget components so that they can be displayed in the UI. Here are some basic examples showing how to add content to these components:
insert image description here
Concrete header files:

#ifndef PROJECTWIN_H
#define PROJECTWIN_H

#include <QWidget>
#include <QStandardPaths>
#include <QDir>
#include <QDebug>
#include <QTreeWidget>
#include <QTreeWidgetItem>
#include <QGridLayout>
#include <QVBoxLayout>
#include <QSplitter>
#include <QVector>
#include "FileMonitorMgr.h"

namespace Ui {
    
    
class ProjectWin;
}


const QString styles = "QTreeView\
{\
        background-color: #5B677A;\
        font-size:17px;\
        color: white;\
}\
    QTreeView::item:hover\
{\
        background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #e7effd, stop: 1 #cbdaf1);\
        border: 1px solid #bfcde4;\
}\
    QTreeView::item:hover\
{\
        background: rgb(69, 187, 217);\
}\
    QTreeView::item:selected:active\
{\
        background: rgb(255, 62, 150);\
}\
    QTreeView::item:selected:!active\
{\
        background: rgb(63, 147, 168);\
}\
    QTreeView::branch\
{\
        background:#5B677A;\
}\
    QTreeView::branch:has-children:!has-siblings:closed,QTreeView::branch:closed:has-children:has-siblings\
{\
        border-image: none;\
        background:#5B677A;\
        image: url(image/Folder-1.png);\
}\
    QTreeView::branch:open:has-children:!has-siblings,QTreeView::branch:open:has-children:has-siblings\
{\
        border-image: none;\
        background:#5B677A;\
        image: url(image/Open-Folder.png);\
}";


class ProjectWin : public QWidget
{
    
    
    Q_OBJECT

public:
    static ProjectWin* getInstance();
    ~ProjectWin();

    FileMonitorMgr *m_fileMgr;
private:
    QTreeWidget* m_picTree;
    QTreeWidget* m_paraTree;
    QWidget* m_naviWgt;

private:
    void initWidget();
    void initPicTree();   
private:
    Ui::ProjectWin *ui;
    QGridLayout* m_grid;
    QWidget* m_centralWidget;
    QTabWidget* m_tabWidget;
    QTabWidget* m_tabWidgetPara;
    QTabWidget* m_tabWidgetNavi;
    QVBoxLayout* m_mainLayout;

    static ProjectWin* m_pInstance;
private:
    explicit ProjectWin(QWidget *parent = nullptr);
    static void destroyInstance();
public:
Q_SIGNALS:
    void sigShowImageBorder(const QString &imageName);
public Q_SLOTS:
    void slotPicTree(QVector<QString> lst, QString path);
    void slotParaTree(QVector<QString> lst, QString path);
    void slotNavi(const QString& file);
    void onItemClicked(QTreeWidgetItem *item, int column);
};

#endif // PROJECTWIN_H

implementation file

#include "ProjectWin.h"
#include "ui_ProjectWin.h"

#pragma execution_character_set("utf-8")

ProjectWin* ProjectWin::m_pInstance = nullptr;

ProjectWin* ProjectWin::getInstance()
{
    
    
    if(!m_pInstance)
    {
    
    
        m_pInstance = new ProjectWin();
        atexit(destroyInstance);
    }
    return m_pInstance;
}

void ProjectWin::destroyInstance()
{
    
    
    if(m_pInstance)
    {
    
    
        delete m_pInstance;
        m_pInstance = nullptr;
    }
}

ProjectWin::~ProjectWin()
{
    
    
    delete ui;
}

ProjectWin::ProjectWin(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::ProjectWin)
{
    
    
    ui->setupUi(this);

    //图像列表
    m_tabWidget = new QTabWidget();
    m_picTree = new QTreeWidget();
    m_picTree->setContextMenuPolicy(Qt::CustomContextMenu);
    m_picTree->setColumnCount(1);
    m_picTree->setHeaderHidden(true);
    connect(m_picTree, &QTreeWidget::itemClicked, this, &ProjectWin::onItemClicked);

    //图像参数
    m_tabWidgetPara = new QTabWidget();
    m_paraTree = new QTreeWidget();
    m_paraTree->setContextMenuPolicy(Qt::CustomContextMenu);
    m_paraTree->setColumnCount(1);
    m_paraTree->setHeaderHidden(true);

    //导航
    m_tabWidgetNavi = new QTabWidget();
    m_naviWgt = new QWidget();

    //创建三个部件组
    QWidget* picGroup = new QWidget();
    QWidget* paraGroup = new QWidget();
    QWidget* naviGroup = new QWidget();

//    // 只设置QWidget的边框为0,不影响子元素
//    picGroup->setStyleSheet("QWidget { border: 0px }");
//    paraGroup->setStyleSheet("QWidget { border: 0px }");
//    naviGroup->setStyleSheet("QWidget { border: 0px }");

    QVBoxLayout* picLayout = new QVBoxLayout();
    picLayout->setMargin(0);
    picLayout->setSpacing(0);
    picLayout->addWidget(m_tabWidget);
    picLayout->addWidget(m_picTree);
    picGroup->setLayout(picLayout);

    QVBoxLayout* paraLayout = new QVBoxLayout();
    paraLayout->setMargin(0);
    paraLayout->setSpacing(0);
    paraLayout->addWidget(m_tabWidgetPara);
    paraLayout->addWidget(m_paraTree);
    paraGroup->setLayout(paraLayout);

    QVBoxLayout* naviLayout = new QVBoxLayout();
    naviLayout->setMargin(0);
    naviLayout->setSpacing(0);
    naviLayout->addWidget(m_tabWidgetNavi);
    naviGroup->setLayout(naviLayout);

    // 设置窗口的主布局
    QVBoxLayout* mainLayout = new QVBoxLayout();
    mainLayout->setMargin(0);
    mainLayout->setSpacing(0);
    mainLayout->addWidget(picGroup);
    mainLayout->addWidget(paraGroup);
    mainLayout->addWidget(naviGroup);
    this->setLayout(mainLayout);
}

void ProjectWin::onItemClicked(QTreeWidgetItem *item, int column)
{
    
    
    QString imageName = item->text(0);
    emit sigShowImageBorder(imageName);
}

void ProjectWin::initWidget()
{
    
    

    //    m_picTree->header()->hide();//设置隐藏头
}

void ProjectWin::initPicTree()
{
    
    

}

void ProjectWin::slotPicTree(QVector<QString> lst, QString path)
{
    
    
    QTreeWidgetItem* topItem = new QTreeWidgetItem(m_picTree);
    topItem->setText(0, path);
    topItem->setCheckState(0, Qt::Checked);
    m_picTree->addTopLevelItem(topItem);
    int count = lst.size();
    //添加顶层节点
    if (lst.size() > 0)
    {
    
    
        for (int i = 0; i < lst.size(); i++)
        {
    
    
            //int size = lst.at(i).size();
            //int pos = lst.at(i).lastIndexOf("/");
            //QString temp = lst.at(i).right(size - pos - 1);
            QTreeWidgetItem* item = new QTreeWidgetItem(topItem);
            item->setText(0, lst.at(i));
            item->setCheckState(0, Qt::Checked);
        }
    }

    m_picTree->expandAll();
    //    m_grid = new QGridLayout(this);
    //    m_grid->addWidget(m_picTree);
    m_picTree->setStyleSheet(styles);

    //    this->setLayout(m_grid);

    m_tabWidget->addTab(m_picTree, u8"彩C");
}

void ProjectWin::slotParaTree(QVector<QString> lst, QString path)
{
    
    
    QTreeWidgetItem* topItem = new QTreeWidgetItem(m_paraTree);
    topItem->setText(0, path);
    topItem->setCheckState(0, Qt::Checked);
    m_paraTree->addTopLevelItem(topItem);
    int count = lst.size();
    //添加顶层节点
    if (lst.size() > 0)
    {
    
    
        for (int i = 0; i < lst.size(); i++)
        {
    
    
            //int size = lst.at(i).size();
            //int pos = lst.at(i).lastIndexOf("/");
            //QString temp = lst.at(i).right(size - pos - 1);
            QTreeWidgetItem* item = new QTreeWidgetItem(topItem);
            item->setText(0, lst.at(i));
            item->setCheckState(0, Qt::Checked);
        }
    }

    m_paraTree->expandAll();
    //    m_grid = new QGridLayout(this);
    //    m_grid->addWidget(m_picTree);
    m_paraTree->setStyleSheet(styles);

    //    this->setLayout(m_grid);


    m_tabWidgetPara->addTab(m_paraTree, u8"图像参数数据");
    m_paraTree->setStyleSheet(styles);
}

void ProjectWin::slotNavi(const QString& file)
{
    
    
    m_tabWidgetNavi->addTab(m_naviWgt, u8"导航");
}

insert image description here

1. Problems

1. I used the QVBoxLayout layouter in the code, each QTabWidget and the corresponding QTreeWidget (or QWidget) are wrapped by a new QWidget (group1, group2 and group3). These QWidgets are then added to the main layout. In this way, the ProjectWin form will be divided into three pieces. From the above interface, it is divided into 5 parts. In fact, it looks like 5 parts, not 3 parts. This problem should be caused by adding some blank margins and spacing by default when QVBoxLayout adds QWidget. If you want the window to be divided into 3 parts, you can try to set the margin and spacing of the layout to 0, so that each part can occupy the space of the window evenly.
2. The second problem is that the layouter fails.
The reason is that I added the layouter to the UI file of the ProjectWin class through the mouse, so although the QVBoxLayout layouter is added to the .cpp, the layouter still fails. The solution is to add it to the UI file. Delete the layouter in , manually add the layouter code to the code

Two, the correct code

#include "ProjectWin.h"
#include "ui_ProjectWin.h"

#pragma execution_character_set("utf-8")

ProjectWin* ProjectWin::m_pInstance = nullptr;

ProjectWin* ProjectWin::getInstance()
{
    
    
    if(!m_pInstance)
    {
    
    
        m_pInstance = new ProjectWin();
        atexit(destroyInstance);
    }
    return m_pInstance;
}

void ProjectWin::destroyInstance()
{
    
    
    if(m_pInstance)
    {
    
    
        delete m_pInstance;
        m_pInstance = nullptr;
    }
}

ProjectWin::~ProjectWin()
{
    
    
    delete ui;
}

ProjectWin::ProjectWin(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::ProjectWin)
{
    
    
    ui->setupUi(this);

    //图像列表
    m_tabWidget = new QTabWidget();
    m_picTree = new QTreeWidget();
    m_picTree->setContextMenuPolicy(Qt::CustomContextMenu);
    m_picTree->setColumnCount(1);
    m_picTree->setHeaderHidden(true);
    connect(m_picTree, &QTreeWidget::itemClicked, this, &ProjectWin::onItemClicked);

    //图像参数
    m_tabWidgetPara = new QTabWidget();
    m_paraTree = new QTreeWidget();
    m_paraTree->setContextMenuPolicy(Qt::CustomContextMenu);
    m_paraTree->setColumnCount(1);
    m_paraTree->setHeaderHidden(true);

    //导航
    m_tabWidgetNavi = new QTabWidget();
    m_naviWgt = new QWidget();

    //创建三个部件组
    QWidget* picGroup = new QWidget();
    QWidget* paraGroup = new QWidget();
    QWidget* naviGroup = new QWidget();

    // 只设置QWidget的边框为0,不影响子元素
    picGroup->setStyleSheet("QWidget { border: 0px }");
    paraGroup->setStyleSheet("QWidget { border: 0px }");
    naviGroup->setStyleSheet("QWidget { border: 0px }");

    QVBoxLayout* picLayout = new QVBoxLayout();
    picLayout->setMargin(0);
    picLayout->setSpacing(0);
    picLayout->addWidget(m_tabWidget);
    picLayout->addWidget(m_picTree);
    picGroup->setLayout(picLayout);

    QVBoxLayout* paraLayout = new QVBoxLayout();
    paraLayout->setMargin(0);
    paraLayout->setSpacing(0);
    paraLayout->addWidget(m_tabWidgetPara);
    paraLayout->addWidget(m_paraTree);
    paraGroup->setLayout(paraLayout);

    QVBoxLayout* naviLayout = new QVBoxLayout();
    naviLayout->setMargin(0);
    naviLayout->setSpacing(0);
    naviLayout->addWidget(m_tabWidgetNavi);
    naviGroup->setLayout(naviLayout);

    // 设置窗口的主布局
    QVBoxLayout* mainLayout = new QVBoxLayout();
    mainLayout->setMargin(0);
    mainLayout->setSpacing(0);
    mainLayout->addWidget(picGroup);
    mainLayout->addWidget(paraGroup);
    mainLayout->addWidget(naviGroup);
    this->setLayout(mainLayout);
}

void ProjectWin::onItemClicked(QTreeWidgetItem *item, int column)
{
    
    
    QString imageName = item->text(0);
    emit sigShowImageBorder(imageName);
}

void ProjectWin::initWidget()
{
    
    

    //    m_picTree->header()->hide();//设置隐藏头
}

void ProjectWin::initPicTree()
{
    
    

}

void ProjectWin::slotPicTree(QVector<QString> lst, QString path)
{
    
    
    QTreeWidgetItem* topItem = new QTreeWidgetItem(m_picTree);
    topItem->setText(0, path);
    topItem->setCheckState(0, Qt::Checked);
    m_picTree->addTopLevelItem(topItem);
    int count = lst.size();
    //添加顶层节点
    if (lst.size() > 0)
    {
    
    
        for (int i = 0; i < lst.size(); i++)
        {
    
    
            //int size = lst.at(i).size();
            //int pos = lst.at(i).lastIndexOf("/");
            //QString temp = lst.at(i).right(size - pos - 1);
            QTreeWidgetItem* item = new QTreeWidgetItem(topItem);
            item->setText(0, lst.at(i));
            item->setCheckState(0, Qt::Checked);
        }
    }

    m_picTree->expandAll();
    //    m_grid = new QGridLayout(this);
    //    m_grid->addWidget(m_picTree);
    m_picTree->setStyleSheet(styles);

    //    this->setLayout(m_grid);

    m_tabWidget->addTab(m_picTree, u8"彩C");
}

void ProjectWin::slotParaTree(QVector<QString> lst, QString path)
{
    
    
    QTreeWidgetItem* topItem = new QTreeWidgetItem(m_paraTree);
    topItem->setText(0, path);
    topItem->setCheckState(0, Qt::Checked);
    m_paraTree->addTopLevelItem(topItem);
    int count = lst.size();
    //添加顶层节点
    if (lst.size() > 0)
    {
    
    
        for (int i = 0; i < lst.size(); i++)
        {
    
    
            //int size = lst.at(i).size();
            //int pos = lst.at(i).lastIndexOf("/");
            //QString temp = lst.at(i).right(size - pos - 1);
            QTreeWidgetItem* item = new QTreeWidgetItem(topItem);
            item->setText(0, lst.at(i));
            item->setCheckState(0, Qt::Checked);
        }
    }

    m_paraTree->expandAll();
    //    m_grid = new QGridLayout(this);
    //    m_grid->addWidget(m_picTree);
    m_paraTree->setStyleSheet(styles);

    //    this->setLayout(m_grid);


    m_tabWidgetPara->addTab(m_paraTree, u8"图像参数数据");
    m_paraTree->setStyleSheet(styles);
}

void ProjectWin::slotNavi(const QString& file)
{
    
    
    m_tabWidgetNavi->addTab(m_naviWgt, u8"导航");
}

3. Operation effect

insert image description here

Guess you like

Origin blog.csdn.net/aoxuestudy/article/details/130625935