Qt系列文章目录

文章目录

  • Qt系列文章目录
  • 前言
  • 一、QSplitter是什么?
  • 二、具体代码
    • 1.头文件
    • 2.实现文件
  • 总结

前言

在Qt中把QWidget窗体三等分,我想实现QWidget中的三等分窗口能够像QDockWidget类一样用鼠标拖动这三等分窗体边缘使屏占比改变。一般我们会直接使用QDockWidget,但是我们这里只想鼠标拖拽,不需要窗体停靠的功能。
QDockWidget类提供了一个特殊的窗口部件,它可以是被锁在QMainWindow窗口内部或者是作为顶级窗口悬浮在桌面上。QDockWidget可以移动、悬浮,在许多工程软件中,都是使用dock布局窗口,用户可以自由组合窗口界面。
我们可以使用QSplitter控件,布局器中控件大小是根据窗口大小自动调整,用户能拉伸窗口但是不能直接拉伸界面内部的某个控件
先看一下效果

一、QSplitter是什么?

一个QSplitter是一个可以包含其他控件的控件,这些控件被一个分隔条隔开,托拽这个分隔条,可以改变splitter的子控件的大小。

QSplitter控件经常做为布局管理器使用,给用户提供更多的界面控制。
默认情况下,QSplitter动态调整子节点的大小,也即是鼠标按下拖动的时候,控件大小也随着变,如果希望QSplitter只在调整大小操作结束时调整子节点的大小,也即是鼠标按下拖动的时候不调整大小,释放鼠标之后,也即是调整结束后才调整大小,用setOpaqueResize(false) 来设置。

控件之间的初始大小分布由初始大小与拉伸因子相乘确定。还可以使用 setSizes() 来设置所有 控件的大小。函数 sizes() 返回用户设置的大小。或者,我们以分别使用 saveState() 和restoreState() 从QByteArray保存和恢复 之前控件的大小状态,等下一次启动的时候把这个状态再恢复就好啦。

当我们 hide() 一个子节点控件时,它的空间将被分配给其他的子节点。当我们 show() 它时,它将被恢复。
1.QSplitter的构造方法:

QSplitter *splitterMain=new QSplitter(Qt::Horizontal,0);

第一个参数通过Qt::Horizontal 和 Qt::Vertical来设定为水平分割或垂直分割。第二个设定0代表是主窗口,无父窗口。

不过子splitter设置的

new QSplitter(Qt::Vertical,splitterMain);

代表主窗口是splitterMain。则子splitter就被添加到splitterMain中。

添加时为从左至右(或从上至下)添加;

二、具体代码

1.头文件

#ifndef PROJECTWIN_H#define PROJECTWIN_H#include #include #include #include #include #include #include #include #include #include #include #include #include #include #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_OBJECTpublic:static ProjectWin* getInstance();~ProjectWin();FileMonitorMgr *m_fileMgr;QString m_paraFolder;private:QTreeWidget* m_picTree;//QTreeWidget* m_paraTree;QWidget* m_naviWgt;private:void initWidget();void initPicTree();void readParaFile(QString filePath);private:Ui::ProjectWin *ui;QGridLayout* m_grid;QWidget* m_centralWidget;QTabWidget* m_tabWidget;QTabWidget* m_tabWidgetPara;QTabWidget* m_tabWidgetNavi;QTextEdit*m_paraText;QVBoxLayout* m_mainLayout;static ProjectWin* m_pInstance;private:explicit ProjectWin(QWidget *parent = nullptr);static void destroyInstance();public:Q_SIGNALS:void sigShowImageBorder(const QString &imageName);//void appendText(const QString &text);public Q_SLOTS:void slotPicTree(QVector<QString> lst, QString path);void slotNavi(const QString& file);void onItemClicked(QTreeWidgetItem *item, int column);void slotParaInfo(QString imageName);void slotImageSelectNode(QString imageName);void slotUpdatePicTree(const QStringList& fileList);};#endif // PROJECTWIN_H

2.实现文件

