Pagina principala
Informatii
Internationalizarea
pROgrame KDE/Qt
Download
Documentatii
Despre LKR
Contact
Resurse
Harta site-ului

Utilizarea KConfig XT


   Zack Rusin
   2004

Acest articol reprezinta traducerea si adaptarea dupa originalul publicat la: http://developer.kde.org/documentation/tutorials/kconfigxt/kconfigxt.html. Tot acest efort de traducere este meritul lui Daniel Ionescu <dan.ionescu@seca.ro>.

Acest articol va va prezenta conceptele principale ale generatiei viitoare a cadrului de lucru pentru configurare si va arata cum sa-l folositi eficient in aplicatia dumneavoastra.

Acest tutorial presupune ca cititorul a dezvoltat deja o aplicatie KDE si este familiarizat cu KConfig. Cunostinte de baza despre XML si conceptele din spatele DTD sint de asemenea necesare.

In acest tutorial caracteristicile cele mai avansate si optionale ale KConfig XT si descrierea lor sint marcate prin text italic. Daca va hotarati sa le sariti in timpul primei lecturi, asigurati-va ca va veti intoarce la ele la un moment dat.

Ideea principala din spatele KConfig XT este de a face munca dezvoltatorului de aplicatii mai usoara si totodata administrarea instalarii programelor KDE mai usor de realizat.

Cele patru parti ale noului cadru de lucru sint:

  • KConfigSkeleton - este o clasa din biblioteca de functii "libkdecore" ce garanteaza un acces mai flexibil la optiunile de configurare,
  • fisierul XML ce contine informatii despre optiunile de configurare (fisierul ".kcfg")
  • un fisier de tip "ini" ce furnizeaza optiunile de generare a codului (fisierul ".kcfgc")
  • kconfig_compiler - care genereaza codul sursa C++ din fisierele ".kcfg" si ".kcfgc". Clasa generata se bazeaza pe KConfigSkeleton si furnizeaza aplicatiei un API pentru accesarea datelor sale de configurare.

Structura DTD a .kcfg

Structura fisierului ".kcfg" este descrisa de DTD-ul sau sau de catre biblioteca "kdecore". Fisierul kcfg.dtd este disponibil la http://www.kde.org/standards/kcfg/1.0/kcfg.dtd. Retineti ca navigatoarele de web nu afiseaza DTD-urile intr-o forma vizuala. Descarcati DTD-ul in mod direct si cititi-l ca pe un fisier de tip text. Va rog sa parcurgeti fisierul DTD inainte de a merge mai departe.

Sa cream un fisier simplu kcfg. Luati ca referinta codul de mai jos pe masura ce parcurgem fiecare pas.


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE kcfg
  SYSTEM "http://www.kde.org/standards/kcfg/1.0/kcfg.dtd">
<kcfg>
  <kcfgfile name="kjotsrc"/>
  <group name="kjots">
    <entry name="SplitterSizes" type="IntList">
      <label>How the main window is divided.</label>
    </entry>
    <entry name="Width" type="Int">
      <label>Width of the main window.</label>
      <default>600</default>
    </entry>
    <entry name="Height" type="Int">
      <label>Height of the main window.</label>
      <default>400</default>
    </entry>
    <entry name="OpenBooks" type="StringList">
      <label>All books that are opened.</label>
    </entry>
    <entry name="CurrentBook" type="String">
      <label>The book currently opened.</label>
    </entry>
    <entry name="Font" type="Font">
      <label>The font used to display the
      contents of books.</label>
      <default code="true"
      >KGlobalSettings::generalFont()</default>
    </entry>
  </group>
