Erste Schritte in der Programmierung mit Qt Widgets

Ein Tutorium für Qt Widgets basierte Notepad-Anwendung.

In diesem Thema vermitteln wir grundlegende Qt-Kenntnisse, indem wir eine einfache Notepad-Anwendung mit C++ und dem Qt Widgets Modul. Die Anwendung ist ein kleiner Texteditor, mit dem Sie eine Textdatei erstellen, speichern, drucken oder wieder öffnen und erneut bearbeiten können. Sie können auch die zu verwendende Schriftart einstellen.

"Notepad application"

Ausführen des Beispiels

Zum Ausführen des Beispiels von Qt Creatorzu starten, öffnen Sie den Modus Welcome und wählen Sie das Beispiel aus Examples. Weitere Informationen finden Sie unter Erstellen und Ausführen eines Beispiels.

Erstellen des Notepad-Projekts

Das Einrichten eines neuen Projekts in Qt Creator wird durch einen Assistenten unterstützt, der Sie Schritt für Schritt durch den Prozess der Projekterstellung führt. Der Assistent fordert Sie auf, die für den jeweiligen Projekttyp erforderlichen Einstellungen einzugeben, und erstellt das Projekt für Sie.

Hinweis: Der Benutzeroberflächentext in Qt Creator und der Inhalt der erzeugten Dateien hängen von der von Ihnen verwendeten Version von Qt Creator ab.

"Qt Creator New Project dialog"

Um das Notepad-Projekt zu erstellen, wählen Sie File > New Project > Application (Qt) > Qt Widgets Application > Choose, und folgen Sie den Anweisungen des Assistenten. Geben Sie im Dialogfeld Class Information den Klassennamen Notepad ein und wählen Sie QMainWindow als Basisklasse.

"Class Information Dialog"

Der Qt Widgets Application Assistent erstellt ein Projekt, das eine Hauptquelldatei und eine Reihe von Dateien enthält, die eine Benutzeroberfläche (Notepad-Widget) spezifizieren:

  • CMakeLists.txt - die Projektdatei.
  • main.cpp - die Hauptquelldatei für die Anwendung.
  • notepad.cpp - die Quelldatei der Notepad-Klasse des Notepad-Widgets.
  • notepad.h - die Header-Datei der Notepad-Klasse für das Notepad-Widget.
  • notepad.ui - das UI-Formular für das Notepad-Widget.

Die Dateien enthalten den notwendigen Boilerplate-Code, damit Sie das Projekt erstellen und ausführen können. In den folgenden Abschnitten werden wir uns den Inhalt der Dateien genauer ansehen.

Mehr erfahren

ÜberHier
Verwendung von Qt CreatorQt Creator
Erstellen anderer Arten von Anwendungen mit Qt CreatorQt Creator Anleitungen

Haupt-Quelldatei

Der Assistent erzeugt den folgenden Code in der Datei main.cpp:

#include "notepad.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Notepad w;
    w.show();
    return a.exec();
}

Wir werden den Code Zeile für Zeile durchgehen. Die folgenden Zeilen enthalten die Header-Dateien für das Notepad-Widget und QApplication. Alle Qt-Klassen haben eine Header-Datei, die nach ihnen benannt ist.

#include "notepad.h"

#include <QApplication>

Die folgende Zeile definiert die main-Funktion, die der Einstiegspunkt für alle C- und C++-basierten Anwendungen ist:

int main(int argc, char *argv[])

In der folgenden Zeile wird ein QApplication Objekt erstellt. Dieses Objekt verwaltet anwendungsweite Ressourcen und ist notwendig, um jedes Qt-Programm auszuführen, das Qt Widgets verwendet. Es konstruiert ein Anwendungsobjekt mit argc Befehlszeilenargumenten, das in argv ausgeführt wird. (Für GUI-Anwendungen, die Qt Widgets nicht verwenden, können Sie stattdessen QGuiApplication verwenden).

    QApplication a(argc, argv);

