Erweiterung des Aufgabenmenüs
Erstellen eines benutzerdefinierten Widget-Plugins für den „ Qt Widgets -Designer“ und Bereitstellen benutzerdefinierter Einträge im Aufgabenmenü, die mit dem Plugin verknüpft sind.
Das Beispiel „Task-Menü-Erweiterung“ zeigt, wie ein benutzerdefiniertes Widget-Plugin für den „Qt Widgets -Designer“ erstellt wird und wie mithilfe der Klasse „ QDesignerTaskMenuExtension “ benutzerdefinierte Task-Menüeinträge bereitgestellt werden, die mit dem Plugin verknüpft sind.
Qt Widgets Designer." src="images/taskmenuextension-example.webp" title="Screenshot einer benutzerdefinierten Aktion „Status bearbeiten…“ im Kontextmenü des Qt Widgets Designer."/>
Um ein benutzerdefiniertes Widget bereitzustellen, das mit dem „ Qt Widgets Designer“ verwendet werden kann, müssen wir eine in sich geschlossene Implementierung bereitstellen. In diesem Beispiel verwenden wir ein benutzerdefiniertes Widget, das zur Demonstration der Funktion zur Erweiterung des Aufgabenmenüs entwickelt wurde: das TicTacToe-Widget.
Eine Erweiterung ist ein Objekt, das das Verhalten des „ Qt Widgets -Designers“ modifiziert. Der „ QDesignerTaskMenuExtension “ kann benutzerdefinierte Einträge im Aufgabenmenü bereitstellen, wenn ein Widget mit dieser Erweiterung ausgewählt wird.
Im „ Qt Widgets -Designer“ stehen vier Arten von Erweiterungen zur Verfügung:
- QDesignerContainerExtension bietet eine Erweiterung, mit der Sie Seiten zu einem mehrseitigen Container-Plugin im „ Qt Widgets Designer“ hinzufügen (und löschen) können.
- QDesignerMemberSheetExtension bietet eine Erweiterung, mit der Sie die Mitgliedsfunktionen eines Widgets bearbeiten können, das bei der Konfiguration von Verbindungen im Modus zur Bearbeitung von Signalen und Slots des „ Qt Widgets “-Designers angezeigt wird.
- QDesignerPropertySheetExtension bietet eine Erweiterung, mit der Sie die Eigenschaften eines Widgets bearbeiten können, das im Eigenschaftseditor des „ Qt Widgets “-Designers angezeigt wird.
- QDesignerTaskMenuExtension bietet eine Erweiterung, mit der Sie benutzerdefinierte Menüeinträge zum Aufgabenmenü des „ Qt Widgets “-Designers hinzufügen können.
Sie können alle Erweiterungen nach dem gleichen Muster wie in diesem Beispiel verwenden, indem Sie lediglich die jeweilige Basisklasse der Erweiterung ersetzen. Weitere Informationen finden Sie im Qt Widgets Designer C++ Classes.
Das Beispiel „Task-Menü-Erweiterung“ besteht aus fünf Klassen:
TicTacToeist ein benutzerdefiniertes Widget, mit dem der Benutzer das Tic-Tac-Toe-Spiel spielen kann.TicTacToePluginmacht die Klasse „TicTacToe“ für den „ Qt Widgets “-Designer verfügbar.TicTacToeTaskMenuFactoryerstellt ein „TicTacToeTaskMenu“-Objekt.TicTacToeTaskMenustellt die Task-Menü-Erweiterung bereit, d. h. die zum Plugin gehörenden Einträge im Task-Menü.TicTacToeDialogermöglicht es dem Benutzer, den Zustand eines in den „ Qt Widgets Designer“ geladenen Tic-Tac-Toe-Plugins zu ändern.
Die Projektdatei für benutzerdefinierte Widget-Plugins benötigt einige zusätzliche Informationen, um sicherzustellen, dass sie im „ Qt Widgets Designer“ funktionieren. Beispielsweise sind benutzerdefinierte Widget-Plugins auf Komponenten angewiesen, die mit dem „ Qt Widgets Designer“ bereitgestellt werden, und dies muss in der von uns verwendeten Projektdatei angegeben werden. Wir werden uns zunächst die Projektdatei des Plugins ansehen.
Anschließend werden wir die Klasse „ TicTacToePlugin “ näher betrachten und einen Blick auf die Klassen „ TicTacToeTaskMenuFactory “ und „ TicTacToeTaskMenu “ werfen. Zuletzt werden wir die Klasse „ TicTacToeDialog “ näher betrachten, bevor wir einen kurzen Blick auf die Klassendefinition des Widgets „ TicTacToe “ werfen.
Projektdateien
CMake
In den Projektdateien muss angegeben werden, dass ein Plugin erstellt werden soll, das mit den „ Qt Widgets “-Designer-Bibliotheken verknüpft ist:
find_package(Qt6 REQUIRED COMPONENTS Core Designer Gui Widgets)
qt_add_plugin(taskmenuextension)
target_link_libraries(taskmenuextension PUBLIC
Qt::Core
Qt::Designer
Qt::Gui
Qt::Widgets
)Das folgende Beispiel zeigt, wie die Header- und Quelldateien des Widgets hinzugefügt werden:
target_sources(taskmenuextension PRIVATE
tictactoe.cpp tictactoe.h
tictactoedialog.cpp tictactoedialog.h
tictactoeplugin.cpp tictactoeplugin.h
tictactoetaskmenu.cpp tictactoetaskmenu.h
)Wir stellen eine Implementierung der Plugin-Schnittstelle bereit, damit der „ Qt Widgets Designer“ das benutzerdefinierte Widget verwenden kann. In diesem speziellen Beispiel stellen wir außerdem Implementierungen der Aufgabenmenü-Erweiterung und der Erweiterungsfabrik sowie eine Dialogimplementierung bereit.
Es ist wichtig sicherzustellen, dass das Plugin an einem Ort installiert wird, der von „ Qt Widgets Designer“ durchsucht wird. Dazu geben wir einen Zielpfad für das Projekt an und fügen ihn der Liste der zu installierenden Elemente hinzu:
set(INSTALL_EXAMPLEDIR "${QT6_INSTALL_PREFIX}/${QT6_INSTALL_PLUGINS}/designer")
install(TARGETS taskmenuextension
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
)Die Aufgabenmenü-Erweiterung wird als Bibliothek erstellt. Sie wird bei der Installation des Projekts (über „ ninja install “ oder ein gleichwertiges Installationsverfahren) zusammen mit den anderen Qt Widgets -Designer-Plugins installiert.
Weitere Informationen zu Plugins finden Sie in der Dokumentation „How to Create Qt Plugins “.
qmake
Das folgende Beispiel zeigt, wie ein Plugin mit den Bibliotheken des „ Qt Widgets -Designers“ verknüpft wird:
TEMPLATE = lib
CONFIG += plugin
QT += widgets designerDas folgende Beispiel zeigt, wie die Header- und Quelldateien des Widgets hinzugefügt werden:
HEADERS += tictactoe.h \
tictactoedialog.h \
tictactoeplugin.h \
tictactoetaskmenu.h
SOURCES += tictactoe.cpp \
tictactoedialog.cpp \
tictactoeplugin.cpp \
tictactoetaskmenu.cpp
OTHER_FILES += tictactoe.jsonDas folgende Beispiel zeigt, wie ein Plugin im Plugin-Pfad des „ Qt Widgets “-Designers installiert wird:
target.path = $$[QT_INSTALL_PLUGINS]/designer
INSTALLS += targetKlassendefinition von „TicTacToePlugin“
Die Klasse „ TicTacToePlugin “ stellt die TicTacToe-Klasse „ the “ dem „ Qt Widgets Designer“ zur Verfügung. Ihre Definition entspricht der Plugin-Klasse aus dem Beispiel „Custom Widget Plugin“, das ausführlich erläutert wird. Der einzige Teil der Klassendefinition, der spezifisch für dieses bestimmte benutzerdefinierte Widget ist, ist der Klassenname.
Um sicherzustellen, dass Qt das Widget als Plugin erkennt, müssen relevante Informationen über das Widget durch Hinzufügen des Makros „ Q_PLUGIN_METADATA() “ exportiert werden:
#ifndef TICTACTOEPLUGIN_H
#define TICTACTOEPLUGIN_H
#include <QtUiPlugin/QDesignerCustomWidgetInterface>
class QIcon;
class QWidget;
class TicTacToePlugin : public QObject, public QDesignerCustomWidgetInterface
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QDesignerCustomWidgetInterface")
Q_INTERFACES(QDesignerCustomWidgetInterface)
public:
explicit TicTacToePlugin(QObject *parent = nullptr);
QString name() const override;
QString group() const override;
QString toolTip() const override;
QString whatsThis() const override;
QString includeFile() const override;
QIcon icon() const override;
bool isContainer() const override;
QWidget *createWidget(QWidget *parent) override;
bool isInitialized() const override;
void initialize(QDesignerFormEditorInterface *formEditor) override;
QString domXml() const override;
private:
bool initialized = false;
};
#endifDie Plugin-Klasse liefert dem „ Qt Widgets “ Designer grundlegende Informationen über unser Plugin, wie beispielsweise den Klassennamen und die Include-Datei. Darüber hinaus weiß sie, wie Instanzen des Widgets „ TicTacToe “ erstellt werden. „TicTacToePlugin“ definiert außerdem die Funktion „ initialize()“, die aufgerufen wird, nachdem das Plugin in den „ Qt Widgets “ Designer geladen wurde. Der Parameter „ QDesignerFormEditorInterface “ der Funktion bietet dem Plugin einen Zugang zu allen APIs des „ Qt Widgets “-Designers.
Die Klasse „ TicTacToePlugin “ erbt sowohl von „ QObject “ als auch von „ QDesignerCustomWidgetInterface “. Bei der Verwendung von Mehrfachvererbung ist es wichtig, sicherzustellen, dass alle Schnittstellen (d. h. die Klassen, die nicht von „ Q_OBJECT “ erben) dem Metaobjektsystem mithilfe des Makros „ Q_INTERFACES()“ bekannt gegeben werden. Dies ermöglicht es dem „ Qt Widgets Designer“, mit „ qobject_cast()“ nach unterstützten Schnittstellen abzufragen, wobei lediglich ein „ QObject “-Zeiger verwendet wird.
Implementierung der Klasse `TicTacToePlugin`
Die Implementierung der Klasse `TicTacToePlugin` entspricht größtenteils der Plugin-Klasse aus dem Beispiel „Custom Widget Plugin “:
TicTacToePlugin::TicTacToePlugin(QObject *parent)
: QObject(parent)
{
}
QString TicTacToePlugin::name() const
{
return u"TicTacToe"_s;
}
QString TicTacToePlugin::group() const
{
return u"Display Widgets [Examples]"_s;
}
QString TicTacToePlugin::toolTip() const
{
return u"Tic Tac Toe Example, demonstrating class QDesignerTaskMenuExtension (C++)"_s;
}
QString TicTacToePlugin::whatsThis() const
{
return {};
}
QString TicTacToePlugin::includeFile() const
{
return u"tictactoe.h"_s;
}
QIcon TicTacToePlugin::icon() const
{
return {};
}
bool TicTacToePlugin::isContainer() const
{
return false;
}
QWidget *TicTacToePlugin::createWidget(QWidget *parent)
{
auto *ticTacToe = new TicTacToe(parent);
ticTacToe->setState(u"-X-XO----"_s);
return ticTacToe;
}
bool TicTacToePlugin::isInitialized() const
{
return initialized;
}Die einzige Funktion, die sich wesentlich unterscheidet, ist die Funktion `initialize()`:
void TicTacToePlugin::initialize(QDesignerFormEditorInterface *formEditor)
{Die Funktion ` initialize() ` nimmt ein ` QDesignerFormEditorInterface `-Objekt als Argument entgegen. Die Klasse ` QDesignerFormEditorInterface ` bietet Zugriff auf die Komponenten des „ Qt Widgets “-Designers.
Im „ Qt Widgets Designer“ können Sie zwei Arten von Plugins erstellen: benutzerdefinierte Widget-Plugins und Tool-Plugins. „ QDesignerFormEditorInterface “ bietet Zugriff auf alle Komponenten des „ Qt Widgets Designer“, die Sie normalerweise zum Erstellen eines Tool-Plugins benötigen: den Erweiterungsmanager, den Objektinspektor, den Eigenschaftseditor und die Widget-Box. Benutzerdefinierte Widget-Plugins haben Zugriff auf dieselben Komponenten.
if (initialized)
return;
auto *manager = formEditor->extensionManager();
Q_ASSERT(manager != nullptr);Beim Erstellen von Erweiterungen im Zusammenhang mit benutzerdefinierten Widget-Plugins müssen wir auf den aktuellen Erweiterungsmanager des „ Qt Widgets “-Designers zugreifen, den wir über den Parameter „ QDesignerFormEditorInterface “ abrufen.
Qt Widgets Der „ QDesignerFormEditorInterface “ des Designers enthält Informationen zu allen Komponenten von „ Qt Designer “: dem Aktionseditor, dem Objektinspektor, dem Eigenschaftseditor, der Widget-Box sowie den Erweiterungs- und Formularfenster-Managern.
Die Klasse „ QExtensionManager “ stellt Funktionen zur Erweiterungsverwaltung für den „ Qt Widgets Designer“ bereit. Mithilfe des aktuellen Erweiterungsmanagers des „ Qt Widgets Designers“ können Sie die Erweiterung für ein bestimmtes Objekt abrufen. Außerdem können Sie eine Erweiterung für ein bestimmtes Objekt registrieren oder deren Registrierung aufheben. Beachten Sie, dass eine Erweiterung ein Objekt ist, das das Verhalten des „ Qt Widgets Designers“ verändert.
Bei der Registrierung einer Erweiterung wird eigentlich die zugehörige Erweiterungsfabrik registriert. In „ Qt Widgets “ Designer werden Erweiterungsfabriken verwendet, um benannte Erweiterungen bei Bedarf nachzuschlagen und zu erstellen. In diesem Beispiel wird die Erweiterung für das Aufgabenmenü also erst erstellt, wenn der Benutzer ein Aufgabenmenü anfordert.
manager->registerExtensions(new TicTacToeTaskMenuFactory(manager),
Q_TYPEID(QDesignerTaskMenuExtension));
initialized = true;
}
QString TicTacToePlugin::domXml() const
{
return uR"(
<ui language="c++">
<widget class="TicTacToe" name="ticTacToe"/>
<customwidgets>
<customwidget>
<class>TicTacToe</class>
<propertyspecifications>
<tooltip name="state">Tic Tac Toe state</tooltip>
<stringpropertyspecification name="state" notr="true" type="singleline"/>
</propertyspecifications>
</customwidget>
</customwidgets>
</ui>
)"_s;
}Wir erstellen ein ` TicTacToeTaskMenuFactory `-Objekt, das wir mithilfe des aktuellen ` extension manager ` des ` Qt Widgets `-Designers registrieren, der aus dem Parameter ` QDesignerFormEditorInterface ` abgerufen wird. Das erste Argument ist die neu erstellte Factory und das zweite Argument ist eine Erweiterungskennung, bei der es sich um eine Zeichenkette handelt. Das Makro ` Q_TYPEID() ` wandelt die Zeichenkette einfach in ein ` QLatin1String` um.
Die Klasse „ TicTacToeTaskMenuFactory “ ist eine Unterklasse von „ QExtensionFactory “. Wenn der Benutzer ein Aufgabenmenü anfordert, indem er mit der rechten Maustaste auf ein Widget mit der angegebenen Aufgabenmenü-Erweiterung klickt, durchläuft der Erweiterungsmanager von „ Qt Widgets Designer“ alle registrierten Fabriken und ruft die erste auf, die in der Lage ist, eine Aufgabenmenü-Erweiterung für das ausgewählte Widget zu erstellen. Diese Factory erstellt wiederum ein Objekt vom Typ „ TicTacToeTaskMenu “ (die Erweiterung).
Wir verzichten darauf, die Funktion ` QDesignerCustomWidgetInterface::domXml()` neu zu implementieren (die Standardeinstellungen für das Widget im von „ Qt Widgets Designer“ verwendeten Standard-XML-Format enthält), da keine Standardwerte erforderlich sind.
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QDesignerCustomWidgetInterface")Schließlich verwenden wir das Makro ` Q_PLUGIN_METADATA()` zum Exportieren der Klasse `TicTacToePlugin` für die Verwendung mit den Plugin-Verwaltungsklassen von Qt: Dieses Makro stellt sicher, dass der „ Qt Widgets “-Designer auf das benutzerdefinierte Widget zugreifen und es instanziieren kann. Ohne dieses Makro gibt es für den „ Qt Widgets “-Designer keine Möglichkeit, das Widget zu verwenden.
Klassendefinition von `TicTacToeTaskMenuFactory`
Die Klasse „ TicTacToeTaskMenuFactory “ erbt von „ QExtensionFactory “, die eine Standard-Erweiterungsfabrik für den „ Qt Widgets Designer“ bereitstellt.
class TicTacToeTaskMenuFactory : public QExtensionFactory
{
Q_OBJECT
public:
explicit TicTacToeTaskMenuFactory(QExtensionManager *parent = nullptr);
protected:
QObject *createExtension(QObject *object, const QString &iid, QObject *parent) const override;
};Der Zweck der Unterklasse besteht darin, die Funktion „ QExtensionFactory::createExtension()“ neu zu implementieren, sodass sie eine Erweiterung für das Aufgabenmenü von „ TicTacToe “ erstellen kann.
Implementierung der Klasse „TicTacToeTaskMenuFactory“
Der Klassenkonstruktor ruft einfach den Konstruktor der Basisklasse „ QExtensionFactory “ auf:
TicTacToeTaskMenuFactory::TicTacToeTaskMenuFactory(QExtensionManager *parent)
: QExtensionFactory(parent)
{
}Wie oben beschrieben, wird die Factory aufgerufen, wenn der Benutzer ein Aufgabenmenü anfordert, indem er mit der rechten Maustaste auf ein Widget mit der angegebenen Aufgabenmenü-Erweiterung im „ Qt Widgets Designer“ klickt.
Qt Widgets Das Verhalten des Designers ist unabhängig davon, ob die angeforderte Erweiterung mit einem Container, einem Member-Sheet, einem Property-Sheet oder einem Aufgabenmenü verknüpft ist: Sein Erweiterungsmanager durchläuft alle registrierten Erweiterungsfabriken und ruft für jede davon „ createExtension() “ auf, bis eine davon reagiert und die angeforderte Erweiterung erstellt.
QObject *TicTacToeTaskMenuFactory::createExtension(QObject *object,
const QString &iid,
QObject *parent) const
{
if (iid != Q_TYPEID(QDesignerTaskMenuExtension))
return nullptr;
if (auto *tic = qobject_cast<TicTacToe*>(object))
return new TicTacToeTaskMenu(tic, parent);
return nullptr;
}Daher prüfen wir in „ TicTacToeTaskMenuFactory::createExtension() “ als Erstes, ob es sich bei der angeforderten Erweiterung um eine Aufgabenmenü-Erweiterung handelt. Ist dies der Fall und handelt es sich bei dem anfordernden Widget um ein „ TicTacToe “-Widget, erstellen wir ein „ TicTacToeTaskMenu “-Objekt und geben es zurück. Andernfalls geben wir einfach einen Nullzeiger zurück, sodass der Erweiterungsmanager von „ Qt Widgets Designer“ seine Suche durch die registrierten Fabriken fortsetzen kann.
Klassendefinition von `TicTacToeTaskMenu`

