Archive:Development/Tutorials/Saving and loading (zh CN)

From KDE TechBase
Revision as of 12:28, 20 August 2008 by Tangooricha (talk | contribs)


Development/Tutorials/Saving_and_loading


教程4 - 保存与装载
Tutorial Series   初学者教程
Previous   教程3 - KActions
What's Next   教程5 - 使用KCmdLineArgs
Further Reading   KIO::NetAccess QFile

摘要

现在我们拥有了一个基本的文本编辑器的界面,已经到了做一些有用的事情的时候了。从最根本的来说,一个文本编辑器需要能够从磁盘中装载文件,并且能够创建新文件并保存你创建/编辑过的文件。

KDE提供了许多开发者易于使用的用于操作文件的类。KIO库允许你十分容易地像使用标准文件对话框一样通过网络访问文件。

代码

main.cpp

  1. include <KApplication>
  2. include <KAboutData>
  3. include <KCmdLineArgs>
  1. include "mainwindow.h"

int main (int argc, char *argv[]) {

 KAboutData aboutData( "tutorial4", "tutorial4",
     ki18n("Tutorial 4"), "1.0",
     ki18n("A simple text area which can load and save."),
     KAboutData::License_GPL,
     ki18n("Copyright (c) 2007 Developer") );
 KCmdLineArgs::init( argc, argv, &aboutData );
 KApplication app;

 MainWindow* window = new MainWindow();
 window->show();
 return app.exec();

} main.cpp 与教程3中的相比没什么变化,除了说明参数从教程3变为了教程4。

mainwindow.h

  1. ifndef MAINWINDOW_H
  2. define MAINWINDOW_H
  1. include <KXmlGuiWindow>
  2. include <KTextEdit>

class MainWindow : public KXmlGuiWindow {

 Q_OBJECT //与教程3相比,新增加的
 
 public:
   MainWindow(QWidget *parent=0);
 
 private:
   KTextEdit* textArea;
   void setupActions();
   QString fileName; //新增加的
 private slots: //新增加的
   void newFile(); //新增加的
   void openFile(); //新增加的
   void saveFile(); //新增加的
   void saveFileAs(); //新增加的
   void saveFileAs(const QString &outputFileName); //新增加的

};

  1. endif

由于我们想要添加装载和保存文件的能力,所以我们必须添加将用来完成这些工作的函数。由于这些函数将会通过Qt的信号/槽机制被调用,所以我们必须注明这些函数是槽函数,就像我们在第19行做的那样。由于我们正在头文件中使用槽,所以我们同样必须添加Q_OBJECT宏。

我们同样想要跟踪当前打开的文件的文件名,所以我们申明了一个QString fileName

mainwindow.cpp

  1. include "mainwindow.h"
  1. include <KApplication>
  2. include <KAction>
  3. include <KLocale>
  4. include <KActionCollection>
  5. include <KStandardAction>
  6. include <KFileDialog> //新增加的
  7. include <KMessageBox> //新增加的
  8. include <KIO/NetAccess> //新增加的
  9. include <KSaveFile> //新增加的
  10. include <QTextStream> //新增加的

MainWindow::MainWindow(QWidget *parent)

   : KXmlGuiWindow(parent),
     fileName(QString()) //新增加的

{

 textArea = new KTextEdit;
 setCentralWidget(textArea);

 setupActions();

}

void MainWindow::setupActions() {

 KAction* clearAction = new KAction(this);
 clearAction->setText(i18n("Clear"));
 clearAction->setIcon(KIcon("document-new"));
 clearAction->setShortcut(Qt::CTRL + Qt::Key_W);
 actionCollection()->addAction("clear", clearAction);
 connect(clearAction, SIGNAL(triggered(bool)),
         textArea, SLOT(clear()));

 KStandardAction::quit(kapp, SLOT(quit()),
                       actionCollection());

 KStandardAction::open(this, SLOT(openFile()),
                       actionCollection()); //新增加的

 KStandardAction::save(this, SLOT(saveFile()),
                       actionCollection()); //新增加的

 KStandardAction::saveAs(this, SLOT(saveFileAs()),
                       actionCollection()); //新增加的

 KStandardAction::openNew(this, SLOT(newFile()),
                       actionCollection()); //新增加的

 setupGUI();

}

//从这里开始都是新增加的

void MainWindow::newFile() {

 fileName.clear();
 textArea->clear();

}

void MainWindow::saveFileAs(const QString &outputFileName) {

 KSaveFile file(outputFileName);
 file.open();
 
 QByteArray outputByteArray;
 outputByteArray.append(textArea->toPlainText().toUtf8());
 file.write(outputByteArray);
 file.finalize();
 file.close();
 
 fileName = outputFileName;

}

void MainWindow::saveFileAs() {

 saveFileAs(KFileDialog::getSaveFileName());

}

void MainWindow::saveFile() {

 if(!fileName.isEmpty())
 {
   saveFileAs(fileName);
 }
 else
 {
   saveFileAs();
 }

}

void MainWindow::openFile() {

 QString fileNameFromDialog = KFileDialog::getOpenFileName();
 QString tmpFile;
 if(KIO::NetAccess::download(fileNameFromDialog, tmpFile, 
        this))
 {
   QFile file(tmpFile);
   file.open(QIODevice::ReadOnly);
   textArea->setPlainText(QTextStream(&file).readAll());
   fileName = fileNameFromDialog;
   KIO::NetAccess::removeTempFile(tmpFile);
 }
 else
 {
   KMessageBox::error(this, 
       KIO::NetAccess::lastErrorString());
 }

}