Development/Tutorials/Saving and loading (ru): Difference between revisions

From KDE TechBase
m (Text replace - "<code cppqt>" to "<syntaxhighlight lang="cpp-qt">")
No edit summary
 
(5 intermediate revisions by one other user not shown)
Line 1: Line 1:
{{Template:I18n/Language Navigation Bar|Development/Tutorials/Saving_and_loading}}
 


{{TutorialBrowser|
{{TutorialBrowser|
Line 25: Line 25:


===main.cpp===
===main.cpp===
<code cppqt n>
<syntaxhighlight lang="cpp-qt" line>
#include <KApplication>
#include <KApplication>
#include <KAboutData>
#include <KAboutData>
Line 46: Line 46:
   return app.exec();
   return app.exec();
}
}
</code>
</syntaxhighlight>
<tt>main.cpp</tt> практически не изменился с урока 3.
<tt>main.cpp</tt> практически не изменился с урока 3.


===mainwindow.h===
===mainwindow.h===
<code cppqt n>
<syntaxhighlight lang="cpp-qt" line>
#ifndef MAINWINDOW_H
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#define MAINWINDOW_H
Line 78: Line 78:


#endif
#endif
</code>
</syntaxhighlight>
Если мы хотим добавить возможность загружать и сохранять файлы, мы должны добавить функции которые будут делать это. Т.к. функции будут вызваны через механизм Qt [http://doc.trolltech.com/latest/signalsandslots.html сигнал/слот] мы должны обозначить, что эти функции - слоты, что мы и делаем на строке 19. Раз мы используем слоты, мы должны добавить макрос [http://doc.trolltech.com/latest/qobject.html#Q_OBJECT <tt>Q_OBJECT</tt>].
Если мы хотим добавить возможность загружать и сохранять файлы, мы должны добавить функции которые будут делать это. Т.к. функции будут вызваны через механизм Qt [http://doc.trolltech.com/latest/signalsandslots.html сигнал/слот] мы должны обозначить, что эти функции - слоты, что мы и делаем на строке 19. Раз мы используем слоты, мы должны добавить макрос [http://doc.trolltech.com/latest/qobject.html#Q_OBJECT <tt>Q_OBJECT</tt>].


Line 84: Line 84:


===mainwindow.cpp===
===mainwindow.cpp===
<code cppqt n>
<syntaxhighlight lang="cpp-qt" line>
#include "mainwindow.h"
#include "mainwindow.h"


Line 196: Line 196:
   }
   }
}
}
</code>
</syntaxhighlight>


===tutorial4ui.rc===
===tutorial4ui.rc===
<code xml n>
<syntaxhighlight lang="xml" line>
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="UTF-8"?>
<gui name="tutorial4"
<gui name="tutorial4"
Line 220: Line 220:


</gui>
</gui>
</code>
</syntaxhighlight>
Этот файл идентичен <tt>tutorial3ui.rc</tt> из урока 3, только поле  <tt>name</tt> изменилось на 'tutorial4'. Нам не нужно добавлять никакую информацию о любом <tt>KStandardAction</tt> т.к. их обработкой занимается KDE автоматически.
Этот файл идентичен <tt>tutorial3ui.rc</tt> из урока 3, только поле  <tt>name</tt> изменилось на 'tutorial4'. Нам не нужно добавлять никакую информацию о любом <tt>KStandardAction</tt> т.к. их обработкой занимается KDE автоматически.


Line 230: Line 230:
<syntaxhighlight lang="cpp-qt">
<syntaxhighlight lang="cpp-qt">
fileName(QString())
fileName(QString())
</code>
</syntaxhighlight>
в конструктор <tt>MainWindow</tt> на строке 16. Это очищает <tt>fileName</tt> с самого начала.
в конструктор <tt>MainWindow</tt> на строке 16. Это очищает <tt>fileName</tt> с самого начала.