</kcfg>
kjots.kcfg

  1. Folositi editorul de text favorit pentru a deschide fisierul "numele_aplicatiei.kcfg" (bineinteles, inlocuind "numele_aplicatiei" cu numele aplicatiei pe care doriti sa o convertiti la KConfig XT).
  2. Incepeti acest fisier deschizind tagul <kcfgfile> care contine atributul "name" a carui valoare corespunde actualului fisier KConfig pe care il descrie. (Fisierul KConfig propriu-zis descrie fisiere "rc").
  3. Adaugati tagurile optionale <include> care contin numele fisierelor antet C++ necesare compilarii codului cerut pentru a calcula valorile implicite.
  4. Restul tagurilor <entry> din fisierul XML sint grupate sub tagul <group> care descrie grupurile corespunzatoare din fisierul de configurare.
    1. Individual, fiecare <entry> trebuie sa aiba cel putin atributul "name" sau "key". "name" este folosit pentru a crea functiile de accesare si modificare. De asemenea, este folosit ca cheie in fisierul de configurare. Daca <key> este dat, dar nu si <name>, "name" este construit eliminind toate spatiile din continutul lui <key>.
    2. Intotdeauna adaugati aplicatiei dumneavoastra un tag <label> sau un tag <whatsthis>, prin care descrieti optiunile de configurare. Tagul <label> este folosit pentru o scurta descriere a unui <entry>, in timp ce tagul <whatsthis> contine o documentatie mai ampla. Acest lucru este important pentru utilitare precum KConfigEditor care pot fi folosite de administratorii de sistem la configurarea masinilor prin retea.
    3. Un <entry> trebuie sa aiba un tip. Lista cu tipurile permise este specificata in DTD si urmeaza intr-o maniera libera lista tipurilor suportate de QVariant cu exceptia, bineinteles, a tipurilor binare (de exemplu: Pixmap, Image...) care nu sint suportate. Alaturi de aceste tipuri de baza sint suportate si incluse urmatoarele tipuri speciale:
      • Path - Acesta este un sir de caractere ce este tratat intr-un mod special, ca o cale catre un fisier. In particular, cind sint stocate in fisierul de configurare, caile din directorul personal sint prefixate cu $HOME.
      • Enum - Acesta indica o enumerare. Posibilele valori ale "enum" ar trebui furnizate printr-un tag <choices>. Valorile unei enumerari sint accesate ca intregi de catre aplicatie, dar sint stocate ca siruri de caractere in fisierul de configurare. Aceasta face posibila adaugarea, mai tirziu, mai multor valori fara a distruge compatibilitatea.
      • IntList - Acesta indica o lista de intregi. Aceasta informatie este furnizata aplicatiei ca un obiect QValueList<int>, folositor pentru stocarea geometriei obiectelor QSplitter.

      Un <entry> poate avea, optional, o valoare implicita care este folosita cind valoarea nu este specificata in nici un fisier de configurare. Valorile implicite sint interpretate ca valori constante de tip caracter. Daca o valoare implicita trebuie sa fie calculata sau daca trebuie sa fie obtinuta prin apelul unei functii, tagul <default> trebuie sa contina atributul code="true". Astfel, continutul tagului <default> este considerat a fi o expresie C++.

      Codul aditional pentru calculul valorilor implicite poate fi furnizat prin tagul <code>. Continutul tagului <code> este considerat o expresie C++. O utilizare tipica a acestuia este calcularea unei valori implicite comune la care apoi, <entry>-urile multiple ce urmeaza pot face referire.

Fisierele .kcfgc