In der folgenden Zeile wird das Notepad-Objekt erstellt. Dies ist das Objekt, für das der Assistent die Klasse und die UI-Datei erstellt hat. Die Benutzeroberfläche enthält visuelle Elemente, die in Qt widgets genannt werden. Beispiele für Widgets sind Texteingabefelder, Bildlaufleisten, Beschriftungen und Optionsfelder. Ein Widget kann auch ein Container für andere Widgets sein, z. B. ein Dialog oder ein Hauptanwendungsfenster.

    Notepad w;

In der folgenden Zeile wird das Notepad-Widget in einem eigenen Fenster auf dem Bildschirm angezeigt. Widgets können auch als Container fungieren. Ein Beispiel hierfür ist QMainWindow, das oft mehrere Arten von Widgets enthält. Widgets sind standardmäßig nicht sichtbar; die Funktion show() macht das Widget sichtbar.

    w.show();

Die folgende Zeile lässt QApplication in seine Ereignisschleife eintreten. Wenn eine Qt-Anwendung läuft, werden Ereignisse erzeugt und an die Widgets der Anwendung gesendet. Beispiele für Ereignisse sind das Drücken der Maus und das Anschlagen von Tasten.

    return a.exec();

Mehr erfahren

ÜberHier
Widgets und FenstergeometrieFenster- und Dialog-Widgets
Ereignisse und EreignisbehandlungDas Ereignissystem

Entwerfen einer Benutzeroberfläche

Der Assistent erzeugt eine Benutzeroberflächendefinition im XML-Format: notepad.ui. Wenn Sie die Datei notepad.ui in Qt Creator öffnen, wird sie automatisch im integrierten Qt Widgets Designer geöffnet.

Wenn Sie die Anwendung erstellen, startet Qt Creator die Qt User Interface Compiler (uic), die die .ui-Datei liest und eine entsprechende C++-Header-Datei, ui_notepad.h, erstellt.

Verwendung von Qt Widgets Designer

Der Assistent erstellt eine Anwendung, die QMainWindow verwendet. Sie hat ein eigenes Layout, dem Sie eine Menüleiste, Dock-Widgets, Symbolleisten und eine Statusleiste hinzufügen können. Der mittlere Bereich kann von jeder Art von Widget belegt werden. Der Assistent platziert das Notepad-Widget dort.

So fügen Sie Widgets in Qt Widgets Designer hinzu:

  1. Doppelklicken Sie im Modus Qt Creator Edit auf die Datei notepad.ui in der Ansicht Projects, um die Datei im integrierten Qt Widgets Designer zu starten.
  2. Ziehen Sie die Widgets Text Edit (QTextEdit) auf das Formular und legen Sie sie dort ab.
  3. Drücken Sie Strg+A (oder Cmd+A), um die Widgets auszuwählen, und klicken Sie auf Lay out Vertically (oder drücken Sie Strg+L), um ein vertikales Layout anzuwenden (QVBoxLayout).
  4. Drücken Sie Strg+S (oder Cmd+S), um Ihre Änderungen zu speichern.

Die Benutzeroberfläche sieht nun in Qt Widgets Designer wie folgt aus:

Sie können die generierte XML-Datei im Code-Editor anzeigen:

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Notepad</class>
 <widget class="QMainWindow" name="Notepad">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>800</width>
    <height>400</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Notepad</string>
  </property>
  <widget class="QWidget" name="centralWidget">
   <layout class="QVBoxLayout" name="verticalLayout">
    <item>
     <widget class="QTextEdit" name="textEdit"/>
    </item>
   </layout>
  </widget>
  <widget class="QMenuBar" name="menuBar">
    ...

Die folgende Zeile enthält die XML-Deklaration, die die im Dokument verwendete XML-Version und Zeichenkodierung angibt:

<?xml version="1.0" encoding="UTF-8"?>

Der Rest der Datei spezifiziert ein ui -Element, das ein Notepad-Widget definiert:

<ui version="4.0">