Die Klasse „ TicTacToeTaskMenu “ erbt von „ QDesignerTaskMenuExtension “, wodurch Sie benutzerdefinierte Einträge (in Form von QActions) zum Aufgabenmenü im „ Qt Widgets Designer“ hinzufügen können.
class TicTacToeTaskMenu : public QObject, public QDesignerTaskMenuExtension
{
Q_OBJECT
Q_INTERFACES(QDesignerTaskMenuExtension)
public:
explicit TicTacToeTaskMenu(TicTacToe *tic, QObject *parent);
QAction *preferredEditAction() const override;
QList<QAction *> taskActions() const override;
private slots:
void editState();
private:
QAction *editStateAction;
TicTacToe *ticTacToe;
};Wir implementieren die Funktionen „ preferredEditAction() “ und „ taskActions() “ neu. Beachten Sie, dass wir einen Konstruktor implementieren, der zwei Argumente entgegennimmt: das übergeordnete Widget und das „ TicTacToe “-Widget, für das das Aufgabenmenü angefordert wird.
Außerdem deklarieren wir den privaten Slot „ editState() “, unseren benutzerdefinierten „ editStateAction “ sowie einen privaten Zeiger auf das „ TicTacToe “-Widget, dessen Zustand wir ändern möchten.
Implementierung der Klasse „TicTacToeTaskMenu“
TicTacToeTaskMenu::TicTacToeTaskMenu(TicTacToe *tic, QObject *parent)
: QObject(parent)
, editStateAction(new QAction(tr("Edit State..."), this))
, ticTacToe(tic)
{
connect(editStateAction, &QAction::triggered, this, &TicTacToeTaskMenu::editState);
}Im Konstruktor speichern wir zunächst die Referenz auf das als Parameter übergebene „ TicTacToe “-Widget, d. h. das Widget, dessen Zustand wir ändern möchten. Diese benötigen wir später, wenn unsere benutzerdefinierte Aktion aufgerufen wird. Außerdem erstellen wir unseren benutzerdefinierten „ editStateAction “ und verbinden ihn mit dem „ editState() “-Slot.
void TicTacToeTaskMenu::editState()
{
TicTacToeDialog dialog(ticTacToe);
dialog.exec();
}Der Slot „ editState() “ wird immer dann aufgerufen, wenn der Benutzer im Aufgabenmenü eines „ TicTacToe “-Widgets die Option „Edit State...“ auswählt. Der Slot erstellt ein „ TicTacToeDialog “, das den aktuellen Zustand des Widgets anzeigt und es dem Benutzer ermöglicht, dessen Zustand durch das Spielen des Spiels zu bearbeiten.
QAction *TicTacToeTaskMenu::preferredEditAction() const
{
return editStateAction;
}Wir implementieren die Funktion „ preferredEditAction() “ neu, sodass sie unser benutzerdefiniertes „ editStateAction “ als die Aktion zurückgibt, die aufgerufen werden soll, wenn ein „ TicTacToe “-Widget ausgewählt und die Taste F2 gedrückt wird.
QList<QAction *> TicTacToeTaskMenu::taskActions() const
{
return QList<QAction *>{editStateAction};
}Wir implementieren die Funktion „ taskActions() “ neu, sodass sie eine Liste unserer benutzerdefinierten Aktionen zurückgibt, wodurch diese im Aufgabenmenü eines „ TicTacToe “-Widgets über den Standardmenüeinträgen angezeigt werden.
Klassendefinition von `TicTacToeDialog`

