Qt保存和恢复页面布局

一、前言

很多软件在界面上的操作是很灵活的,例如PS,它的主面板是一个个吸附窗口堆叠起来的,用户可以自由拖拽、吸附,并且关闭软件再次打开软件,发现之前的拖拽、吸附完全保存下来了,所以用户可以自由的构建自己舒适的办公环境(软件界面),那这个效果是怎么实现的呢?

在Qt中使用​​saveState()​​​和​​restoreState(QByteArray)​​就可以完美的实现这种效果。

QByteArray QMainWindow::saveState(int version = 0) const;
bool QMainWindow::restoreState(const QByteArray &state, int version = 0);

二、效果展示

1、自由调整布局

2、重新打开软件

学习Qt开发不知道做什么?UP主为大家整理的这些领域都涉及到Qt开发:嵌入式领域、桌面端开发、移动端、微控制器MCU、客户端(游戏、直播等等)、汽车领域行业、 消费类电子设备、医疗领域行业、工业自动化领域等等

Qt框架,GUI应用程序,跨平台开发,信号与槽机制,QML语言,模型视图编程,多线程编程,数据库编程,网络编程,XML解析,JSON解析,图形图像处理,用户界面设计,动画效果,OpenGL,WebKit,嵌入式开发,客户端/服务器应用程序.自定义控件QT6,C++语言基础,qt基础编程,qt软件开发,Qt架构设计,qt布局管理器,qt嵌入式开发,qt编程入门,qt数据库编程,qt跨平台框架,QT项目实战,Quick模块,OpenCV,Qt实战,OpenCV教程,QT界面开发,Qt框架,C++数据结构,Qt线程,桌面应用开发,qt桌面应用开发,Socket网络编程,qt开发工程师,qt开发,应用程序开发框架,图形视图框架,数据库编程,Qt开发编程,Qt开发控件,Qt开发工程师,QT开发必备技能栈,qt编码,qt网络编程,qt网络通信,Qt信号,Qt槽机制,qt字符串,qt数据类型,qt容器,qt客户端开发,qt软件工程师,qt页面绘制

三、关键步骤

在程序的出口处,使用saveState保存界面布局

QString strPath = QCoreApplication::applicationDirPath() + "/UILayout.ini";
QFile file(strPath);
if(file.open(QIODevice::WriteOnly)) {
QDataStream outfile(&file);
QByteArray ba = this->saveState();
outfile<<ba;
file.close();
}

在程序的入口处,使用restoreState恢复界面布局

QString strPath = QCoreApplication::applicationDirPath() + "/UILayout.ini";
QFile file(strPath);
if(file.open(QIODevice::ReadOnly)) {
QByteArray ba;
QDataStream in(&file);
in>>ba;
file.close();
this->restoreState(ba);
}
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//程序入口处
QString strPath = QCoreApplication::applicationDirPath() + "/UILayout.ini";
QFile file(strPath);
if(file.open(QIODevice::ReadOnly)) {
QByteArray ba;
QDataStream in(&file);
in>>ba;
file.close();
this->restoreState(ba);
}
}
void MainWindow::closeEvent(QCloseEvent *event)
{
//程序出口处
QString strPath = QCoreApplication::applicationDirPath() + "/UILayout.ini";
QFile file(strPath);
if(file.open(QIODevice::WriteOnly))
{
QDataStream outfile(&file);
QByteArray ba = this->saveState();
outfile<<ba;
file.close();
}
}

四、详细代码

Qt框架,GUI应用程序,跨平台开发,信号与槽机制,QML语言,模型视图编程,多线程编程,数据库编程,网络编程,XML解析,JSON解析,图形图像处理,用户界面设计,动画效果,OpenGL,WebKit,嵌入式开发,客户端/服务器应用程序.自定义控件QT6,C++语言基础,qt基础编程,qt软件开发,Qt架构设计,qt布局管理器,qt嵌入式开发,qt编程入门,qt数据库编程,qt跨平台框架,QT项目实战,Quick模块,OpenCV,Qt实战,OpenCV教程,QT界面开发,Qt框架,C++数据结构,Qt线程,桌面应用开发,qt桌面应用开发,Socket网络编程,qt开发工程师,qt开发,应用程序开发框架,图形视图框架,数据库编程,Qt开发编程,Qt开发控件,Qt开发工程师,QT开发必备技能栈,qt编码,qt网络编程,qt网络通信,Qt信号,Qt槽机制,qt字符串,qt数据类型,qt容器,qt客户端开发,qt软件工程师,qt页面绘制 