Die UI-Datei wird zusammen mit dem Header und der Quelldatei der Notepad-Klasse verwendet. Wir werden uns den Rest der UI-Datei in den späteren Abschnitten ansehen.

Notepad-Header-Datei

Der Assistent hat eine Header-Datei für die Notepad-Klasse erstellt, die die notwendigen #includes, einen Konstruktor, einen Destruktor und das UI-Objekt enthält. Die Datei sieht wie folgt aus:

#include <QMainWindow>

QT_BEGIN_NAMESPACE
namespace Ui {
class Notepad;
}
QT_END_NAMESPACE

class Notepad : public QMainWindow
{
    Q_OBJECT

public:
    explicit Notepad(QWidget *parent = nullptr);
    ~Notepad();

private:
    Ui::Notepad *ui;
    QString currentFile;
};

Die folgende Zeile enthält QMainWindow, das ein Hauptanwendungsfenster bereitstellt:

#include <QMainWindow>

Die folgenden Zeilen deklarieren die Notepad-Klasse im Ui-Namensraum, dem Standard-Namensraum für die UI-Klassen, die vom Tool uic aus .ui-Dateien erzeugt werden:

namespace Ui {
class Notepad;
}

Die Klassendeklaration enthält das Makro Q_OBJECT. Es muss an erster Stelle in der Klassendefinition stehen und deklariert unsere Klasse als QObject. Natürlich muss sie auch von QObject erben. Eine QObject fügt einer normalen C++-Klasse mehrere Fähigkeiten hinzu. Vor allem können der Klassenname und die Slotnamen zur Laufzeit abgefragt werden. Es ist auch möglich, die Parametertypen eines Slots abzufragen und ihn aufzurufen.

class Notepad : public QMainWindow
{
    Q_OBJECT

Die folgenden Zeilen deklarieren einen Konstruktor, der ein Standardargument namens parent hat. Der Wert 0 zeigt an, dass das Widget kein Elternteil hat (es ist ein Top-Level-Widget).

public:
    explicit Notepad(QWidget *parent = nullptr);

Die folgende Zeile deklariert einen virtuellen Destruktor, um die Ressourcen freizugeben, die das Objekt während seines Lebenszyklus erworben hat. Gemäß der C++-Namenskonvention haben Destruktoren denselben Namen wie die Klasse, der sie zugeordnet sind, mit einer vorangestellten Tilde (~). In QObject sind Destruktoren virtuell, um sicherzustellen, dass die Destruktoren der abgeleiteten Klassen ordnungsgemäß aufgerufen werden, wenn ein Objekt durch einen Zeiger auf die Basisklasse gelöscht wird.

    ~Notepad();

Die folgenden Zeilen deklarieren eine Mitgliedsvariable, die ein Zeiger auf die Notepad UI-Klasse ist. Eine Member-Variable ist mit einer bestimmten Klasse verbunden und für alle ihre Methoden zugänglich.

private:
    Ui::Notepad *ui;
    QString currentFile;
};
Notepad-Quelldatei

Die Quelldatei, die der Assistent für die Klasse Notepad erstellt hat, sieht wie folgt aus:

#include "notepad.h"
#include "ui_notepad.h"

Notepad::Notepad(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::Notepad)
{
    ui->setupUi(this);

}

Die folgenden Zeilen enthalten die Header-Datei der Klasse Notepad, die vom Assistenten erzeugt wurde, und die UI-Header-Datei, die vom Tool uic erzeugt wurde:

#include "notepad.h"
#include "ui_notepad.h"

Die folgende Zeile definiert den Notepad Konstruktor:

Notepad::Notepad(QWidget *parent) :

Die folgende Zeile ruft den QMainWindow -Konstruktor auf, der die Basisklasse für die Notepad-Klasse ist:

    QMainWindow(parent),

Die folgende Zeile erstellt die Instanz der Klasse UI und weist sie dem Mitglied ui zu:

    ui(new Ui::Notepad)