Dupa crearea unui fisier ".kcfg" creati un fisier ".kcfgc" care descrie optiunile pentru generarea fisierului C++. Fisierul ".kcfgc" este un simplu fisier de tip "ini" cu formatul tipic entry=value. Pentru a crea un simplu fisier ".kcfgc" parcurgeti urmatorii pasi:

  1. Deschideti un fisier nou in editorul de text preferat.
  2. Incepeti cu inregistrarea File=nume_aplicatie.kcfg care specifica unde sint stocate optiunile de configurare.
  3. Adaugati inregistrarea ClassName=NumeleClaseiDeConfigurare care specifica numele clasei ce va fi generata din fisierul ".kcfg.". Observatie: clasa generata va fi derivata din KConfigSkeleton. Asigurati-va ca NumeleClaseiDeConfigurare nu este numele unei clase folosite in aplicatia dumneavoastra. Salvati acest fisier sub denumirea "numeleclaseideconfigurare.kcfgc". Aceasta va asigura generarea fisierelor numeleclaseideconfigurare.{h,cpp} in care se va afla clasa de configurare.
  4. Adaugati orice inregistrare aditionala de care aplicatia dumneavoatra poate avea nevoie. Aceste inregistrari aditionale pot fi:
    • NameSpace - specifica spatiul de nume in care trebuie sa fie clasa de configurare generata,
    • Inherits - daca aveti nevoie ca clasa generata sa mosteneasca clasa dumneavoastra particularizata,
    • Singleton - daca clasa de configurare ar trebui sa fie un singleton,
    • MemberVariables - specifica accesul la variabilele membre; implicit este privat,
    • ItemAccessors - are legatura cu elementul de mai sus; daca variabilele membre sint publice, atunci nu ar mai avea sens generarea functiilor de acces (accessors). Implicit ele sint generate,
    • Mutators - similar cu elementul de mai sus, dar se aplica metodelor mutator,
    • GlobalEnums - specifica daca variabilele de tip enum ar trebui sa fie globale sau daca ele ar trebui sa fie intotdeauna prefixate in mod explicit cu numele tipului lor.

Ajustarea fisierului Makefile.am

Dupa crearea fisierelor ".kcfg" si ".kcfgc", urmatorul pas este ajustarea fisierului Makefile.am pentru a permite compilatorului kconfig generarea clasei cerute la momentul compilarii.

Din fericire modificarile sint simple si necesita doar doi pasi:

  1. Adaugarea fisierului ".kcfgc" la inregistrarea numele_aplicatiei_SOURCES,
  2. Adaugati o inregistrare care arata astfel:
    kde_kcfg_DATA = numele_aplicatiei.kcfg

Prima modificare asigura faptul ca clasa de configurare este generata in mod corespunzator, iar a doua ca fisierul ".kcfg" este instalat si poate fi folosit de utilitare precum KConfigEditor.

Folosire si ferestre de dialog

Dupa ce ati facut toate modificarile de mai sus sinteti gata sa folositi KConfig XT. Fisierul antet generat de kconfig_compiler va avea acelasi nume cu valoarea pe care ati specificat-o in atributul ClassName din fisierul ".kcfgc" la care se adauga extensia ".h". Includeti acel fisier ori de cite ori doriti sa accesati optiunile de configurare.

Folosirea va depinde de adaugarea inregistrarii Singleton=true in fisierul kcfgc. Una din cele mai dragute particularitati ale KConfig XT este integrarea usoara cu ferestrele de dialog generate de Qt Designer. Puteti sa faceti acest lucru folosind KConfigDialog. Iata care sint pasii:

  1. Creati KConfigDialog si transmiteti instanta datelor de configurare ca unul dintre argumente. Constructorul poate arata ca in exemplul urmator: KConfigDialog* dialog = new KConfigDialog(this, "settings", SetariAplicatie::self()); presupunind ca SetatiAplicatie este valoarea variabilei ClassName din fisierul kcfgc si clasa de configurare este de tip singleton.
  2. In Qt Designer creati elemente de interfata care pot fi folosite la configurarea optiunilor dumneavoastra. Pentru a face aceste elemente de interfata sa interactioneze cu kcfg, trebuie sa le denumiti pe fiecare folosind urmatoarea schema:
    1. Prefixati numele elementului de interfata care poate controla una dintre optiuni cu kcfg_
    2. Adaugati la numele elementului de interfata valoarea atributului "name" din fisierul kcfg care corespunde optiunii pe care elementul de interfata trebuie sa o controleze.
  3. Adaugati elementul de interfata generat de Qt Designer la KConfigDialog.
  4. Faceti vizibila fereastra de dialog in momentul in care ati terminat.

