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