Die folgende Zeile richtet die Benutzeroberfläche ein:

{
    ui->setupUi(this);

Im Destruktor löschen wir die ui:

Notepad::~Notepad()
{
    delete ui;
}
Projektdatei

Der Assistent generiert für uns die folgende Projektdatei, CMakeLists.txt:

# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause

cmake_minimum_required(VERSION 3.16)
project(notepad LANGUAGES CXX)

find_package(Qt6
    REQUIRED COMPONENTS Core Gui Widgets
    OPTIONAL_COMPONENTS PrintSupport
)

qt_standard_project_setup()

qt_add_executable(notepad
    main.cpp
    notepad.cpp notepad.h notepad.ui
)

set_target_properties(notepad PROPERTIES
    WIN32_EXECUTABLE TRUE
    MACOSX_BUNDLE TRUE
)

target_link_libraries(notepad PRIVATE
    Qt6::Core
    Qt6::Gui
    Qt6::Widgets
)

if(TARGET Qt6::PrintSupport)
    target_link_libraries(notepad PRIVATE Qt6::PrintSupport)
endif()

# Resources:
set(notepad_resource_files
    "images/bold.png"
    "images/copy.png"
    "images/create.png"
    "images/cut.png"
    "images/edit_redo.png"
    "images/edit_undo.png"
    "images/exit.png"
    "images/font.png"
    "images/info.png"
    "images/italic.png"
    "images/new.png"
    "images/open.png"
    "images/paste.png"
    "images/pencil.png"
    "images/print.png"
    "images/save.png"
    "images/save_as.png"
    "images/underline.png"
)

qt_add_resources(notepad "notepad"
    PREFIX
        "/"
    FILES
        ${notepad_resource_files}
)

install(TARGETS notepad
    BUNDLE  DESTINATION .
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
)

qt_generate_deploy_app_script(
    TARGET notepad
    OUTPUT_SCRIPT deploy_script
    NO_UNSUPPORTED_PLATFORM_ERROR
)
install(SCRIPT ${deploy_script})

Die Projektdatei gibt die im Projekt enthaltenen Quell-, Header- und UI-Dateien an.

Mehr erfahren

ÜberHier
Qt Widgets Designer verwendenQt Widgets Designer-Handbuch
LayoutsLayout-Verwaltung, Widgets und Layouts, Layout-Beispiele
Die Widgets, die mit Qt geliefert werdenQt Widgets-Galerie
Hauptfenster und HauptfensterklassenAnwendungs-Hauptfenster, Hauptfenster-Beispiele
QObjects und das Qt-Objektmodell (Dies ist wichtig, um Qt zu verstehen)Objekt-Modell
qmake und das Qt-Build-Systemqmake Handbuch

Hinzufügen von Benutzerinteraktion

Um dem Editor Funktionalität hinzuzufügen, beginnen wir mit dem Hinzufügen von Menüpunkten und Schaltflächen in einer Symbolleiste.

Klicken Sie auf "Type Here", und fügen Sie die Optionen New, Open, Save, Save as, Print und Exit hinzu. Dadurch werden 5 Zeilen im Aktionseditor unten erstellt. Um die Aktionen mit den Slots zu verbinden, klicken Sie mit der rechten Maustaste auf eine Aktion und wählen Sie Go to slot > triggered(), und vervollständigen Sie den Code für den jeweiligen Slot.

Wenn wir die Aktionen auch zu einer Symbolleiste hinzufügen wollen, können wir jeder QAction ein Symbol zuweisen und dann die QAction auf die Symbolleiste ziehen. Sie weisen ein Symbol zu, indem Sie einen Symbolnamen in die Eigenschaft "Symbol" der betreffenden Aktion eingeben. Wenn das QAction auf die Symbolleiste gezogen wurde, wird durch Anklicken des Symbols der zugehörige Slot gestartet.

Vervollständigen Sie die Methode newDocument():

void Notepad::newDocument()
{
    currentFile.clear();
    ui->textEdit->setText(QString());
}

Die Variable currentFile ist eine globale Variable, die die Datei enthält, die gerade bearbeitet wird, und clear() löscht den Textpuffer. Die Variable currentFile ist im privaten Teil von notepad.h definiert:

private:
    Ui::Notepad *ui;
    QString currentFile;
Öffnen einer Datei

Klicken Sie in notepad.ui mit der rechten Maustaste auf actionOpen und wählen Sie Go to Slot.

Die vollständige Methode open().

void Notepad::open()
{
    QString fileName = QFileDialog::getOpenFileName(this, "Open the file");
    if (fileName.isEmpty())
        return;
    QFile file(fileName);
    currentFile = fileName;
    if (!file.open(QIODevice::ReadOnly | QFile::Text)) {
        QMessageBox::warning(this, "Warning", "Cannot open file: " + file.errorString());
        return;
    }
    setWindowTitle(fileName);
    QTextStream in(&file);
    QString text = in.readAll();
    ui->textEdit->setText(text);
    file.close();
}

QFileDialog::getOpenFileName öffnet einen Dialog, in dem Sie eine Datei auswählen können. QFile Objekt myfile hat die ausgewählte file_name als Parameter. Wir speichern die ausgewählte Datei auch in der globalen Variable currentFile für spätere Zwecke. Wir öffnen die Datei mit file.open als schreibgeschützte Textdatei. Wenn sie nicht geöffnet werden kann, wird eine Warnung ausgegeben, und das Programm hält an.

Wir definieren ein QTextStream instream für den Parameter myfile. Der Inhalt der Datei myfile wird in QString text kopiert. setText(text) füllt den Puffer unseres Editors mit text.

Speichern einer Datei

Wir erstellen die Methode zum Speichern einer Datei auf die gleiche Weise wie beim Öffnen einer Datei, indem wir mit der rechten Maustaste auf actionSave klicken und Go to Slot auswählen.

void Notepad::save()
{
    QString fileName;
    // If we don't have a filename from before, get one.
    if (currentFile.isEmpty()) {
        fileName = QFileDialog::getSaveFileName(this, "Save");
        if (fileName.isEmpty())
            return;
        currentFile = fileName;
    } else {
        fileName = currentFile;
    }
    QFile file(fileName);
    if (!file.open(QIODevice::WriteOnly | QFile::Text)) {
        QMessageBox::warning(this, "Warning", "Cannot save file: " + file.errorString());
        return;
    }
    setWindowTitle(fileName);
    QTextStream out(&file);
    QString text = ui->textEdit->toPlainText();
    out << text;
    file.close();
}

QFile Das Objekt myfile ist mit der globalen Variablen current_file verknüpft, der Variablen, die die Datei enthält, mit der wir gearbeitet haben. Wenn myfile nicht geöffnet werden kann, wird eine Fehlermeldung ausgegeben und die Methode abgebrochen. Wir erstellen ein QTextStream outstream . Der Inhalt des Editorpuffers wird in Klartext umgewandelt und dann in outstream geschrieben.

Speichern einer Datei unter einem anderen Namen
void Notepad::saveAs()
{
    QString fileName = QFileDialog::getSaveFileName(this, "Save as");
    if (fileName.isEmpty())
        return;
    QFile file(fileName);

    if (!file.open(QFile::WriteOnly | QFile::Text)) {
        QMessageBox::warning(this, "Warning", "Cannot save file: " + file.errorString());
        return;
    }
    currentFile = fileName;
    setWindowTitle(fileName);
    QTextStream out(&file);
    QString text = ui->textEdit->toPlainText();
    out << text;
    file.close();
}

Der einzige Unterschied besteht darin, dass Sie hier einen neuen Dateinamen für die zu erstellende Datei eingeben müssen.

Drucken einer Datei

Wenn Sie die Druckfunktionalität nutzen möchten, müssen Sie PrintSupport zur Projektdatei hinzufügen:

find_package(Qt6
    REQUIRED COMPONENTS Core Gui Widgets
    OPTIONAL_COMPONENTS PrintSupport
)

In notepad.cpp deklarieren wir ein QPrinter-Objekt namens printDev:

void Notepad::print()
{
#if defined(QT_PRINTSUPPORT_LIB) && QT_CONFIG(printer)
    QPrinter printDev;
#if QT_CONFIG(printdialog)
    QPrintDialog dialog(&printDev, this);
    if (dialog.exec() == QDialog::Rejected)
        return;
#endif // QT_CONFIG(printdialog)
    ui->textEdit->print(&printDev);
#endif // QT_CONFIG(printer)
}

Wir starten ein Drucker-Dialogfeld und speichern den ausgewählten Drucker im Objekt printDev. Wenn wir auf Cancel geklickt und keinen Drucker ausgewählt haben, kehrt die Methode zurück. Der eigentliche Druckerbefehl wird mit ui->textEdit->print gegeben, mit unserem QPrinter-Objekt als Parameter.

Eine Schriftart auswählen
void Notepad::selectFont()
{
    bool fontSelected;
    QFont font = QFontDialog::getFont(&fontSelected, this);
    if (fontSelected)
        ui->textEdit->setFont(font);
}

Wir deklarieren einen booleschen Wert, der angibt, ob wir eine Schriftart mit QFontDialog ausgewählt haben. Wenn ja, setzen wir die Schriftart mit ui->textEdit->setFont(myfont).

Kopieren, Ausschneiden, Einfügen, Rückgängig machen und Wiederherstellen

Wenn Sie einen Text markieren und ihn in die Zwischenablage kopieren wollen, rufen Sie die entsprechende Methode von ui->textEdit auf. Das Gleiche gilt für Ausschneiden, Einfügen, Rückgängig machen und Wiederherstellen.

Diese Tabelle zeigt den Namen der zu verwendenden Methode.

AufgabeAufgerufene Methode
Kopierenui->textEdit->copy()
Ausschneidenui->TextBearbeiten->Ausschneiden()
Einfügenui->TextBearbeiten->Einfügen()
Rückgängig machenui->TextBearbeiten->Rückgängig()
Wiederholenui->TextBearbeiten->Wiederherstellen()

Mehr erfahren

ÜberHier
Dateien und E/A-GeräteQFile, QIODevice
tr() und InternationalisierungQt Linguist Handbuch, Quellcode für die Übersetzung schreiben, Internationalisierung mit Qt

Bauen und Ausführen über die Kommandozeile

Um eine Beispielanwendung von der Kommandozeile aus zu bauen, erstellen Sie ein Build-Verzeichnis für sie. Wechseln Sie in das Build-Verzeichnis und führen Sie qt-cmake aus, um Ihr Projekt für die Erstellung zu konfigurieren. Wenn das Projekt erfolgreich konfiguriert wurde, können Sie mit den generierten Dateien das Projekt bauen.

md <build_directory>
cd <build_directory>
<qt_installation_directory>\bin\qt-cmake -GNinja <source_directory>
<generator>

Die Befehle erstellen eine ausführbare Datei im Build-Verzeichnis. Das Tool CMake liest die Projektdatei und erstellt Anweisungen, wie die Anwendung zu erstellen ist. Der Generator verwendet dann die Anweisungen, um die ausführbare Binärdatei zu erzeugen.

Um beispielsweise das Notepad-Beispiel unter Windows zu erstellen, geben Sie bei Verwendung von Ninja als Generator die folgenden Befehle ein:

md notepad-build
cd notepad-build
C:\Qt\6.8.2\msvc2019_64\bin\qt-cmake -GNinja C:\Examples\notepad
ninja

Wenn Sie nicht Ninja als Generator verwenden, verwenden Sie den Generator-unabhängigen CMake-Befehl, um die Anwendung anstelle von ninja zu erstellen:

cmake --build

Beispielprojekt @ code.qt.io

© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.