Line 246: Line 246:
   textArea->clear();
   textArea->clear();
}
}
</code>
</syntaxhighlight>
<tt>fileName.clear()</tt> очищает переменную <tt>fileName</tt> типа QString, что отражает тот факт, что этого документа еще нет на диске. <tt>textArea->clear()</tt> очищает область текста, используя функцию <tt>clear</tt>, которую мы подключили к <tt>KAction</tt> в уроке 3.
<tt>fileName.clear()</tt> очищает переменную <tt>fileName</tt> типа QString, что отражает тот факт, что этого документа еще нет на диске. <tt>textArea->clear()</tt> очищает область текста, используя функцию <tt>clear</tt>, которую мы подключили к <tt>KAction</tt> в уроке 3.


Line 258: Line 258:
<syntaxhighlight lang="cpp-qt">
<syntaxhighlight lang="cpp-qt">
void MainWindow::saveFileAs(const QString &outputFileName)
void MainWindow::saveFileAs(const QString &outputFileName)
</code>
</syntaxhighlight>


Мы создаем объект <tt>KSaveFile</tt> и открываем файл:
Мы создаем объект <tt>KSaveFile</tt> и открываем файл:
Line 264: Line 264:
KSaveFile file(outputFileName);
KSaveFile file(outputFileName);
file.open();
file.open();
</code>
</syntaxhighlight>


Теперь у нас есть файл для записи, нам нужно отформатировать текст в текстовой области в формат, который может быть записан в файл. Для этого, мы создаем {{qt|QByteArray}} и заполняем его обычным текстом из текстовой области:
Теперь у нас есть файл для записи, нам нужно отформатировать текст в текстовой области в формат, который может быть записан в файл. Для этого, мы создаем {{qt|QByteArray}} и заполняем его обычным текстом из текстовой области:
Line 270: Line 270:
QByteArray outputByteArray;
QByteArray outputByteArray;
outputByteArray.append(textArea->toPlainText().toUtf8());
outputByteArray.append(textArea->toPlainText().toUtf8());
</code>
</syntaxhighlight>
Теперь у нас есть <tt>QByteArray</tt>, запишем его в файл с помощью <tt>KSaveFile::write()</tt>. Если бы мы использовали <tt>QFile</tt>, он бы моментально начал бы изменения в файле. Однако, если возникнет проблема посреди записи, файл будет поврежден. По этой причине <tt>KSaveFile</tt> сначала записывает данные во временный файл, а потом, когда вы вызываете <tt>KSaveFile::finalize()</tt> изменения попадают в текущий файл.
Теперь у нас есть <tt>QByteArray</tt>, запишем его в файл с помощью <tt>KSaveFile::write()</tt>. Если бы мы использовали <tt>QFile</tt>, он бы моментально начал бы изменения в файле. Однако, если возникнет проблема посреди записи, файл будет поврежден. По этой причине <tt>KSaveFile</tt> сначала записывает данные во временный файл, а потом, когда вы вызываете <tt>KSaveFile::finalize()</tt> изменения попадают в текущий файл.
<syntaxhighlight lang="cpp-qt">
<syntaxhighlight lang="cpp-qt">
Line 276: Line 276:
file.finalize();
file.finalize();
file.close();
file.close();
</code>
</syntaxhighlight>
Наконец, мы записываем в переменную <tt>MainWindow</tt> <tt>fileName</tt> имя файла в который только, что сохранили:
Наконец, мы записываем в переменную <tt>MainWindow</tt> <tt>fileName</tt> имя файла в который только, что сохранили:
<syntaxhighlight lang="cpp-qt">
<syntaxhighlight lang="cpp-qt">
fileName = outputFileName;
fileName = outputFileName;
</code>
</syntaxhighlight>


====saveFileAs()====
====saveFileAs()====
Line 291: Line 291:
   saveFileAs(KFileDialog::getSaveFileName());
   saveFileAs(KFileDialog::getSaveFileName());
}
}
</code>
</syntaxhighlight>


Это наше первое использование библиотеки KIO. {{class|KFileDialog}} предоставляет набор функций для отображения файловых диалогов, которые используют все приложения KDE. Вызов <tt>KFileDialog::getSaveFileName()</tt> отобразит диалог, где пользователь может выбрать файл в который сохранить или создать новый файл для сохранения. Функция возвращает полный путь к файлу, который передается функции <tt>saveFileAs(QString)</tt>.
Это наше первое использование библиотеки KIO. {{class|KFileDialog}} предоставляет набор функций для отображения файловых диалогов, которые используют все приложения KDE. Вызов <tt>KFileDialog::getSaveFileName()</tt> отобразит диалог, где пользователь может выбрать файл в который сохранить или создать новый файл для сохранения. Функция возвращает полный путь к файлу, который передается функции <tt>saveFileAs(QString)</tt>.
Line 309: Line 309:
   }
   }
}
}
</code>
</syntaxhighlight>


Тут ничего сложного или нового в этой функции, просто условие показывать или нет диалог сохранения. Если <tt>fileName</tt> не пустой, тогда файл сохраняется под именем <tt>fileName</tt>. Но если это не так, то отображаем диалог сохранения, чтобы пользователь мог выбрать файл для сохранения.
Тут ничего сложного или нового в этой функции, просто условие показывать или нет диалог сохранения. Если <tt>fileName</tt> не пустой, тогда файл сохраняется под именем <tt>fileName</tt>. Но если это не так, то отображаем диалог сохранения, чтобы пользователь мог выбрать файл для сохранения.
Line 320: Line 320:
<syntaxhighlight lang="cpp-qt">
<syntaxhighlight lang="cpp-qt">
QString fileNameFromDialog = KFileDialog::getOpenFileName();
QString fileNameFromDialog = KFileDialog::getOpenFileName();
</code>
</syntaxhighlight>


Затем мы используем библиотеку KIO, чтобы загрузить файл. Это позволяет нам открывать файлы с помощью QFile даже если они расположены удаленно. Мы вызываем функцию {{class|NetAccess}} <tt>download()</tt>
Затем мы используем библиотеку KIO, чтобы загрузить файл. Это позволяет нам открывать файлы с помощью QFile даже если они расположены удаленно. Мы вызываем функцию {{class|NetAccess}} <tt>download()</tt>
<syntaxhighlight lang="cpp-qt">
<syntaxhighlight lang="cpp-qt">
KIO::NetAccess::download(fileNameFromDialog, tmpFile, this)
KIO::NetAccess::download(fileNameFromDialog, tmpFile, this)
</code>
</syntaxhighlight>
Первый аргумент имя файла, который вы хотите загрузить. Второй -- QString, содержащий путь ко временной копии фала. Именно с <tt>tmpFile</tt> мы будем работать.
Первый аргумент имя файла, который вы хотите загрузить. Второй -- QString, содержащий путь ко временной копии фала. Именно с <tt>tmpFile</tt> мы будем работать.


Line 331: Line 331:
<syntaxhighlight lang="cpp-qt">
<syntaxhighlight lang="cpp-qt">
KMessageBox::error(this, KIO::NetAccess::lastErrorString());
KMessageBox::error(this, KIO::NetAccess::lastErrorString());
</code>
</syntaxhighlight>


В противном случае, мы продолжаем открывать файл.
В противном случае, мы продолжаем открывать файл.
Line 339: Line 339:
QFile file(tmpFile);
QFile file(tmpFile);
file.open(QIODevice::ReadOnly);
file.open(QIODevice::ReadOnly);
</code>
</syntaxhighlight>


Для отображения содержимого файла, мы используем {{qt|QTextStream}}. Мы создаем QTextStream и передаем в его конструктор содержимое фала, вызываем функцию QFile <tt>readAll()</tt>, что бы прочитать текст из файла. И вот это передается в функцию <tt>setPlainText()</tt> нашей текстовой области.
Для отображения содержимого файла, мы используем {{qt|QTextStream}}. Мы создаем QTextStream и передаем в его конструктор содержимое фала, вызываем функцию QFile <tt>readAll()</tt>, что бы прочитать текст из файла. И вот это передается в функцию <tt>setPlainText()</tt> нашей текстовой области.
Line 345: Line 345:
<syntaxhighlight lang="cpp-qt">
<syntaxhighlight lang="cpp-qt">
textArea->setPlainText(QTextStream(&file).readAll());
textArea->setPlainText(QTextStream(&file).readAll());
</code>
</syntaxhighlight>


