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

From KDE TechBase
(kielenhuoltoa)
Line 16: Line 16:
==Lyhyesti==
==Lyhyesti==


Nyt kun meillä on perus tekstieditori, on aika tehdä siitä jollain tavalla hyödyllinen. Jokaisen tekstieditorilla pitäisi pystyä vähintäänkin tallettamaan tehdyt työt levylle sekä avata tekstitiedostoja käsittelyä varten.
Nyt kun meillä on yksinkertainen tekstieditori, on aika tehdä siitä jollain tavalla hyödyllinen. Jokaisella tekstieditorilla pitäisi pystyä ainakin tallentamaan tehdyt työt levylle sekä avaamaan tekstitiedostoja käsittelyä varten.


KDE tarjoaa joukon luokkia tiedostojen kanssa työskentelyä varten jotka helpottavat ohjelmistokehittäjän elämää. KIO-kirjasto mahdollistaa helpon tiedostojen käsittelyn verkkoprotokollien yli sekä se tarjoaa vakioidun tiedosto valikon tiedostojen avaamista ja tallettamista varten.
KDE tarjoaa tiedostojen kanssa työskentelyä varten joukon luokkia, jotka helpottavat ohjelmistokehittäjän elämää. KIO-kirjasto mahdollistaa helpon tiedostojen käsittelyn verkkoprotokollien yli sekä tarjoaa vakioidun tiedostovalikon tiedostojen avaamista ja tallentamista varten.


[[image:introtokdetutorial4.png|frame|center]]
[[image:introtokdetutorial4.png|frame|center]]
Line 306: Line 306:
</code>
</code>


Tässä funktiossa ei ole mitään erityistä tai uutta. Tässä vain päätellään, näytetäänkö tallennusvalikko vai ei. Jos <tt>fileName</tt> ei ole tyhjä, tallennetaan tiedosto mitään kysymättä nimellä joka on sijoitettuna <tt>fileName</tt>:n kutsumalla saveFileAs(QString)-funktiota, muuten kutsutaan yllä olevaa saveFileAs()-funktiota.
Tässä funktiossa ei ole mitään erityistä tai uutta. Tässä vain päätellään, näytetäänkö tallennusvalikko vai ei. Jos <tt>fileName</tt> ei ole tyhjä, tallennetaan tiedosto mitään kysymättä nimellä, joka on sijoitettuna <tt>fileName</tt>:n kutsumalla saveFileAs(QString)-funktiota, muuten kutsutaan yllä olevaa saveFileAs()-funktiota.


===Tiedoston avaaminen===
===Tiedoston avaaminen===


Lopulta olemme valmiit tarkastelemaan tiedoston avaamista levyltä. Kaikki koodi tätä tarkoitusta varten on sijoitettu <tt>MainWindow::openFile()</tt>-funktioon.
Lopulta olemme valmiita tarkastelemaan tiedoston avaamista levyltä. Kaikki koodi tätä tarkoitusta varten on sijoitettu <tt>MainWindow::openFile()</tt>-funktioon.


Ensin meidän pitää kysyä käyttäjältä, mikä tiedosto halutaan avattavan. Tätä tarkoitusta varten me käytämme toista <tt>KFileDialog</tt>-funktiota, <tt>getOpenFileName()</tt>:
Ensin meidän pitää kysyä käyttäjältä, mikä tiedosto halutaan avata. Tätä tarkoitusta varten käytetään toista <tt>KFileDialog</tt>-funktiota, <tt>getOpenFileName()</tt>:
<code cppqt>
<code cppqt>
QString fileNameFromDialog = KFileDialog::getOpenFileName();
QString fileNameFromDialog = KFileDialog::getOpenFileName();
</code>
</code>


