Anzeige:
Ergebnis 1 bis 3 von 3

Thema: Qt Tutorial: Lektion 6

  1. #1
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477

    Qt Tutorial: Lektion 6

    Lektion 6: Einfache GUI

    Autor: anda_skoa

    Diese Lektion zeigt, wie man mehrere Widgets in einem übergeordneten Widget zusammenfassen kann.
    Außerdem wird gezeigt, wie man die Funktionalität der Widgets benutzt.

    Erst mal wieder unsere Dateien:

    lektion6.pro
    Code:
    TEMPLATE = app
    
    CONFIG += qt thread warn_on
    
    SOURCES = lektion6.cpp qttutwidget.cpp
    HEADERS = qttutwidget.h
    
    TARGET = lektion6
    
    MOC_DIR = mocs
    OBJECTS_DIR = obj
    Die letzten beiden Zeilen sind neu. Sie weisen qmake an, zwei Verzeichnisse als Ablageort für bestimmte Nebenprodukte des Erstellungsprozesses zu benutzen.
    Das MOC_DIR enthält dann die von MOC, dem Qt Meta Object Compiler, generierten Dateien.
    Das OBJECTS_DIR enthält die vom Compiler erzeugten Object Dateien (.o Dateien).

    Diese Maßnahme hält das Projektverzeichnis sauberer.

    lektion6.cpp
    Code:
    #include <qapplication.h>
    
    #include "qttutwidget.h"
    
    int main( int argc, char* argv[] )
    {
        QApplication app( argc, argv );
    
        QtTutWidget  tutwidget( 0 );
        tutwidget.resize( 200,30 );
    
        app.setMainWidget( &tutwidget );
    
        tutwidget.show();
    
        return app.exec();
    }
    Bis auf minimale Änderungen identisch mit lektion5.cpp

    qttutwidget.h
    Code:
    #ifndef QTTUTWIDGET_H
    #define QTTUTWIDGET_H
    
    #include <qwidget.h>
    
    class QLineEdit;
    
    class QtTutWidget : public QWidget
    {
        Q_OBJECT
    public:
        QtTutWidget(QWidget* parent=0, const char* name=0);
    
    protected slots:
        void slotButtonClicked();
    
    protected:
        QLineEdit* m_lineEdit;
    };
    
    #endif
    Unser Widget ist nun direkt von QWidget abgeleitet. Es muss diesmal kein spezielles Aussehen haben, da wir es nur als Container für die anderen Widgets benutzen.

    Code:
    class QLineEdit;
    Eines dieser Widget ist ein QLineEdit. Wir haben in unserem Hauptwidget einen Pointer auf eine Instant dieser Klasse, darum müssen wir den Typ hier bekannt machen (forward declaration).

    Code:
        Q_OBJECT
    Unser Widget besitzt einen Slot und muss darum mit dem Q_OBJECT Makro markiert werden.
    Diese Markierung führt dazu, dass qmake beim Erstellen des Makefiles eine Regel für den MOC und diese Datei erstellt.
    Der MOC generiert dann Code, der für die Signal/Slot Benutzung wichtig ist.
    Fehlt dieses Makro, dann ist unser Slot nur eine normale Methode.

    Code:
    protected slots:
        void slotButtonClicked();
    Hier deklarieren wir einen parameterlosen Slot.
    Wie bei Methoden kann es public, protected und private Slots geben.
    Der Name der Methode ist egal, wir haben hier jedoch "slot" als Namensteil gewählt, um in der CPP Datei leichter erkennen zu können, dass wir es mit einem Slot zu tun haben.

    Code:
    protected:
        QLineEdit* m_lineEdit;
    Deklarierung eines QLineEdit Pointers.
    QWidget Instanzen werden normalerweise immer mit new am Heap erzeugt, liegen also als Pointer vor.
    Ein QLineEdit ist ein einzeiliges Texteingabefeld.

    qttutwidget.cpp
    Code:
    #include <qpushbutton.h>
    #include <qlineedit.h>
    #include <qlayout.h>
    #include <qmessagebox.h>
    
    #include "qttutwidget.h"
    
    QtTutWidget::QtTutWidget(QWidget* parent, const char* name)
      : QWidget(parent, name)
    {
        QLayout* layout = new QHBoxLayout(this);
    
        m_lineEdit = new QLineEdit(this);
        QPushButton* button = new QPushButton("Hier klicken", this);
    
        layout->add(m_lineEdit);
        layout->add(button);
    
        QObject::connect(button, SIGNAL(clicked()), this, SLOT(slotButtonClicked()));
    }
    
    void QtTutWidget::slotButtonClicked()
    {
        QString text = m_lineEdit->text();
        if (text.stripWhiteSpace().isEmpty()) return;
    
        QMessageBox::information(this, "Wichtig", text);
    }
    Die CPP Datei unseres Widgets ist nun viel kürzer als in der letzten Lektion, dafür gibt es mehr #include Direktiven:
    Code:
    #include <qpushbutton.h>
    #include <qlineedit.h>
    #include <qlayout.h>
    #include <qmessagebox.h>
    qpushbutton.h kennen wir ja bereits.
    qlineedit.h ist die Headerdatei für unseren QLineEdit.

    qlayout.h ist eine Headerdatei, die verschiedene Layoutklassen deklariert.
    Qt verfügt über einen einfachen, aber sehr effektiven Layouting Mechanismus, der die Größe von Widgets zur Laufzeit verändern kann, um die Sichtbarkeit der Wigdetinhalte zu gewährleisten.
    Wir verwenden in hier, um uns nicht weiter um die Positionen der Widgets in unserem Containerwidget kümmern zu müssen.
    Das Layout wird sicher stellen, dass beide Kindwidgets sichtbar sind und sich nicht überlappen.

    qmessagebox.h ist der Header der Klasse QMessageBox.
    Diese Klasse kann für kleine Meldungen und Rückfragen benutzt werden, die dann vom Benutzer bestätigt werden müssen.

    Code:
    QtTutWidget::QtTutWidget(QWidget* parent, const char* name)
      : QWidget(parent, name)
    Da wir nun von QWidget ableiten, benutzen wir natürlich auch diesen Konstruktor.

    Code:
        QLayout* layout = new QHBoxLayout(this);
    Hier ezeugen wir ein QHBoxLayout.
    Ein HBoxLayout ordnet die Widget in diesem Layout horizontal an.
    Als Parameter bekommt sein Konstruktor das Widget, für dessen Layout es zuständig ist, also in diesem Fall unser Containerwidget.

    Code:
        m_lineEdit = new QLineEdit(this);
        QPushButton* button = new QPushButton("Hier klicken", this);
    Wir erzeugen unsere beiden Widgets und geben als Parentwidget unser Containerwidget an.
    Das hat zur Folge, dass sie gelöscht werden, wenn unser Widget gelöscht wird. Darum brauchen wir keine
    delete Aufrufe im Destruktor unseres Widgets.
    Den Pointer auf den Button brauchen wir hier nur im Konstruktor, darum haben wir im Gegensatz zum LineEdit eine lokale Variable gewählt.

    Code:
        layout->add(m_lineEdit);
        layout->add(button);
    Wir geben die beiden Widgets in unser Layout. Zuerst den LineEdit, denn er soll links vom Button sein.
    Wäre das Layout ein VBoxLayout, dann wäre der LineEdit über dem Button.

    Code:
        QObject::connect(button, SIGNAL(clicked()), this, SLOT(slotButtonClicked()));
    Wir verbinden das clicked() Signal des Buttons mit unserem Slot.

    Code:
    void QtTutWidget::slotButtonClicked()
    {
    Der Slot sieht in der CPP Datei wie eine normale Methode aus und kann auch wie eine normale Methode aufgerufen werden.
    In unserem Fall wird er Slot über den Signal/Slot Mechanismus von Qt aufgerufen, wann immer der Button geklickt wird.

    Code:
        QString text = m_lineEdit->text();
    Wir holen uns den Text, der gerade im LineEdit steht uns speichern ihn in einer lokalen Variable.

    Code:
        if (text.stripWhiteSpace().isEmpty()) return;
    Hier prüfen wir, ob der Text leer ist.
    Eigentlich würde isEmpty() reichen, aber wir wollen auch keine Eingaben zulassen, die nur aus Leerzeichen bestehen, darum entfernen wir alle Leerzeichen vom Anfang und vom Ende des Textes, bevor wird die Prüfung machen.
    Falls der Text leer ist, kehren wir aus der Funktion zurück.

    Code:
        QMessageBox::information(this, "Wichtig", text);
    Für die Standardfälle brauchen wir selbst keine QMessageBox anzulegen, denn Trolltech hat dafür ein paar statische Methoden vorbereitet, die wir nur noch mit den nötigen Parametern aufrufen müssen.
    Hier verwenden wir information, was in einer MessageBox mit einem Rufzeichen-Icon und einem OK Button resultiert.

    Als Fenstertitel setzen wir "Wichtig" und als Text unseren LineEdit Inhalt.

    Erzeugung
    Wie auch in den letzten Lektionen mit qmake und make.

    Experimente
    - Experimentieren mit HBoxLayout und VBoxLayout.
    - Beobachten des Layoutings beim Verändern der Fenstergröße mit der Maus.
    - Ausprobieren verschiedener static Methoden von QMessageBox.

    -----------------

    Vielleicht kann jemand von den anderen Qt Entwicklern hier als Lektion 7 das selbe Beispiel mit Hilfe von Qt Designer machen.
    Also Widget mit LineEdit und Button, H-Layout.
    Davon QtTutWidget ableiten und die Änderungen im Ctor zeigen.

    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

  2. #2
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477
    Ins Tutorial übernommen.

    Da offensichtlich niemand die Lektion 7 machen will, werd ich es halt wieder selber machen

    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

  3. #3
    Registrierter Benutzer
    Registriert seit
    31.03.2003
    Beiträge
    75
    Hallo, ich hab mal ne Anregung für die 7 Tutorials.

    Immer wenn ne neue Lektion kommt, dann werden bestehende Dateien erweitert (gut) aber bekommen neune Namen (lektiona.cpp -> lektionb.cpp) usw.

    Es ist besser für jemanden (wie mich ) der das durchmacht wenn die Dateianmen usw. über Lektionen hinweig gleich bleiben und man das ganze als ein einziges "Projekt" wachsen sieht.

    Es reicht ja wenn man dann schreibt wir erweitern nun die datei xyz.cpp aus Lektion a ...

    (wobei die Datei xyz.cpp immer gleich heisst, auch nachdem sie erweitert wurde)

    So würde ich es zumindet besser finden.

    EDIT: da fällt mir ein man könnte gas ganze noch mit ein paar Screenshots würzen

    Gruß
    Geändert von stefan-tiger (05-03-2005 um 13:18 Uhr)

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •