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

Programarea setarilor utilizator in KDE 3


   Andreas Nicolai
   18 Mai 2003

Partea a-V-a: O implementare simpla a dialogului de setari

Dupa atita munca nu este nimic de vazut decit banalul text "Hello World"...

That's the hassle with being a programmer - you can work for hours and days and still the user won't see a difference... and where you don't see a difference there's obviously nothing been done. That's "logic" from the user's point of view! But maybe you choose to concentrate on coding new user interface gimix like those redmond guys permanently do. So at least the user will 'see' the 'progress'... hehe, well, this has nothing to do with this tutorial, but I just wanted to point that out :-)

Este timpul sa implementam dialogul. Ne trebuie o alta clasa pe care acum o vom numi PrefDialog si va mosteni KDialogBase. Deschideti deci vrajitorul "New class" si creati clasa. Ar trebui sa terminati cu urmatoarele fisiere (din nou le-am modificat, dar ar trebui sa le recunoasteti):


#ifndef PREFDIALOG_H
#define PREFDIALOG_H

#include <qwidget.h>
#include <kdialogbase.h>

class PrefDialog : public KDialogBase {
    Q_OBJECT
  public:
    PrefDialog(QWidget *parent, const char *name=0, WFlags f=0);
};

#endif  // PREFDIALOG_H
prefdialog.h


#include "prefdialog.h"
#include "prefdialog.moc"

PrefDialog::PrefDialog(QWidget *parent, const char *name, WFlags f)
 : KDialogBase(parent, name, f)
{
}
prefdialog.cpp

Fara
KDevelop:
Va trebui sa creati cele doua fisiere si sa modificati Makefile.am. Presupun ca de acum incolo va descurcati singur, asa ca pe viitor nu va mai explic acest lucru.

Trebuie sa cream paginile de configurare cind se afiseaza dialogul. Pentru a accesa aceste pagini mai usor vom stoca pointeri la pagini in variabile membru din clasa dialogului, deci trebuie sa adaugam

  • prototipurile claselor PrefGeneral si PrefStyle in prefdialog.h
  • variabilele membru (private) "m_prefGeneral" si "m_prefStyle"

Noul prefdialog.h va arata asa:


#ifndef PREFDIALOG_H
#define PREFDIALOG_H

#include <qwidget.h>
#include <kdialogbase.h>

class PrefGeneral;
class PrefStyle;

/// Dialogul de preferinte.
class PrefDialog : public KDialogBase {
    Q_OBJECT
  public:
    /// Constructorul
    PrefDialog(QWidget *parent, const char *name=0, WFlags f=0);

  private:
    PrefGeneral    *m_prefGeneral;
    PrefStyle      *m_prefStyle;
};

#endif  // PREFDIALOG_H
prefdialog.h

Nota:
Folosind prototipul claselor ne ajuta sa avem putine dependentele de compilare. Imaginativa ce s-ar intimpla daca ati face o modificare in pagina "General". In primul rind toate fisierele sursa ce utilizeaza prefgenerallayout.h (insemnind toate fisierele care includ prefgenerallayout.h) trebuie recompilate. In cazul nostru prefgeneral.h include pagina "General" asa ca toate fisierele cel utilizeaza trebuie recompilate, adica prefgeneral.cpp si prefdialog.cpp. Daca am fi inclus prefgeneral.h in fisierul antet prefdialog.h, atunci toate fisierele care vor face referire la el vor fi si ele recompilate. Folosind prototipul clasei in loc de includere de fisiere antet reduce dependentele de compilare macar la un fisier, deoarece cu siguranta prefdialog.h va mai fi folosit de inca cel putin un alt fisier.

Acum sa aruncam o privire asupra modificarilor facute in fisierul prefdialog.cpp.


#include <qlayout.h>        // pentru QVBoxLayout
#include <qlabel.h>         // pentru QLabel
#include <qframe.h>         // pentru QFrame
#include <kcolorbutton.h>   // pentru KColorButton
#include <kpushbutton.h>    // pentru KPushButton
#include <klocale.h>        // pentru i18n()
#include <kiconloader.h>    // pentru KIconLoader
#include <kglobal.h>        // pentru KGlobal

#include "prefdialog.h"     // clasa PrefDialog
#include "prefdialog.moc"

#include "prefgeneral.h"    // clasa PrefGeneral
#include "prefstyle.h"      // clasa PrefStyle

PrefDialog::PrefDialog(QWidget *parent, const char *name, WFlags f)
 : KDialogBase(IconList, i18n("Preferences"),
   Default|Ok|Apply|Cancel, Ok, parent, name, f)
{
    // adaugam pagina "General options"
    QFrame *frame = addPage(i18n("General"), i18n("General options"),
        KGlobal::iconLoader()->loadIcon("kfm",KIcon::Panel,0,false) );
    QVBoxLayout *frameLayout = new QVBoxLayout( frame, 0, 0 );
    m_prefGeneral = new PrefGeneral(frame);
    frameLayout->addWidget(m_prefGeneral);

    // adaugam pagina "Style settings"
    frame = addPage(i18n("Style"), i18n("Style settings"),
        KGlobal::iconLoader()->loadIcon("style",KIcon::Panel,0,false) );
    frameLayout = new QVBoxLayout( frame, 0, 0 );
    m_prefStyle = new PrefStyle(frame);
    frameLayout->addWidget(m_prefStyle);
}
prefdialog.cpp

