Tiedostonkäsittely ja asetusten tallentaminen Graafisen käyttöliittymän ohjelmointi Luento 14
Sisällys Asetusten tallentaminen (QSettings) Windowsin rekisteri Ini-tiedostot Tietovirrat ja tiedostonkäsittely QFileDialog Natiividialogi Qt:n filedialogi QStream Text stream Data stream Undo-Redo-toiminnallisuus
Asetusten tallentaminen (QSettings)
Asetusten tallentaminen QSettings Abstrahoi sovellusasetusten tallentamisen: asetukset voidaan tallentaa alustariippumattomasti Rekisteri (Windows) Ini-tiedosto (Unix) XML-tiedosto (Mac) Käyttää hyväkseen sovelluksen nimeä ja organisaation nimeä (ja domainia) QCoreApplication::setOrganizationName("Joku_lafka"); QCoreApplication::setApplicationName("Huippusofta");
QSettings Tallentaa asetukset avain-arvo-pareina (QString avain, QVariant arvo) value(), setvalue(), contains(), remove() Hierarkkisuus begingroup endgroup Soveltuu hyvin asetuksien säilömiseen, mutta ei tarkoitettu suurien datamäärien tallentamiseen
Esimerkki Widget::Widget(QWidget *parent) { QCoreApplication::setOrganizationName("Grako2010"); QCoreApplication::setApplicationName("esim_luento14"); QSettings settings; QVariant v = settings.value("mainwindow/pos",qvariant()); if(v.isvalid()) { QPoint p = v.topoint(); this->move(p); } } Widget::~Widget() { QSettings settings; settings.setvalue("mainwindow/pos",pos()); delete ui; } Default value, invalid variant
Asetusten etsiminen (Fallback-mekanismi) 1. Käyttäjä, sovellus 2. Käyttäjä, organisaatio 3. Järjestelmä, sovellus 4. Järjestelmä, organisaatio clear() ei tyhjennä fallback-asetuksia setfallbacksenabled(bool b)
Scope-asia jatkuu... enum QSettings::Scope QSettings::UserScope (oletus) QSettings::SystemScope HKEY_CURRENT_USER\Software\Grako2010\ esim_luento14 HKEY_LOCAL_MACHINE\Software\Grako2010\ esim_luento14 void QSettings::setPath(Format format, Scope scope, const QString& path)
Windowsin rekisteri Koostuu viidestä päähaarasta HKEY_CLASSES_ROOT HKEY_CURRENT_USER HKEY_LOCAL_MACHINE HKEY_USERS HKEY_CURRENT_CONFIG HKEY_CURRENT_USER/Software/Organization name / Software name HKEY_LOCAL_MACHINE/Software/Organization name / Software name
RegEdit32.exe
Rekisteriarvon etsiminen QSettings QStringList childkeys() QStringList childgroups() QStringList allkeys() bool contains(qstring key) begingroup()/endgroup()
Ini-tiedostot Formaatti, jota Qt tukee kaikilla alustoilla. Peräisin Windows-maailmasta Ei standardia Konversio QVariantista QStringiksi. Jos ei onnistu, käytetään @-syntaksia: paikka = @Point(100 100) Näppäriä. Unixissa NativeFormat ja IniFormat sama, ainoastaan tiedostotarkenne eroaa (.conf/.ini)
Ini-tiedostot (yhä) QSettings lukee Latin-1-enkoodattuja initiedostoja, mutta generoi ASCII-tiedostoja ASCII-yhteensopimattomat merkit eskapoidaan oletusarvoisesti ( standard ini escape sequences ) void QSettings::setIniCodec(QTextCodec* codec) Case-insensitive, kuten Windowsin rekisterikin
Ini-tiedostot (vieläkin) Windows-sovellusten yleinen tapa jättää hakemistopolkujen kenoviivat eskapoimatta muodostaa ongelman.
Halutun ini-tiedoston käsittely QSettings::QSettings ( const QString & filename, Format format, QObject * parent = 0 ) Format Qsettings::NativeFormat (Unix) QSettings::IniFormat Macissa vastaavasti myös: QSettings settings("/users/tjh/misc/plistfile.plist", QSettings::NativeFormat); Ja Windowsissa: QSettings settings("hkey_current_user\\software\\foo\\bar", QSettings::NativeFormat);
Demo QSettings-luokan käytöstä
Tiedostodialogit
QFileDialog properties enum QFileDialog::AcceptMode QFileDialog::AcceptOpen QFileDialog::AcceptSave enum QFileDialog::FileMode QFileDialog::AnyFile QFileDialog::ExistingFile QFileDialog::Directory QFileDialog::ExistingFiles enum QFileDialog::Option QFileDialog::ShowDirsOnly QFileDialog::DontConfirmOverwrite QFileDialog::DontUseNativeDialog
Tiedostofiltterin asettaminen Tiedostofiltteri void QFileDialog::setNameFilter ( const QString & filter ) QStringList filters; filters << "Image files (*.png *.xpm *.jpg)" << "Text files (*.txt)" << "Any files (*)"; QFileDialog dialog(this); dialog.setnamefilters(filters);
Natiivin filedialogin avaaminen QFileDialogin staattiset metodit avaavat natiivin tiedostodialogin QFileDialog::getExistingDirectory [static] QFileDialog::getOpenFileName [static] QFileDialog::getOpenFileNames [static] QFileDialog::getSaveFileName [static]
Tietovirrat ja tiedostoon tallentaminen
Text stream QTextStream(QIODevice* device) QIODevice QFile QBuffer
Tekstin kirjoittaminen virtaan QFile data("output.txt"); if (data.open(qfile::writeonly QFile::Truncate)) { QTextStream out(&data); out << "Grako 2010"; }
Muotoilu Kasa metodeja (lukujen) muotoiluun Globaaleja manipulaattorifunktioita (vrt. C++:n <iostream>-standardikirjasto) bin, oct, dec, hex fixed, scientific left, center, right ws qsetfieldwidth(), qsetpadchar(), qsetrealnumberprecision()
Muuta setcodec() setlocale() setfieldwidth(), setfieldalignment() setintegerbase()
Tekstin lukeminen virrasta Lohkoittain readline() readall() read(qint64 maxlen) Sanoittain Streamaus stringeihin tai puskureihin Väli erottelee, alussa whitespace skipataan. Merkeittäin skipwhitespace()
Lukeminen virrasta, esim. QFile data( input.txt"); if (data.open(qfile::readonly) { QTextStream in(&data); int value; in >> value; } // Rivien lukeminen QString line; do { line = data.readline(); } while (!line.isnull());
Data stream QDataStream (QIODevice* d) Binääridatan serialisointiin QIODeviceen C++:n perustietotyypit Monimutkaisempi data pilkottuna yksinkertaisempiin osiin monet Qt:n tyypit tuettuja Yhteensopivuus (kirjoitus/luku) setbyteorder(byteorder bo) QDataStream::BigEndian (MSB ensin, oletus) QDataStream::LittleEndian (LSB ensin) setfloatingpointprecision(floatingpointprecision p) Sarjallistamisformaatin muuttuminen versiointi readrawdata(), writerawdata(), readbytes(), writebytes()
Virtaan kirjoittaminen QFile file("file.dat"); file.open(qiodevice::writeonly); QDataStream out(&file); out<<"kissoja on "; //merkkijonon serialisointi out << (qint32)7; //... ja kokonaisluku
Virrasta lukeminen QFile file("file.dat"); file.open(qiodevice::readonly); QDataStream in(&file); QString s; qint32 kissoja; in >> s >> kissoja;
Muistiin kirjoittaminen QByteArray bytearray; QBuffer buffer(&bytearray); buffer.open(qiodevice::writeonly); QDataStream out(&buffer);
Binääri- vai tekstiformaatti? Binääri Tehokkaampaa Muutosherkkää Versiointi Versionumeron kovakoodaus: QDataStream::setVersion Kryptisempää voi olla hyvä tai huono asia Teksti Selkokielistä Helposti muiden ohjelmien käytössä Helposti muokattavaa XML-formaatti? QXmlStreamReader QSettings?
Demo tiedostodialogeista ja streameista
Undo Redo
Undo Redo Toteutusvaihtoehtoja 1. Tallennetaan ohjelman tila talteen jokaisen toiminnon yhteydessä Esim. sarjallistetaan muistiin QByteArray-oliona Helppoa, mutta hyvin tehotonta, käyttökelpoinen vain hyvin harvoissa tapauksissa 2. Pidetään kirjaa tehdyistä toiminnoista Command pattern Qt:n Undo framework
Undo framework Kaikki toiminnot suoritetaan komentoina, jotka tallennetaan undo-pinoon. Jokainen komento osaa peruuttaa itsensä, jolloin on mahdollista palata suorituksessa taaksepäin.
Undo framework QUndoCommand Kantaluokka undo-pinoon laitettaville komennoille QUndoStack Lista suoritetuista komennoista QUndoGroup Joukko undo-pinoja (erilliset pinot esim. erillisille avatuille dokumenteille, yksi aktiivinen pino) QUndoView Widgetti, joka näyttää undo-pinon sisällön, antaa siirtyä pinossa
Esimerkki class AppendText : public QUndoCommand { public: AppendText(QString *doc, const QString &text) : m_document(doc), m_text(text) { settext("append text"); } virtual void undo() { m_document->chop(m_text.length()); } virtual void redo() { m_document->append(m_text); } private: QString *m_document; QString m_text; };
Esimerkki http://doc.qt.nokia.com/4.7/tools-undoframework.html
Demo undo redosta
Lähteitä ja hyödyllisiä linkkejä http://doc.qt.nokia.com/4.7/qsettings.html http://doc.qt.nokia.com/4.7/qfiledialog.html http://doc.qt.nokia.com/4.7/qtextstream.html http://doc.qt.nokia.com/4.7/qdatastream.html http://doc.qt.nokia.com/4.7/qundo.html http://doc.qt.nokia.com/4.7/qundocommand.html http://doc.qt.nokia.com/4.7/qundostack.html http://doc.qt.nokia.com/4.7/qundogroup.html http://doc.qt.nokia.com/4.7/qundoview.html