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.
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.
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.
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
Über | Hier |
---|---|
Verwendung von Qt Creator | Qt Creator |
Erstellen anderer Arten von Anwendungen mit Qt Creator | Qt 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
Über | Hier |
---|---|
Widgets und Fenstergeometrie | Fenster- und Dialog-Widgets |
Ereignisse und Ereignisbehandlung | Das 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:
- 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.
- Ziehen Sie die Widgets Text Edit (QTextEdit) auf das Formular und legen Sie sie dort ab.
- 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).
- 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
Über | Hier |
---|---|
Qt Widgets Designer verwenden | Qt Widgets Designer-Handbuch |
Layouts | Layout-Verwaltung, Widgets und Layouts, Layout-Beispiele |
Die Widgets, die mit Qt geliefert werden | Qt Widgets-Galerie |
Hauptfenster und Hauptfensterklassen | Anwendungs-Hauptfenster, Hauptfenster-Beispiele |
QObjects und das Qt-Objektmodell (Dies ist wichtig, um Qt zu verstehen) | Objekt-Modell |
qmake und das Qt-Build-System | qmake 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.
Aufgabe | Aufgerufene Methode |
---|---|
Kopieren | ui->textEdit->copy() |
Ausschneiden | ui->TextBearbeiten->Ausschneiden() |
Einfügen | ui->TextBearbeiten->Einfügen() |
Rückgängig machen | ui->TextBearbeiten->Rückgängig() |
Wiederholen | ui->TextBearbeiten->Wiederherstellen() |
Mehr erfahren
Über | Hier |
---|---|
Dateien und E/A-Geräte | QFile, QIODevice |
tr() und Internationalisierung | Qt 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
© 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.