原文地址:http://www.dazzle.plus.com/linux/QtCreator/part09.htm
第9部份:文件保存
XML文件保存
这里我们让用户以XML格式文件保存他们的模拟数据。我们添加一个新的文件菜单动作“另存为...”,使用QFileDialog中的功能让用户选择文件名和存储目录,并使用QXmlStreamWriter来编写XML格式文件。
增强MainWindow
我们需要添加一个公共槽方法接收用户选择新的菜单动作的信号。
bool fileSaveAs(); // 如果保存成功返回true
引入类QFileDialog,QXmlStreamWriter和QDateTime头文件。
#include <QFileDialog> #include <QXmlStreamWriter> #include <QDateTime>
在构造函数里更新创建菜单行代码,返回的指针存储在一个本地变量。
QMenu* fileMenu = menuBar()->addMenu( "&File" );
我们仍然在构造函数里创建并添加一个新的菜单保存动作。
// 创建文件菜单项 QAction* saveAction = fileMenu->addAction( "&Save As...", this, SLOT(fileSaveAs()) ); saveAction->setShortcut( QKeySequence::Save );
最后我们添加新的公共槽方法代码。在这个槽方法里我们询问用户文件名和文件保存目录,判断是否可以创建文件,然后使用QXmlStreamerWriter编写一份XML文件。在XML文件里我们创建一个“qsimulate”元素设置一些详实的信息,然后调用场景的一个新方法添加更详细的信息。如果XML文件被创建成功,槽返回真,否则返回假。
/************************************ fileSaveAs *************************************/ bool MainWindow::fileSaveAs() { // 用户选择的文件名和文件保存目录 QString filename = QFileDialog::getSaveFileName(); if ( filename.isEmpty() ) return false; // 打开文件并判断是否可写 QFile file( filename ); if ( !file.open( QIODevice::WriteOnly ) ) { showMessage( QString("Failed to write to '%1'").arg(filename) ); return false; } // 打开xml流,写入模拟数据 QXmlStreamWriter stream( &file ); stream.setAutoFormatting( true ); stream.writeStartDocument(); stream.writeStartElement( "qsimulate" ); stream.writeAttribute( "version", "2009-05" ); stream.writeAttribute( "user", QString(getenv("USERNAME")) ); stream.writeAttribute( "when", QDateTime::currentDateTime().toString(Qt::ISODate) ); m_scene->writeStream( &stream ); stream.writeEndDocument(); // 关闭文件,显示消息 file.close(); showMessage( QString("Saved to '%1'").arg(filename) ); return true; }
增强scene
scene.h
添加类QXmlStreamWriter的前置定义。
class QXmlStreamWriter;
添加一个场景的新的公共方法定义,使用QXmlStreamWriter写模拟数据。
void writeStream( QXmlStreamWriter* ); // 写场景数据到xml流
引入类QXmlStreamWriter头文件。
#include <QXmlStreamWriter>
添加场景新方法代码。这个方法里为场景里的每个电台创建一个“station”元素和它的x,y坐标属性。
/************************************ writeStream ************************************/ void Scene::writeStream( QXmlStreamWriter* stream ) { // 写电台数据到xml流 foreach( QGraphicsItem* item, items() ) { Station* station = dynamic_cast<Station*>( item ); if ( station ) { stream->writeEmptyElement( "station" ); stream->writeAttribute( "x", QString("%1").arg(station->x()) ); stream->writeAttribute( "y", QString("%1").arg(station->y()) ); } } }
编译和运行
当你尝试运行程序新的代码将自动被编译。测试程序,保存一份新的文件,检查文件内容。
下面的小例子是我们程序保存的文件。
<?xml version="1.0" encoding="UTF-8"?> <qsimulate version="2009-05" user="crookr" when="2009-11-06T23:38:47"> <station x="71" y="151"/> <station x="128" y="94"/> <station x="202" y="145"/> <station x="211" y="55"/> <station x="298" y="77"/> <station x="295" y="149"/> <station x="31" y="75"/> </qsimulate>