上一篇文章介绍了如何使用QFileDialog来选择文件路径并读入项目界面,本文介绍如何使用Qt的序列化技术来将用户定义的一些变量保存到文件,用到的主要模块是QDataStream。
对象序列化 QDataStream
Qt提供了两个关键的二进制序列化模块:QDataStream
和QTextStream
,本文主要介绍常用简单对象二进制序列化技术QDataStream。希望在界面关闭的时候自动将用户修改的界面属性值保存到一个文件之中,以便后面读入的时候使用。 当然这种操作还有更好的方式,比如编写配置文件或者QSettings,此处只是为了使用模块而构造的一个场景。
![在这里插入图片描述](https://img-blog.csdnimg.cn/2020082714591970.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xsaXR0bGVzdGFyMTIz,size_16,color_FFFFFF,t_70#pic_center)
开始之前,我们需要先引入一个关键的事件QCloseEvent
,这个事件是用户在关闭界面时自动调用。 按照前面对事件的介绍,Qt中的事件函数一般都是基于事件虚函数重写即可。首先我们要在头文件包含QCloseEvent
。
#include <QCloseEvent>
然后在头文件的protected区域重定义这个事件处理函数:
protected:
void closeEvent(QCloseEvent *event) override; //重写事件函数
在CPP源文件中重写事件处理代码,一般的开发习惯是在最后将事件处理权限交回父类对象之中。
void mainWindow::closeEvent(QCloseEvent *event)
{
/*编写你的事件处理函数*/
return QMainWindow::closeEvent(event); //最后将事件处理交回父类
}
下一步构造一个属性序列化类,在关闭窗口的时候将界面的一些属性保存到本地硬盘之中,方便下次打开界面时读入上次的配置参数。
和前面一样,首先构造一个文件写操作,判断文件是否打开正常:
QFile file("config.ini");
if(!file.open(QIODevice::WriteOnly | QIODevice::Text))
return; //打开失败关闭
然后基于某IO对象(此处是file)构造一个数据序列化对象 out:
QDataStream out(&file)
;
为了保险,设置out的数据版本:
out.setVersion(QDataStream::Qt_4_0); //最好设置数据保存版本
依次写入界面的一些信息,此处主要写入了下拉菜单、编辑框和表格的信息:
out<<ui->lineEdit_input->text() //写入编辑框的值
<<qint8(ui->downList->currentIndex()); //写入下拉菜单编号
qint8 rowCount = ui->tableWidget->rowCount(); //写入表格行数
out<<rowCount;
for (int i=0;i<rowCount;i++) { //写入表格每行内容
out<<ui->tableWidget->item(i,0)->text()<<ui->tableWidget->item(i,1)->text();
}
最后关闭文件:
file.close(); //关闭文件
打开界面修改之后,项目时会将一些信息保存到文件config.ini之中。可以在文件夹路径打开文件,由于保存的是二进制文件,所以有一些信息无法以文本形式显示:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200827150316852.png#pic_center)
下次再打开界面时,我们希望能够直接读入这些信息进入界面,下面来实现这个读入的操作:
这个过程也可以使用界面打开时的事件函数paintEvent(QPaintEvent *event)
或者showEvent(QShowEvent *event)
来处理。 但是此处我们采用槽函数的方式来处理,下面定义一个槽函数:
void readIniFile(); //读入配置信息
在cpp源文件之中对槽函数进行实现:
void mainWindow::readIniFile()
{
}
下面在槽函数之中来对读入文件信息的代码进行实现,首先构造一个文件对象,然后判断是否打开正常,然后基于文件构造一个in对象:
QFile file("config.ini");
if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
return; //打开失败关闭
QDataStream in(&file);
in.setVersion(QDataStream::Qt_4_0); //最好设置数据保存版本
然后依次读入信息并修改界面的值,注意读入的顺序需要前面写入的一样,同时读入的值类型也要一样,特别是qint8的使用,读者可以分析一下原因。
QString lineEditText;
qint8 comboBoxIndex;
in>>lineEditText>>comboBoxIndex; //读入信息
ui->lineEdit_input->setText(lineEditText); //修改编辑框的值
ui->downList->setCurrentIndex(int(comboBoxIndex)); //修改下拉菜单序号
qint8 rowCount;
in>>rowCount;
for (int i=0;i<int(rowCount);i++) //读入并修改表格各个单元格的值
{
QString str1;
QString str2;
in>>str1>>str2;
ui->tableWidget->item(i,0)->setText(str1);
ui->tableWidget->item(i,1)->setText(str2);
}
最后记得关闭文件对象:
file.close(); //关闭文件对象
最后如果界面再打开始时就能读入信息,需要在构造函数中调用定义的槽函数:
ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); //表格均匀布满水平内容
connect(ui->btu_click,&QPushButton::clicked,this,&mainWindow::btnClicked); //建立信号和槽的联系
connect(ui->lineEdit_input,&QLineEdit::editingFinished,this,&mainWindow::inputFinished); //建立信号和槽的联系
connect(ui->downList,&QComboBox::currentTextChanged,this,&mainWindow::chooseChanged); //建立信号和槽的联系
readIniFile(); //构造函数中调用槽函数
然后编译运行代码,修改一些界面值:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200827150634553.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xsaXR0bGVzdGFyMTIz,size_16,color_FFFFFF,t_70#pic_center)
关闭界面,然后再打开界面,界面会记录上次修改的值:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200827150644180.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xsaXR0bGVzdGFyMTIz,size_16,color_FFFFFF,t_70#pic_center)
本文以界面配置信息保存为例来介绍如何使用QDataStream进行序列化的读写操作过程。不是所有的对象都能够被QDataStream序列化处理,Qt给出了可以处理的序列化对象如下,对于用户自己开发的复杂对象想要序列化,需要自己构造对象的“<<”和“>>”运算符。
|
|
bool |
• boolean |
qint8 |
• signed byte |
qint16 |
• signed 16-bit integer |
qint32 |
• signed 32-bit integer |
qint64 |
• signed 64-bit integer |
quint8 |
unsigned byte |
quint16 |
unsigned 16-bit integer |
quint32 |
unsigned 32-bit integer |
quint64 |
unsigned 64-bit integer |
float |
32-bit floating point number using the standard IEEE 754 format |
double |
64-bit floating point number using the standard IEEE 754 format |
const char* |
- The string length (quint32) -The string bytes, excluding the terminating 0 |
QBitArray |
- The array size (quint32) -The array bits, i.e. (size + 7)/8 bytes |
QBrush |
-The brush style (quint8) -The brush color (QColor) -If style is CustomPattern, the brush pixmap (QPixmap) |
QByteArray |
-If the byte array is null: 0xFFFFFFFF (quint32) - Otherwise: the array size (quint32) followed by the array bytes, i.e. size bytes |
QColor |
Color spec (qint8) Alpha value (quint16) Red value (quint16) Green value (quint16) Blue value (quint16) Pad value (quint16) |
QCursor |
Shape ID (qint16) If shape is BitmapCursor: The bitmap (QPixmap), mask (QPixmap), and hot spot (QPoint) |
QDate |
Julian day (quint32) |
QDateTime |
Date (QDate) Time (QTime) The time spec offsetFromUtc (qint32) if Qt::TimeSpec is offsetFromUtc TimeZone(QTimeZone) if Qt::TimeSpec is TimeZone |
QEasingCurve |
type (quint8) func (quint64) hasConfig (bool) If hasConfig is true then these fields follow: list period (double) amplitude (double) overshoot (double) |
QFont |
The family (QString) The style name (QString) The point size (double) The pixel size (qint32) The style hint (quint8) The style strategy (quint16) The char set (quint8) The weight (quint8) The font bits (quint8) The font stretch (quint16) The extended font bits (quint8) The letter spacing (double) The word spacing (double) The hinting preference (quint8) |
QHash<Key, T> |
The number of items (quint32) For all items, the key (Key) and value (T) |
QIcon |
The number of pixmap entries (quint32) For all pixmap entries: The pixmap (QPixmap) The file name (QString) The pixmap size (QSize) The mode (quint32) The state (quint32) |
QImage |
If the image is null a “null image” marker is saved; otherwise the image is saved in PNG or BMP format (depending on the stream version). If you want control of the format, stream the image into a QBuffer (using QImageIOHandler/QImageIOPlugin) and stream that. |
QKeySequence |
A QList, where each integer is a key in the key sequence |
QLinkedList < T > |
The number of items (quint32) The items (T) |
QList< T> |
The number of items (quint32) The items (T) |
QMap<Key, T> |
The number of items (quint32) For all items, the key (Key) and value (T) |
QMargins |
left (int) top (int) right (int) bottom (int) |
QMatrix |
m11 (double) m12 (double) m21 (double) m22 (double) dx(double) dy (double) |
QMatrix4x4 |
m11 (float) m12 (float) m13 (float) m14 (float) m21 (float m22 (float) m23 (float) m24 (float) m31 (float) m32 (float m33 (float) m34 (float) m41 (float) m42 (float) m43 (float m44 (float) |
QPair<T1, T2> |
first (T1) second (T2) |
QPalette |
The disabled, active, and inactive color groups, each of which consists of the following: foreground (QBrush) button (QBrush) light (QBrush) midlight (QBrush) dark (QBrush) mid (QBrush) text (QBrush) brightText (QBrush) buttonText (QBrush) base (QBrush) background (QBrush shadow (QBrush) highlight (QBrush) highlightedText (QBrush link (QBrush) linkVisited (QBrush) |
QPen |
The pen styles (quint8) The pen width (quint16) The pen color (QColor) |
QPicture |
The size of the picture data (quint32) The raw bytes of picture data (char) |
QPixmap |
Save it as a PNG image. |
QPoint |
The x coordinate (qint32) The y coordinate (qint32) |
QQuaternion |
The scalar component (float) The x coordinate (float) The y coordinate (float) The z coordinate (float) |
QRect |
left (qint32) top (qint32) right (qint32) bottom (qint32) |
QRegExp |
The regexp pattern (QString) Case sensitivity (quint8) Regular expression syntax (quint8) Minimal matching (quint8) |
QRegularExpression |
The regular expression pattern (QString) The pattern options (quint32) |
QRegion |
The size of the data, i.e. 8 + 16 * (number of rectangles) (quint32) 10 (qint32) The number of rectangles (quint32) The rectangles in sequential order (QRect) |
QSize |
width (qint32) height (qint32) |
QString |
If the string is null: 0xFFFFFFFF (quint32) Otherwise: The string length in bytes (quint32) followed by the data in UTF-16 |
QTime |
Milliseconds since midnight (quint32) |
QTransform |
m11 (double) m12 (double) m13 (double) m21 (double) m22 (double) m23 (double) m31 (double) m32 (double) m33 (double) |
QUrl |
Holds an URL (QString) |
QVariant |
The type of the data (quint32) The null flag (qint8) The data of the specified type |
QVector2D |
the x coordinate (float) the y coordinate (float) |
QVector3D |
the x coordinate (float) the y coordinate (float) the z coordinate (float) |
QVector4D |
the x coordinate (float) the y coordinate (float) the z coordinate (float) the w coordinate (float) |
QVector< T> |
The number of items (quint32) The items (T) |
欢迎同好沟通交流,批评指正,欢迎关注我的公号:不如起而行之