Skip to content

Commit 243a382

Browse files
authored
Qt6 Migration tutorial and doc updates (#690)
Signed-off-by: Ian Chen <ichen@openrobotics.org>
1 parent c709315 commit 243a382

File tree

10 files changed

+112
-12
lines changed

10 files changed

+112
-12
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ gz_create_docs(
124124
ADDITIONAL_INPUT_DIRS "${CMAKE_SOURCE_DIR}/src/plugins"
125125
IMAGE_PATH_DIRS "${CMAKE_SOURCE_DIR}/tutorials/images"
126126
TAGFILES
127-
"${CMAKE_SOURCE_DIR}/doc/qt.tag.xml=http://doc.qt.io/qt-5/"
127+
"${CMAKE_SOURCE_DIR}/doc/qt.tag.xml=https://doc.qt.io/qt-6/"
128128
"${GZ-MATH_DOXYGEN_TAGFILE} = ${GZ-MATH_API_URL}"
129129
"${GZ-MSGS_DOXYGEN_TAGFILE} = ${GZ-MSGS_API_URL}"
130130
"${GZ-RENDERING_DOXYGEN_TAGFILE} = ${GZ-RENDERING_API_URL}"

Migration.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ release will remove the deprecated code.
77

88
## Gazebo GUI 9.X to 10.X
99

10+
* Upgraded GUI framework from Qt5 to Qt6. All GUI plugins distributed by gz-gui
11+
have been migrated. This upgrade affects all users' custom Gazebo GUI plugins.
12+
Please see the
13+
[Qt6 Migration tutorial](https://github.com/gazebosim/gz-gui/blob/main/tutorials/09_migration_qt6.html)
14+
for information on how to port your Qt5 based plugins to Qt6.
15+
1016
* The environment variable `GZ_GUI_PLUGIN_INSTALL_DIR` is removed. Use
1117
`gz::gui::getPluginInstallDir()` instead.
1218

doc/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
find_package(Doxygen)
22

33
set(GZ_DOXYGEN_TAGFILES
4-
"\"${CMAKE_SOURCE_DIR}/doc/qt.tag.xml=http://doc.qt.io/qt-5/\" \
4+
"\"${CMAKE_SOURCE_DIR}/doc/qt.tag.xml=https://doc.qt.io/qt-6/\" \
55
\"${GZ-MATH_DOXYGEN_TAGFILE} = ${GZ-MATH_API_URL}\" \
66
\"${GZ-MSGS_DOXYGEN_TAGFILE} = ${GZ-MSGS_API_URL}\" \
77
\"${GZ-TRANSPORT_DOXYGEN_TAGFILE} = ${GZ-TRANSPORT_API_URL}\" \
@@ -24,6 +24,6 @@ if (DOXYGEN_FOUND)
2424

2525
COMMENT "Generating API documentation with Doxygen" VERBATIM)
2626

27-
install(FILES ${CMAKE_BINARY_DIR}/doc/${PROJECT_NAME_LOWER}.tag.xml
27+
install(FILES ${CMAKE_BINARY_DIR}/doc/${PROJECT_NAME_LOWER}.tag.xml
2828
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/gz/${PROJECT_NAME_LOWER}_${PROJECT_VERSION_MINOR})
2929
endif()

examples/config/plugin_params.config

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
<!--
1616
Properties passed directly to the QML card.
1717
It includes:
18-
* All Pane properties: https://doc.qt.io/qt-5/qml-qtquick-controls2-pane-members.html
18+
* All Pane properties: https://doc.qt.io/qt-6/qml-qtquick-controls-pane-members.html
1919
* All custom properties within GzCard.qml
2020
-->
2121
<property type="bool" key="showDockButton">false</property>

examples/plugin/custom_context_menu/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ endif()
88

99
set (CMAKE_AUTOMOC ON)
1010

11-
# Find Qt5
11+
# Find Qt6
1212
find_package (Qt6 6.4
1313
COMPONENTS
1414
Core

src/Plugin.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ class Plugin::Implementation
8383

8484
/// \brief Map of card properties to be passed to QML card object.
8585
/// Accepts all QML Pane properties plus custom Gazebo: GUI properties.
86-
/// https://doc.qt.io/qt-5/qml-qtquick-controls2-pane-members.html
86+
/// https://doc.qt.io/qt-6/qml-qtquick-controls-pane-members.html
8787
public: std::map<std::string, QVariant> cardProperties;
8888

8989
/// \brief Holds all anchor information

tutorials.md.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ Gazebo @GZ_DESIGNATION_CAP@ library and how to use the library effectively.
1919

2020
1. \subpage scene "3D Scene": How to use the rendering scene
2121
2. \subpage screenshot "Screenshot": Save screenshots of the 3D scene
22+
3. \subpage migration_qt6 "Qt6 Migration": Migrating Qt5 GUI plugins to Qt6
2223

2324
## License
2425

tutorials/03_plugins.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ Previous Tutorial: \ref commandline
55

66
## About Plugins
77

8-
A Gazebo GUI plugin is a shared library that defines a widget.
8+
A Gazebo GUI plugin is a shared library that defines a widget.
99

10-
The plugin contains [QML](http://doc.qt.io/qt-5/qtqml-index.html) code that specifies what the widget looks like, as well as C++ code that defines the plugin's behavior and ties it to other libraries.
10+
The plugin contains [QML](https://doc.qt.io/qt-6/qtqml-index.html) code that specifies what the widget looks like, as well as C++ code that defines the plugin's behavior and ties it to other libraries.
1111

1212
## Starting a pre-built plugin (example)
1313

tutorials/05_style.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Previous Tutorial: \ref layout
66
## Overview
77

88
Gazebo GUI leverages
9-
[QtQuick Controls 2 Styles](https://doc.qt.io/qt-5.9/qtquickcontrols2-styles.html)
9+
[QtQuick Controls Styles](https://doc.qt.io/qt-6/qtquickcontrols-styles.html)
1010
for styling. The recommended and best supported style is the Material Style,
1111
but it is also possible to use others such as Default and Universal. This tutorial
1212
focuses on customizing the Material style.
@@ -34,7 +34,7 @@ Users can customize the whole application's material style using just a few vari
3434
* Accent color
3535

3636
QML types provided by
37-
[QtQuick Controls 2](https://doc.qt.io/qt-5/qtquick-controls2-qmlmodule.html),
37+
[QtQuick Controls](https://doc.qt.io/qt-6/qtquick-controls-qmlmodule.html),
3838
as well as QML types provided by Gazebo GUI, use these variables as appropriate.
3939
It's recommended that developers make sure their plugins use these variables
4040
for a more integrated experience.
@@ -65,7 +65,7 @@ choose "Style settings".
6565

6666
A dialog will open, where you can change the theme (Light / Dark) and primary /
6767
accent colors. From the color dropdown menu, it is possible to choose one of the
68-
[pre-defined material colors](https://doc.qt.io/qt-5.9/qtquickcontrols2-material.html#pre-defined-material-colors),
68+
[pre-defined material colors](https://doc.qt.io/qt-6/qtquickcontrols-material.html#pre-defined-material-colors),
6969
and from the button next to it, it is possible to choose any custom color.
7070

7171
\note Custom colors won't be automatically shaded based on the theme.
@@ -75,7 +75,7 @@ and from the button next to it, it is possible to choose any custom color.
7575
## Environment variables
7676

7777
See
78-
[Supported Environment Variables in Qt Quick Controls 2](https://doc.qt.io/qt-5.9/qtquickcontrols2-environment.html).
78+
[Supported Environment Variables in Qt Quick Controls](https://doc.qt.io/qt-6/qtquickcontrols-environment.html).
7979

8080
You can try running the following command for example:
8181

tutorials/09_migration_qt6.md

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
\page migration_qt6 Migrating Qt5 GUI plugins to Qt6
2+
3+
Prerequisite Tutorial: \ref plugins
4+
5+
## Overview
6+
7+
Qt5 is planned to be removed in Ubuntu 26.04 LTS. In response to this,
8+
Gazebo GUI has upgraded its GUI framework from Qt5 to Qt6 in `gz-gui10`
9+
(Gazebo Jetty). This directly impacts all users who have developed
10+
their own custom Gazebo GUI plugins in Qt5.
11+
12+
This tutorial will highlight important changes that users need to make
13+
to migrate their existing Qt5 Gazebo GUI plugins to Qt6.
14+
15+
A Gazebo GUI is made up of C++, QML code, and configuration file, see
16+
the \ref plugins tutorial for more information. We expect that most of the
17+
required changes for porting to Qt6 will be in the QML code.
18+
19+
## QML and C++ Integration
20+
21+
In a Gazebo GUI plugin, users can create a QML interface that invokes C++
22+
functionality and vice versa. There is one major syntax change to how
23+
this should be done from `gz-gui10` onwards. Prior to `gz-gui10`, access to
24+
C++ functions or properties was done with the following syntax in QML:
25+
26+
```qml
27+
MyClass::FunctionFoo()
28+
```
29+
30+
The new syntax for doing this in Qt6 based Gazebo GUI plugin is:
31+
32+
```qml
33+
_MyClass::FunctionFoo()
34+
```
35+
36+
As an example, in the Qt5 based `Screenshot` GUI plugin's QML code, we call
37+
[Screenshot.OnScreenshot()](https://github.com/gazebosim/gz-gui/blob/e0c95585919d95a01fbf3af9a33c7fcd653ab154/src/plugins/screenshot/Screenshot.qml#L50)
38+
which inovkes the corresponding [C++ function](https://github.com/gazebosim/gz-gui/blob/e0c95585919d95a01fbf3af9a33c7fcd653ab154/src/plugins/screenshot/Screenshot.cc#L188)
39+
defined in the `Screenshot` C++ class.
40+
41+
In the Qt6 based Gazebo GUI plugin, the code is changed to
42+
[\_Screenshot.OnScreeShot()](https://github.com/gazebosim/gz-gui/blob/c7093159ac92031350cdf2c31283e3fdfd944194/src/plugins/screenshot/Screenshot.qml#L50)
43+
for the QML and C++ binding to work correctly.
44+
45+
This is mainly because Qt6 enforces stricter property rules and that property
46+
names should not begin with an upper case letter. Gazebo adds an
47+
underscore prefix to workaround this problem. No changes should be needed on
48+
the C++ end.
49+
50+
> Note: An alternative approach would be to choose a name that starts
51+
> with a lower case letter, i.e. `myClass.FunctionFoo()`. However, it was
52+
> noted that in many cases there exists an QML object with the id `myClass`
53+
> already which would conflict with the name of the C++ object. For example, the
54+
> Screenshot GUI plugin has a tool button with the id:
55+
> [screenshot](https://github.com/gazebosim/gz-gui/blob/c7093159ac92031350cdf2c31283e3fdfd944194/src/plugins/screenshot/Screenshot.qml#L37).
56+
> Hence a decision was made to add the `_` prefix to avoid any potential
57+
> naming conflicts.
58+
59+
## QML Migration
60+
61+
Gazebo gives users the freedom to import any QML modules in their QML code
62+
and create their UI in a way that is no different from writing other Qt
63+
programs. So users would need to follow the general
64+
[porting guide](https://doc.qt.io/qt-6/portingguide.html), paying attention
65+
to the QML and module changes. Some QML modules and types are obsolete while
66+
some QML types have significant syntax changes.
67+
68+
Common changes for porting Qt5 QML code to Qt6 include:
69+
* Importing a newer version of the Qt module, which can be done by removing the
70+
version number, e.g. `import QtQuick.Dialogs 1.0` becomes
71+
`import QtQuick.Dialogs`.
72+
* Adding the `_` prefix to the C++ object name as described in the
73+
`QML and C++ Integration` section above.
74+
* QML types requiring more code changes include but not limited to:
75+
[FileDialog](https://doc.qt.io/qt-6/qml-qtquick-dialogs-filedialog.html) and
76+
[TreeView](https://doc.qt.io/qt-6/qml-qtquick-treeview.html).
77+
* This [Qt6 migration pull request](https://github.com/gazebosim/gz-sim/pull/2832/files#diff-a93324029765acbdf791f6e6ed06b1ea2e2886a756f949e7948f7824a57b4e7b)
78+
shows examples of porting various Qt5 Gazebo GUI plugins to Qt6.
79+
80+
## Qt App and Event Loop
81+
82+
The core of Gazebo GUI sets up the necessary code for running an Qt application
83+
and its event loop. Here are some related migration notes:
84+
85+
* The main C++ API in Gazebo GUI for retrieving the running Qt Application
86+
is [App()](https://github.com/gazebosim/gz-gui/blob/e0c95585919d95a01fbf3af9a33c7fcd653ab154/include/gz/gui/Application.hh#L224)
87+
which essentially returns a
88+
[qGuiApp](https://doc.qt.io/qt-6/qguiapplication.html#qGuiApp) pointer.
89+
This pointer is no longer always guaranteed to be non-null. Users should check this
90+
pointer to make sure it is valid before using it.
91+
* Users are discouraged from calling
92+
[QCoreApplication::processEvents](https://doc.qt.io/qt-6/qcoreapplication.html#processEvents)
93+
manually in Qt6.

0 commit comments

Comments
 (0)