Qt使用QVBoxLayout布局器失效

Qt系列文章目录

前言

我的需求是:这将创建一个垂直布局,并将三个标题和三个QTreeWidget添加到布局中,从上到下的顺序是:标题1,树1,标题2,树2,标题3,树3。你可以根据自己的需要调整这个布局和部件的设置。
m_tabWidget, m_picTree, m_tabWidgetPara, m_paraTree, m_tabWidgetNavi在你的主布局m_mainLayout中被垂直布局了,但是你没有给这些部件添加任何内容,所以他们可能没有显示出来。

在添加到主布局之前,你需要在你的QTabWidget和QTreeWidget部件中添加一些内容,才能让他们在UI中显示出来。以下是一些基本的例子,展示了如何给这些部件添加内容:
在这里插入图片描述
具体头文件:

#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

实现文件

#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"导航");
}

在这里插入图片描述

一、出现的问题

1.我在代码中使用了QVBoxLayout布局器,每个QTabWidget和对应的QTreeWidget(或QWidget)都被一个新的QWidget(group1,group2和group3)包裹起来。然后,这些QWidget被添加到主布局中。这样,ProjectWin窗体就会被分成三块。从上图的界面看是分成了5部分,其实是看起来像5部分,而不是3部分,这个问题应该是由于 QVBoxLayout 添加 QWidget 时默认添加了一些空白的边距和间距所导致的。如果想要窗口被分割成3部分,可以尝试设置布局的边距和间距为0,这样每个部分就可以平均地占据窗口的空间。
2.第二个问题是布局器失效
原因是我在ProjectWin类的UI文件通过鼠标加入了布局器,所以尽管在.cpp加入了QVBoxLayout布局器,但布局器还是失效了,解决办法是在UI文件中删除布局器,手动在代码中加入布局器代码

二、正确的代码

#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"导航");
}

三、运行效果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值