Затем мы сохраняем путь к только что открытому файлу:
Затем мы сохраняем путь к только что открытому файлу:
<syntaxhighlight lang="cpp-qt">
<syntaxhighlight lang="cpp-qt">
fileName = fileNameFromDialog;
fileName = fileNameFromDialog;
</code>
</syntaxhighlight>
и наконец, удаляем временный файл созданный <tt>NetAccess::download()</tt>:
и наконец, удаляем временный файл созданный <tt>NetAccess::download()</tt>:
<syntaxhighlight lang="cpp-qt">
<syntaxhighlight lang="cpp-qt">
KIO::NetAccess::removeTempFile(tmpFile);
KIO::NetAccess::removeTempFile(tmpFile);
</code>
</syntaxhighlight>


==Сборка, Установка и Запуск==
==Сборка, Установка и Запуск==


===CMakeLists.txt===
===CMakeLists.txt===
<code cmake n>
<syntaxhighlight lang="make" line>
project(tutorial4)
project(tutorial4)
   
   
Line 378: Line 378:
install(FILES tutorial4ui.rc  
install(FILES tutorial4ui.rc  
         DESTINATION ${DATA_INSTALL_DIR}/tutorial4)
         DESTINATION ${DATA_INSTALL_DIR}/tutorial4)
</code>
</syntaxhighlight>
Теперь мы используем библиотеку KIO, мы должны сказать CMake слинковать приложение с ней. Это делается путем передачи <tt>${KDE4_KIO_LIBS}</tt> функции <tt>target_link_libraries()</tt>.
Теперь мы используем библиотеку KIO, мы должны сказать CMake слинковать приложение с ней. Это делается путем передачи <tt>${KDE4_KIO_LIBS}</tt> функции <tt>target_link_libraries()</tt>.


С помощью этого файла, урок может быть собран и запущен тем же путем, что и урок 3. Подробнее см. урок 3.
С помощью этого файла, урок может быть собран и запущен тем же путем, что и урок 3. Подробнее см. урок 3.
<code>
<syntaxhighlight lang="text">
mkdir build && cd build
mkdir build && cd build
cmake .. -DCMAKE_INSTALL_PREFIX=$HOME
cmake .. -DCMAKE_INSTALL_PREFIX=$HOME
make install
make install
$HOME/bin/tutorial4
$HOME/bin/tutorial4
</code>
</syntaxhighlight>


{{note|Измененные настройки сохраняются в вашем каталоге KDE: $HOME/.kde/share/apps/tutorial4.}}
{{note|Измененные настройки сохраняются в вашем каталоге KDE: $HOME/.kde/share/apps/tutorial4.}}

Latest revision as of 16:56, 19 July 2012


Загрузка и сохранение файлов
Tutorial Series   Beginner Tutorial
Previous   Урок 3 - KActions
What's Next   Tutorial 5 - Using KCmdLineArgs
Further Reading   Tutorial: Using KIO Slaves in your Program KIO::NetAccess QFile

Введение

Мы сделали интерфейс простого текстового редактора, самое время добавить к нему чего-нибудь полезного. Самое основное в чем нуждается текстовый редактор - это загрузка файлов с диска, сохранение файлов, которые были созданы/изменены и создание новых файлов.

KDE предоставляет набор классов для работы с файлами, которые делают жизнь разработчика намного легче. Библиотека KIO предоставляет вам легкий доступ к файлам через сеть, а так же стандартные диалоги выбора файла.

Листинг кода

main.cpp

#include <KApplication>
#include <KAboutData>
#include <KCmdLineArgs>
 
#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.

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <KXmlGuiWindow>
#include <KTextEdit>

class MainWindow : public KXmlGuiWindow
{
  Q_OBJECT //новое
  
  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); //новое
};

#endif

