diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2023-01-23 21:13:22 +0100 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2023-01-30 08:16:37 +0100 |
commit | 0e5a54f96dda1ea72fdc43026e3d9bb74886c61e (patch) | |
tree | 6607e647867fe2afff1440ccd3992144c50660f9 /examples | |
parent | c659dc3390dd1bfa298adf1531b731963ac91dc5 (diff) | |
download | qttools-0e5a54f96dda1ea72fdc43026e3d9bb74886c61e.tar.gz |
Qt Designer/calculatorbuilder example: Remove the form class and its autoconnected slots
The autoconnection feature is considered error-prone and is warned
about by clazy. As this removes the need for a class, remove it entirely
and use a lambda for the slot.
As a drive-by, fix the documentation of the project files.
Pick-to: 6.5 6.4
Task-number: QTBUG-110447
Change-Id: Idf78b58445a3f89399f7ae09065f145428ef83fe
Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
Diffstat (limited to 'examples')
6 files changed, 86 insertions, 136 deletions
diff --git a/examples/designer/calculatorbuilder/CMakeLists.txt b/examples/designer/calculatorbuilder/CMakeLists.txt index 293df3453..30a32c089 100644 --- a/examples/designer/calculatorbuilder/CMakeLists.txt +++ b/examples/designer/calculatorbuilder/CMakeLists.txt @@ -15,27 +15,28 @@ set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/designer/calculatorbuilder") find_package(Qt6 REQUIRED COMPONENTS Core Gui UiTools Widgets) -qt_add_executable(calculatorbuilder - calculatorform.cpp calculatorform.h - main.cpp -) +qt_add_executable(calculatorbuilder main.cpp) set_target_properties(calculatorbuilder PROPERTIES WIN32_EXECUTABLE TRUE MACOSX_BUNDLE TRUE ) +#! [0] target_link_libraries(calculatorbuilder PUBLIC Qt::Core Qt::Gui Qt::UiTools Qt::Widgets ) +#! [0] # Resources: +#! [1] set(calculatorbuilder_resource_files "calculatorform.ui" ) +#! [1] qt6_add_resources(calculatorbuilder "calculatorbuilder" PREFIX diff --git a/examples/designer/calculatorbuilder/calculatorbuilder.pro b/examples/designer/calculatorbuilder/calculatorbuilder.pro index 052dbd38a..740c31a6c 100644 --- a/examples/designer/calculatorbuilder/calculatorbuilder.pro +++ b/examples/designer/calculatorbuilder/calculatorbuilder.pro @@ -1,8 +1,6 @@ #! [0] -HEADERS = calculatorform.h RESOURCES = calculatorbuilder.qrc -SOURCES = calculatorform.cpp \ - main.cpp +SOURCES = main.cpp QT += widgets uitools #! [0] diff --git a/examples/designer/calculatorbuilder/calculatorform.cpp b/examples/designer/calculatorbuilder/calculatorform.cpp deleted file mode 100644 index 7af960f7e..000000000 --- a/examples/designer/calculatorbuilder/calculatorform.cpp +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause - -#include "calculatorform.h" - -//! [0] -#include <QtUiTools> -//! [0] -#include <QLabel> -#include <QSpinBox> -#include <QVBoxLayout> - -#include <QFile> - -using namespace Qt::StringLiterals; - -//! [1] -CalculatorForm::CalculatorForm(QWidget *parent) - : QWidget(parent) -{ - QUiLoader loader; - - QFile file(u":/forms/calculatorform.ui"_s); - file.open(QFile::ReadOnly); - QWidget *formWidget = loader.load(&file, this); - file.close(); -//! [1] - -//! [2] - ui_inputSpinBox1 = findChild<QSpinBox*>(u"inputSpinBox1"_s); - ui_inputSpinBox2 = findChild<QSpinBox*>(u"inputSpinBox2"_s); - ui_outputWidget = findChild<QLabel*>(u"outputWidget"_s); -//! [2] - -//! [3] - QMetaObject::connectSlotsByName(this); -//! [3] - -//! [4] - auto *layout = new QVBoxLayout(this); - layout->addWidget(formWidget); - - setWindowTitle(tr("Calculator Builder")); -} -//! [4] - -//! [5] -void CalculatorForm::on_inputSpinBox1_valueChanged(int value) -{ - ui_outputWidget->setText(QString::number(value + ui_inputSpinBox2->value())); -} -//! [5] //! [6] - -//! [6] //! [7] -void CalculatorForm::on_inputSpinBox2_valueChanged(int value) -{ - ui_outputWidget->setText(QString::number(value + ui_inputSpinBox1->value())); -} -//! [7] diff --git a/examples/designer/calculatorbuilder/calculatorform.h b/examples/designer/calculatorbuilder/calculatorform.h deleted file mode 100644 index ca34f1acf..000000000 --- a/examples/designer/calculatorbuilder/calculatorform.h +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause - -#ifndef CALCULATORFORM_H -#define CALCULATORFORM_H - -#include <QWidget> - -QT_BEGIN_NAMESPACE -class QLabel; -class QSpinBox; -QT_END_NAMESPACE - -//! [0] -class CalculatorForm : public QWidget -{ - Q_OBJECT - -public: - explicit CalculatorForm(QWidget *parent = nullptr); - -private slots: - void on_inputSpinBox1_valueChanged(int value); - void on_inputSpinBox2_valueChanged(int value); - -private: - QSpinBox *ui_inputSpinBox1; - QSpinBox *ui_inputSpinBox2; - QLabel *ui_outputWidget; -}; -//! [0] - -#endif // CALCULATORFORM_H diff --git a/examples/designer/calculatorbuilder/main.cpp b/examples/designer/calculatorbuilder/main.cpp index 54f091438..cfc146091 100644 --- a/examples/designer/calculatorbuilder/main.cpp +++ b/examples/designer/calculatorbuilder/main.cpp @@ -1,16 +1,69 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause -#include "calculatorform.h" +//! [0] +#include <QtUiTools> +//! [0] #include <QApplication> +#include <QLabel> +#include <QSpinBox> +#include <QVBoxLayout> + +#include <QFile> + +#include <memory> + +using namespace Qt::StringLiterals; + +//! [1] +static QWidget *loadCalculatorForm(QWidget *parent = nullptr) +{ + QUiLoader loader; + + QFile file(u":/forms/calculatorform.ui"_s); + if (!file.open(QFile::ReadOnly)) + return nullptr; + QWidget *formWidget = loader.load(&file, parent); + file.close(); + if (formWidget == nullptr) + return nullptr; +//! [1] + +//! [2] + auto *inputSpinBox1 = formWidget->findChild<QSpinBox*>(u"inputSpinBox1"_s); + auto *inputSpinBox2 = formWidget->findChild<QSpinBox*>(u"inputSpinBox2"_s); + auto *outputWidget = formWidget->findChild<QLabel*>(u"outputWidget"_s); +//! [2] + +//! [3] + auto updateResult = [inputSpinBox1, inputSpinBox2, outputWidget]() + { + const int sum = inputSpinBox1->value() + inputSpinBox2->value(); + outputWidget->setText(QString::number(sum)); + }; + QObject::connect(inputSpinBox1, &QSpinBox::valueChanged, formWidget, updateResult); + QObject::connect(inputSpinBox2, &QSpinBox::valueChanged, formWidget, updateResult); +//! [3] + + return formWidget; +} int main(int argc, char *argv[]) { Q_INIT_RESOURCE(calculatorbuilder); QApplication app(argc, argv); - CalculatorForm calculator; - calculator.show(); + QWidget w; + auto *formWidget = loadCalculatorForm(&w); + if (formWidget == nullptr) + return -1; + //! [4] + auto *layout = new QVBoxLayout(&w); + layout->addWidget(formWidget); + w.setWindowTitle(QCoreApplication::translate("CalculatorForm", + "Calculator Builder")); + //! [4] + w.show(); return app.exec(); } diff --git a/examples/designer/doc/src/calculatorbuilder.qdoc b/examples/designer/doc/src/calculatorbuilder.qdoc index a3aaae7be..aae2dece7 100644 --- a/examples/designer/doc/src/calculatorbuilder.qdoc +++ b/examples/designer/doc/src/calculatorbuilder.qdoc @@ -25,36 +25,31 @@ \c QtUiTools module library. The project file we use contains all the necessary information to do this: - \snippet calculatorbuilder/calculatorbuilder.pro 0 + \snippet calculatorbuilder/CMakeLists.txt 0 - All the other necessary files are declared as usual. + The UI file is loaded from a resource: - \section1 CalculatorForm Class Definition + \snippet calculatorbuilder/CMakeLists.txt 1 - The \c CalculatorForm class defines the widget used to host the form's - user interface: + For \c qmake: - \snippet calculatorbuilder/calculatorform.h 0 + \snippet calculatorbuilder/calculatorbuilder.pro 0 - Note that we do not need to include a header file to describe the user - interface. We only define two public slots, using the auto-connection - naming convention required by \c uic, and declare private variables - that we will use to access widgets provided by the form after they are - constructed. + All the other necessary files are declared as usual. - \section1 CalculatorForm Class Implementation + \section1 Loading the Calculator Form We will need to use the QUiLoader class that is provided by the \c libQtUiTools library, so we first ensure that we include the header file for the module: - \snippet calculatorbuilder/calculatorform.cpp 0 + \snippet calculatorbuilder/main.cpp 0 - The constructor uses a form loader object to construct the user - interface that we retrieve, via a QFile object, from the example's - resources: + We create a static helper function that creates a top level + widget and loads the user interface that we retrieve, + via a QFile object, from the example's resources: - \snippet calculatorbuilder/calculatorform.cpp 1 + \snippet calculatorbuilder/main.cpp 1 By including the user interface in the example's resources, we ensure that it will be present when the example is run. The \c{loader.load()} @@ -64,32 +59,27 @@ We are interested in three widgets in the generated user interface: two spin boxes and a label. For convenience, we retrieve pointers to these widgets from the widget that was constructed by the \c FormBuilder, - and we record them for later use. The \c qFindChild() template function + and we record them for later use. The \c findChild() template function allows us to query widgets in order to find named child widgets. - \snippet calculatorbuilder/calculatorform.cpp 2 + \snippet calculatorbuilder/main.cpp 2 - The widgets created by the form loader need to be connected to the - specially-named slots in the \c CalculatorForm object. We use Qt's - meta-object system to enable these connections: + The slot that modifies the output widget provided by the form is defined + in a similar way to that in the + \l{calculatorform}{Calculator Form} example, except that we use a + lambda, capturing the widgets found: - \snippet calculatorbuilder/calculatorform.cpp 3 + \snippet calculatorbuilder/main.cpp 3 The form widget is added to a layout, and the window title is set: - \snippet calculatorbuilder/calculatorform.cpp 4 - - The two slots that modify widgets provided by the form are defined - in a similar way to those in the \l{calculatorform}{Calculator - Form} example, except that we read the values from the spin boxes and - write the result to the output widget via the pointers we recorded in - the constructor: - - \snippet calculatorbuilder/calculatorform.cpp 5 - \codeline - \snippet calculatorbuilder/calculatorform.cpp 7 + \snippet calculatorbuilder/main.cpp 4 The advantage of this approach is that we can replace the form when the application is run, but we can still manipulate the widgets it contains as long as they are given appropriate names. + + However, loading a form at runtime incurs a runtime cost compared + to converting it to C++ code using the \l {User Interface Compiler (uic)} + tool. */ |