[<< Contents] [<< Prev] [Next >>]
Here we enable the user to save their simulation data to an XML format file. We add a new File menu action "Save As ...", use QFileDialog functionality to let the user select the filename and location, and use QXmlStreamWriter functionality to write the XML file.
We need to add a public slot to receive the signal when user selects the new menu action.
bool fileSaveAs(); // save simulation to file returning true if successful |
Include the header files for the QFileDialog, QXmlStreamWriter, and QDateTime functionality.
#include <QFileDialog> #include <QXmlStreamWriter> #include <QDateTime> |
In the constructor update the line that creates the File menu to store the returned pointer in a local variable.
QMenu* fileMenu = menuBar()->addMenu( "&File" ); |
Still in the constructor we create and add the new save action to the File menu.
// create file menu options QAction* saveAction = fileMenu->addAction( "&Save As...", this, SLOT(fileSaveAs()) ); saveAction->setShortcut( QKeySequence::Save ); |
Finally we add the code for the new public slot. In this slot we ask the user for the filename and location for the file, check we can write to the file, and then create the XML file using QXmlStreamWriter functionality. Inside the XML file we create a "qsimulate" element with some informative attributes, and then call a new scene method to add further details. The slot returns true if a XML file was successfully produced, otherwise it returns false.
/************************************ fileSaveAs *************************************/
bool MainWindow::fileSaveAs()
{
// get user to select filename and location
QString filename = QFileDialog::getSaveFileName();
if ( filename.isEmpty() ) return false;
// open the file and check we can write to it
QFile file( filename );
if ( !file.open( QIODevice::WriteOnly ) )
{
showMessage( QString("Failed to write to '%1'").arg(filename) );
return false;
}
// open an xml stream writer and write simulation data
QXmlStreamWriter stream( &file );
stream.setAutoFormatting( true );
stream.writeStartDocument();
stream.writeStartElement( "qsimulate" );
stream.writeAttribute( "version", "2008-06" );
stream.writeAttribute( "user", QString(getenv("USER")) );
stream.writeAttribute( "when", QDateTime::currentDateTime().toString(Qt::ISODate) );
m_scene->writeStream( &stream );
stream.writeEndDocument();
// close the file and display useful message
file.close();
showMessage( QString("Saved to '%1'").arg(filename) );
return true;
}
|
Add a forward declaration for the QXmlStreamWriter class.
class QXmlStreamWriter; |
Add the declaration for the new public scene method that writes simulation data to a QXmlStreamWriter.
void writeStream( QXmlStreamWriter* ); // write scene data to xml stream |
Include the header file for QXmlStreamWriter.
#include <QXmlStreamWriter> |
Add the code for our new scene method. This method creates a new "station" element for each station on the scene with attributes giving its x & y coordinates.
/************************************ writeStream ************************************/
void Scene::writeStream( QXmlStreamWriter* stream )
{
// write station data to xml stream
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()) );
}
}
}
|
The new code will automatically re-compile when you attempt to run the application. Play with the application, save a few files and investigate the file contents.
Here is an example small file saved by our application.
<?xml version="1.0" encoding="UTF-8"?>
<qsimulate version="2008-06" user="dazzle" when="2008-06-21T08:58:16">
<station x="69" y="124"/>
<station x="109" y="56"/>
<station x="159" y="95"/>
<station x="213" y="61"/>
<station x="208" y="128"/>
<station x="284" y="108"/>
</qsimulate>
|
[<< Contents] [<< Prev] [Next >>]