现在的位置: 首页 > 综合 > 正文

第10部份:文件导入

2013年11月24日 ⁄ 综合 ⁄ 共 2609字 ⁄ 字号 评论关闭

原文地址:http://www.dazzle.plus.com/linux/QtCreator/part10.htm

第10部份:文件导入

导入XML文件

这里我们可以让用户导入之前保存的XML文件格式的模拟数据。我们新添加一个“打开...”文件菜单,使用QFileDialog功能让用户可以选择要导入的文件,并且使用QXmlStreamWriter读取XML文件内容。

增强MainWindow

mainwindow.h

我们需要添加一个公共槽接收用户选择这个新的菜单动作的信号。

bool fileOpen(); // 如果成功加载模拟数据返回真

mainwindow.cpp

引入QXmlStreamWriter头文件。

#include <QXmlStreamReader>

在构造函数里,在我们先前创建保存动作的下面,创建和添加一个新的打开文件菜单动作。

QAction* openAction    = fileMenu->addAction( "&Open ...",         this, SLOT(fileOpen()) );

设置键盘快捷键。

openAction->setShortcut( QKeySequence::Open );

现在添加公共槽代码。在这个槽中我们询问用户文件名和文件目录,判断文件是否可读,并且使用QXmlStreamReader来处理文件。如果没有错误,新建一个场景替代旧的场景用来加载模拟数据。首先找到“qsimulate”这个元素。调用新场景的方法来读取其它信息。如果能成功读取XML文件,槽返回真,否则返回假。

/************************************* fileOpen **************************************/

bool  MainWindow::fileOpen()
{
  // 用户选择的文件
  QString filename = QFileDialog::getOpenFileName();
  if ( filename.isEmpty() ) return false;

  // 打开文件并判断是否可读
  QFile file( filename );
  if ( !file.open( QIODevice::ReadOnly ) )
  {
    showMessage( QString("Failed to open '%1'").arg(filename) );
    return false;
  }

  // 打开一个xml读取流加载模拟数据
  QXmlStreamReader  stream( &file );
  Scene*            newScene = new Scene( m_undoStack );
  while ( !stream.atEnd() )
  {
    stream.readNext();
    if ( stream.isStartElement() )
    {
      if ( stream.name() == "qsimulate" )
        newScene->readStream( &stream );
      else
        stream.raiseError( QString("Unrecognised element '%1'").arg(stream.name().toString()) );
    }
  }

  // 判断是否发生错误
  if ( stream.hasError() )
  {
    file.close();
    showMessage( QString("Failed to load '%1' (%2)").arg(filename).arg(stream.errorString()) );
    delete newScene;
    return false;
  }

  // 关闭文件,显示新场景,删除旧场景并显示有用的消息
  file.close();
  m_undoStack->clear();
  QGraphicsView*   view = dynamic_cast<QGraphicsView*>( centralWidget() );
  view->setScene( newScene );
  delete m_scene;
  m_scene = newScene;
  showMessage( QString("Loaded '%1'").arg(filename) );
  //作者忘记加上这行代码
  connect( m_scene, SIGNAL(message(QString)), this, SLOT(showMessageQString)) ); 
  return true;
}

增强scene

scene.h

添加类QXmlStreamReader的前置定义。

class QXmlStreamReader;

添加一个新的公共的场景方法从QXmlStreamReader读取模拟数据。

void  readStream( QXmlStreamReader* );                     // 从xml流读取数据

scene.cpp

引入类QXmlStreamReader头文件。

#include <QXmlStreamReader>

添加我们新场景的方法代码。这个方法根据从XML流中读取到“station”元素创建一个新的场景电台,并且从每个节点元素属性读取到的属性值设置它的x,y坐标。

/************************************ readStream *************************************/

void  Scene::readStream( QXmlStreamReader* stream )
{
  // 从xml流读取数据
  while ( !stream->atEnd() )
  {
    stream->readNext();
    if ( stream->isStartElement() && stream->name() == "station" )
    {
      qreal x = 0.0, y = 0.0;
      foreach( QXmlStreamAttribute attribute, stream->attributes() )
      {
        if ( attribute.name() == "x" ) x = attribute.value().toString().toDouble();
        if ( attribute.name() == "y" ) y = attribute.value().toString().toDouble();
      }
      addItem( new Station( x, y ) );
    }
  }
}

编译与运行
当你尝试运行程序新的代码将自动被编译。测试程序,导入你之前保存的文件。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

抱歉!评论已关闭.