Seuraavaksi käytämme KIO-kirjastoa tiedoston avaamiseen. KIO-kirjasto antaa meille mahdollisuuden avata tiedosto QFilen avulla, paikalliselta levyltä tai etäkoneelta, vaikkapa FTP:n yli. Tiedoston avaamiseksi käytämme {{class|NetAccess}}:n <tt>download()</tt>-funktiota:
Seuraavaksi käytämme KIO-kirjastoa tiedoston avaamiseen. KIO-kirjaston avulla voimme avata tiedoston QFilen avulla, paikalliselta levyltä tai etäkoneelta, vaikkapa FTP:n yli. Tiedoston avaamiseksi käytämme {{class|NetAccess}}:n <tt>download()</tt>-funktiota:
<code cppqt>
<code cppqt>
KIO::NetAccess::download(fileNameFromDialog, tmpFile, this)
KIO::NetAccess::download(fileNameFromDialog, tmpFile, this)
</code>
</code>
Ensimmäinen argumentti on avattavan tiedoston nimi. Toinen on QString, joka tiedoston hakemisen jälkeen, sisältää väliaikaisen tiedoston sijainnin. Tämän <tt>tmpFile</tt>:n kanssa jatkamme tästä eteenpäin.
Ensimmäinen argumentti on avattavan tiedoston nimi. Toinen on QString, joka tiedoston hakemisen jälkeen sisältää väliaikaisen tiedoston sijainnin. Tämän <tt>tmpFile</tt>:n kanssa jatkamme tästä eteenpäin.


Funktio palauttaa boolen arvon <tt>tosi</tt> tai <tt>epätosi</tt>, riippuen onnistuiko tiedoston siirto. Jos tiedoston haku epäonnistui, näytetään virheilmoitus:
Funktio palauttaa boolen arvon <tt>tosi</tt> tai <tt>epätosi</tt>, riippuen onnistuiko tiedoston siirto. Jos tiedoston haku epäonnistui, näytetään virheilmoitus:
Line 341: Line 341:
</code>
</code>


Talletetaan avatun tiedoston nimi(polkuineen):
Tallennetaan avatun tiedoston nimi(polkuineen):
<code cppqt>
<code cppqt>
fileName = fileNameFromDialog;
fileName = fileNameFromDialog;
Line 377: Line 377:


=== Komennot ===
=== Komennot ===
Itse käännös, asennus ja suoritus menee samalla tavalla kuin Perehdytyksessä 3.
Itse käännös, asennus ja suoritus tehdään samoin kuin Perehdytyksessä 3.


  mkdir build && cd build
  mkdir build && cd build

Revision as of 08:39, 22 February 2008


Development/Tutorials/Saving_and_loading


Tallettaminen ja Avaaminen
Tutorial Series   Beginner Tutorial
Previous   Perehdytys 3 - KActions ja XMLGUI
What's Next   Tutorial 5 - Using KCmdLineArgs
Further Reading   KIO::NetAccess QFile

Lyhyesti

Nyt kun meillä on yksinkertainen tekstieditori, on aika tehdä siitä jollain tavalla hyödyllinen. Jokaisella tekstieditorilla pitäisi pystyä ainakin tallentamaan tehdyt työt levylle sekä avaamaan tekstitiedostoja käsittelyä varten.

KDE tarjoaa tiedostojen kanssa työskentelyä varten joukon luokkia, jotka helpottavat ohjelmistokehittäjän elämää. KIO-kirjasto mahdollistaa helpon tiedostojen käsittelyn verkkoprotokollien yli sekä tarjoaa vakioidun tiedostovalikon tiedostojen avaamista ja tallentamista varten.

Koodi

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-tiedostoa ei ole muutettu mitenkään paitsi kaikki tutorial 3:t on vaihdettu tutorial 4:ksi.

mainwindow.h

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

class MainWindow : public KXmlGuiWindow {

 Q_OBJECT // *uusi*
 
 public:
   MainWindow(QWidget *parent=0);
 
 private:
   KTextEdit* textArea;
   void setupActions();
   QString fileName; // tiedoston nimi *uusi*
 private slots: // *uusi*
   void newFile(); // uusi tiedosto *uusi*
   void openFile(); // avaa tiedosto *uusi*  
   void saveFile(); // tallenna tiedosto *uusi*
   void saveFileAs(); // tallenna tiedosto nimellä *uusi*
   void saveFileAs(const QString &outputFileName); // *uusi*

};

  1. endif

Tiedostojen avaus ja tallennus mahdollisuuden aikaansaamiseksi meidän tarvitsee lisätä funktiot jotka tekevät tarvittavat asiat. Koska näitä funktoita tullaan kutsumaan Qt:n signal/slot-yhdistämismekanismin kautta, meidän tarvitsee määritellä nämä funktiot slot:ksi. Tämä on toteutettu rivillä 19. Koska käytämme slot:a tässä otsikkotiedostossa, meidän tarvitsee lisätä myös Q_OBJECT makro.

Haluamme myös pitää muistissa avaamamme tiedoston nimen, joten meidän tarvitsee esitellä myös 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> // *uusi*
  7. include <KMessageBox> //*uusi*
  8. include <KIO/NetAccess> //*uusi*
  9. include <KSaveFile> //*uusi*
  10. include <QTextStream> //*uusi*

