QT Workshop

Der Qt Vortrag fand am 7. August statt. Das Thema war eine kurze Einführung in die Fähigkeiten und den Umfang des C++ Frameworks Qt. Die Präsentation kann hier heruntergeladen werden: 

Übungen

FIXME Die Übungen müssen hier noch eingefügt und beschrieben werden…

HELLO WORLD

#include <QApplication>
#include <QtGui>
 
int main(int argc, char *argv[])
{
        QApplication app(argc, argv);
        QPushButton *MyButton = new QPushButton("Hello World");
        MyButton->resize(120,50);
        MyButton->show();
        return app.exec();
}

Kompilieren per Dreisatz:

qmake -project
qmake
make

LAYOUT

GRUNDLAGEN

Layouts können ineinander verschachtelt werden. Die wichtigsten Layouts sind:

  • QVBoxLayout
  • QHBoxLayout
  • QGridLayout

Einem QWidgetwird ein Layout per setLayout() zugewiesen. Ebenfalls kann bei der Erstellung des Layouts das Elternwidget im Konstruktor übergeben werden.

QWidgets werden mit der Methode addWidget() zu Layouts hinzugefügt, Layouts per addLayout()

BEISPIEL

main.cpp

#include <QtGui/QApplication>
#include "mainwidget.h"
 
int main(int argc, char *argv[])
{
    //Mit dieser Zeile können im Quelltext innerhalb tr() auch UTF-8 Zeichen enthalten sein.
    QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
 
    //Standard aus der Qt-Creator Vorlage
    QApplication a(argc, argv);
    MainWidget w;
    w.show();
    return a.exec();
}

mainwidget.h

#ifndef MAINWIDGET_H
#define MAINWIDGET_H
 
//Es empfiehlt sich hier <QtGui/QWidget> durch <QtGui> zu ersetzen
#include <QtGui>
 
class MainWidget : public QWidget
{
    Q_OBJECT
//Das obenstehende Makro Q_OBJECT ist für Ableitungen von QWidget erforderlich
 
//Hier werden alle GUI Objekte deklariert
private:
    QVBoxLayout *MainLayout;
    QHBoxLayout *LayEdit;
    QLabel *LblHello;
    QLineEdit *EdtLine1, *EdtLine2;
    QPushButton *BtnQuit;
 
public:
    MainWidget(QWidget *parent = 0);
    ~MainWidget();
};
 
#endif // MAINWIDGET_H

mainwidget.cpp

#include "mainwidget.h"
 
MainWidget::MainWidget(QWidget *parent)
    : QWidget(parent)
{
    setWindowTitle(tr("Demo Layout"));   //Gewöhnt euch an immer tr() zu verwenden für Strings in QObject
 
    //Erstellen
    MainLayout = new QVBoxLayout(this);
    LayEdit = new QHBoxLayout();
    LblHello = new QLabel(tr("<p>Hallo<br /><b>Wält</b></p>"));
    BtnQuit = new QPushButton(tr("Beend&en"));
    EdtLine1 = new QLineEdit();
    EdtLine2 = new QLineEdit();
 
    //Layout
    MainLayout->addWidget(LblHello);
    MainLayout->addLayout(LayEdit);
    LayEdit->addWidget(EdtLine1);
    LayEdit->addWidget(EdtLine2);
    MainLayout->addWidget(BtnQuit);
 
    //Signals and slots
    connect(BtnQuit, SIGNAL(clicked()), this, SLOT(close()));
    connect(EdtLine1, SIGNAL(textChanged(QString)), EdtLine2, SLOT(setText(QString)));
    connect(EdtLine2, SIGNAL(textChanged(QString)), EdtLine1, SLOT(setText(QString)));
}
 
MainWidget::~MainWidget()
{
 
}
 

SIGNALS UND SLOTS

FIXME Inhalt fehlt noch. Wird während oder nach dem nächsten Workshop Teil ergänzt. :-D

TIPPS UND TRICKS

UTF-8 STRINGS IM QUELLCODE

Damit Strings in Unicode im Quellcode auch richtig verarbeitet werden, kann die folgende Zeile in main() eingefügt werden. Bedingung ist natürlich, dass die Strings in tr() gekapselt sind. Dies ist aber unabhängig davon sowieso zu empfehlen damit spätere Übersetzungen des Programms möglich werden.

QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));

ÜBERSETZUNG VON STANDARDELEMENTEN

Diverse Widgets enthalten vordefinierte Texte auf welche man keinen Einfluss hat. Beispiele dafür sind Buttons in QMessageBox und das Kontextmenü in QTextEdit. Egal welche Sprache auf dem System eingestellt ist, diese Texte sind englisch.

Qt bietet für diese Elemente eigene Übersetzungsdateien. Diese können wie eigene Übersetzungen mit QTranslator geladen werden.

Für Programme welche dynamisch gelinkt werden, sollten die Übersetzungen auch dynamisch geladen werden. Wenn das Programm allerdings statisch kompiliert wird, sollten auch die Übersetzungen per Ressourcendatei eingebunden werden.

Innerhalb von main() wird die Übersetzung z.B. so dynamisch geladen:

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
 
    QTranslator translator;
    translator.load("qt_de", QLibraryInfo::location(QLibraryInfo::TranslationsPath));
    app.installTranslator(&translator);
 
    MainWidget w;
    w.show();
    return app.exec();
}

Statisch kompilierte Programme sollten die Übersetzung hingegen so laden:

translator.load("qt_de", ":/system");

Die Übersetzungsdatei „qt_de.qm“ muss dafür natürlich in das Projektverzeichnis kopiert und in eine Ressourcendatei eingebunden werden. Natürlich kann auch die zu verwendende Sprache dynamisch mit QLocale::system().name() ermittelt werden. Wenn keine Datei mit passenden Namen gefunden wird, startet das Programm ohne Fehlermeldung in englisch.

SPEZIALITÄTEN FÜR WINDOWS

Wer Programme auch für Windows entwickeln möchte, sollte ein paar Sonderheiten dieser Plattform beachten.

PROGRAMMSYMBOL

Symbole welche zur Laufzeit mit setWindowIcon() geladen werden, werden nicht als Symbol der EXE Datei angezeigt. Die folgende Anleitung erklärt wie dies gemacht wird: http://qt-project.org/doc/qt-5.0/appicon.html

STATISCH KOMPILIEREN

Um Programme unter Windows weitergeben zu können ohne dass sich der Empfänger gleich Qt komplett installieren muss, kann es hilfreich sein diese Programme statisch zu kompilieren. Dafür ist eine angepasste Version der Qt Bibliotheken erforderlich. Diese muss man selbst kompilieren. Eine Anleitung dazu gibts hier: http://qt-project.org/wiki/Build_Static_Qt_For_Windows_With_Gcc_German