Qt框架,GUI应用程序,跨平台开发,信号与槽机制,QML语言,模型视图编程,多线程编程,数据库编程,网络编程,XML解析,JSON解析,图形图像处理,用户界面设计,动画效果,OpenGL,WebKit,嵌入式开发,客户端/服务器应用程序.自定义控件QT6,C++语言基础,qt基础编程,qt软件开发,Qt架构设计,qt布局管理器,qt嵌入式开发,qt编程入门,qt数据库编程,qt跨平台框架,QT项目实战,Quick模块,OpenCV,Qt实战,OpenCV教程,QT界面开发,Qt框架,C++数据结构,Qt线程,桌面应用开发,qt桌面应用开发,Socket网络编程,qt开发工程师,qt开发,应用程序开发框架,图形视图框架,数据库编程,Qt开发编程,Qt开发控件,Qt开发工程师,QT开发必备技能栈,qt编码,qt网络编程,qt网络通信,Qt信号,Qt槽机制,qt字符串,qt数据类型,qt容器,qt客户端开发,qt软件工程师,qt页面绘制

Qt框架,GUI应用程序,跨平台开发,信号与槽机制,QML语言,模型视图编程,多线程编程,数据库编程,网络编程,XML解析,JSON解析,图形图像处理,用户界面设计,动画效果,OpenGL,WebKit,嵌入式开发,客户端/服务器应用程序.自定义控件QT6,C++语言基础,qt基础编程,qt软件开发,Qt架构设计,qt布局管理器,qt嵌入式开发,qt编程入门,qt数据库编程,qt跨平台框架,QT项目实战,Quick模块,OpenCV,Qt实战,OpenCV教程,QT界面开发,Qt框架,C++数据结构,Qt线程,桌面应用开发,qt桌面应用开发,Socket网络编程,qt开发工程师,qt开发,应用程序开发框架,图形视图框架,数据库编程,Qt开发编程,Qt开发控件,Qt开发工程师,QT开发必备技能栈,qt编码,qt网络编程,qt网络通信,Qt信号,Qt槽机制,qt字符串,qt数据类型,qt容器,qt客户端开发,qt软件工程师,qt页面绘制

本文福利,费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QT嵌入式开发,Quick模块等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QDebug>
#include <QCloseEvent>
#include <QDataStream>
#include <QByteArray>
#include <QCoreApplication>
#include <QMenuBar>
#include <QToolBar>
#include <QDockWidget>
#include <QLabel>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
void CreateMenuBar();
void CreateToolBar();
void CreateStatusBar();
protected:
void closeEvent(QCloseEvent *event);
private:
Ui::MainWindow *ui;
QDockWidget *dock_Image; // 图像窗口
QDockWidget* dock_Tool;// 工具箱窗口
QDockWidget* dock_Geom;// 几何变换窗口
QDockWidget* dock_Gray;// 灰度变换窗口
QDockWidget* dock_Enhance;// 图像增强窗口
QDockWidget* dock_Morp;// 形态学处理窗口
QDockWidget* dock_Color;// 颜色模型窗口
QDockWidget* dock_Prop;// 属性窗口
QDockWidget* dock_Output;// 输出窗口
};
#endif // MAINWINDOW_H

本文福利,费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QT嵌入式开发,Quick模块等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓

#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
QWidget* p = takeCentralWidget(); //删除中央窗体
if (p) {
delete p;
}
setDockNestingEnabled(true); //允许嵌套dock
//------------------------------------------------------------------------------
//创建菜单栏、工具栏、状态栏
CreateMenuBar();
CreateToolBar();
CreateStatusBar();
//------------------------------------------------------------------------------
//创建DockWidget
QDockWidget* dock_Image = new QDockWidget(tr("图像"), this);
dock_Image->setObjectName("dock_Image");
dock_Image->setFeatures(QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable); // 设置为可移动可浮动,但不可关闭
dock_Image->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); // 可移动范围:左右
dock_Image->setMinimumSize(600, 600); // 设置最小宽高
dock_Tool = new QDockWidget(tr("工具箱"), this); // 工具箱窗口,若想设置特征或移动范围,方法同上。
dock_Tool->setObjectName("dock_Tool");
dock_Geom = new QDockWidget(tr("几何变换"), this); // 几何变换窗口
dock_Geom->setObjectName("dock_Geom");
dock_Gray = new QDockWidget(tr("灰度变换"), this); // 灰度变换窗口
dock_Gray->setObjectName("dock_Gray");
dock_Enhance = new QDockWidget(tr("图像增强"), this); // 图像增强窗口
dock_Enhance->setObjectName("dock_Enhance");
dock_Morp = new QDockWidget(tr("形态学处理"), this); // 形态学处理窗口
dock_Morp->setObjectName("dock_Morp");
dock_Color = new QDockWidget(tr("颜色模型"), this); // 颜色模型窗口
dock_Color->setObjectName("dock_Color");
dock_Prop = new QDockWidget(tr("属性"), this); // 属性窗口
dock_Prop->setObjectName("dock_Prop");
dock_Output = new QDockWidget(tr("输出"), this); // 输出窗口
dock_Output->setObjectName("dock_Output");
// 进行布局
setCentralWidget(dock_Image); // 指定为中心窗口
addDockWidget(Qt::LeftDockWidgetArea, dock_Tool);
addDockWidget(Qt::BottomDockWidgetArea, dock_Output);
addDockWidget(Qt::RightDockWidgetArea, dock_Geom);
addDockWidget(Qt::RightDockWidgetArea, dock_Gray);
addDockWidget(Qt::RightDockWidgetArea, dock_Enhance);
addDockWidget(Qt::RightDockWidgetArea, dock_Morp);
addDockWidget(Qt::RightDockWidgetArea, dock_Color);
addDockWidget(Qt::RightDockWidgetArea, dock_Prop);
// 分割窗口
splitDockWidget(dock_Tool, dock_Image, Qt::Horizontal); // 水平
splitDockWidget(dock_Geom, dock_Output, Qt::Vertical); // 垂直
// 合并窗口
tabifyDockWidget(dock_Geom, dock_Gray);
tabifyDockWidget(dock_Gray, dock_Enhance);
tabifyDockWidget(dock_Enhance, dock_Morp);
tabifyDockWidget(dock_Morp, dock_Color);
tabifyDockWidget(dock_Output, dock_Prop);
dock_Geom->raise(); // raise()函数可使指定窗口置于最前
//-------------------------------------------------------------------------
//程序入口处
QString strPath = QCoreApplication::applicationDirPath() + "/UILayout.ini";
QFile file(strPath);
if(file.open(QIODevice::ReadOnly))
{
QByteArray ba;
QDataStream in(&file);
in>>ba;
file.close();
this->restoreState(ba);
}
}
MainWindow::~MainWindow()
{
}
void MainWindow::closeEvent(QCloseEvent *event)
{
//程序出口处
QString strPath = QCoreApplication::applicationDirPath() + "/UILayout.ini";
QFile file(strPath);
if(file.open(QIODevice::WriteOnly))
{
QDataStream outfile(&file);
QByteArray ba = this->saveState();
outfile<<ba;
file.close();
}
}
void MainWindow::CreateMenuBar()
{
QMenuBar * menuBar = new QMenuBar(this);
QMenu * menuFile = new QMenu("File", this);
QAction * newFile = new QAction(QIcon(), "NewFile", this);
QAction * openFile = new QAction(QIcon(), "OpenFile", this);
QAction * save = new QAction(QIcon(), "Save", this);
menuFile->addAction(newFile);
menuFile->addAction(openFile);
menuFile->addAction(save);
QMenu * menuEdit = new QMenu("Edit", this);
QAction * cut = new QAction(QIcon(), "Cut", this);
QAction * copy = new QAction(QIcon(), "Copy", this);
QAction * paste = new QAction(QIcon(), "Paste", this);
menuEdit->addAction(cut);
menuEdit->addAction(copy);
menuEdit->addAction(paste);
menuBar->addMenu(menuFile);
menuBar->addMenu(menuEdit);
this->setMenuBar(menuBar);
}
void MainWindow::CreateToolBar()
{
QToolBar * toolBar1 = new QToolBar(this);
toolBar1->setObjectName("toolBar1");
QAction * action1_1 = new QAction("action1_1", this);
QAction * action1_2 = new QAction("action1_2", this);
QAction * action1_3 = new QAction("action1_3", this);
QAction * action1_4 = new QAction("action1_4", this);
toolBar1->addAction(action1_1);
toolBar1->addAction(action1_2);
toolBar1->addAction(action1_3);
toolBar1->addAction(action1_4);
QToolBar * toolBar2 = new QToolBar(this);
toolBar2->setObjectName("toolBar2");
QAction * action2_1 = new QAction("action2_1", this);
QAction * action2_2 = new QAction("action2_2", this);
QAction * action2_3 = new QAction("action2_3", this);
QAction * action2_4 = new QAction("action2_4", this);
toolBar2->addAction(action2_1);
toolBar2->addAction(action2_2);
toolBar2->addAction(action2_3);
toolBar2->addAction(action2_4);
QToolBar * toolBar3 = new QToolBar(this);
toolBar3->setObjectName("toolBar3");
QAction * action3_1 = new QAction("action3_1", this);
QAction * action3_2 = new QAction("action3_2", this);
QAction * action3_3 = new QAction("action3_3", this);
QAction * action3_4 = new QAction("action3_4", this);
toolBar3->addAction(action3_1);
toolBar3->addAction(action3_2);
toolBar3->addAction(action3_3);
toolBar3->addAction(action3_4);
this->addToolBar(toolBar1);
this->addToolBar(toolBar2);
this->addToolBar(toolBar3);
}
void MainWindow::CreateStatusBar()
{
//创建状态栏
QStatusBar *status = new QStatusBar(this);
status->setObjectName("status");
status->setObjectName("状态栏");
status->setStyleSheet("QStatusBar::item{border: 0px}"); //设置不显示label的边框
//主窗口添加状态栏
this->setStatusBar(status);
//创建标签
QLabel *statusLabel = new QLabel("我是状态栏", this);
//状态栏添加信息
status->showMessage("我在3秒后会消失", 3000);//显示在左侧,并且3秒后自动消失
status->addPermanentWidget(statusLabel);//添加右侧标签(永久性)
}

本文福利,费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QT嵌入式开发,Quick模块等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值