Если мы хотим добавить возможность загружать и сохранять файлы, мы должны добавить функции которые будут делать это. Т.к. функции будут вызваны через механизм Qt сигнал/слот мы должны обозначить, что эти функции - слоты, что мы и делаем на строке 19. Раз мы используем слоты, мы должны добавить макрос Q_OBJECT.

Так же нам нужно хранить имя открытого файла, поэтому объявляем переменную QString fileName.

mainwindow.cpp

#include "mainwindow.h"

#include <KApplication>
#include <KAction>
#include <KLocale>
#include <KActionCollection>
#include <KStandardAction>
#include <KFileDialog> //новое
#include <KMessageBox> //новое
#include <KIO/NetAccess> //новое
#include <KSaveFile> //новое
#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());
  }
}

tutorial4ui.rc

<?xml version="1.0" encoding="UTF-8"?>
<gui name="tutorial4"
     version="1"
     xmlns="http://www.kde.org/standards/kxmlgui/1.0"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://www.kde.org/standards/kxmlgui/1.0
                         http://www.kde.org/standards/kxmlgui/1.0/kxmlgui.xsd" >

  <MenuBar>
    <Menu name="file" >
      <Action name="clear" />
    </Menu>
  </MenuBar>

  <ToolBar name="mainToolBar" >
    <text>Main Toolbar</text>
    <Action name="clear" />
  </ToolBar>

</gui>

Этот файл идентичен tutorial3ui.rc из урока 3, только поле name изменилось на 'tutorial4'. Нам не нужно добавлять никакую информацию о любом KStandardAction т.к. их обработкой занимается KDE автоматически.

Объяснение

Хорошо, теперь напишем код, который будет загружать и сохранять. Все это мы допишем в mainwindow.cpp

Первая штука, которую добавим

fileName(QString())

в конструктор MainWindow на строке 16. Это очищает fileName с самого начала.

Добавление действий

Первое, что мы собираемся сделать, это предоставить пользователю интерфейс, что бы он мог сказать приложению "загрузить" и "сохранить". Как действие quit в уроке 3, мы будем использовать KStandardActions. На строках с 37 по 47 мы добавляем действия тем же путем, что и действие quit. Каждое из них мы соединяем с соответствующим слотом, который мы объявили в заголовочном файле.

Создание нового документа

Первая функция, которую мы создали - newFile():

void MainWindow::newFile()
{
  fileName.clear();
  textArea->clear();
}

fileName.clear() очищает переменную fileName типа QString, что отражает тот факт, что этого документа еще нет на диске. textArea->clear() очищает область текста, используя функцию clear, которую мы подключили к KAction в уроке 3.

Сохранение файла

saveFileAs(QString)

Теперь разберем наш первый обработчик. Мы собираемся реализовать функцию, которая сохраняет содержимое текстовой области в файл имя которого передается в функцию. KDE предоставляет класс для безопасного сохранения файла именуемый KSaveFile, который является производным от Qt'шного QFile.

Прототип функции:

void MainWindow::saveFileAs(const QString &outputFileName)

Мы создаем объект KSaveFile и открываем файл:

KSaveFile file(outputFileName);
file.open();

Теперь у нас есть файл для записи, нам нужно отформатировать текст в текстовой области в формат, который может быть записан в файл. Для этого, мы создаем QByteArray и заполняем его обычным текстом из текстовой области:

QByteArray outputByteArray;
outputByteArray.append(textArea->toPlainText().toUtf8());

Теперь у нас есть QByteArray, запишем его в файл с помощью KSaveFile::write(). Если бы мы использовали QFile, он бы моментально начал бы изменения в файле. Однако, если возникнет проблема посреди записи, файл будет поврежден. По этой причине KSaveFile сначала записывает данные во временный файл, а потом, когда вы вызываете KSaveFile::finalize() изменения попадают в текущий файл.

file.write(outputByteArray);
file.finalize();
file.close();

Наконец, мы записываем в переменную MainWindow fileName имя файла в который только, что сохранили:

fileName = outputFileName;

saveFileAs()

Эта функция к которой подключек слот saveAs. Она просто вызывает saveFileAs(QString) и передает ей имя файла возвращенное KFileDialog::getSaveFileName().