Exemplu

Iata un exemplu de utilizare KConfig XT pentru aplicatia numita "Exemplu", cu urmatorul fisier "exemplu.kcfg":


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE kcfg
  SYSTEM"http://www.kde.org/standards/kcfg/1.0/kcfg.dtd">
<kcfg> <kcfgfile name="exemplurc"/>
  <group name="network">
    <entry name="ServerName" type="String">
      <label>Defineste eticheta model de server.</label>
    </entry>
    <entry name="Port" type="Int">
      <label>Defineste portul server-ului</label>
      <default>21</default>
    </entry>
  </group>
</kcfg>
exemplu.kcfg

Iata si modul de folosire a clasei generate pentru fisierul kcfgc dat.


File=exemplu.kcfg
ClassName=SetariExemplu
Singleton=true
Mutators=true
exemplu.kcfgc

Fisierele antet nu ar trebui sa se modifice, dar fisierele cpp trebuie sa contina acum urmatorul cod pentru a accesa si stoca datele de configurare:


...
#include <SetariExemplu.h>
...
void ClasaExemplu::readConfig() {
	m_server  = SetariExemplu::serverName();
	m_port    = SetariExemplu::port();
}

void ClasaExemplu:saveSettings() {
	SetariExemplu::setServerName( m_server );
	SetariExemplu::setPort( m_port );
	SetariExemplu::writeConfig();
}
exemplu.cpp

Pentru a adauga o fereastra de dialog trebuie sa o creati cu Qt Designer astfel incit numele elementelor de interfata sa corespunda cu numele optiunilor pe care trebuie sa le editeze si, in plus, sa fie prefixate cu "kcfg_". Poate fi ceva de genul acesta:

Exemplu de dialog

Puteti folosi fereastra de dialog cu urmatorul cod:


//O instanta a acestui dialog poate exista deja sau poate
//fi pastrata de-o parte, in care caz nu trebuie decit
//sa o afisam in loc sa cream alta noua
if (KConfigDialog::showDialog("settings"))
     return;
 
//KConfigDialog nu a gasit nici o instanta a acestui
//dialog, astfel ca o vom crea:
KConfigDialog* dialog = new KConfigDialog(this,"settings",
                                   SetariExemplu::self());
ExampleDesignerWidget* confWdg =
	new ExampleDesignerWidget(0, "Exemplu");
 
dialog->addPage(confWdg, i18n("Exemplu"), "exemplu");
 
//Utilizatorul a editat configuratia - actualizez
//copia locala a datelor de configurare
connect(dialog, SIGNAL(settingsChanged()),
         this, SLOT(updateConfiguration()));
 
dialog->show();
exemplu.cpp

Asta este tot. Va puteti uita la codul programelor KReversi si KTron din pachetul de programe "kdegames" pentru a vedea un exemplu elocvent de utilizare al lui KConfig XT.

Concluzii

KConfig XT este un cadru de lucru pentru configurare foarte usor de folosit, extensibil si flexibil. Sper ca acest tutorial va face acest cadru de lucru mai usor de inteles pentru dumneavoastra.

Capcane si trucuri mai des intilnite

  • Nu uitati sa adaugati atributul "type" tagului <entry> in fisierul .kcfg.
  • Intotdeauna incercati sa adaugati ambele taguri <label> si <whatsthis> fiecarei inregistrari.
  • Incercati sa folositi specificatorii "code" in .kfcg cit mai rar posibil. In curind, aceasta caracteristica ar putea fi eliminata.
  • Punind MemberVariables=public in .kcfgc, nu este o idee buna - veti evita modificarile accidentale ale acestor variabile membre folosind agregarea si fortind folosirea mutatorilor.
  • Daca aplicatia dumneavoastra nu are un obiect central (creat inainte si distrus dupa toate celelalte obiecte), atunci puneti intotdeauna inregistrarea Singleton=true in fisierul .kcfgc.