Development/Tutorials/Saving and loading
Development/Tutorials/Saving_and_loading
Languages: عربي | Asturianu | Català | Česky | Kaszëbsczi | Dansk | Deutsch | English | Esperanto | Español | Eesti | فارسی | Suomi | Français | Galego | Italiano | 日本語 | 한국어 | Norwegian | Polski | Português Brasileiro | Română | Русский | Svenska | Slovenčina | Slovenščina | српски | Türkçe | Tiếng Việt | Українська | 简体中文 | 繁體中文
Tutorial Series | Beginner Tutorial |
Previous | Tutorial 3 - KActions |
What's Next | TODO (milliams) |
Further Reading | KIO::NetAccess QFile |
Abstract
Now that we have a basic text editor interface, it's time to make it do something useful.At the most basic a text editor needs to be able to load files from disc, save files that you've created or edited and create new files.
KDE provides a number of classes for working with files which make life a lot easier for developers. The KIO library allows you to easily access files through network-transparent protocols as well as providing standard file dialogs.
The Code
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 hasn't changed from tutorial 3 except to change any reference to tutorial 3 to tutorial 4.
mainwindow.h
- ifndef MAINWINDOW_H
- define MAINWINDOW_H
- include <KXmlGuiWindow>
- include <KTextEdit>
class MainWindow : public KXmlGuiWindow
{
Q_OBJECT //new from tutorial3
public:
MainWindow(QWidget *parent=0);
private:
KTextEdit* textArea;
void setupActions();
QString fileName; //new
private slots: //new
void newFile(); //new
void openFile(); //new
void saveFile(); //new
void saveFileAs(); //new
void saveFileAs(const QString &outputFileName); //new
};
- endif
Since we want to add the ability to load and save files, we must add the functions which will do the work. Since the functions will be called through Qt's signal/slot mechanism we must specify that these functions are slots as we do on line 19. Since we are using slots in this header file, we must also add the Q_OBJECT macro.
We also want to keep track of the filename of the currently opened file so we create a QString fileName.
mainwindow.cpp
- include "mainwindow.h"
- include <KApplication>
- include <KAction>
- include <KLocale>
- include <KActionCollection>
- include <KStandardAction>
- include <KFileDialog> //new
- include <KMessageBox> //new
- include <KIO/NetAccess> //new
- include <KSaveFile> //new
- include <QTextStream>
MainWindow::MainWindow(QWidget *parent)
: KXmlGuiWindow(parent),
fileName(QString()) //new
{
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()); //new
KStandardAction::save(this, SLOT(saveFile()),
actionCollection()); //new
KStandardAction::saveAs(this, SLOT(saveFileAs()),
actionCollection()); //new
KStandardAction::openNew(this, SLOT(newFile()),
actionCollection()); //new
setupGUI();
}
//New from here on
void MainWindow::newFile()
{
fileName.clear();
textArea->clear();
}
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());
}
}
void MainWindow::saveFile()
{
if(!fileName.isEmpty())
{
saveFileAs(fileName);
}
else
{
saveFileAs();
}
}
void MainWindow::saveFileAs()
{
saveFileAs(KFileDialog::getSaveFileName());
}
void MainWindow::saveFileAs(const QString &outputFileName)
{
KSaveFile file(outputFileName);
file.open();
QByteArray outputByteArray;
outputByteArray.append(textArea->toPlainText());
file.write(outputByteArray);
file.finalize();
file.close();
fileName = outputFileName;
}
tutorial4ui.rc
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
<gui name="tutorial4" version="1">
<ToolBar name="mainToolBar" >
<text>Main Toolbar</text>
<Action name="clear" />
</ToolBar>
<MenuBar>
<Menu name="file" >
<Action name="clear" />
</Menu>
</MenuBar>
</gui>
This is identical to tutorial3ui.rc from tutorial 3 except the name has changed to 'tutorial4'. We do not need to add any information about any of the KStandardActions since the placement of those actions is handled automatically by KDE.
Explanation
Make, Install And Run
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)
Since we are now using the KIO library, we must tell CMake to link against it. We do this by passing ${KDE4_KIO_LIBS} to the target_link_libraries() function.
With this file, the tutorial can built and run in the same way as tutorial 3. For more information, see tutorial 3.
mkdir build && cd build cmake .. -DCMAKE_INSTALL_PREFIX=$HOME make install $HOME/bin/tutorial4