void MainWindow::saveFileAs()
{
  saveFileAs(KFileDialog::getSaveFileName());
}

Это наше первое использование библиотеки KIO. KFileDialog предоставляет набор функций для отображения файловых диалогов, которые используют все приложения KDE. Вызов KFileDialog::getSaveFileName() отобразит диалог, где пользователь может выбрать файл в который сохранить или создать новый файл для сохранения. Функция возвращает полный путь к файлу, который передается функции saveFileAs(QString).

saveFile()

void MainWindow::saveFile()
{
  if(!fileName.isEmpty())
  {
    saveFileAs(fileName);
  }
  else
  {
    saveFileAs();
  }
}

Тут ничего сложного или нового в этой функции, просто условие показывать или нет диалог сохранения. Если fileName не пустой, тогда файл сохраняется под именем fileName. Но если это не так, то отображаем диалог сохранения, чтобы пользователь мог выбрать файл для сохранения.

Загрузка файла

Наконец, мы не можем обойтись без загрузки фала с диска. Код для этого содержится в MainWindow::openFile().

Сначала мы должны спросить пользователя, какой файл он хочет открыть. Это делается с помощью KFileDialog, на этот раз getOpenFileName():

QString fileNameFromDialog = KFileDialog::getOpenFileName();

Затем мы используем библиотеку KIO, чтобы загрузить файл. Это позволяет нам открывать файлы с помощью QFile даже если они расположены удаленно. Мы вызываем функцию NetAccess download()

KIO::NetAccess::download(fileNameFromDialog, tmpFile, this)

Первый аргумент имя файла, который вы хотите загрузить. Второй -- QString, содержащий путь ко временной копии фала. Именно с tmpFile мы будем работать.

Функция возвращает true или false в зависимости от результата передачи (успешно/ошибка). Если произошла ошибка, мы отображаем сообщение с ошибкой:

KMessageBox::error(this, KIO::NetAccess::lastErrorString());

В противном случае, мы продолжаем открывать файл.

Мы создаем QFile работая со временным файлом созданным NetAccess::download() и открываем его в режиме только для чтения:

QFile file(tmpFile);
file.open(QIODevice::ReadOnly);

Для отображения содержимого файла, мы используем QTextStream. Мы создаем QTextStream и передаем в его конструктор содержимое фала, вызываем функцию QFile readAll(), что бы прочитать текст из файла. И вот это передается в функцию setPlainText() нашей текстовой области.

textArea->setPlainText(QTextStream(&file).readAll());

Затем мы сохраняем путь к только что открытому файлу:

fileName = fileNameFromDialog;

и наконец, удаляем временный файл созданный NetAccess::download():

KIO::NetAccess::removeTempFile(tmpFile);

Сборка, Установка и Запуск

CMakeLists.txt

project(tutorial4)
 
find_package(KDE4 REQUIRED)
include_directories(${KDE4_INCLUDES})
 
set(tutorial4_SRCS 
  main.cpp
  mainwindow.cpp
)
 
kde4_add_executable(tutorial4 ${tutorial4_SRCS})
 
target_link_libraries(tutorial4 ${KDE4_KDEUI_LIBS} 
                                ${KDE4_KIO_LIBS})
 
install(TARGETS tutorial4 DESTINATION ${BIN_INSTALL_DIR})
install(FILES tutorial4ui.rc 
        DESTINATION ${DATA_INSTALL_DIR}/tutorial4)

Теперь мы используем библиотеку KIO, мы должны сказать CMake слинковать приложение с ней. Это делается путем передачи ${KDE4_KIO_LIBS} функции target_link_libraries().

С помощью этого файла, урок может быть собран и запущен тем же путем, что и урок 3. Подробнее см. урок 3.

mkdir build && cd build
cmake .. -DCMAKE_INSTALL_PREFIX=$HOME
make install
$HOME/bin/tutorial4
Note
Измененные настройки сохраняются в вашем каталоге KDE: $HOME/.kde/share/apps/tutorial4.


Moving On

Теперь вы можете переходить к уроку KCmdLineArgs.