La inceput includem o multime de fisiere, cele mai multe fiind antetele widget-urilor pe care le avem in paginile dialogului. Dupa aceea mai avem nevoie de niste clase pentru generarea paginilor dialogului (care vor fi explicate in paragrafele urmatoare).

Clasa KDialogBase este un prototip pentru diferite de dialoguri. Deoarece avem nevoie de un dialog cu o lista de iconite si citeva butoane implicite, vom folosi un contructor special pentru clasa de baza. Parametrii contructorului sint urmatorii:

  1. tipul dialogului: IconList inseamna ca vom avea o lista de iconite in stinga dialogului
  2. titlul dialogului.
    Nota:
    Folosim metoda i18n() care permite internationalizarea. Acest concept va fi explicat intr-un alt tutorial. Trebuie doar sa retineti ca orice text afisat utilizatorului trebuie pus in interiorul acestei functii.
  3. butoanele care trebuie sa le contina dialogul. In cazul de fata vrem 4 butoane.
  4. butonul selectat implicit.
  5. widget-ul parinte
  6. numele cu care poate fi identificat
  7. fanioane optiuni pentru fereastra

Acum dialogul este creat. Trebuie doar sa adaugam paginile de configurare. Acesta este un proces din trei pasi. Sa aruncam o privire la primul:

QFrame *frame = addPage(i18n("General"), i18n("General options"),
        KGlobal::iconLoader()->loadIcon("kfm",KIcon::Panel,0,false));

addPage() este o functie membru a KDialogBase si primeste urmatorii parametrii:

  1. numele paginii care va aparea in lista de iconite
  2. numele paginii care va fi afisat deasupra paginii de configurare
  3. iconita care va fi folosita in lista de iconite

Primii doi parametrii nu ne pun probleme, dar de unde luam iconita? Ca de obicei KDE ne ajuta. Datorita posibilitatilor complexe de configurare ale KDE, iconitele pot fi instalate in directoare diferite. Clasa KIconLoader ne ajuta sa localizam iconita care ne trebuie. Putem sa cerem incarcatorului de iconite global din spatiul de nume KGlobal sa ne returneze iconita cu un anumit nume. Parametrii cei mai importanti sint numele iconitei si tipul acesteia, care corespunde unei anumite marimi a acesteia. Incarcatorul de iconite se straduieste foarte mult sa gaseasca iconita in toate directoarele care pot contine iconite. De obicei in programele noastre vrem sa punem la dispozitie propriul nostru set de iconite care vor fi instalate in directorul aplicatiei. In acest tutorial noi vom "imprumuta" doua iconite tipice care ar trebui sa fie disponibile in orice instalare normala de KDE. Dupa ce iconita este gasita, pagina este adaugata asa ca putem sa trecem la pasul 2.

QVBoxLayout *frameLayout = new QVBoxLayout(frame, 0, 0);

Al doilea pas persupune crearea unui aranjament vertical in care vor fi puse paginile de configurare. Acest aranjament va fi cel de baza pentru pagina pe care tocmai am adaugata.

m_prefGeneral = new PrefGeneral(frame);

In cele din urma vom crea o instanta a paginii de configurare "General options" pe care o adaugam la aranjament.

Nota:
Cream toate obiectele folosind operatorul new, dar niciodata nu folosim operatorul delete ca sa le distrugem. De ce nu? Imediat ce un obiect QObject (QObject este clasa de baza pentru toate obiectele KDE si QT) este creat ca fiu al (insemnind "detinut de") altui obiect QObject, acest parinte are grija sa distruga toti "fiii" pe care ii detine. Deci regula este foarte simpla: de fiecare data cind un obiect este creat via new si obiectul este detinut de un alt obiect QObject va fi distrus automat. Altfel va trebui sa-l distrugeti singuri.

In cazul nostru QFrame este detinut de dialog, QVBoxLayout este detinut de cadru (QFrame) si obiectul PrefGeneral este detinut de aranjament (QVBoxLayout). Toate aceste obiectele vor fi distruse de catre parinti atunci cind acesti vor fi distrusi.

Facem acelasi lucru si cu a doua pagina. Cel putin ar trebui sa puteti compila fisierele. Oricum, tot o sa vedeti textul "Hello world" in fereastra. Ne trebuie o metoda sa executam dialogul din fereastra principala. Aceasta functionalitate o vom implementa in partea a VI-a.



Traducere de Bogdan Daniel Vatra. Adaptare de Claudiu Costin.