MainWindow::MainWindow(QWidget *parent)

   : KXmlGuiWindow(parent),
     fileName(QString()) //*uusi*

{

 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()); //*uusi*

 KStandardAction::save(this, SLOT(saveFile()),
                       actionCollection()); //*uusi*

 KStandardAction::saveAs(this, SLOT(saveFileAs()),
                       actionCollection()); //*uusi*

 KStandardAction::openNew(this, SLOT(newFile()),
                       actionCollection()); //*uusi*

 setupGUI();

}

// * uutta tästä eteenpäin *

void MainWindow::newFile() {

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

}

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;

}

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"?> <!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> Tämä on muuten identtinen tutorial3ui.rc kanssa, paitsi nimi on muutettu 'tutorial4':ksi. Koska kaikki uudet toiminnot ovat KStandardAction:ta jotka KDE osaa automaattisesti käsitellä, tähän tiedostoon ei tarvitse lisätä mitään.

Selvitys

Selvitetään nyt hieman koodia joka tekee avaamisen sekä ja tallettamisen. Kaikki tarvittava on sijoitettu mainwindow.cpp-tiedostoon.

Ensimmäisenä, rivillä 16, meidän pitää lisätä fileName(QString()) MainWindow:n muodostajaan. Tällä varmistetaan että tiedoston nimi on tyhjä aloitettaessa.

Toimintojen lisääminen

Ensinnäkin meidän pitää lisätä liittymä ohjelman ulkopuolelle, jotta käyttäjät voivat kertoa ohjelmalle avataanko vai talletetaanko tiedosto. Samaan tapaan kuin Perehdytyksessä 3, lopeta-toiminnon kanssa, käytämme tähänkin tarkoitukseen KStandardActions:a riveillä 37-47. Kaikki uudet toiminnot on kytketty sopiviin sloteihin jotka esittelimme otsikkotiedostossa riveillä 20-24.

Uusi asiakirja

Ensimmäisenä funktio jonka loimme on newFile()-funktio. void MainWindow::newFile() {

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

} fileName.clear() asettaa fileName (QString) merkkijonon tyhjäksi kuvaamaan että tätä tiedostoa ei ole olemassa talletettuna minnekkään. textArea->clear() tyhjentää tekstialueen käyttäen samaa KAction:n clear-funktiota johon kytkimme Tyhjennä-toimionnon Perehdytyksessä 3.

Tiedoston tallettaminen

saveFileAs(QString)

Siirrymme nyt ensimmäiseen tiedostoja käsittelevään koodiin. Seuraavaksi syvennymme funktioon jonka tehtävänä on tallentaa tekstialueen sisältö paramterinä annetulla tiedostonimellä. KDE tarjoaa turvalliseen tiedoston tallettamiseen Qt:n QFile:a johdetun KSaveFile-luokan.

Funktion prototyyppi on: void MainWindow::saveFileAs(const QString &outputFileName)

Seuraavaksi luomme KSaveFile-objektin ja avaamme sen KSaveFile file(outputFileName); file.open();

Nyt kun meillä on tiedosto johon kirjoittaa, meidän pitää muotoilla teksti alueen sisältö sellaiseen muotoon joka on mahdollista kirjoittaa tiedostoon. Tätä tarkoitusta varten luomme QByteArray:n johon syötämme tekstialueen sisällön tekstinä, ilman muotoiluja, seuraavasti: QByteArray outputByteArray; outputByteArray.append(textArea->toPlainText()); Nyt meillä on KSaveFile::write():n kanssa käytettävä QByteArray calmiina. Normaalin QFile:n käyttäminen olisi myös mahdollista, ja se tallettaisi muutokset välittömästi, mutta jos tällöin tapahtuisi jokin virhe tallentamisen aikana, tulisi tiedostosta viallinen. Tästä syystä KSaveFile luo ensin väliaikaisen tiedoston, ja vasta kun kutsutaan KSaveFile::finalize()-funktiota, luodaan varsinainen tiedosto. file.write(outputByteArray); file.finalize(); file.close(); Ja lopuksi asetetaan MainWindows:n fileName osoittamaan tiedostoon jonka juuri tallensimme: fileName = outputFileName;

saveFileAs()

Tähän funktioon on yhdistetty saveAs(Tallenna nimellä) toiminto. Tämä funktio kutsuu saveFileAs(QString)-funktiota jolle lähetetään parametrinä KFileDialog::getSaveFileName():n palauttama tiedoston nimi.