Die Klasse „ TicTacToeDialog “ erbt von „ QDialog “. Der Dialog ermöglicht es dem Benutzer, den Status des aktuell ausgewählten Tic-Tac-Toe-Plugins zu ändern.
class TicTacToeDialog : public QDialog
{
Q_OBJECT
public:
explicit TicTacToeDialog(TicTacToe *plugin = nullptr, QWidget *parent = nullptr);
QSize sizeHint() const override;
private slots:
void resetState();
void saveState();
private:
TicTacToe *editor;
TicTacToe *ticTacToe;
QDialogButtonBox *buttonBox;
};Wir implementieren die Funktion „ sizeHint() “ neu. Außerdem deklarieren wir zwei private Slots: „ resetState() “ und „ saveState() “. Zusätzlich zu den Schaltflächen und Layouts des Dialogs deklarieren wir zwei Zeiger vom Typ „ TicTacToe “: einen auf das Widget, mit dem der Benutzer interagieren kann, und einen auf das ursprüngliche benutzerdefinierte Widget-Plugin, dessen Zustand der Benutzer bearbeiten möchte.
Implementierung der Klasse `TicTacToeDialog`
TicTacToeDialog::TicTacToeDialog(TicTacToe *tic, QWidget *parent)
: QDialog(parent)
, editor(new TicTacToe)
, ticTacToe(tic)
, buttonBox(new QDialogButtonBox(QDialogButtonBox::Ok
| QDialogButtonBox::Cancel
| QDialogButtonBox::Reset))
{
editor->setState(ticTacToe->state());
connect(buttonBox->button(QDialogButtonBox::Reset), &QAbstractButton::clicked,
this, &TicTacToeDialog::resetState);
connect(buttonBox, &QDialogButtonBox::accepted, this, &TicTacToeDialog::saveState);
connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
auto *mainLayout = new QVBoxLayout(this);
mainLayout->addWidget(editor);
mainLayout->addWidget(buttonBox);
setWindowTitle(tr("Edit State"));
}Im Konstruktor speichern wir zunächst die Referenz auf das als Parameter übergebene „TicTacToe“-Widget, d. h. das Widget, dessen Zustand der Benutzer ändern möchte. Anschließend erstellen wir ein neues „ TicTacToe “-Widget und setzen dessen Zustand so, dass er dem Zustand des als Parameter übergebenen Widgets entspricht.
Schließlich erstellen wir die Schaltflächen und das Layout des Dialogs.
QSize TicTacToeDialog::sizeHint() const
{
return {250, 250};
}Wir implementieren die Funktion „ sizeHint() “ neu, um sicherzustellen, dass der Dialog eine angemessene Größe erhält.
void TicTacToeDialog::resetState()
{
editor->clearBoard();
}Der Slot „ resetState() “ wird immer dann aufgerufen, wenn der Benutzer die Schaltfläche „Zurücksetzen“ drückt. Dabei rufen wir lediglich die Funktion „ clearBoard() “ für das Editor-Widget auf, d. h. das Widget „ TicTacToe “, das wir im Konstruktor des Dialogs erstellt haben.
void TicTacToeDialog::saveState()
{Der Slot „ saveState() “ wird aufgerufen, sobald der Benutzer auf die Schaltfläche „OK“ klickt, und überträgt den Zustand des Editor-Widgets an das Widget, dessen Zustand wir ändern möchten. Damit die Zustandsänderung für den „ Qt Widgets Designer“ sichtbar wird, müssen wir die Zustandseigenschaft des letzteren Widgets mithilfe der Klasse „ QDesignerFormWindowInterface “ setzen.
QDesignerFormWindowInterface Qt Widgets bietet Ihnen Informationen über das zugehörige Formularfenster und ermöglicht es Ihnen, dessen Eigenschaften zu ändern. Die Schnittstelle ist nicht dafür vorgesehen, direkt instanziiert zu werden, sondern soll Zugriff auf die aktuellen Formularfenster des „ -Designers“ gewähren, die vom Formularfenster-Manager des „ -Designers“ verwaltet werden. Qt Widgets
Wenn Sie nach dem Formularfenster suchen, das ein bestimmtes Widget enthält, können Sie die statische Funktion ` QDesignerFormWindowInterface::findFormWindow()` verwenden:
if (auto *formWindow = QDesignerFormWindowInterface::findFormWindow(ticTacToe))
formWindow->cursor()->setProperty("state", editor->state());Nachdem wir das Formularfenster des Widgets abgerufen haben (dessen Zustand wir ändern möchten), verwenden wir die Funktion ` QDesignerFormWindowInterface::cursor()`, um den Cursor des Formularfensters abzurufen.
Die Klasse „ QDesignerFormWindowCursorInterface “ bietet eine Schnittstelle zum Textcursor des Formularfensters. Sobald wir den Cursor haben, können wir schließlich die Eigenschaft „state“ mithilfe der Funktion „ QDesignerFormWindowCursorInterface::setProperty()“ setzen.
accept();
}Abschließend rufen wir die Funktion ` QEvent::accept()` auf, die das „accept“-Flag des Ereignisobjekts setzt. Das Setzen des Parameters ` accept ` zeigt an, dass der Ereignisempfänger das Ereignis annehmen möchte. Unerwünschte Ereignisse könnten sonst an das übergeordnete Widget weitergeleitet werden.
Definition der Klasse „TicTacToe“
Die Klasse „ TicTacToe “ ist ein benutzerdefiniertes Widget, mit dem der Benutzer das Tic-Tac-Toe-Spiel spielen kann.
class TicTacToe : public QWidget
{
Q_OBJECT
Q_PROPERTY(QString state READ state WRITE setState)
public:
explicit TicTacToe(QWidget *parent = nullptr);
QSize minimumSizeHint() const override;
QSize sizeHint() const override;
void setState(const QString &newState);
QString state() const;
void clearBoard();
protected:
void mousePressEvent(QMouseEvent *event) override;
void paintEvent(QPaintEvent *event) override;
private:
static constexpr char16_t Empty = '-';
static constexpr char16_t Cross = 'X';
static constexpr char16_t Nought = 'O';
QRect cellRect(int position) const;
int cellWidth() const { return width() / 3; }
int cellHeight() const { return height() / 3; }
QString myState;
int turnNumber = 0;
};Die wichtigsten Details, die bei der Definition der Klasse „ TicTacToe “ zu beachten sind, sind die Deklaration der Eigenschaft „ state “ sowie deren Funktionen „ state() “ und „ setState() “.
Wir müssen den Zustand des Widgets „ TicTacToe “ als Eigenschaft deklarieren, damit er für den „ Qt Widgets Designer“ sichtbar ist; so kann der „ Qt Widgets Designer“ ihn auf dieselbe Weise verwalten wie die Eigenschaften, die das Widget „ TicTacToe “ von „ QWidget “ und „ QObject “ erbt – beispielsweise mithilfe des Eigenschaftseditors.
© 2026 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.