#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_tabWidget->setStyleSheet("border: 0; background: transparent");//m_tabWidget->setStyleSheet("border: 0");m_picTree = new QTreeWidget();//m_picTree->setStyleSheet("border: 0; background: transparent");m_picTree->hide();m_picTree->setStyleSheet("border: 1");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_paraText = new QTextEdit();m_tabWidgetPara->addTab(m_paraText, u8"分裂器中间的窗体"/*u8"图像参数数据"*/);m_tabWidgetPara->setStyleSheet("border: 1");m_paraText->setStyleSheet("border: 1");//m_tabWidgetPara->setTabText(0, u8"图像参数数据");//导航m_tabWidgetNavi = new QTabWidget();m_naviWgt = new QWidget();m_tabWidgetNavi->addTab(m_naviWgt, u8"分裂器最下面的窗体"/*u8"导航"*/);//创建三个部件组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 }");QSplitter* splitter= new QSplitter(Qt::Vertical, this);splitter->addWidget(picGroup);splitter->addWidget(paraGroup);splitter->addWidget(naviGroup);QList<int> sizes;sizes << this->height() / 3 << this->height() / 3 << this->height() / 3;splitter->setSizes(sizes);// 设置拉伸比例,其中1、1、1表示三个窗口的初始尺寸比例都是1,即相等splitter->setStretchFactor(0, 1);splitter->setStretchFactor(1, 1);splitter->setStretchFactor(2, 1);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_paraText);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);mainLayout->addWidget(splitter);this->setLayout(mainLayout);//connect(this, &ProjectWin::appendText, m_paraText, &QTextEdit::append);}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::readParaFile(QString filePath){if (!m_paraText) {qDebug() << "m_paraText is null!";return;}m_paraText->clear();QString txtFile = filePath.left(filePath.size() -3);txtFile += "txt";QFile file(txtFile);if(!file.open(QIODevice::ReadOnly)) {qDebug() << file.errorString();return;}QTextStream in(&file);in.setCodec("UTF-8");// 设置编码为UTF-8while(!in.atEnd()) {QString line = in.readLine();//emit appendText(line);// 使用信号来添加文本m_paraText->append(line);// 这里处理每一行qDebug() << line;}file.close();}void ProjectWin::slotPicTree(QVector<QString> lst, QString path){m_paraFolder = path;m_picTree->show();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::slotParaInfo(QString imageName){QString fullPath = m_paraFolder + "/" + imageName;readParaFile(fullPath);}void ProjectWin::slotImageSelectNode(QString imageName){QList<QTreeWidgetItem *> items = m_picTree->findItems(imageName, Qt::MatchExactly | Qt::MatchRecursive);if(!items.empty()){m_picTree->setCurrentItem(items.at(0));}}void ProjectWin::slotUpdatePicTree(const QStringList &fileList){for(const QString& str : fileList){QTreeWidgetItem* item = new QTreeWidgetItem(m_picTree);item->setText(0, str);item->setCheckState(0, Qt::Checked);}}void ProjectWin::slotNavi(const QString& file){m_tabWidgetNavi->addTab(m_naviWgt, u8"导航");}

总结

主要是看ProjectWin的构造函数

ProjectWin::ProjectWin(QWidget *parent) :QWidget(parent),ui(new Ui::ProjectWin){ui->setupUi(this);//图像列表m_tabWidget = new QTabWidget();//m_tabWidget->setStyleSheet("border: 0; background: transparent");//m_tabWidget->setStyleSheet("border: 0");m_picTree = new QTreeWidget();//m_picTree->setStyleSheet("border: 0; background: transparent");m_picTree->hide();m_picTree->setStyleSheet("border: 1");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_paraText = new QTextEdit();m_tabWidgetPara->addTab(m_paraText, u8"分裂器中间的窗体"/*u8"图像参数数据"*/);m_tabWidgetPara->setStyleSheet("border: 1");m_paraText->setStyleSheet("border: 1");//m_tabWidgetPara->setTabText(0, u8"图像参数数据");//导航m_tabWidgetNavi = new QTabWidget();m_naviWgt = new QWidget();m_tabWidgetNavi->addTab(m_naviWgt, u8"分裂器最下面的窗体"/*u8"导航"*/);//创建三个部件组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 }");QSplitter* splitter= new QSplitter(Qt::Vertical, this);splitter->addWidget(picGroup);splitter->addWidget(paraGroup);splitter->addWidget(naviGroup);QList<int> sizes;sizes << this->height() / 3 << this->height() / 3 << this->height() / 3;splitter->setSizes(sizes);// 设置拉伸比例,其中1、1、1表示三个窗口的初始尺寸比例都是1,即相等splitter->setStretchFactor(0, 1);splitter->setStretchFactor(1, 1);splitter->setStretchFactor(2, 1);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_paraText);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);mainLayout->addWidget(splitter);this->setLayout(mainLayout);//connect(this, &ProjectWin::appendText, m_paraText, &QTextEdit::append);}