void MainWindow::saveFileAs() {

 saveFileAs(KFileDialog::getSaveFileName());

}

Tässä kohdassa käytämme ensimmäisen kerran KIO-kirjastoa. KFileDialog-luokka tarjoaa meille joukon funktioita joita kaikki KDE ohjelmat käyttävät yleisten tiedostovalikoiden näyttämiseen. KFileDialog::getSaveFileName()-funktion kutsuminen tuo esille tiedostovalikon jossa käyttäjä voi valita tai vaihtaa tiedoston nimeä tai tallennussijaintia. Funktio palauttaa täydellisen tiedoston nimen, jonka me välitimme saveFileAs(QString)-funktiolle.

saveFile()

void MainWindow::saveFile() {

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

}

Tässä funktiossa ei ole mitään erityistä tai uutta. Tässä vain päätellään, näytetäänkö tallennusvalikko vai ei. Jos fileName ei ole tyhjä, tallennetaan tiedosto mitään kysymättä nimellä, joka on sijoitettuna fileName:n kutsumalla saveFileAs(QString)-funktiota, muuten kutsutaan yllä olevaa saveFileAs()-funktiota.

Tiedoston avaaminen

Lopulta olemme valmiita tarkastelemaan tiedoston avaamista levyltä. Kaikki koodi tätä tarkoitusta varten on sijoitettu MainWindow::openFile()-funktioon.

Ensin meidän pitää kysyä käyttäjältä, mikä tiedosto halutaan avata. Tätä tarkoitusta varten käytetään toista KFileDialog-funktiota, getOpenFileName(): QString fileNameFromDialog = KFileDialog::getOpenFileName();

Seuraavaksi käytämme KIO-kirjastoa tiedoston avaamiseen. KIO-kirjaston avulla voimme avata tiedoston QFilen avulla, paikalliselta levyltä tai etäkoneelta, vaikkapa FTP:n yli. Tiedoston avaamiseksi käytämme NetAccess:n download()-funktiota: KIO::NetAccess::download(fileNameFromDialog, tmpFile, this) Ensimmäinen argumentti on avattavan tiedoston nimi. Toinen on QString, joka tiedoston hakemisen jälkeen sisältää väliaikaisen tiedoston sijainnin. Tämän tmpFile:n kanssa jatkamme tästä eteenpäin.

Funktio palauttaa boolen arvon tosi tai epätosi, riippuen onnistuiko tiedoston siirto. Jos tiedoston haku epäonnistui, näytetään virheilmoitus: KMessageBox::error(this, KIO::NetAccess::lastErrorString());

Muussa tapauksessa jatketaan tiedoston avaamista.

Luomme uuden QFile:n välittämällä sen muodostajaan NetAccess::download():n luoman väliaikaistiedoston jonka jälkeen avataan se kirjoitussuojattuna: QFile file(tmpFile); file.open(QIODevice::ReadOnly);

Tuodaksemme avaamamme tiedoston sisällön ruudulle näkyviin, tarvitsee meidän käyttää QTextStream-luokkaa. QTextStream:n muodostajalle välitämme äsken avaamamme tiedoston (QFile file) ja kutsumme QFile:n readAll()-funktiota saadaksemme tekstin tiedostosta. Seuraavaksi välitämme tämän kaiken meidän tekstialueen setPlainText()-funktiolle: textArea->setPlainText(QTextStream(&file).readAll());

Tallennetaan avatun tiedoston nimi(polkuineen): fileName = fileNameFromDialog;

Ja lopuksi poistetaan NetAccess::download():n luoma väliaikaistiedosto: KIO::NetAccess::removeTempFile(tmpFile);

Käännä, Asenna ja Suorita

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)

Koska otimme nyt KIO-kirjaston käyttöön, tarvitsee meidän kertoa CMakelle että linkittäjän tarvitsee ottaa myös tämä mukaan. Tätä varten lisäämme target_link_libraries()-funktioon tiedon ${KDE4_KIO_LIBS}.

Komennot

Itse käännös, asennus ja suoritus tehdään samoin kuin Perehdytyksessä 3.

mkdir build && cd build
cmake .. -DCMAKE_INSTALL_PREFIX=$HOME
make install
$HOME/bin/tutorial4

Seuraavaksi

Seuraavana perehdytys: Komentoriviparametrit. (keskeneräinen, englanniksi)