summaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/CMakeLists.txt23
-rw-r--r--examples/corelib/CMakeLists.txt10
-rw-r--r--examples/corelib/bindableproperties/bindablesubscription/CMakeLists.txt16
-rw-r--r--examples/corelib/bindableproperties/bindablesubscription/bindablesubscription.cpp6
-rw-r--r--examples/corelib/bindableproperties/bindablesubscription/bindablesubscription.h2
-rw-r--r--examples/corelib/bindableproperties/bindablesubscription/bindableuser.h11
-rw-r--r--examples/corelib/bindableproperties/bindablesubscription/main.cpp9
-rw-r--r--examples/corelib/bindableproperties/doc/src/bindableproperties.qdoc32
-rw-r--r--examples/corelib/bindableproperties/subscription/CMakeLists.txt16
-rw-r--r--examples/corelib/bindableproperties/subscription/main.cpp9
-rw-r--r--examples/corelib/bindableproperties/subscription/subscription.cpp6
-rw-r--r--examples/corelib/bindableproperties/subscription/subscription.h2
-rw-r--r--examples/corelib/bindableproperties/subscription/user.h13
-rw-r--r--examples/corelib/ipc/CMakeLists.txt7
-rw-r--r--examples/corelib/ipc/localfortuneclient/CMakeLists.txt17
-rw-r--r--examples/corelib/ipc/localfortuneserver/CMakeLists.txt17
-rw-r--r--examples/corelib/ipc/sharedmemory/CMakeLists.txt16
-rw-r--r--examples/corelib/ipc/sharedmemory/dialog.cpp9
-rw-r--r--examples/corelib/mimetypes/CMakeLists.txt5
-rw-r--r--examples/corelib/mimetypes/mimetypebrowser/CMakeLists.txt15
-rw-r--r--examples/corelib/permissions/CMakeLists.txt47
-rw-r--r--examples/corelib/permissions/Info.plist59
-rw-r--r--examples/corelib/permissions/android/AndroidManifest.xml53
-rw-r--r--examples/corelib/permissions/main.cpp87
-rw-r--r--examples/corelib/platform/CMakeLists.txt3
-rw-r--r--examples/corelib/platform/androidnotifier/CMakeLists.txt9
-rw-r--r--examples/corelib/platform/androidnotifier/android/AndroidManifest.xml7
-rw-r--r--examples/corelib/platform/androidnotifier/doc/src/androidnotifier-example.qdoc3
-rw-r--r--examples/corelib/serialization/CMakeLists.txt9
-rw-r--r--examples/corelib/serialization/cbordump/CMakeLists.txt11
-rwxr-xr-xexamples/corelib/serialization/cbordump/cbortag.py188
-rw-r--r--examples/corelib/serialization/cbordump/doc/images/cbordump.pngbin0 -> 9556 bytes
-rw-r--r--examples/corelib/serialization/cbordump/doc/src/cbordump.qdoc55
-rw-r--r--examples/corelib/serialization/cbordump/main.cpp144
-rw-r--r--examples/corelib/serialization/cbordump/tag-transform.xslt25
-rw-r--r--examples/corelib/serialization/convert/CMakeLists.txt11
-rw-r--r--examples/corelib/serialization/convert/cborconverter.cpp20
-rw-r--r--examples/corelib/serialization/convert/datastreamconverter.cpp6
-rw-r--r--examples/corelib/serialization/convert/doc/images/convert.pngbin0 -> 49201 bytes
-rw-r--r--examples/corelib/serialization/convert/doc/src/convert.qdoc82
-rw-r--r--examples/corelib/serialization/convert/jsonconverter.cpp7
-rw-r--r--examples/corelib/serialization/convert/main.cpp12
-rw-r--r--examples/corelib/serialization/convert/xmlconverter.cpp7
-rw-r--r--examples/corelib/serialization/rsslisting/CMakeLists.txt (renamed from examples/xml/rsslisting/CMakeLists.txt)22
-rw-r--r--examples/corelib/serialization/rsslisting/doc/images/rsslisting.pngbin0 -> 19739 bytes
-rw-r--r--examples/corelib/serialization/rsslisting/doc/src/rsslisting.qdoc129
-rw-r--r--examples/corelib/serialization/rsslisting/main.cpp (renamed from examples/widgets/tools/undo/main.cpp)16
-rw-r--r--examples/corelib/serialization/rsslisting/rsslisting.cpp126
-rw-r--r--examples/corelib/serialization/rsslisting/rsslisting.h (renamed from examples/xml/rsslisting/rsslisting.h)19
-rw-r--r--examples/corelib/serialization/rsslisting/rsslisting.pro (renamed from examples/xml/rsslisting/rsslisting.pro)4
-rw-r--r--examples/corelib/serialization/savegame/CMakeLists.txt11
-rw-r--r--examples/corelib/serialization/savegame/character.cpp46
-rw-r--r--examples/corelib/serialization/savegame/character.h14
-rw-r--r--examples/corelib/serialization/savegame/doc/src/savegame.qdoc149
-rw-r--r--examples/corelib/serialization/savegame/game.cpp74
-rw-r--r--examples/corelib/serialization/savegame/game.h10
-rw-r--r--examples/corelib/serialization/savegame/level.cpp52
-rw-r--r--examples/corelib/serialization/savegame/level.h12
-rw-r--r--examples/corelib/serialization/savegame/main.cpp27
-rw-r--r--examples/corelib/serialization/serialization.pro6
-rw-r--r--examples/corelib/serialization/streambookmarks/CMakeLists.txt (renamed from examples/xml/streambookmarks/CMakeLists.txt)20
-rw-r--r--examples/corelib/serialization/streambookmarks/doc/images/xmlstreamexample-filemenu.png (renamed from examples/xml/streambookmarks/doc/images/xmlstreamexample-filemenu.png)bin9380 -> 9380 bytes
-rw-r--r--examples/corelib/serialization/streambookmarks/doc/images/xmlstreamexample-helpmenu.png (renamed from examples/xml/streambookmarks/doc/images/xmlstreamexample-helpmenu.png)bin10856 -> 10856 bytes
-rw-r--r--examples/corelib/serialization/streambookmarks/doc/images/xmlstreamexample-screenshot.png (renamed from examples/xml/streambookmarks/doc/images/xmlstreamexample-screenshot.png)bin22323 -> 22323 bytes
-rw-r--r--examples/corelib/serialization/streambookmarks/doc/src/qxmlstreambookmarks.qdoc (renamed from examples/xml/streambookmarks/doc/src/qxmlstreambookmarks.qdoc)42
-rw-r--r--examples/corelib/serialization/streambookmarks/jennifer.xbel (renamed from examples/xml/streambookmarks/jennifer.xbel)0
-rw-r--r--examples/corelib/serialization/streambookmarks/main.cpp (renamed from examples/xml/streambookmarks/main.cpp)0
-rw-r--r--examples/corelib/serialization/streambookmarks/mainwindow.cpp (renamed from examples/xml/streambookmarks/mainwindow.cpp)0
-rw-r--r--examples/corelib/serialization/streambookmarks/mainwindow.h (renamed from examples/xml/streambookmarks/mainwindow.h)0
-rw-r--r--examples/corelib/serialization/streambookmarks/streambookmarks.pro (renamed from examples/xml/streambookmarks/streambookmarks.pro)4
-rw-r--r--examples/corelib/serialization/streambookmarks/xbelreader.cpp (renamed from examples/xml/streambookmarks/xbelreader.cpp)0
-rw-r--r--examples/corelib/serialization/streambookmarks/xbelreader.h (renamed from examples/xml/streambookmarks/xbelreader.h)0
-rw-r--r--examples/corelib/serialization/streambookmarks/xbelwriter.cpp (renamed from examples/xml/streambookmarks/xbelwriter.cpp)0
-rw-r--r--examples/corelib/serialization/streambookmarks/xbelwriter.h (renamed from examples/xml/streambookmarks/xbelwriter.h)0
-rw-r--r--examples/corelib/threads/CMakeLists.txt5
-rw-r--r--examples/corelib/threads/doc/src/mandelbrot.qdoc17
-rw-r--r--examples/corelib/threads/doc/src/waitconditions.qdoc2
-rw-r--r--examples/corelib/threads/mandelbrot/CMakeLists.txt15
-rw-r--r--examples/corelib/threads/mandelbrot/main.cpp6
-rw-r--r--examples/corelib/threads/mandelbrot/mandelbrotwidget.cpp55
-rw-r--r--examples/corelib/threads/mandelbrot/mandelbrotwidget.h8
-rw-r--r--examples/corelib/threads/queuedcustomtype/CMakeLists.txt15
-rw-r--r--examples/corelib/threads/semaphores/CMakeLists.txt11
-rw-r--r--examples/corelib/threads/semaphores/semaphores.cpp3
-rw-r--r--examples/corelib/threads/waitconditions/CMakeLists.txt11
-rw-r--r--examples/corelib/threads/waitconditions/waitconditions.cpp66
-rw-r--r--examples/corelib/tools/CMakeLists.txt5
-rw-r--r--examples/corelib/tools/contiguouscache/CMakeLists.txt15
-rw-r--r--examples/corelib/tools/customtype/CMakeLists.txt15
-rw-r--r--examples/corelib/tools/customtypesending/CMakeLists.txt15
-rw-r--r--examples/dbus/CMakeLists.txt10
-rw-r--r--examples/dbus/chat/CMakeLists.txt19
-rw-r--r--examples/dbus/chat/chat.cpp119
-rw-r--r--examples/dbus/chat/chat.h20
-rw-r--r--examples/dbus/chat/chat.pro2
-rw-r--r--examples/dbus/chat/chatsetnickname.ui149
-rw-r--r--examples/dbus/complexpingpong/CMakeLists.txt7
-rw-r--r--examples/dbus/complexpingpong/complexping.cpp40
-rw-r--r--examples/dbus/complexpingpong/complexping.h9
-rw-r--r--examples/dbus/complexpingpong/complexpong.cpp20
-rw-r--r--examples/dbus/complexpingpong/complexpong.h11
-rw-r--r--examples/dbus/dbus.pro3
-rw-r--r--examples/dbus/doc/images/dbus-chat-example.pngbin38530 -> 0 bytes
-rw-r--r--examples/dbus/doc/images/dbus-chat-example.webpbin0 -> 17556 bytes
-rw-r--r--examples/dbus/doc/src/chat.qdoc4
-rw-r--r--examples/dbus/doc/src/complexpingpong.qdoc4
-rw-r--r--examples/dbus/doc/src/listnames.qdoc15
-rw-r--r--examples/dbus/doc/src/pingpong.qdoc2
-rw-r--r--examples/dbus/listnames/CMakeLists.txt27
-rw-r--r--examples/dbus/listnames/listnames.cpp58
-rw-r--r--examples/dbus/listnames/listnames.pro8
-rw-r--r--examples/dbus/pingpong/CMakeLists.txt13
-rw-r--r--examples/dbus/pingpong/ping.cpp21
-rw-r--r--examples/dbus/pingpong/pong.cpp32
-rw-r--r--examples/dbus/pingpong/pong.h16
-rw-r--r--examples/dbus/pingpong/pong.pro2
-rw-r--r--examples/dbus/remotecontrolledcar/CMakeLists.txt14
-rw-r--r--examples/dbus/remotecontrolledcar/car/CMakeLists.txt20
-rw-r--r--examples/dbus/remotecontrolledcar/car/car.cpp9
-rw-r--r--examples/dbus/remotecontrolledcar/car/car.h18
-rw-r--r--examples/dbus/remotecontrolledcar/car/car.pro2
-rw-r--r--examples/dbus/remotecontrolledcar/car/car.xml11
-rw-r--r--examples/dbus/remotecontrolledcar/car/main.cpp4
-rw-r--r--examples/dbus/remotecontrolledcar/common/car.xml (renamed from examples/dbus/remotecontrolledcar/controller/car.xml)3
-rw-r--r--examples/dbus/remotecontrolledcar/controller/CMakeLists.txt21
-rw-r--r--examples/dbus/remotecontrolledcar/controller/controller.cpp42
-rw-r--r--examples/dbus/remotecontrolledcar/controller/controller.h10
-rw-r--r--examples/dbus/remotecontrolledcar/controller/controller.pro2
-rw-r--r--examples/dbus/remotecontrolledcar/doc/images/remotecontrolledcar-car-example.pngbin8833 -> 0 bytes
-rw-r--r--examples/dbus/remotecontrolledcar/doc/images/remotecontrolledcar-car-example.webpbin0 -> 14484 bytes
-rw-r--r--examples/dbus/remotecontrolledcar/doc/src/dbus-remotecontrolledcar.qdoc4
-rw-r--r--examples/embedded/CMakeLists.txt5
-rw-r--r--examples/embedded/digiflip/CMakeLists.txt15
-rw-r--r--examples/embedded/digiflip/digiflip.cpp9
-rw-r--r--examples/embedded/flickable/CMakeLists.txt15
-rw-r--r--examples/embedded/flightinfo/CMakeLists.txt18
-rw-r--r--examples/embedded/flightinfo/flightinfo.cpp14
-rw-r--r--examples/embedded/lightmaps/CMakeLists.txt17
-rw-r--r--examples/embedded/lightmaps/lightmaps.cpp4
-rw-r--r--examples/embedded/raycasting/CMakeLists.txt15
-rw-r--r--examples/embedded/styleexample/CMakeLists.txt16
-rw-r--r--examples/gui/CMakeLists.txt7
-rw-r--r--examples/gui/analogclock/CMakeLists.txt37
-rw-r--r--examples/gui/analogclock/analogclock.pro10
-rw-r--r--examples/gui/analogclock/main.cpp123
-rw-r--r--examples/gui/doc/images/analogclock-window-example.pngbin14556 -> 0 bytes
-rw-r--r--examples/gui/doc/images/analogclockwindow-viewport.pngbin29668 -> 0 bytes
-rw-r--r--examples/gui/doc/images/rhiwindow_example.jpgbin0 -> 47775 bytes
-rw-r--r--examples/gui/doc/src/analogclockwindow.qdoc114
-rw-r--r--examples/gui/doc/src/rhiwindow.qdoc439
-rw-r--r--examples/gui/gui.pro4
-rw-r--r--examples/gui/rasterwindow/CMakeLists.txt13
-rw-r--r--examples/gui/rhiwindow/CMakeLists.txt59
-rw-r--r--examples/gui/rhiwindow/main.cpp100
-rw-r--r--examples/gui/rhiwindow/rhiwindow.cpp435
-rw-r--r--examples/gui/rhiwindow/rhiwindow.h78
-rw-r--r--examples/gui/rhiwindow/rhiwindow.pri4
-rw-r--r--examples/gui/rhiwindow/rhiwindow.pro9
-rw-r--r--examples/gui/rhiwindow/rhiwindow.qrc8
-rw-r--r--examples/gui/rhiwindow/shaders/color.frag15
-rw-r--r--examples/gui/rhiwindow/shaders/color.vert17
-rw-r--r--examples/gui/rhiwindow/shaders/prebuilt/color.frag.qsbbin0 -> 1035 bytes
-rw-r--r--examples/gui/rhiwindow/shaders/prebuilt/color.vert.qsbbin0 -> 1131 bytes
-rw-r--r--examples/gui/rhiwindow/shaders/prebuilt/quad.frag.qsbbin0 -> 1023 bytes
-rw-r--r--examples/gui/rhiwindow/shaders/prebuilt/quad.vert.qsbbin0 -> 982 bytes
-rw-r--r--examples/gui/rhiwindow/shaders/quad.frag11
-rw-r--r--examples/gui/rhiwindow/shaders/quad.vert10
-rw-r--r--examples/network/CMakeLists.txt19
-rw-r--r--examples/network/blockingfortuneclient/CMakeLists.txt17
-rw-r--r--examples/network/blockingfortuneclient/blockingclient.cpp9
-rw-r--r--examples/network/blockingfortuneclient/fortunethread.cpp2
-rw-r--r--examples/network/broadcastreceiver/CMakeLists.txt17
-rw-r--r--examples/network/broadcastreceiver/receiver.cpp3
-rw-r--r--examples/network/broadcastsender/CMakeLists.txt17
-rw-r--r--examples/network/broadcastsender/sender.cpp2
-rw-r--r--examples/network/dnslookup/CMakeLists.txt13
-rw-r--r--examples/network/dnslookup/dnslookup.cpp163
-rw-r--r--examples/network/doc/images/blockingfortuneclient-example.pngbin9199 -> 7013 bytes
-rw-r--r--examples/network/doc/images/fortuneclient-example.pngbin8282 -> 7814 bytes
-rw-r--r--examples/network/doc/images/fortuneserver-example.pngbin7883 -> 6167 bytes
-rw-r--r--examples/network/doc/images/googlesuggest-example.pngbin21272 -> 0 bytes
-rw-r--r--examples/network/doc/images/http-example.pngbin8099 -> 0 bytes
-rw-r--r--examples/network/doc/images/http-example.webpbin0 -> 8250 bytes
-rw-r--r--examples/network/doc/images/loopback-example.pngbin6195 -> 0 bytes
-rw-r--r--examples/network/doc/images/multicastreceiver-example.pngbin13042 -> 0 bytes
-rw-r--r--examples/network/doc/images/multicastreceiver-example.webpbin0 -> 3280 bytes
-rw-r--r--examples/network/doc/images/multicastsender-example.pngbin21092 -> 0 bytes
-rw-r--r--examples/network/doc/images/multicastsender-example.webpbin0 -> 3502 bytes
-rw-r--r--examples/network/doc/images/threadedfortuneserver-example.pngbin16232 -> 5558 bytes
-rw-r--r--examples/network/doc/src/blockingfortuneclient.qdoc8
-rw-r--r--examples/network/doc/src/fortuneclient.qdoc8
-rw-r--r--examples/network/doc/src/fortuneserver.qdoc10
-rw-r--r--examples/network/doc/src/googlesuggest.qdoc153
-rw-r--r--examples/network/doc/src/http.qdoc6
-rw-r--r--examples/network/doc/src/loopback.qdoc14
-rw-r--r--examples/network/doc/src/multicastreceiver.qdoc8
-rw-r--r--examples/network/doc/src/multicastsender.qdoc6
-rw-r--r--examples/network/doc/src/network-download.qdoc17
-rw-r--r--examples/network/doc/src/network-downloadmanager.qdoc17
-rw-r--r--examples/network/doc/src/threadedfortuneserver.qdoc7
-rw-r--r--examples/network/download/CMakeLists.txt27
-rw-r--r--examples/network/download/download.pro8
-rw-r--r--examples/network/download/main.cpp166
-rw-r--r--examples/network/downloadmanager/CMakeLists.txt29
-rw-r--r--examples/network/downloadmanager/downloadmanager.cpp165
-rw-r--r--examples/network/downloadmanager/downloadmanager.h46
-rw-r--r--examples/network/downloadmanager/downloadmanager.pro17
-rw-r--r--examples/network/downloadmanager/main.cpp35
-rw-r--r--examples/network/downloadmanager/textprogressbar.cpp60
-rw-r--r--examples/network/downloadmanager/textprogressbar.h24
-rw-r--r--examples/network/fortuneclient/CMakeLists.txt17
-rw-r--r--examples/network/fortuneclient/client.cpp17
-rw-r--r--examples/network/fortuneserver/CMakeLists.txt17
-rw-r--r--examples/network/fortuneserver/server.cpp12
-rw-r--r--examples/network/googlesuggest/CMakeLists.txt36
-rw-r--r--examples/network/googlesuggest/googlesuggest.cpp184
-rw-r--r--examples/network/googlesuggest/googlesuggest.h37
-rw-r--r--examples/network/googlesuggest/googlesuggest.pro8
-rw-r--r--examples/network/googlesuggest/main.cpp14
-rw-r--r--examples/network/googlesuggest/searchbox.cpp35
-rw-r--r--examples/network/googlesuggest/searchbox.h28
-rw-r--r--examples/network/http/CMakeLists.txt18
-rw-r--r--examples/network/http/httpwindow.cpp62
-rw-r--r--examples/network/http/httpwindow.h6
-rw-r--r--examples/network/http/main.cpp4
-rw-r--r--examples/network/loopback/CMakeLists.txt35
-rw-r--r--examples/network/loopback/dialog.cpp155
-rw-r--r--examples/network/loopback/dialog.h51
-rw-r--r--examples/network/loopback/loopback.pro9
-rw-r--r--examples/network/loopback/main.cpp14
-rw-r--r--examples/network/multicastreceiver/CMakeLists.txt17
-rw-r--r--examples/network/multicastreceiver/receiver.cpp4
-rw-r--r--examples/network/multicastsender/CMakeLists.txt17
-rw-r--r--examples/network/multistreamclient/CMakeLists.txt17
-rw-r--r--examples/network/multistreamserver/CMakeLists.txt17
-rw-r--r--examples/network/network-chat/CMakeLists.txt18
-rw-r--r--examples/network/network-chat/chatdialog.cpp2
-rw-r--r--examples/network/network-chat/client.cpp2
-rw-r--r--examples/network/network-chat/peermanager.cpp2
-rw-r--r--examples/network/network.pro5
-rw-r--r--examples/network/securesocketclient/CMakeLists.txt18
-rw-r--r--examples/network/secureudpclient/CMakeLists.txt18
-rw-r--r--examples/network/secureudpclient/addressdialog.h6
-rw-r--r--examples/network/secureudpclient/association.cpp4
-rw-r--r--examples/network/secureudpclient/association.h4
-rw-r--r--examples/network/secureudpclient/main.cpp2
-rw-r--r--examples/network/secureudpclient/mainwindow.cpp2
-rw-r--r--examples/network/secureudpclient/mainwindow.h8
-rw-r--r--examples/network/secureudpserver/CMakeLists.txt18
-rw-r--r--examples/network/secureudpserver/main.cpp2
-rw-r--r--examples/network/secureudpserver/mainwindow.h4
-rw-r--r--examples/network/secureudpserver/nicselector.h4
-rw-r--r--examples/network/secureudpserver/server.cpp6
-rw-r--r--examples/network/secureudpserver/server.h4
-rw-r--r--examples/network/threadedfortuneserver/CMakeLists.txt17
-rw-r--r--examples/network/threadedfortuneserver/dialog.cpp10
-rw-r--r--examples/network/threadedfortuneserver/fortunethread.cpp4
-rw-r--r--examples/network/threadedfortuneserver/fortunethread.h4
-rw-r--r--examples/network/torrent/CMakeLists.txt18
-rw-r--r--examples/network/torrent/filemanager.cpp22
-rw-r--r--examples/network/torrent/filemanager.h32
-rw-r--r--examples/network/torrent/mainwindow.cpp4
-rw-r--r--examples/network/torrent/metainfo.h2
-rw-r--r--examples/network/torrent/peerwireclient.cpp101
-rw-r--r--examples/network/torrent/peerwireclient.h8
-rw-r--r--examples/network/torrent/ratecontroller.cpp6
-rw-r--r--examples/network/torrent/torrentclient.cpp90
-rw-r--r--examples/network/torrent/torrentclient.h3
-rw-r--r--examples/network/torrent/torrentserver.cpp2
-rw-r--r--examples/network/torrent/trackerclient.cpp14
-rw-r--r--examples/network/torrent/trackerclient.h1
-rw-r--r--examples/opengl/2dpainting/CMakeLists.txt19
-rw-r--r--examples/opengl/CMakeLists.txt14
-rw-r--r--examples/opengl/computegles31/CMakeLists.txt46
-rw-r--r--examples/opengl/computegles31/Qt-logo-medium.pngbin24817 -> 0 bytes
-rw-r--r--examples/opengl/computegles31/computegles31.pro11
-rw-r--r--examples/opengl/computegles31/computegles31.qrc5
-rw-r--r--examples/opengl/computegles31/glwindow.cpp372
-rw-r--r--examples/opengl/computegles31/glwindow.h63
-rw-r--r--examples/opengl/computegles31/main.cpp101
-rw-r--r--examples/opengl/contextinfo/CMakeLists.txt17
-rw-r--r--examples/opengl/contextinfo/widget.cpp4
-rw-r--r--examples/opengl/cube/CMakeLists.txt19
-rw-r--r--examples/opengl/cube/cube.pngbin30341 -> 88913 bytes
-rw-r--r--examples/opengl/cube/mainwidget.cpp17
-rw-r--r--examples/opengl/doc/images/hellogles3-example.png (renamed from examples/opengl/hellogles3/doc/images/hellogles3-example.png)bin61792 -> 61792 bytes
-rw-r--r--examples/opengl/doc/images/stereoexample-leftbuffer.pngbin0 -> 9987 bytes
-rw-r--r--examples/opengl/doc/images/stereoexample-rightbuffer.pngbin0 -> 10002 bytes
-rw-r--r--examples/opengl/doc/src/cube.qdoc10
-rw-r--r--examples/opengl/doc/src/hellogles3.qdoc147
-rw-r--r--examples/opengl/doc/src/openglwindow.qdoc2
-rw-r--r--examples/opengl/doc/src/stereoqopenglwidget.qdoc41
-rw-r--r--examples/opengl/hellogl2/CMakeLists.txt19
-rw-r--r--examples/opengl/hellogles3/CMakeLists.txt15
-rw-r--r--examples/opengl/hellogles3/doc/src/hellogles3.qdoc22
-rw-r--r--examples/opengl/hellowindow/CMakeLists.txt36
-rw-r--r--examples/opengl/hellowindow/hellowindow.cpp305
-rw-r--r--examples/opengl/hellowindow/hellowindow.h72
-rw-r--r--examples/opengl/hellowindow/hellowindow.pro9
-rw-r--r--examples/opengl/hellowindow/main.cpp125
-rw-r--r--examples/opengl/opengl.pro11
-rw-r--r--examples/opengl/openglwindow/CMakeLists.txt15
-rw-r--r--examples/opengl/openglwindow/openglwindow.h4
-rw-r--r--examples/opengl/paintedwindow/CMakeLists.txt34
-rw-r--r--examples/opengl/paintedwindow/main.cpp18
-rw-r--r--examples/opengl/paintedwindow/paintedwindow.cpp185
-rw-r--r--examples/opengl/paintedwindow/paintedwindow.h57
-rw-r--r--examples/opengl/paintedwindow/paintedwindow.pro8
-rw-r--r--examples/opengl/qopenglwidget/CMakeLists.txt50
-rw-r--r--examples/opengl/qopenglwidget/bubble.cpp99
-rw-r--r--examples/opengl/qopenglwidget/bubble.h39
-rw-r--r--examples/opengl/qopenglwidget/glwidget.cpp540
-rw-r--r--examples/opengl/qopenglwidget/glwidget.h85
-rw-r--r--examples/opengl/qopenglwidget/main.cpp43
-rw-r--r--examples/opengl/qopenglwidget/mainwindow.cpp188
-rw-r--r--examples/opengl/qopenglwidget/mainwindow.h39
-rw-r--r--examples/opengl/qopenglwidget/qopenglwidget.pro15
-rw-r--r--examples/opengl/qopenglwidget/qt.pngbin2991 -> 0 bytes
-rw-r--r--examples/opengl/qopenglwidget/texture.qrc5
-rw-r--r--examples/opengl/qopenglwindow/CMakeLists.txt46
-rw-r--r--examples/opengl/qopenglwindow/background.frag30
-rw-r--r--examples/opengl/qopenglwindow/background_renderer.cpp167
-rw-r--r--examples/opengl/qopenglwindow/background_renderer.h46
-rw-r--r--examples/opengl/qopenglwindow/main.cpp154
-rw-r--r--examples/opengl/qopenglwindow/qopenglwindow.pro16
-rw-r--r--examples/opengl/qopenglwindow/shaders.qrc5
-rw-r--r--examples/opengl/stereoqopenglwidget/CMakeLists.txt (renamed from examples/opengl/threadedqopenglwidget/CMakeLists.txt)27
-rw-r--r--examples/opengl/stereoqopenglwidget/glwidget.cpp277
-rw-r--r--examples/opengl/stereoqopenglwidget/glwidget.h53
-rw-r--r--examples/opengl/stereoqopenglwidget/main.cpp31
-rw-r--r--examples/opengl/stereoqopenglwidget/mainwindow.cpp25
-rw-r--r--examples/opengl/stereoqopenglwidget/mainwindow.h (renamed from examples/opengl/threadedqopenglwidget/mainwindow.h)8
-rw-r--r--examples/opengl/stereoqopenglwidget/stereoqopenglwidget.pro11
-rw-r--r--examples/opengl/textures/CMakeLists.txt19
-rw-r--r--examples/opengl/textures/glwidget.cpp8
-rw-r--r--examples/opengl/threadedqopenglwidget/glwidget.cpp71
-rw-r--r--examples/opengl/threadedqopenglwidget/glwidget.h40
-rw-r--r--examples/opengl/threadedqopenglwidget/main.cpp88
-rw-r--r--examples/opengl/threadedqopenglwidget/mainwindow.cpp16
-rw-r--r--examples/opengl/threadedqopenglwidget/renderer.cpp267
-rw-r--r--examples/opengl/threadedqopenglwidget/renderer.h61
-rw-r--r--examples/opengl/threadedqopenglwidget/threadedqopenglwidget.pro13
-rw-r--r--examples/qmake/precompile/main.cpp3
-rw-r--r--examples/qpa/CMakeLists.txt5
-rw-r--r--examples/qpa/qrasterwindow/CMakeLists.txt13
-rw-r--r--examples/qpa/qrasterwindow/main.cpp2
-rw-r--r--examples/qpa/windows/CMakeLists.txt17
-rw-r--r--examples/qpa/windows/window.h5
-rw-r--r--examples/qtconcurrent/CMakeLists.txt13
-rw-r--r--examples/qtconcurrent/imagescaling/CMakeLists.txt20
-rw-r--r--examples/qtconcurrent/imagescaling/doc/images/imagescaling.webpbin0 -> 46826 bytes
-rw-r--r--examples/qtconcurrent/imagescaling/doc/images/imagescaling_example.pngbin21049 -> 0 bytes
-rw-r--r--examples/qtconcurrent/imagescaling/doc/src/qtconcurrent-imagescaling.qdoc115
-rw-r--r--examples/qtconcurrent/imagescaling/imagescaling.cpp101
-rw-r--r--examples/qtconcurrent/imagescaling/imagescaling.h13
-rw-r--r--examples/qtconcurrent/imagescaling/main.cpp7
-rw-r--r--examples/qtconcurrent/map/CMakeLists.txt28
-rw-r--r--examples/qtconcurrent/map/doc/src/qtconcurrent-map.qdoc14
-rw-r--r--examples/qtconcurrent/map/main.cpp35
-rw-r--r--examples/qtconcurrent/map/map.pro9
-rw-r--r--examples/qtconcurrent/primecounter/CMakeLists.txt40
-rw-r--r--examples/qtconcurrent/primecounter/doc/images/primecounter.pngbin0 -> 9732 bytes
-rw-r--r--examples/qtconcurrent/primecounter/doc/src/qtconcurrent-primecounter.qdoc88
-rw-r--r--examples/qtconcurrent/primecounter/main.cpp18
-rw-r--r--examples/qtconcurrent/primecounter/primecounter.cpp139
-rw-r--r--examples/qtconcurrent/primecounter/primecounter.h49
-rw-r--r--examples/qtconcurrent/primecounter/primecounter.pro9
-rw-r--r--examples/qtconcurrent/primecounter/primecounter.ui177
-rw-r--r--examples/qtconcurrent/progressdialog/CMakeLists.txt34
-rw-r--r--examples/qtconcurrent/progressdialog/doc/images/qtconcurrent-progressdialog.pngbin4608 -> 0 bytes
-rw-r--r--examples/qtconcurrent/progressdialog/doc/src/qtconcurrent-progressdialog.qdoc14
-rw-r--r--examples/qtconcurrent/progressdialog/main.cpp53
-rw-r--r--examples/qtconcurrent/progressdialog/progressdialog.pro7
-rw-r--r--examples/qtconcurrent/qtconcurrent.pro13
-rw-r--r--examples/qtconcurrent/runfunction/CMakeLists.txt29
-rw-r--r--examples/qtconcurrent/runfunction/doc/src/qtconcurrent-runfunction.qdoc15
-rw-r--r--examples/qtconcurrent/runfunction/main.cpp24
-rw-r--r--examples/qtconcurrent/runfunction/runfunction.pro7
-rw-r--r--examples/qtconcurrent/wordcount/CMakeLists.txt17
-rw-r--r--examples/qtconcurrent/wordcount/doc/src/qtconcurrent-wordcount.qdoc43
-rw-r--r--examples/qtconcurrent/wordcount/main.cpp146
-rw-r--r--examples/qtestlib/CMakeLists.txt5
-rw-r--r--examples/qtestlib/tutorial1/CMakeLists.txt17
-rw-r--r--examples/qtestlib/tutorial2/CMakeLists.txt17
-rw-r--r--examples/qtestlib/tutorial2/testqstring.cpp4
-rw-r--r--examples/qtestlib/tutorial3/CMakeLists.txt17
-rw-r--r--examples/qtestlib/tutorial4/CMakeLists.txt17
-rw-r--r--examples/qtestlib/tutorial4/testgui.cpp2
-rw-r--r--examples/qtestlib/tutorial5/CMakeLists.txt17
-rw-r--r--examples/qtestlib/tutorial5/benchmarking.cpp9
-rw-r--r--examples/sql/CMakeLists.txt7
-rw-r--r--examples/sql/books/CMakeLists.txt18
-rw-r--r--examples/sql/books/bookwindow.cpp2
-rw-r--r--examples/sql/cachedtable/CMakeLists.txt17
-rw-r--r--examples/sql/doc/src/cachedtable.qdoc3
-rw-r--r--examples/sql/drilldown/CMakeLists.txt17
-rw-r--r--examples/sql/masterdetail/CMakeLists.txt19
-rw-r--r--examples/sql/masterdetail/mainwindow.cpp2
-rw-r--r--examples/sql/querymodel/CMakeLists.txt17
-rw-r--r--examples/sql/relationaltablemodel/CMakeLists.txt17
-rw-r--r--examples/sql/sqlbrowser/CMakeLists.txt18
-rw-r--r--examples/sql/sqlwidgetmapper/CMakeLists.txt17
-rw-r--r--examples/sql/tablemodel/CMakeLists.txt17
-rw-r--r--examples/vulkan/CMakeLists.txt9
-rw-r--r--examples/vulkan/doc/images/hellovulkantexture.pngbin10259 -> 0 bytes
-rw-r--r--examples/vulkan/doc/images/hellovulkanwindow.pngbin2736 -> 0 bytes
-rw-r--r--examples/vulkan/doc/src/hellovulkantexture.qdoc18
-rw-r--r--examples/vulkan/doc/src/hellovulkantriangle.qdoc48
-rw-r--r--examples/vulkan/doc/src/hellovulkanwindow.qdoc78
-rw-r--r--examples/vulkan/hellovulkancubes/CMakeLists.txt17
-rw-r--r--examples/vulkan/hellovulkantexture/CMakeLists.txt47
-rw-r--r--examples/vulkan/hellovulkantexture/hellovulkantexture.cpp792
-rw-r--r--examples/vulkan/hellovulkantexture/hellovulkantexture.h61
-rw-r--r--examples/vulkan/hellovulkantexture/hellovulkantexture.pro7
-rw-r--r--examples/vulkan/hellovulkantexture/hellovulkantexture.qrc7
-rw-r--r--examples/vulkan/hellovulkantexture/main.cpp32
-rw-r--r--examples/vulkan/hellovulkantexture/qt256.pngbin6208 -> 0 bytes
-rw-r--r--examples/vulkan/hellovulkantexture/texture.frag12
-rw-r--r--examples/vulkan/hellovulkantexture/texture.vert18
-rw-r--r--examples/vulkan/hellovulkantexture/texture_frag.spvbin556 -> 0 bytes
-rw-r--r--examples/vulkan/hellovulkantexture/texture_vert.spvbin968 -> 0 bytes
-rw-r--r--examples/vulkan/hellovulkantriangle/CMakeLists.txt13
-rw-r--r--examples/vulkan/hellovulkantriangle/main.cpp7
-rw-r--r--examples/vulkan/hellovulkanwidget/CMakeLists.txt15
-rw-r--r--examples/vulkan/hellovulkanwidget/hellovulkanwidget.h5
-rw-r--r--examples/vulkan/hellovulkanwindow/CMakeLists.txt33
-rw-r--r--examples/vulkan/hellovulkanwindow/hellovulkanwindow.cpp81
-rw-r--r--examples/vulkan/hellovulkanwindow/hellovulkanwindow.h30
-rw-r--r--examples/vulkan/hellovulkanwindow/hellovulkanwindow.pro6
-rw-r--r--examples/vulkan/hellovulkanwindow/main.cpp33
-rw-r--r--examples/vulkan/shared/trianglerenderer.h5
-rw-r--r--examples/vulkan/vulkan.pro4
-rw-r--r--examples/widgets/CMakeLists.txt7
-rw-r--r--examples/widgets/animation/easing/CMakeLists.txt16
-rw-r--r--examples/widgets/animation/easing/animation.h4
-rw-r--r--examples/widgets/animation/easing/window.cpp18
-rw-r--r--examples/widgets/animation/easing/window.h5
-rw-r--r--examples/widgets/desktop/screenshot/CMakeLists.txt15
-rw-r--r--examples/widgets/desktop/screenshot/screenshot.cpp2
-rw-r--r--examples/widgets/desktop/systray/CMakeLists.txt15
-rw-r--r--examples/widgets/dialogs/CMakeLists.txt12
-rw-r--r--examples/widgets/dialogs/classwizard/CMakeLists.txt52
-rw-r--r--examples/widgets/dialogs/classwizard/classwizard.cpp394
-rw-r--r--examples/widgets/dialogs/classwizard/classwizard.h119
-rw-r--r--examples/widgets/dialogs/classwizard/classwizard.pro10
-rw-r--r--examples/widgets/dialogs/classwizard/classwizard.qrc11
-rw-r--r--examples/widgets/dialogs/classwizard/images/background.pngbin22578 -> 0 bytes
-rw-r--r--examples/widgets/dialogs/classwizard/images/banner.pngbin3947 -> 0 bytes
-rw-r--r--examples/widgets/dialogs/classwizard/images/logo1.pngbin1619 -> 0 bytes
-rw-r--r--examples/widgets/dialogs/classwizard/images/logo2.pngbin1619 -> 0 bytes
-rw-r--r--examples/widgets/dialogs/classwizard/images/logo3.pngbin1619 -> 0 bytes
-rw-r--r--examples/widgets/dialogs/classwizard/images/watermark1.pngbin14516 -> 0 bytes
-rw-r--r--examples/widgets/dialogs/classwizard/images/watermark2.pngbin14912 -> 0 bytes
-rw-r--r--examples/widgets/dialogs/classwizard/main.cpp28
-rw-r--r--examples/widgets/dialogs/dialogs.pro5
-rw-r--r--examples/widgets/dialogs/extension/CMakeLists.txt34
-rw-r--r--examples/widgets/dialogs/extension/extension.pro9
-rw-r--r--examples/widgets/dialogs/extension/finddialog.cpp77
-rw-r--r--examples/widgets/dialogs/extension/finddialog.h41
-rw-r--r--examples/widgets/dialogs/extension/main.cpp16
-rw-r--r--examples/widgets/dialogs/findfiles/CMakeLists.txt34
-rw-r--r--examples/widgets/dialogs/findfiles/findfiles.pro10
-rw-r--r--examples/widgets/dialogs/findfiles/main.cpp14
-rw-r--r--examples/widgets/dialogs/findfiles/window.cpp264
-rw-r--r--examples/widgets/dialogs/findfiles/window.h50
-rw-r--r--examples/widgets/dialogs/licensewizard/CMakeLists.txt17
-rw-r--r--examples/widgets/dialogs/licensewizard/licensewizard.cpp5
-rw-r--r--examples/widgets/dialogs/standarddialogs/CMakeLists.txt15
-rw-r--r--examples/widgets/dialogs/standarddialogs/dialog.cpp74
-rw-r--r--examples/widgets/dialogs/standarddialogs/dialog.h1
-rw-r--r--examples/widgets/dialogs/standarddialogs/main.mm47
-rw-r--r--examples/widgets/dialogs/tabdialog/CMakeLists.txt15
-rw-r--r--examples/widgets/dialogs/trivialwizard/CMakeLists.txt15
-rw-r--r--examples/widgets/dialogs/trivialwizard/trivialwizard.cpp2
-rw-r--r--examples/widgets/doc/dropsite.qdoc4
-rw-r--r--examples/widgets/doc/images/graphicsanchorlayout-example.pngbin24372 -> 0 bytes
-rw-r--r--examples/widgets/doc/images/mousebutton-buttontester.pngbin17428 -> 0 bytes
-rw-r--r--examples/widgets/doc/images/stylepluginexample.pngbin5259 -> 15331 bytes
-rw-r--r--examples/widgets/doc/images/undodemo.pngbin84941 -> 0 bytes
-rw-r--r--examples/widgets/doc/images/weatheranchorlayout-example.pngbin88805 -> 0 bytes
-rw-r--r--examples/widgets/doc/mousebuttons.qdoc70
-rw-r--r--examples/widgets/doc/src/addressbook-tutorial.qdoc948
-rw-r--r--examples/widgets/doc/src/addressbook.qdoc18
-rw-r--r--examples/widgets/doc/src/analogclock.qdoc5
-rw-r--r--examples/widgets/doc/src/application.qdoc5
-rw-r--r--examples/widgets/doc/src/classwizard.qdoc167
-rw-r--r--examples/widgets/doc/src/codeeditor.qdoc173
-rw-r--r--examples/widgets/doc/src/diagramscene.qdoc2
-rw-r--r--examples/widgets/doc/src/elasticnodes.qdoc2
-rw-r--r--examples/widgets/doc/src/elidedlabel.qdoc131
-rw-r--r--examples/widgets/doc/src/extension.qdoc121
-rw-r--r--examples/widgets/doc/src/findfiles.qdoc269
-rw-r--r--examples/widgets/doc/src/fridgemagnets.qdoc2
-rw-r--r--examples/widgets/doc/src/graphicsview-anchorlayout.qdoc57
-rw-r--r--examples/widgets/doc/src/graphicsview-simpleanchorlayout.qdoc2
-rw-r--r--examples/widgets/doc/src/graphicsview-weatheranchorlayout.qdoc14
-rw-r--r--examples/widgets/doc/src/i18n.qdoc16
-rw-r--r--examples/widgets/doc/src/imageviewer.qdoc4
-rw-r--r--examples/widgets/doc/src/licensewizard.qdoc4
-rw-r--r--examples/widgets/doc/src/screenshot.qdoc2
-rw-r--r--examples/widgets/doc/src/sdi.qdoc13
-rw-r--r--examples/widgets/doc/src/shapedclock.qdoc75
-rw-r--r--examples/widgets/doc/src/shortcuteditor.qdoc230
-rw-r--r--examples/widgets/doc/src/styleplugin.qdoc51
-rw-r--r--examples/widgets/doc/src/styles.qdoc2
-rw-r--r--examples/widgets/doc/src/syntaxhighlighter.qdoc6
-rw-r--r--examples/widgets/doc/src/tooltips.qdoc16
-rw-r--r--examples/widgets/doc/src/trivialwizard.qdoc2
-rw-r--r--examples/widgets/doc/src/undo.qdoc20
-rw-r--r--examples/widgets/doc/src/undoframework.qdoc41
-rw-r--r--examples/widgets/doc/src/wiggly.qdoc144
-rw-r--r--examples/widgets/draganddrop/CMakeLists.txt3
-rw-r--r--examples/widgets/draganddrop/draggableicons/CMakeLists.txt15
-rw-r--r--examples/widgets/draganddrop/draggableicons/dragwidget.cpp2
-rw-r--r--examples/widgets/draganddrop/draggabletext/CMakeLists.txt15
-rw-r--r--examples/widgets/draganddrop/dropsite/CMakeLists.txt15
-rw-r--r--examples/widgets/draganddrop/dropsite/droparea.cpp10
-rw-r--r--examples/widgets/draganddrop/dropsite/droparea.h3
-rw-r--r--examples/widgets/draganddrop/dropsite/dropsitewindow.cpp40
-rw-r--r--examples/widgets/draganddrop/fridgemagnets/CMakeLists.txt15
-rw-r--r--examples/widgets/draganddrop/fridgemagnets/dragwidget.cpp2
-rw-r--r--examples/widgets/draganddrop/puzzle/CMakeLists.txt15
-rw-r--r--examples/widgets/effects/blurpicker/CMakeLists.txt15
-rw-r--r--examples/widgets/effects/fademessage/CMakeLists.txt15
-rw-r--r--examples/widgets/gallery/CMakeLists.txt15
-rw-r--r--examples/widgets/gestures/CMakeLists.txt5
-rw-r--r--examples/widgets/gestures/imagegestures/CMakeLists.txt15
-rw-r--r--examples/widgets/graphicsview/CMakeLists.txt5
-rw-r--r--examples/widgets/graphicsview/anchorlayout/CMakeLists.txt33
-rw-r--r--examples/widgets/graphicsview/anchorlayout/anchorlayout.pro9
-rw-r--r--examples/widgets/graphicsview/anchorlayout/main.cpp89
-rw-r--r--examples/widgets/graphicsview/basicgraphicslayouts/CMakeLists.txt15
-rw-r--r--examples/widgets/graphicsview/chip/CMakeLists.txt21
-rw-r--r--examples/widgets/graphicsview/chip/mainwindow.cpp3
-rw-r--r--examples/widgets/graphicsview/collidingmice/CMakeLists.txt15
-rw-r--r--examples/widgets/graphicsview/diagramscene/CMakeLists.txt15
-rw-r--r--examples/widgets/graphicsview/diagramscene/diagramitem.cpp4
-rw-r--r--examples/widgets/graphicsview/diagramscene/mainwindow.cpp15
-rw-r--r--examples/widgets/graphicsview/diagramscene/mainwindow.h4
-rw-r--r--examples/widgets/graphicsview/dragdroprobot/CMakeLists.txt15
-rw-r--r--examples/widgets/graphicsview/elasticnodes/CMakeLists.txt15
-rw-r--r--examples/widgets/graphicsview/elasticnodes/graphwidget.cpp4
-rw-r--r--examples/widgets/graphicsview/elasticnodes/node.cpp4
-rw-r--r--examples/widgets/graphicsview/embeddeddialogs/CMakeLists.txt16
-rw-r--r--examples/widgets/graphicsview/flowlayout/CMakeLists.txt15
-rw-r--r--examples/widgets/graphicsview/flowlayout/flowlayout.cpp6
-rw-r--r--examples/widgets/graphicsview/flowlayout/flowlayout.h5
-rw-r--r--examples/widgets/graphicsview/flowlayout/window.h5
-rw-r--r--examples/widgets/graphicsview/graphicsview.pro4
-rw-r--r--examples/widgets/graphicsview/simpleanchorlayout/CMakeLists.txt15
-rw-r--r--examples/widgets/graphicsview/weatheranchorlayout/CMakeLists.txt50
-rw-r--r--examples/widgets/graphicsview/weatheranchorlayout/images/5days.jpgbin5748 -> 0 bytes
-rw-r--r--examples/widgets/graphicsview/weatheranchorlayout/images/details.jpgbin5323 -> 0 bytes
-rw-r--r--examples/widgets/graphicsview/weatheranchorlayout/images/place.jpgbin62438 -> 0 bytes
-rw-r--r--examples/widgets/graphicsview/weatheranchorlayout/images/tabbar.jpgbin849 -> 0 bytes
-rw-r--r--examples/widgets/graphicsview/weatheranchorlayout/images/title.jpgbin3472 -> 0 bytes
-rw-r--r--examples/widgets/graphicsview/weatheranchorlayout/images/weather-few-clouds.pngbin18976 -> 0 bytes
-rw-r--r--examples/widgets/graphicsview/weatheranchorlayout/main.cpp239
-rw-r--r--examples/widgets/graphicsview/weatheranchorlayout/weatheranchorlayout.pro8
-rw-r--r--examples/widgets/graphicsview/weatheranchorlayout/weatheranchorlayout.qrc10
-rw-r--r--examples/widgets/itemviews/CMakeLists.txt5
-rw-r--r--examples/widgets/itemviews/addressbook/CMakeLists.txt15
-rw-r--r--examples/widgets/itemviews/addressbook/addresswidget.cpp14
-rw-r--r--examples/widgets/itemviews/addressbook/addresswidget.h8
-rw-r--r--examples/widgets/itemviews/addressbook/mainwindow.cpp10
-rw-r--r--examples/widgets/itemviews/basicsortfiltermodel/CMakeLists.txt15
-rw-r--r--examples/widgets/itemviews/chart/CMakeLists.txt17
-rw-r--r--examples/widgets/itemviews/chart/pieview.cpp4
-rw-r--r--examples/widgets/itemviews/coloreditorfactory/CMakeLists.txt15
-rw-r--r--examples/widgets/itemviews/combowidgetmapper/CMakeLists.txt15
-rw-r--r--examples/widgets/itemviews/customsortfiltermodel/CMakeLists.txt15
-rw-r--r--examples/widgets/itemviews/dirview/CMakeLists.txt15
-rw-r--r--examples/widgets/itemviews/editabletreemodel/CMakeLists.txt16
-rw-r--r--examples/widgets/itemviews/editabletreemodel/treeitem.cpp4
-rw-r--r--examples/widgets/itemviews/fetchmore/CMakeLists.txt15
-rw-r--r--examples/widgets/itemviews/flattreeview/CMakeLists.txt15
-rw-r--r--examples/widgets/itemviews/frozencolumn/CMakeLists.txt15
-rw-r--r--examples/widgets/itemviews/interview/CMakeLists.txt15
-rw-r--r--examples/widgets/itemviews/pixelator/CMakeLists.txt25
-rw-r--r--examples/widgets/itemviews/puzzle/CMakeLists.txt15
-rw-r--r--examples/widgets/itemviews/simpledommodel/CMakeLists.txt17
-rw-r--r--examples/widgets/itemviews/simpletreemodel/CMakeLists.txt15
-rw-r--r--examples/widgets/itemviews/simplewidgetmapper/CMakeLists.txt15
-rw-r--r--examples/widgets/itemviews/spinboxdelegate/CMakeLists.txt15
-rw-r--r--examples/widgets/itemviews/spreadsheet/CMakeLists.txt25
-rw-r--r--examples/widgets/itemviews/spreadsheet/printview.h2
-rw-r--r--examples/widgets/itemviews/spreadsheet/spreadsheet.cpp2
-rw-r--r--examples/widgets/itemviews/stardelegate/CMakeLists.txt15
-rw-r--r--examples/widgets/itemviews/storageview/CMakeLists.txt15
-rw-r--r--examples/widgets/layouts/CMakeLists.txt3
-rw-r--r--examples/widgets/layouts/basiclayouts/CMakeLists.txt15
-rw-r--r--examples/widgets/layouts/basiclayouts/dialog.cpp19
-rw-r--r--examples/widgets/layouts/basiclayouts/main.cpp4
-rw-r--r--examples/widgets/layouts/borderlayout/CMakeLists.txt15
-rw-r--r--examples/widgets/layouts/dynamiclayouts/CMakeLists.txt15
-rw-r--r--examples/widgets/layouts/dynamiclayouts/dialog.cpp2
-rw-r--r--examples/widgets/layouts/dynamiclayouts/main.cpp4
-rw-r--r--examples/widgets/layouts/flowlayout/CMakeLists.txt15
-rw-r--r--examples/widgets/layouts/flowlayout/flowlayout.cpp4
-rw-r--r--examples/widgets/mainwindows/CMakeLists.txt4
-rw-r--r--examples/widgets/mainwindows/application/CMakeLists.txt15
-rw-r--r--examples/widgets/mainwindows/dockwidgets/CMakeLists.txt25
-rw-r--r--examples/widgets/mainwindows/dockwidgets/mainwindow.cpp2
-rw-r--r--examples/widgets/mainwindows/mainwindow/CMakeLists.txt15
-rw-r--r--examples/widgets/mainwindows/mainwindow/colorswatch.cpp2
-rw-r--r--examples/widgets/mainwindows/mainwindow/main.cpp4
-rw-r--r--examples/widgets/mainwindows/mainwindow/mainwindow.cpp4
-rw-r--r--examples/widgets/mainwindows/mainwindow/toolbar.cpp14
-rw-r--r--examples/widgets/mainwindows/mainwindow/toolbar.h4
-rw-r--r--examples/widgets/mainwindows/mainwindows.pro3
-rw-r--r--examples/widgets/mainwindows/mdi/CMakeLists.txt15
-rw-r--r--examples/widgets/mainwindows/menus/CMakeLists.txt15
-rw-r--r--examples/widgets/mainwindows/sdi/CMakeLists.txt51
-rw-r--r--examples/widgets/mainwindows/sdi/images/copy.pngbin1338 -> 0 bytes
-rw-r--r--examples/widgets/mainwindows/sdi/images/cut.pngbin1323 -> 0 bytes
-rw-r--r--examples/widgets/mainwindows/sdi/images/new.pngbin852 -> 0 bytes
-rw-r--r--examples/widgets/mainwindows/sdi/images/open.pngbin2073 -> 0 bytes
-rw-r--r--examples/widgets/mainwindows/sdi/images/paste.pngbin1645 -> 0 bytes
-rw-r--r--examples/widgets/mainwindows/sdi/images/save.pngbin2699 -> 0 bytes
-rw-r--r--examples/widgets/mainwindows/sdi/main.cpp37
-rw-r--r--examples/widgets/mainwindows/sdi/mainwindow.cpp445
-rw-r--r--examples/widgets/mainwindows/sdi/mainwindow.h70
-rw-r--r--examples/widgets/mainwindows/sdi/sdi.pro11
-rw-r--r--examples/widgets/mainwindows/sdi/sdi.qrc10
-rw-r--r--examples/widgets/painting/CMakeLists.txt3
-rw-r--r--examples/widgets/painting/affine/CMakeLists.txt34
-rw-r--r--examples/widgets/painting/affine/main.cpp4
-rw-r--r--examples/widgets/painting/basicdrawing/CMakeLists.txt15
-rw-r--r--examples/widgets/painting/composition/CMakeLists.txt34
-rw-r--r--examples/widgets/painting/composition/composition.cpp10
-rw-r--r--examples/widgets/painting/composition/composition.h1
-rw-r--r--examples/widgets/painting/concentriccircles/CMakeLists.txt15
-rw-r--r--examples/widgets/painting/deform/CMakeLists.txt34
-rw-r--r--examples/widgets/painting/fontsampler/CMakeLists.txt22
-rw-r--r--examples/widgets/painting/fontsampler/mainwindow.cpp4
-rw-r--r--examples/widgets/painting/gradients/CMakeLists.txt34
-rw-r--r--examples/widgets/painting/gradients/gradients.cpp2
-rw-r--r--examples/widgets/painting/gradients/main.cpp3
-rw-r--r--examples/widgets/painting/imagecomposition/CMakeLists.txt15
-rw-r--r--examples/widgets/painting/painterpaths/CMakeLists.txt17
-rw-r--r--examples/widgets/painting/painterpaths/window.cpp10
-rw-r--r--examples/widgets/painting/pathstroke/CMakeLists.txt34
-rw-r--r--examples/widgets/painting/pathstroke/main.cpp3
-rw-r--r--examples/widgets/painting/pathstroke/pathstroke.cpp2
-rw-r--r--examples/widgets/painting/shared/CMakeLists.txt11
-rw-r--r--examples/widgets/painting/shared/fbopaintdevice.cpp17
-rw-r--r--examples/widgets/painting/shared/fbopaintdevice.h2
-rw-r--r--examples/widgets/painting/shared/hoverpoints.cpp4
-rw-r--r--examples/widgets/painting/shared/use_lib.cmake3
-rw-r--r--examples/widgets/painting/transformations/CMakeLists.txt15
-rw-r--r--examples/widgets/richtext/CMakeLists.txt3
-rw-r--r--examples/widgets/richtext/calendar/CMakeLists.txt15
-rw-r--r--examples/widgets/richtext/orderform/CMakeLists.txt21
-rw-r--r--examples/widgets/richtext/syntaxhighlighter/CMakeLists.txt15
-rw-r--r--examples/widgets/richtext/syntaxhighlighter/highlighter.cpp2
-rw-r--r--examples/widgets/richtext/textedit/CMakeLists.txt25
-rw-r--r--examples/widgets/richtext/textedit/textedit.cpp2
-rw-r--r--examples/widgets/scroller/graphicsview/CMakeLists.txt15
-rw-r--r--examples/widgets/tools/CMakeLists.txt7
-rw-r--r--examples/widgets/tools/completer/CMakeLists.txt15
-rw-r--r--examples/widgets/tools/customcompleter/CMakeLists.txt15
-rw-r--r--examples/widgets/tools/echoplugin/CMakeLists.txt11
-rw-r--r--examples/widgets/tools/echoplugin/echowindow/CMakeLists.txt15
-rw-r--r--examples/widgets/tools/echoplugin/plugin/CMakeLists.txt13
-rw-r--r--examples/widgets/tools/i18n/CMakeLists.txt60
-rw-r--r--examples/widgets/tools/i18n/i18n.pro27
-rw-r--r--examples/widgets/tools/i18n/i18n.qrc18
-rw-r--r--examples/widgets/tools/i18n/languagechooser.cpp139
-rw-r--r--examples/widgets/tools/i18n/languagechooser.h49
-rw-r--r--examples/widgets/tools/i18n/main.cpp17
-rw-r--r--examples/widgets/tools/i18n/mainwindow.cpp66
-rw-r--r--examples/widgets/tools/i18n/mainwindow.h39
-rw-r--r--examples/widgets/tools/i18n/translations/i18n_ar.qmbin736 -> 0 bytes
-rw-r--r--examples/widgets/tools/i18n/translations/i18n_ar.ts57
-rw-r--r--examples/widgets/tools/i18n/translations/i18n_cs.qmbin796 -> 0 bytes
-rw-r--r--examples/widgets/tools/i18n/translations/i18n_cs.ts57
-rw-r--r--examples/widgets/tools/i18n/translations/i18n_de.qmbin848 -> 0 bytes
-rw-r--r--examples/widgets/tools/i18n/translations/i18n_de.ts57
-rw-r--r--examples/widgets/tools/i18n/translations/i18n_el.qmbin804 -> 0 bytes
-rw-r--r--examples/widgets/tools/i18n/translations/i18n_el.ts57
-rw-r--r--examples/widgets/tools/i18n/translations/i18n_en.qmbin810 -> 0 bytes
-rw-r--r--examples/widgets/tools/i18n/translations/i18n_en.ts57
-rw-r--r--examples/widgets/tools/i18n/translations/i18n_eo.qmbin806 -> 0 bytes
-rw-r--r--examples/widgets/tools/i18n/translations/i18n_eo.ts57
-rw-r--r--examples/widgets/tools/i18n/translations/i18n_fr.qmbin844 -> 0 bytes
-rw-r--r--examples/widgets/tools/i18n/translations/i18n_fr.ts57
-rw-r--r--examples/widgets/tools/i18n/translations/i18n_it.qmbin808 -> 0 bytes
-rw-r--r--examples/widgets/tools/i18n/translations/i18n_it.ts57
-rw-r--r--examples/widgets/tools/i18n/translations/i18n_jp.qmbin722 -> 0 bytes
-rw-r--r--examples/widgets/tools/i18n/translations/i18n_jp.ts57
-rw-r--r--examples/widgets/tools/i18n/translations/i18n_ko.qmbin690 -> 0 bytes
-rw-r--r--examples/widgets/tools/i18n/translations/i18n_ko.ts57
-rw-r--r--examples/widgets/tools/i18n/translations/i18n_no.qmbin804 -> 0 bytes
-rw-r--r--examples/widgets/tools/i18n/translations/i18n_no.ts57
-rw-r--r--examples/widgets/tools/i18n/translations/i18n_ru.qmbin806 -> 0 bytes
-rw-r--r--examples/widgets/tools/i18n/translations/i18n_ru.ts59
-rw-r--r--examples/widgets/tools/i18n/translations/i18n_sv.qmbin814 -> 0 bytes
-rw-r--r--examples/widgets/tools/i18n/translations/i18n_sv.ts57
-rw-r--r--examples/widgets/tools/i18n/translations/i18n_zh.qmbin700 -> 0 bytes
-rw-r--r--examples/widgets/tools/i18n/translations/i18n_zh.ts57
-rw-r--r--examples/widgets/tools/plugandpaint/CMakeLists.txt11
-rw-r--r--examples/widgets/tools/plugandpaint/app/CMakeLists.txt11
-rw-r--r--examples/widgets/tools/plugandpaint/plugins/basictools/CMakeLists.txt11
-rw-r--r--examples/widgets/tools/plugandpaint/plugins/extrafilters/CMakeLists.txt11
-rw-r--r--examples/widgets/tools/regularexpression/CMakeLists.txt15
-rw-r--r--examples/widgets/tools/settingseditor/CMakeLists.txt15
-rw-r--r--examples/widgets/tools/styleplugin/CMakeLists.txt11
-rw-r--r--examples/widgets/tools/styleplugin/plugin/CMakeLists.txt33
-rw-r--r--examples/widgets/tools/styleplugin/plugin/plugin.pro12
-rw-r--r--examples/widgets/tools/styleplugin/plugin/simplestyle.cpp2
-rw-r--r--examples/widgets/tools/styleplugin/stylewindow/CMakeLists.txt9
-rw-r--r--examples/widgets/tools/styleplugin/stylewindow/main.cpp9
-rw-r--r--examples/widgets/tools/styleplugin/stylewindow/stylewindow.cpp8
-rw-r--r--examples/widgets/tools/tools.pro4
-rw-r--r--examples/widgets/tools/treemodelcompleter/CMakeLists.txt15
-rw-r--r--examples/widgets/tools/undo/CMakeLists.txt66
-rw-r--r--examples/widgets/tools/undo/commands.cpp130
-rw-r--r--examples/widgets/tools/undo/commands.h76
-rw-r--r--examples/widgets/tools/undo/document.cpp401
-rw-r--r--examples/widgets/tools/undo/document.h86
-rw-r--r--examples/widgets/tools/undo/icons/background.pngbin93 -> 0 bytes
-rw-r--r--examples/widgets/tools/undo/icons/blue.pngbin1659 -> 0 bytes
-rw-r--r--examples/widgets/tools/undo/icons/circle.pngbin1359 -> 0 bytes
-rw-r--r--examples/widgets/tools/undo/icons/exit.pngbin1731 -> 0 bytes
-rw-r--r--examples/widgets/tools/undo/icons/fileclose.pngbin1121 -> 0 bytes
-rw-r--r--examples/widgets/tools/undo/icons/filenew.pngbin1266 -> 0 bytes
-rw-r--r--examples/widgets/tools/undo/icons/fileopen.pngbin1771 -> 0 bytes
-rw-r--r--examples/widgets/tools/undo/icons/filesave.pngbin1022 -> 0 bytes
-rw-r--r--examples/widgets/tools/undo/icons/green.pngbin1766 -> 0 bytes
-rw-r--r--examples/widgets/tools/undo/icons/ok.pngbin979 -> 0 bytes
-rw-r--r--examples/widgets/tools/undo/icons/red.pngbin1653 -> 0 bytes
-rw-r--r--examples/widgets/tools/undo/mainwindow.cpp410
-rw-r--r--examples/widgets/tools/undo/mainwindow.h49
-rw-r--r--examples/widgets/tools/undo/mainwindow.ui322
-rw-r--r--examples/widgets/tools/undo/undo.pro17
-rw-r--r--examples/widgets/tools/undo/undo.qrc20
-rw-r--r--examples/widgets/tools/undoframework/CMakeLists.txt22
-rw-r--r--examples/widgets/tools/undoframework/icons/cross.png (renamed from examples/widgets/tools/undoframework/images/cross.png)bin356 -> 356 bytes
-rw-r--r--examples/widgets/tools/undoframework/icons/rectangle.png (renamed from examples/widgets/tools/undo/icons/rectangle.png)bin690 -> 690 bytes
-rw-r--r--examples/widgets/tools/undoframework/icons/redo.png (renamed from examples/widgets/tools/undo/icons/redo.png)bin985 -> 985 bytes
-rw-r--r--examples/widgets/tools/undoframework/icons/remove.png (renamed from examples/widgets/tools/undo/icons/remove.png)bin1833 -> 1833 bytes
-rw-r--r--examples/widgets/tools/undoframework/icons/triangle.png (renamed from examples/widgets/tools/undo/icons/triangle.png)bin850 -> 850 bytes
-rw-r--r--examples/widgets/tools/undoframework/icons/undo.png (renamed from examples/widgets/tools/undo/icons/undo.png)bin962 -> 962 bytes
-rw-r--r--examples/widgets/tools/undoframework/mainwindow.cpp91
-rw-r--r--examples/widgets/tools/undoframework/mainwindow.h4
-rw-r--r--examples/widgets/tools/undoframework/undoframework.qrc8
-rw-r--r--examples/widgets/touch/CMakeLists.txt5
-rw-r--r--examples/widgets/touch/dials/CMakeLists.txt16
-rw-r--r--examples/widgets/touch/fingerpaint/CMakeLists.txt25
-rw-r--r--examples/widgets/touch/knobs/CMakeLists.txt15
-rw-r--r--examples/widgets/touch/pinchzoom/CMakeLists.txt15
-rw-r--r--examples/widgets/tutorials/CMakeLists.txt5
-rw-r--r--examples/widgets/tutorials/addressbook/CMakeLists.txt7
-rw-r--r--examples/widgets/tutorials/addressbook/README40
-rw-r--r--examples/widgets/tutorials/addressbook/addressbook.pro6
-rw-r--r--examples/widgets/tutorials/addressbook/part1/CMakeLists.txt34
-rw-r--r--examples/widgets/tutorials/addressbook/part1/addressbook.cpp30
-rw-r--r--examples/widgets/tutorials/addressbook/part1/addressbook.h29
-rw-r--r--examples/widgets/tutorials/addressbook/part1/main.cpp17
-rw-r--r--examples/widgets/tutorials/addressbook/part1/part1.pro11
-rw-r--r--examples/widgets/tutorials/addressbook/part2/CMakeLists.txt34
-rw-r--r--examples/widgets/tutorials/addressbook/part2/addressbook.cpp123
-rw-r--r--examples/widgets/tutorials/addressbook/part2/addressbook.h47
-rw-r--r--examples/widgets/tutorials/addressbook/part2/main.cpp17
-rw-r--r--examples/widgets/tutorials/addressbook/part2/part2.pro11
-rw-r--r--examples/widgets/tutorials/addressbook/part3/CMakeLists.txt34
-rw-r--r--examples/widgets/tutorials/addressbook/part3/addressbook.cpp182
-rw-r--r--examples/widgets/tutorials/addressbook/part3/addressbook.h49
-rw-r--r--examples/widgets/tutorials/addressbook/part3/main.cpp15
-rw-r--r--examples/widgets/tutorials/addressbook/part3/part3.pro11
-rw-r--r--examples/widgets/tutorials/addressbook/part4/CMakeLists.txt34
-rw-r--r--examples/widgets/tutorials/addressbook/part4/addressbook.cpp258
-rw-r--r--examples/widgets/tutorials/addressbook/part4/addressbook.h62
-rw-r--r--examples/widgets/tutorials/addressbook/part4/main.cpp15
-rw-r--r--examples/widgets/tutorials/addressbook/part4/part4.pro11
-rw-r--r--examples/widgets/tutorials/addressbook/part5/CMakeLists.txt35
-rw-r--r--examples/widgets/tutorials/addressbook/part5/addressbook.cpp283
-rw-r--r--examples/widgets/tutorials/addressbook/part5/addressbook.h65
-rw-r--r--examples/widgets/tutorials/addressbook/part5/finddialog.cpp51
-rw-r--r--examples/widgets/tutorials/addressbook/part5/finddialog.h31
-rw-r--r--examples/widgets/tutorials/addressbook/part5/main.cpp15
-rw-r--r--examples/widgets/tutorials/addressbook/part5/part5.pro13
-rw-r--r--examples/widgets/tutorials/addressbook/part6/CMakeLists.txt35
-rw-r--r--examples/widgets/tutorials/addressbook/part6/addressbook.cpp366
-rw-r--r--examples/widgets/tutorials/addressbook/part6/addressbook.h66
-rw-r--r--examples/widgets/tutorials/addressbook/part6/finddialog.cpp47
-rw-r--r--examples/widgets/tutorials/addressbook/part6/finddialog.h31
-rw-r--r--examples/widgets/tutorials/addressbook/part6/main.cpp15
-rw-r--r--examples/widgets/tutorials/addressbook/part6/part6.pro14
-rw-r--r--examples/widgets/tutorials/addressbook/part7/CMakeLists.txt35
-rw-r--r--examples/widgets/tutorials/addressbook/part7/addressbook.cpp419
-rw-r--r--examples/widgets/tutorials/addressbook/part7/addressbook.h68
-rw-r--r--examples/widgets/tutorials/addressbook/part7/finddialog.cpp47
-rw-r--r--examples/widgets/tutorials/addressbook/part7/finddialog.h31
-rw-r--r--examples/widgets/tutorials/addressbook/part7/main.cpp15
-rw-r--r--examples/widgets/tutorials/addressbook/part7/part7.pro14
-rw-r--r--examples/widgets/tutorials/gettingStarted/CMakeLists.txt1
-rw-r--r--examples/widgets/tutorials/gettingStarted/gettingStarted.pro4
-rw-r--r--examples/widgets/tutorials/gettingStarted/gsQt/CMakeLists.txt5
-rw-r--r--examples/widgets/tutorials/gettingStarted/gsQt/gsqt.pro7
-rw-r--r--examples/widgets/tutorials/gettingStarted/gsQt/part1/CMakeLists.txt33
-rw-r--r--examples/widgets/tutorials/gettingStarted/gsQt/part1/main.cpp15
-rw-r--r--examples/widgets/tutorials/gettingStarted/gsQt/part1/part1.pro8
-rw-r--r--examples/widgets/tutorials/gettingStarted/gsQt/part2/CMakeLists.txt33
-rw-r--r--examples/widgets/tutorials/gettingStarted/gsQt/part2/main.cpp27
-rw-r--r--examples/widgets/tutorials/gettingStarted/gsQt/part2/part2.pro8
-rw-r--r--examples/widgets/tutorials/gettingStarted/gsQt/part3/CMakeLists.txt33
-rw-r--r--examples/widgets/tutorials/gettingStarted/gsQt/part3/main.cpp61
-rw-r--r--examples/widgets/tutorials/gettingStarted/gsQt/part3/part3.pro8
-rw-r--r--examples/widgets/tutorials/gettingStarted/gsQt/part4/CMakeLists.txt33
-rw-r--r--examples/widgets/tutorials/gettingStarted/gsQt/part4/main.cpp73
-rw-r--r--examples/widgets/tutorials/gettingStarted/gsQt/part4/part4.pro8
-rw-r--r--examples/widgets/tutorials/gettingStarted/gsQt/part5/CMakeLists.txt33
-rw-r--r--examples/widgets/tutorials/gettingStarted/gsQt/part5/main.cpp99
-rw-r--r--examples/widgets/tutorials/gettingStarted/gsQt/part5/part5.pro8
-rw-r--r--examples/widgets/tutorials/modelview/1_readonly/CMakeLists.txt15
-rw-r--r--examples/widgets/tutorials/modelview/1_readonly/mymodel.h3
-rw-r--r--examples/widgets/tutorials/modelview/2_formatting/CMakeLists.txt15
-rw-r--r--examples/widgets/tutorials/modelview/2_formatting/mymodel.cpp8
-rw-r--r--examples/widgets/tutorials/modelview/2_formatting/mymodel.h3
-rw-r--r--examples/widgets/tutorials/modelview/3_changingmodel/CMakeLists.txt15
-rw-r--r--examples/widgets/tutorials/modelview/3_changingmodel/mymodel.cpp4
-rw-r--r--examples/widgets/tutorials/modelview/3_changingmodel/mymodel.h9
-rw-r--r--examples/widgets/tutorials/modelview/4_headers/CMakeLists.txt15
-rw-r--r--examples/widgets/tutorials/modelview/4_headers/mymodel.h3
-rw-r--r--examples/widgets/tutorials/modelview/5_edit/CMakeLists.txt15
-rw-r--r--examples/widgets/tutorials/modelview/5_edit/mainwindow.cpp11
-rw-r--r--examples/widgets/tutorials/modelview/5_edit/mainwindow.h9
-rw-r--r--examples/widgets/tutorials/modelview/6_treeview/CMakeLists.txt15
-rw-r--r--examples/widgets/tutorials/modelview/6_treeview/mainwindow.h12
-rw-r--r--examples/widgets/tutorials/modelview/7_selections/CMakeLists.txt15
-rw-r--r--examples/widgets/tutorials/modelview/7_selections/mainwindow.cpp32
-rw-r--r--examples/widgets/tutorials/modelview/7_selections/mainwindow.h12
-rw-r--r--examples/widgets/tutorials/modelview/CMakeLists.txt3
-rw-r--r--examples/widgets/tutorials/notepad/CMakeLists.txt26
-rw-r--r--examples/widgets/tutorials/notepad/gettingstartedqt.qdoc (renamed from examples/widgets/tutorials/gettingstartedqt.qdoc)0
-rw-r--r--examples/widgets/tutorials/tutorials.pro2
-rw-r--r--examples/widgets/tutorials/widgets/CMakeLists.txt3
-rw-r--r--examples/widgets/tutorials/widgets/childwidget/CMakeLists.txt15
-rw-r--r--examples/widgets/tutorials/widgets/nestedlayouts/CMakeLists.txt15
-rw-r--r--examples/widgets/tutorials/widgets/toplevel/CMakeLists.txt15
-rw-r--r--examples/widgets/tutorials/widgets/windowlayout/CMakeLists.txt15
-rw-r--r--examples/widgets/widgets/CMakeLists.txt8
-rw-r--r--examples/widgets/widgets/analogclock/CMakeLists.txt15
-rw-r--r--examples/widgets/widgets/analogclock/analogclock.cpp6
-rw-r--r--examples/widgets/widgets/calculator/CMakeLists.txt15
-rw-r--r--examples/widgets/widgets/calculator/calculator.cpp41
-rw-r--r--examples/widgets/widgets/calculator/calculator.h3
-rw-r--r--examples/widgets/widgets/calendarwidget/CMakeLists.txt15
-rw-r--r--examples/widgets/widgets/charactermap/CMakeLists.txt15
-rw-r--r--examples/widgets/widgets/codeeditor/CMakeLists.txt34
-rw-r--r--examples/widgets/widgets/codeeditor/codeeditor.cpp134
-rw-r--r--examples/widgets/widgets/codeeditor/codeeditor.h68
-rw-r--r--examples/widgets/widgets/codeeditor/codeeditor.pro8
-rw-r--r--examples/widgets/widgets/codeeditor/main.cpp18
-rw-r--r--examples/widgets/widgets/digitalclock/CMakeLists.txt15
-rw-r--r--examples/widgets/widgets/elidedlabel/CMakeLists.txt35
-rw-r--r--examples/widgets/widgets/elidedlabel/elidedlabel.cpp74
-rw-r--r--examples/widgets/widgets/elidedlabel/elidedlabel.h36
-rw-r--r--examples/widgets/widgets/elidedlabel/elidedlabel.pro20
-rw-r--r--examples/widgets/widgets/elidedlabel/main.cpp16
-rw-r--r--examples/widgets/widgets/elidedlabel/testwidget.cpp119
-rw-r--r--examples/widgets/widgets/elidedlabel/testwidget.h38
-rw-r--r--examples/widgets/widgets/groupbox/CMakeLists.txt15
-rw-r--r--examples/widgets/widgets/groupbox/window.cpp4
-rw-r--r--examples/widgets/widgets/icons/CMakeLists.txt17
-rw-r--r--examples/widgets/widgets/icons/mainwindow.cpp2
-rw-r--r--examples/widgets/widgets/imageviewer/CMakeLists.txt25
-rw-r--r--examples/widgets/widgets/imageviewer/imageviewer.cpp6
-rw-r--r--examples/widgets/widgets/lineedits/CMakeLists.txt15
-rw-r--r--examples/widgets/widgets/mousebuttons/CMakeLists.txt34
-rw-r--r--examples/widgets/widgets/mousebuttons/buttontester.cpp184
-rw-r--r--examples/widgets/widgets/mousebuttons/buttontester.h29
-rw-r--r--examples/widgets/widgets/mousebuttons/main.cpp36
-rw-r--r--examples/widgets/widgets/mousebuttons/mousebuttons.pro16
-rw-r--r--examples/widgets/widgets/movie/CMakeLists.txt15
-rw-r--r--examples/widgets/widgets/scribble/CMakeLists.txt25
-rw-r--r--examples/widgets/widgets/scribble/mainwindow.cpp2
-rw-r--r--examples/widgets/widgets/shapedclock/CMakeLists.txt15
-rw-r--r--examples/widgets/widgets/shapedclock/shapedclock.cpp14
-rw-r--r--examples/widgets/widgets/shapedclock/shapedclock.h1
-rw-r--r--examples/widgets/widgets/shortcuteditor/CMakeLists.txt39
-rw-r--r--examples/widgets/widgets/shortcuteditor/actionmanager.cpp57
-rw-r--r--examples/widgets/widgets/shortcuteditor/actionmanager.h33
-rw-r--r--examples/widgets/widgets/shortcuteditor/application.cpp15
-rw-r--r--examples/widgets/widgets/shortcuteditor/application.h27
-rw-r--r--examples/widgets/widgets/shortcuteditor/main.cpp13
-rw-r--r--examples/widgets/widgets/shortcuteditor/mainwindow.cpp46
-rw-r--r--examples/widgets/widgets/shortcuteditor/mainwindow.h22
-rw-r--r--examples/widgets/widgets/shortcuteditor/shortcuteditordelegate.cpp71
-rw-r--r--examples/widgets/widgets/shortcuteditor/shortcuteditordelegate.h34
-rw-r--r--examples/widgets/widgets/shortcuteditor/shortcuteditormodel.cpp273
-rw-r--r--examples/widgets/widgets/shortcuteditor/shortcuteditormodel.h71
-rw-r--r--examples/widgets/widgets/shortcuteditor/shortcuteditorwidget.cpp33
-rw-r--r--examples/widgets/widgets/shortcuteditor/shortcuteditorwidget.h32
-rw-r--r--examples/widgets/widgets/sliders/CMakeLists.txt15
-rw-r--r--examples/widgets/widgets/sliders/window.cpp42
-rw-r--r--examples/widgets/widgets/sliders/window.h4
-rw-r--r--examples/widgets/widgets/spinboxes/CMakeLists.txt15
-rw-r--r--examples/widgets/widgets/styles/CMakeLists.txt15
-rw-r--r--examples/widgets/widgets/stylesheet/CMakeLists.txt16
-rw-r--r--examples/widgets/widgets/stylesheet/mainwindow.cpp1
-rw-r--r--examples/widgets/widgets/stylesheet/qss/coffee.qss5
-rw-r--r--examples/widgets/widgets/tablet/CMakeLists.txt15
-rw-r--r--examples/widgets/widgets/tetrix/CMakeLists.txt15
-rw-r--r--examples/widgets/widgets/tooltips/CMakeLists.txt15
-rw-r--r--examples/widgets/widgets/tooltips/sortingbox.cpp50
-rw-r--r--examples/widgets/widgets/tooltips/sortingbox.h8
-rw-r--r--examples/widgets/widgets/validators/CMakeLists.txt16
-rw-r--r--examples/widgets/widgets/validators/validatorwidget.h5
-rw-r--r--examples/widgets/widgets/widgets.pro4
-rw-r--r--examples/widgets/widgets/wiggly/CMakeLists.txt35
-rw-r--r--examples/widgets/widgets/wiggly/dialog.cpp27
-rw-r--r--examples/widgets/widgets/wiggly/dialog.h19
-rw-r--r--examples/widgets/widgets/wiggly/main.cpp16
-rw-r--r--examples/widgets/widgets/wiggly/wiggly.pro11
-rw-r--r--examples/widgets/widgets/wiggly/wigglywidget.cpp64
-rw-r--r--examples/widgets/widgets/wiggly/wigglywidget.h32
-rw-r--r--examples/widgets/widgets/windowflags/CMakeLists.txt15
-rw-r--r--examples/widgets/windowcontainer/CMakeLists.txt19
-rw-r--r--examples/xml/CMakeLists.txt11
-rw-r--r--examples/xml/dombookmarks/CMakeLists.txt17
-rw-r--r--examples/xml/dombookmarks/doc/src/dombookmarks.qdoc88
-rw-r--r--examples/xml/dombookmarks/mainwindow.cpp10
-rw-r--r--examples/xml/dombookmarks/mainwindow.h2
-rw-r--r--examples/xml/dombookmarks/xbeltree.cpp23
-rw-r--r--examples/xml/dombookmarks/xbeltree.h2
-rw-r--r--examples/xml/htmlinfo/CMakeLists.txt47
-rw-r--r--examples/xml/htmlinfo/apache_org.html281
-rw-r--r--examples/xml/htmlinfo/htmlinfo.pro10
-rw-r--r--examples/xml/htmlinfo/main.cpp82
-rw-r--r--examples/xml/htmlinfo/resources.qrc10
-rw-r--r--examples/xml/htmlinfo/simpleexample.html11
-rw-r--r--examples/xml/htmlinfo/trolltech_com.html955
-rw-r--r--examples/xml/htmlinfo/w3c_org.html507
-rw-r--r--examples/xml/htmlinfo/youtube_com.html1585
-rw-r--r--examples/xml/rsslisting/main.cpp26
-rw-r--r--examples/xml/rsslisting/rsslisting.cpp211
-rw-r--r--examples/xml/xml.pro8
-rw-r--r--examples/xml/xmlstreamlint/CMakeLists.txt32
-rw-r--r--examples/xml/xmlstreamlint/doc/src/xmlstreamlint.qdoc51
-rw-r--r--examples/xml/xmlstreamlint/main.cpp90
-rw-r--r--examples/xml/xmlstreamlint/xmlstreamlint.pro7
943 files changed, 8430 insertions, 25777 deletions
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index a4fb347ba5..2bc1e4d378 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -1,36 +1,39 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
qt_examples_build_begin(EXTERNAL_BUILD)
add_subdirectory(corelib)
add_subdirectory(embedded)
add_subdirectory(qpa)
-if(TARGET Qt::DBus)
+if(TARGET Qt6::DBus)
add_subdirectory(dbus)
endif()
-if(TARGET Qt::Network)
+if(TARGET Qt6::Network)
add_subdirectory(network)
endif()
-if(TARGET Qt::Test)
+if(TARGET Qt6::Test)
add_subdirectory(qtestlib)
endif()
-if(TARGET Qt::Concurrent)
+if(TARGET Qt6::Concurrent)
add_subdirectory(qtconcurrent)
endif()
-if(TARGET Qt::Sql)
+if(TARGET Qt6::Sql)
add_subdirectory(sql)
endif()
-if(TARGET Qt::Widgets)
+if(TARGET Qt6::Widgets)
add_subdirectory(widgets)
endif()
-if(TARGET Qt::Xml)
+if(TARGET Qt6::Xml)
add_subdirectory(xml)
endif()
-if(TARGET Qt::Gui)
+if(TARGET Qt6::Gui)
add_subdirectory(gui)
endif()
-if(QT_FEATURE_opengl AND TARGET Qt::Gui)
+if(QT_FEATURE_opengl AND TARGET Qt6::Gui)
add_subdirectory(opengl)
endif()
-if(QT_FEATURE_vulkan AND TARGET Qt::Gui)
+if(QT_FEATURE_vulkan AND TARGET Qt6::Gui)
add_subdirectory(vulkan)
endif()
diff --git a/examples/corelib/CMakeLists.txt b/examples/corelib/CMakeLists.txt
index aff53c8202..638db2dda9 100644
--- a/examples/corelib/CMakeLists.txt
+++ b/examples/corelib/CMakeLists.txt
@@ -1,9 +1,17 @@
-add_subdirectory(bindableproperties)
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
add_subdirectory(ipc)
add_subdirectory(mimetypes)
add_subdirectory(serialization)
add_subdirectory(tools)
add_subdirectory(platform)
+if(QT_FEATURE_permissions)
+ add_subdirectory(permissions)
+endif()
if(QT_FEATURE_thread)
add_subdirectory(threads)
endif()
+if(QT_FEATURE_widgets)
+ add_subdirectory(bindableproperties)
+endif()
diff --git a/examples/corelib/bindableproperties/bindablesubscription/CMakeLists.txt b/examples/corelib/bindableproperties/bindablesubscription/CMakeLists.txt
index 6332c45e1a..c4a2e5fcfc 100644
--- a/examples/corelib/bindableproperties/bindablesubscription/CMakeLists.txt
+++ b/examples/corelib/bindableproperties/bindablesubscription/CMakeLists.txt
@@ -1,9 +1,9 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(bindablesubscription LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTOUIC ON)
-
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
@@ -12,6 +12,8 @@ set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/corelib/bindableproperties/bindab
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
+qt_standard_project_setup()
+
qt_add_executable(bindablesubscription
../shared/subscriptionwindow.cpp ../shared/subscriptionwindow.h ../shared/subscriptionwindow.ui
main.cpp
@@ -19,10 +21,10 @@ qt_add_executable(bindablesubscription
bindableuser.cpp bindableuser.h
)
-target_link_libraries(bindablesubscription PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Widgets
+target_link_libraries(bindablesubscription PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Widgets
)
# Resources:
diff --git a/examples/corelib/bindableproperties/bindablesubscription/bindablesubscription.cpp b/examples/corelib/bindableproperties/bindablesubscription/bindablesubscription.cpp
index 1b65c87f5f..a52b68f85b 100644
--- a/examples/corelib/bindableproperties/bindablesubscription/bindablesubscription.cpp
+++ b/examples/corelib/bindableproperties/bindablesubscription/bindablesubscription.cpp
@@ -13,7 +13,7 @@ BindableSubscription::BindableSubscription(BindableUser *user) : m_user(user)
m_price.setBinding([this] { return qRound(calculateDiscount() * m_duration * basePrice()); });
m_isValid.setBinding([this] {
- return m_user->country() != BindableUser::None && m_user->age() > 12;
+ return m_user->country() != BindableUser::Country::AnyCountry && m_user->age() > 12;
});
}
@@ -44,8 +44,8 @@ double BindableSubscription::calculateDiscount() const
int BindableSubscription::basePrice() const
{
- if (m_user->country() == BindableUser::None)
+ if (m_user->country() == BindableUser::Country::AnyCountry)
return 0;
- return (m_user->country() == BindableUser::Norway) ? 100 : 80;
+ return (m_user->country() == BindableUser::Country::Norway) ? 100 : 80;
}
diff --git a/examples/corelib/bindableproperties/bindablesubscription/bindablesubscription.h b/examples/corelib/bindableproperties/bindablesubscription/bindablesubscription.h
index b135618bec..3406693b94 100644
--- a/examples/corelib/bindableproperties/bindablesubscription/bindablesubscription.h
+++ b/examples/corelib/bindableproperties/bindablesubscription/bindablesubscription.h
@@ -14,7 +14,7 @@ class BindableUser;
class BindableSubscription
{
public:
- enum Duration { Monthly = 1, Quarterly = 4, Yearly = 12 };
+ enum Duration { Monthly = 1, Quarterly = 3, Yearly = 12 };
BindableSubscription(BindableUser *user);
BindableSubscription(const BindableSubscription &) = delete;
diff --git a/examples/corelib/bindableproperties/bindablesubscription/bindableuser.h b/examples/corelib/bindableproperties/bindablesubscription/bindableuser.h
index b7e44d52ec..d172a7cb22 100644
--- a/examples/corelib/bindableproperties/bindablesubscription/bindableuser.h
+++ b/examples/corelib/bindableproperties/bindablesubscription/bindableuser.h
@@ -4,6 +4,7 @@
#ifndef BINDABLEUSER_H
#define BINDABLEUSER_H
+#include <QLocale>
#include <QProperty>
//! [bindable-user-class]
@@ -11,13 +12,9 @@
class BindableUser
{
public:
- enum Country {
- None,
- Finland,
- Germany,
- Norway,
- };
+ using Country = QLocale::Territory;
+public:
BindableUser() = default;
BindableUser(const BindableUser &) = delete;
@@ -30,7 +27,7 @@ public:
QBindable<int> bindableAge() { return &m_age; }
private:
- QProperty<Country> m_country { None };
+ QProperty<Country> m_country { QLocale::AnyTerritory };
QProperty<int> m_age { 0 };
};
diff --git a/examples/corelib/bindableproperties/bindablesubscription/main.cpp b/examples/corelib/bindableproperties/bindablesubscription/main.cpp
index c861f8af4c..6cf73c1337 100644
--- a/examples/corelib/bindableproperties/bindablesubscription/main.cpp
+++ b/examples/corelib/bindableproperties/bindablesubscription/main.cpp
@@ -37,15 +37,15 @@ int main(int argc, char *argv[])
// Initialize user data
QPushButton *germany = w.findChild<QPushButton *>("btnGermany");
QObject::connect(germany, &QPushButton::clicked, [&] {
- user.setCountry(BindableUser::Germany);
+ user.setCountry(BindableUser::Country::Germany);
});
QPushButton *finland = w.findChild<QPushButton *>("btnFinland");
QObject::connect(finland, &QPushButton::clicked, [&] {
- user.setCountry(BindableUser::Finland);
+ user.setCountry(BindableUser::Country::Finland);
});
QPushButton *norway = w.findChild<QPushButton *>("btnNorway");
QObject::connect(norway, &QPushButton::clicked, [&] {
- user.setCountry(BindableUser::Norway);
+ user.setCountry(BindableUser::Country::Norway);
});
QSpinBox *ageSpinBox = w.findChild<QSpinBox *>("ageSpinBox");
@@ -58,7 +58,8 @@ int main(int argc, char *argv[])
// Track price changes
//! [update-ui]
auto priceChangeHandler = subscription.bindablePrice().subscribe([&] {
- priceDisplay->setText(QString::number(subscription.price()));
+ QLocale lc{QLocale::AnyLanguage, user.country()};
+ priceDisplay->setText(lc.toCurrencyString(subscription.price() / subscription.duration()));
});
auto priceValidHandler = subscription.bindableIsValid().subscribe([&] {
diff --git a/examples/corelib/bindableproperties/doc/src/bindableproperties.qdoc b/examples/corelib/bindableproperties/doc/src/bindableproperties.qdoc
index 644693acb8..e63662dfbb 100644
--- a/examples/corelib/bindableproperties/doc/src/bindableproperties.qdoc
+++ b/examples/corelib/bindableproperties/doc/src/bindableproperties.qdoc
@@ -15,7 +15,7 @@
\image bindable_properties_example.png
- \section1 Modelling Subscription System with Signal/Slot Approach
+ \section1 Modeling Subscription System with Signal/Slot Approach
Let's first consider the usual pre-Qt 6 implementation.
To model the subscription service the \c Subscription class is used:
@@ -48,7 +48,7 @@
\note Both methods need to check if the data is actually changed and
only then emit the signals. \c setDuration() also needs to recalculate
- the price, when the duration has changed.
+ the price when the duration has changed.
The \c Subscription is not valid unless the user has a valid country and
age, so the validity is updated in the following way:
@@ -63,25 +63,25 @@
\snippet bindableproperties/subscription/user.cpp user-setters
In the \c main() function we initialize instances of \c User and
- \c Subsrcription:
+ \c Subscription:
\snippet bindableproperties/subscription/main.cpp init
- And do the proper signal-slot connections, to update the \c user and
- \c subsrcription data when UI elements change. That is straightforward,
+ And do the proper signal-slot connections to update the \c user and
+ \c subscription data when UI elements change. That is straightforward,
so we will skip this part.
- Next, we connect to \c Subscription::priceChanged(), to update the price
+ Next, we connect to \c Subscription::priceChanged() to update the price
in the UI when the price changes.
\snippet bindableproperties/subscription/main.cpp connect-price-changed
- We also connect to \c Subscription::isValidChanged(), to disable the price
+ We also connect to \c Subscription::isValidChanged() to disable the price
display if the subscription isn't valid.
\snippet bindableproperties/subscription/main.cpp connect-validity-changed
- Because the subsrcription price and validity also depend on the user's
+ Because the subscription price and validity also depend on the user's
country and age, we also need to connect to the \c User::countryChanged()
and \c User::ageChanged() signals and update \c subscription accordingly.
@@ -90,12 +90,12 @@
This works, but there are some problems:
\list
- \li There's a lot of boilerplate code for the signal-slot connections,
- to be able to react to changes to \c user or \c subscription. If any of
- the dependencies of the price changes, we need to remember to emit the
- corresponding notifier signals, to recalculate the price and update it in
+ \li There's a lot of boilerplate code for the signal-slot connections
+ in order to properly track changes to both \c user and \c subscription.
+ If any of the dependencies of the price changes, we need to remember to emit the
+ corresponding notifier signals, recalculate the price, and update it in
the UI.
- \li If more dependencies for price calculation are added in future, we'll
+ \li If more dependencies for price calculation are added in the future, we'll
need to add more signal-slot connections and make sure all the dependencies
are properly updated whenever any of them changes. The overall complexity
will grow, and the code will become harder to maintain.
@@ -109,7 +109,7 @@
Now let's see how the \l {Qt Bindable Properties} can help to solve the
same problem. First, let's have a look at the \c BindableSubscription class,
- which is similar to the \c Subscription class, but is implemented using the
+ which is similar to the \c Subscription class, but is implemented using
bindable properties:
\snippet bindableproperties/bindablesubscription/bindablesubscription.h bindable-subscription-class
@@ -156,7 +156,7 @@
changes the value. The subscriptions will stay alive as long as the
corresponding handlers are alive.
- Also note that the copy constructors of both \c BindableSubsrciption and
+ Also note that the copy constructors of both \c BindableSubscription and
\c BindableUser are disabled, since it's not defined what should happen
with their bindings when copying.
@@ -166,7 +166,7 @@
\list
\li The boilerplate code for the signal-slot connections is removed, the
dependencies are now tracked automatically.
- \li The code is easier to maintain. Adding more dependencies in future
+ \li The code is easier to maintain. Adding more dependencies in the future
will only require adding the corresponding bindable properties and setting
the binding expressions that reflect the relationships between each other.
\li The \c Subscription and \c User classes don't depend on the metaobject
diff --git a/examples/corelib/bindableproperties/subscription/CMakeLists.txt b/examples/corelib/bindableproperties/subscription/CMakeLists.txt
index 9b624e4e29..0dd027fc24 100644
--- a/examples/corelib/bindableproperties/subscription/CMakeLists.txt
+++ b/examples/corelib/bindableproperties/subscription/CMakeLists.txt
@@ -1,9 +1,9 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(subscription LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTOUIC ON)
-
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
@@ -12,6 +12,8 @@ set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/corelib/bindableproperties/subscr
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
+qt_standard_project_setup()
+
qt_add_executable(subscription
../shared/subscriptionwindow.cpp ../shared/subscriptionwindow.h ../shared/subscriptionwindow.ui
main.cpp
@@ -19,10 +21,10 @@ qt_add_executable(subscription
user.cpp user.h
)
-target_link_libraries(subscription PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Widgets
+target_link_libraries(subscription PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Widgets
)
# Resources:
diff --git a/examples/corelib/bindableproperties/subscription/main.cpp b/examples/corelib/bindableproperties/subscription/main.cpp
index 8b3f37ab7c..1f41486728 100644
--- a/examples/corelib/bindableproperties/subscription/main.cpp
+++ b/examples/corelib/bindableproperties/subscription/main.cpp
@@ -40,15 +40,15 @@ int main(int argc, char *argv[])
// Initialize user data
QPushButton *germany = w.findChild<QPushButton *>("btnGermany");
QObject::connect(germany, &QPushButton::clicked, &user, [&] {
- user.setCountry(User::Germany);
+ user.setCountry(User::Country::Germany);
});
QPushButton *finland = w.findChild<QPushButton *>("btnFinland");
QObject::connect(finland, &QPushButton::clicked, &user, [&] {
- user.setCountry(User::Finland);
+ user.setCountry(User::Country::Finland);
});
QPushButton *norway = w.findChild<QPushButton *>("btnNorway");
QObject::connect(norway, &QPushButton::clicked, &user, [&] {
- user.setCountry(User::Norway);
+ user.setCountry(User::Country::Norway);
});
QSpinBox *ageSpinBox = w.findChild<QSpinBox *>("ageSpinBox");
@@ -65,7 +65,8 @@ int main(int argc, char *argv[])
//! [connect-price-changed]
QObject::connect(&subscription, &Subscription::priceChanged, [&] {
- priceDisplay->setText(QString::number(subscription.price()));
+ QLocale lc{QLocale::AnyLanguage, user.country()};
+ priceDisplay->setText(lc.toCurrencyString(subscription.price() / subscription.duration()));
});
//! [connect-price-changed]
diff --git a/examples/corelib/bindableproperties/subscription/subscription.cpp b/examples/corelib/bindableproperties/subscription/subscription.cpp
index 16bb6cfdd6..5d040f76d9 100644
--- a/examples/corelib/bindableproperties/subscription/subscription.cpp
+++ b/examples/corelib/bindableproperties/subscription/subscription.cpp
@@ -57,10 +57,10 @@ double Subscription::calculateDiscount() const
int Subscription::basePrice() const
{
- if (m_user->country() == User::None)
+ if (m_user->country() == User::Country::AnyTerritory)
return 0;
- return (m_user->country() == User::Norway) ? 100 : 80;
+ return (m_user->country() == User::Country::Norway) ? 100 : 80;
}
//! [calculate-base-price]
@@ -70,7 +70,7 @@ int Subscription::basePrice() const
void Subscription::updateValidity()
{
bool isValid = m_isValid;
- m_isValid = m_user->country() != User::None && m_user->age() > 12;
+ m_isValid = m_user->country() != User::Country::AnyTerritory && m_user->age() > 12;
if (m_isValid != isValid)
emit isValidChanged();
diff --git a/examples/corelib/bindableproperties/subscription/subscription.h b/examples/corelib/bindableproperties/subscription/subscription.h
index 5fa705772b..8f0d34e948 100644
--- a/examples/corelib/bindableproperties/subscription/subscription.h
+++ b/examples/corelib/bindableproperties/subscription/subscription.h
@@ -15,7 +15,7 @@ class Subscription : public QObject
{
Q_OBJECT
public:
- enum Duration { Monthly = 1, Quarterly = 4, Yearly = 12 };
+ enum Duration { Monthly = 1, Quarterly = 3, Yearly = 12 };
Subscription(User *user);
diff --git a/examples/corelib/bindableproperties/subscription/user.h b/examples/corelib/bindableproperties/subscription/user.h
index 1e16f9e901..dd32a4fe23 100644
--- a/examples/corelib/bindableproperties/subscription/user.h
+++ b/examples/corelib/bindableproperties/subscription/user.h
@@ -4,6 +4,7 @@
#ifndef USER_H
#define USER_H
+#include <QLocale>
#include <QObject>
//! [user-class]
@@ -13,13 +14,9 @@ class User : public QObject
Q_OBJECT
public:
- enum Country {
- None,
- Finland,
- Germany,
- Norway,
- };
+ using Country = QLocale::Territory;
+public:
Country country() const { return m_country; }
void setCountry(Country country);
@@ -31,8 +28,8 @@ signals:
void ageChanged();
private:
- Country m_country = Country::None;
- int m_age = 0;
+ Country m_country { QLocale::AnyTerritory };
+ int m_age { 0 };
};
//! [user-class]
diff --git a/examples/corelib/ipc/CMakeLists.txt b/examples/corelib/ipc/CMakeLists.txt
index 9cc34c8ea2..d1cfc7bc1b 100644
--- a/examples/corelib/ipc/CMakeLists.txt
+++ b/examples/corelib/ipc/CMakeLists.txt
@@ -1,10 +1,13 @@
-if(NOT TARGET Qt::Widgets)
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT TARGET Qt6::Widgets)
return()
endif()
if(QT_FEATURE_sharedmemory)
qt_internal_add_example(sharedmemory)
endif()
-if(QT_FEATURE_localserver AND TARGET Qt::Network)
+if(QT_FEATURE_localserver AND TARGET Qt6::Network)
qt_internal_add_example(localfortuneserver)
qt_internal_add_example(localfortuneclient)
endif()
diff --git a/examples/corelib/ipc/localfortuneclient/CMakeLists.txt b/examples/corelib/ipc/localfortuneclient/CMakeLists.txt
index c6b5d53e37..b3337e1f46 100644
--- a/examples/corelib/ipc/localfortuneclient/CMakeLists.txt
+++ b/examples/corelib/ipc/localfortuneclient/CMakeLists.txt
@@ -1,8 +1,9 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(localfortuneclient LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
@@ -11,6 +12,8 @@ set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/corelib/ipc/localfortuneclient")
find_package(Qt6 REQUIRED COMPONENTS Core Gui Network Widgets)
+qt_standard_project_setup()
+
qt_add_executable(localfortuneclient
client.cpp client.h
main.cpp
@@ -21,11 +24,11 @@ set_target_properties(localfortuneclient PROPERTIES
MACOSX_BUNDLE TRUE
)
-target_link_libraries(localfortuneclient PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Network
- Qt::Widgets
+target_link_libraries(localfortuneclient PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Network
+ Qt6::Widgets
)
install(TARGETS localfortuneclient
diff --git a/examples/corelib/ipc/localfortuneserver/CMakeLists.txt b/examples/corelib/ipc/localfortuneserver/CMakeLists.txt
index 990dfddf3e..411fc04eb5 100644
--- a/examples/corelib/ipc/localfortuneserver/CMakeLists.txt
+++ b/examples/corelib/ipc/localfortuneserver/CMakeLists.txt
@@ -1,8 +1,9 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(localfortuneserver LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
@@ -11,6 +12,8 @@ set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/corelib/ipc/localfortuneserver")
find_package(Qt6 REQUIRED COMPONENTS Core Gui Network Widgets)
+qt_standard_project_setup()
+
qt_add_executable(localfortuneserver
main.cpp
server.cpp server.h
@@ -21,11 +24,11 @@ set_target_properties(localfortuneserver PROPERTIES
MACOSX_BUNDLE TRUE
)
-target_link_libraries(localfortuneserver PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Network
- Qt::Widgets
+target_link_libraries(localfortuneserver PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Network
+ Qt6::Widgets
)
install(TARGETS localfortuneserver
diff --git a/examples/corelib/ipc/sharedmemory/CMakeLists.txt b/examples/corelib/ipc/sharedmemory/CMakeLists.txt
index 323c356b72..21f5ff339b 100644
--- a/examples/corelib/ipc/sharedmemory/CMakeLists.txt
+++ b/examples/corelib/ipc/sharedmemory/CMakeLists.txt
@@ -1,9 +1,9 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(sharedmemory LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTOUIC ON)
-
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
@@ -12,6 +12,8 @@ set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/corelib/ipc/sharedmemory")
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
+qt_standard_project_setup()
+
qt_add_executable(sharedmemory
dialog.cpp dialog.h dialog.ui
main.cpp
@@ -22,10 +24,10 @@ set_target_properties(sharedmemory PROPERTIES
MACOSX_BUNDLE TRUE
)
-target_link_libraries(sharedmemory PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Widgets
+target_link_libraries(sharedmemory PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Widgets
)
install(TARGETS sharedmemory
diff --git a/examples/corelib/ipc/sharedmemory/dialog.cpp b/examples/corelib/ipc/sharedmemory/dialog.cpp
index 67e4f012a3..b656cc0c67 100644
--- a/examples/corelib/ipc/sharedmemory/dialog.cpp
+++ b/examples/corelib/ipc/sharedmemory/dialog.cpp
@@ -89,8 +89,13 @@ void Dialog::loadFromFile()
int size = buffer.size();
if (!sharedMemory.create(size)) {
- ui.label->setText(tr("Unable to create shared memory segment."));
- return;
+ if (sharedMemory.error() == QSharedMemory::AlreadyExists) {
+ sharedMemory.attach();
+ } else {
+ ui.label->setText(tr("Unable to create or attach to shared memory segment: %1")
+ .arg(sharedMemory.errorString()));
+ return;
+ }
}
sharedMemory.lock();
char *to = (char*)sharedMemory.data();
diff --git a/examples/corelib/mimetypes/CMakeLists.txt b/examples/corelib/mimetypes/CMakeLists.txt
index 79561aa0be..9ba3873bf4 100644
--- a/examples/corelib/mimetypes/CMakeLists.txt
+++ b/examples/corelib/mimetypes/CMakeLists.txt
@@ -1,3 +1,6 @@
-if(TARGET Qt::Widgets)
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(TARGET Qt6::Widgets)
qt_internal_add_example(mimetypebrowser)
endif()
diff --git a/examples/corelib/mimetypes/mimetypebrowser/CMakeLists.txt b/examples/corelib/mimetypes/mimetypebrowser/CMakeLists.txt
index 38abfba4b2..c03ccae085 100644
--- a/examples/corelib/mimetypes/mimetypebrowser/CMakeLists.txt
+++ b/examples/corelib/mimetypes/mimetypebrowser/CMakeLists.txt
@@ -1,8 +1,9 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(mimetypebrowser LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
@@ -11,6 +12,8 @@ set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/corelib/mimetypes/mimetypebrowser
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
+qt_standard_project_setup()
+
qt_add_executable(mimetypebrowser
main.cpp
mainwindow.cpp mainwindow.h
@@ -22,10 +25,10 @@ set_target_properties(mimetypebrowser PROPERTIES
MACOSX_BUNDLE FALSE
)
-target_link_libraries(mimetypebrowser PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Widgets
+target_link_libraries(mimetypebrowser PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Widgets
)
install(TARGETS mimetypebrowser
diff --git a/examples/corelib/permissions/CMakeLists.txt b/examples/corelib/permissions/CMakeLists.txt
new file mode 100644
index 0000000000..39a207b1ce
--- /dev/null
+++ b/examples/corelib/permissions/CMakeLists.txt
@@ -0,0 +1,47 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+cmake_minimum_required(VERSION 3.16)
+project(permissions LANGUAGES CXX)
+
+if(NOT DEFINED INSTALL_EXAMPLESDIR)
+ set(INSTALL_EXAMPLESDIR "examples")
+endif()
+
+set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/corelib/permissions")
+
+find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
+
+qt_standard_project_setup()
+
+qt_add_executable(permissions
+ MANUAL_FINALIZATION
+ main.cpp
+ android/AndroidManifest.xml
+)
+
+set_target_properties(permissions PROPERTIES
+ MACOSX_BUNDLE TRUE
+ MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Info.plist"
+ MACOSX_BUNDLE_GUI_IDENTIFIER "io.qt.examples.permissions"
+ QT_ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android"
+)
+
+target_link_libraries(permissions PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Widgets
+)
+
+install(TARGETS permissions
+ RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
+ BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
+ LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+)
+
+if(APPLE AND NOT CMAKE_GENERATOR STREQUAL "Xcode")
+ add_custom_command(TARGET permissions
+ POST_BUILD COMMAND codesign -s - permissions.app)
+endif()
+
+qt_finalize_executable(permissions)
diff --git a/examples/corelib/permissions/Info.plist b/examples/corelib/permissions/Info.plist
new file mode 100644
index 0000000000..57625d03dc
--- /dev/null
+++ b/examples/corelib/permissions/Info.plist
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+
+ <key>CFBundleName</key>
+ <string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
+ <key>CFBundleIdentifier</key>
+ <string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
+ <key>CFBundleExecutable</key>
+ <string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
+
+ <key>CFBundleVersion</key>
+ <string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
+ <key>CFBundleShortVersionString</key>
+ <string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
+
+ <key>LSMinimumSystemVersion</key>
+ <string>${CMAKE_OSX_DEPLOYMENT_TARGET}</string>
+
+ <key>NSHumanReadableCopyright</key>
+ <string>${MACOSX_BUNDLE_COPYRIGHT}</string>
+
+ <key>CFBundleIconFile</key>
+ <string>${MACOSX_BUNDLE_ICON_FILE}</string>
+
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+
+ <key>NSSupportsAutomaticGraphicsSwitching</key>
+ <true/>
+
+ <key>NSBluetoothAlwaysUsageDescription</key>
+ <string>Testing BluetoothAlways</string>
+ <key>NSCalendarsUsageDescription</key>
+ <string>Testing Calendars</string>
+ <key>NSCameraUsageDescription</key>
+ <string>Testing Camera</string>
+ <key>NSContactsUsageDescription</key>
+ <string>Testing Contacts</string>
+ <key>NSHealthShareUsageDescription</key>
+ <string>Testing HealthShare</string>
+ <key>NSHealthUpdateUsageDescription</key>
+ <string>Testing HealthUpdate</string>
+ <key>NSLocationUsageDescription</key>
+ <string>Testing Location on macOS</string>
+ <key>NSLocationWhenInUseUsageDescription</key>
+ <string>Testing Location when in use on iOS</string>
+ <key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
+ <string>Testing Location always and when in use on iOS</string>
+ <key>NSMicrophoneUsageDescription</key>
+ <string>Testing Microphone</string>
+
+</dict>
+</plist>
diff --git a/examples/corelib/permissions/android/AndroidManifest.xml b/examples/corelib/permissions/android/AndroidManifest.xml
new file mode 100644
index 0000000000..557ec8007e
--- /dev/null
+++ b/examples/corelib/permissions/android/AndroidManifest.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="org.qtproject.example"
+ android:installLocation="auto"
+ android:versionCode="-- %%INSERT_VERSION_CODE%% --"
+ android:versionName="-- %%INSERT_VERSION_NAME%% --">
+ <uses-permission android:name="android.permission.CAMERA" />
+ <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
+ <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+ <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+ <uses-permission android:name="android.permission.RECORD_AUDIO" />
+ <uses-permission android:name="android.permission.BLUETOOTH" />
+ <uses-permission android:name="android.permission.READ_CONTACTS" />
+ <uses-permission android:name="android.permission.WRITE_CONTACTS" />
+ <uses-permission android:name="android.permission.READ_CALENDAR" />
+ <uses-permission android:name="android.permission.WRITE_CALENDAR" />
+ <!-- %%INSERT_PERMISSIONS -->
+ <!-- %%INSERT_FEATURES -->
+ <supports-screens
+ android:anyDensity="true"
+ android:largeScreens="true"
+ android:normalScreens="true"
+ android:smallScreens="true" />
+ <application
+ android:name="org.qtproject.qt.android.bindings.QtApplication"
+ android:hardwareAccelerated="true"
+ android:label="-- %%INSERT_APP_NAME%% --"
+ android:requestLegacyExternalStorage="true"
+ android:allowNativeHeapPointerTagging="false"
+ android:allowBackup="true"
+ android:fullBackupOnly="false">
+ <activity
+ android:name="org.qtproject.qt.android.bindings.QtActivity"
+ android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation|mcc|mnc|density"
+ android:label="-- %%INSERT_APP_NAME%% --"
+ android:launchMode="singleTop"
+ android:screenOrientation="unspecified"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+
+ <meta-data
+ android:name="android.app.lib_name"
+ android:value="-- %%INSERT_APP_LIB_NAME%% --" />
+
+ <meta-data
+ android:name="android.app.extract_android_style"
+ android:value="minimal" />
+ </activity>
+ </application>
+</manifest>
diff --git a/examples/corelib/permissions/main.cpp b/examples/corelib/permissions/main.cpp
new file mode 100644
index 0000000000..913aed2fec
--- /dev/null
+++ b/examples/corelib/permissions/main.cpp
@@ -0,0 +1,87 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include <QtCore/qmetaobject.h>
+#include <QtWidgets/qapplication.h>
+#include <QtWidgets/qwidget.h>
+#include <QtWidgets/qpushbutton.h>
+#include <QtWidgets/qlayout.h>
+#include <QtWidgets/qmessagebox.h>
+
+#if !QT_CONFIG(permissions)
+#error "This example requires the permissions feature, which is not enabled on this platform"
+#endif
+
+#include <QtCore/qpermissions.h>
+
+class PermissionWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit PermissionWidget(QWidget *parent = nullptr) : QWidget(parent)
+ {
+ QVBoxLayout *layout = new QVBoxLayout(this);
+
+ static const QPermission permissions[] = {
+ QCameraPermission{},
+ QMicrophonePermission{},
+ QBluetoothPermission{},
+ QContactsPermission{},
+ QCalendarPermission{},
+ QLocationPermission{}
+ };
+
+ for (auto permission : permissions) {
+ auto permissionName = QString::fromLatin1(permission.type().name());
+ QPushButton *button = new QPushButton(permissionName.sliced(1, permissionName.length() - 11));
+ connect(button, &QPushButton::clicked, this, &PermissionWidget::buttonClicked);
+ button->setProperty("permission", QVariant::fromValue(permission));
+ layout->addWidget(button);
+ }
+
+ QPalette pal = palette();
+ pal.setBrush(QPalette::Window, QGradient(QGradient::HappyAcid));
+ setPalette(pal);
+ }
+
+private:
+ void buttonClicked()
+ {
+ auto *button = static_cast<QPushButton*>(sender());
+
+ auto permission = button->property("permission").value<QPermission>();
+ Q_ASSERT(permission.type().isValid());
+
+ switch (qApp->checkPermission(permission)) {
+ case Qt::PermissionStatus::Undetermined:
+ qApp->requestPermission(permission, this,
+ [button](const QPermission &permission) {
+ Q_UNUSED(permission);
+ emit button->clicked(); // Try again
+ }
+ );
+ return;
+ case Qt::PermissionStatus::Denied:
+ QMessageBox::warning(this, button->text(),
+ tr("Permission is needed to use %1. Please grant permission "\
+ "to this application in the system settings.").arg(button->text()));
+ return;
+ case Qt::PermissionStatus::Granted:
+ break; // Proceed
+ }
+
+ // All good, can use the feature
+ QMessageBox::information(this, button->text(),
+ tr("Accessing %1").arg(button->text()));
+ }
+};
+
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+ PermissionWidget widget;
+ widget.show();
+ return app.exec();
+}
+
+#include "main.moc"
diff --git a/examples/corelib/platform/CMakeLists.txt b/examples/corelib/platform/CMakeLists.txt
index 1a10578a1f..8eeda13095 100644
--- a/examples/corelib/platform/CMakeLists.txt
+++ b/examples/corelib/platform/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
if(ANDROID)
add_subdirectory(androidnotifier)
endif()
diff --git a/examples/corelib/platform/androidnotifier/CMakeLists.txt b/examples/corelib/platform/androidnotifier/CMakeLists.txt
index 0caa208a95..e5271edd79 100644
--- a/examples/corelib/platform/androidnotifier/CMakeLists.txt
+++ b/examples/corelib/platform/androidnotifier/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(androidnotifier LANGUAGES CXX)
@@ -5,14 +8,14 @@ if(NOT ANDROID)
message(FATAL_ERROR "Example only works on Android")
endif()
-set(CMAKE_AUTOMOC ON)
-
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
find_package(Qt6 REQUIRED COMPONENTS Widgets)
+qt_standard_project_setup()
+
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/corelib/platform/androidnotifier")
qt_add_executable(androidnotifier
@@ -20,6 +23,8 @@ qt_add_executable(androidnotifier
main.cpp
notificationclient.cpp
notificationclient.h
+ android/src/org/qtproject/example/androidnotifier/NotificationClient.java
+ android/AndroidManifest.xml
)
target_link_libraries(androidnotifier PRIVATE
diff --git a/examples/corelib/platform/androidnotifier/android/AndroidManifest.xml b/examples/corelib/platform/androidnotifier/android/AndroidManifest.xml
index 4850a8e8e6..b2d9cc7680 100644
--- a/examples/corelib/platform/androidnotifier/android/AndroidManifest.xml
+++ b/examples/corelib/platform/androidnotifier/android/AndroidManifest.xml
@@ -23,13 +23,16 @@
android:hardwareAccelerated="true"
android:label="Qt Notifier"
android:requestLegacyExternalStorage="true"
- android:icon="@drawable/icon">
+ android:icon="@drawable/icon"
+ android:allowBackup="true"
+ android:fullBackupOnly="false">
<activity
android:name="org.qtproject.qt.android.bindings.QtActivity"
android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation|mcc|mnc|density"
android:label="Qt Notifier"
android:launchMode="singleTop"
- android:screenOrientation="unspecified">
+ android:screenOrientation="unspecified"
+ android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
diff --git a/examples/corelib/platform/androidnotifier/doc/src/androidnotifier-example.qdoc b/examples/corelib/platform/androidnotifier/doc/src/androidnotifier-example.qdoc
index 8d2a9a47e4..186be9ec5a 100644
--- a/examples/corelib/platform/androidnotifier/doc/src/androidnotifier-example.qdoc
+++ b/examples/corelib/platform/androidnotifier/doc/src/androidnotifier-example.qdoc
@@ -4,6 +4,7 @@
/*!
\title Qt Android Notifier
\example platform/androidnotifier
+ \examplecategory {Mobile}
\brief Demonstrates calling Java code from Qt in an Android application.
\image androidnotifier.png
@@ -47,7 +48,7 @@
The call to the Java meethod use \l QJniObject which relies on the Java Native
Interface (JNI) APIs to communicate with Java. Also, in the previous snippet,
- we are passing the app's context object which the the static Java code can use
+ we are passing the app's context object, which the static Java code can use
to tap into the app's specific properties and APIs.
To make sure our smiley buttons do what they are supposed to, we add the
diff --git a/examples/corelib/serialization/CMakeLists.txt b/examples/corelib/serialization/CMakeLists.txt
index 7f3701ad99..7dd5d476d1 100644
--- a/examples/corelib/serialization/CMakeLists.txt
+++ b/examples/corelib/serialization/CMakeLists.txt
@@ -1,3 +1,12 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
qt_internal_add_example(cbordump)
qt_internal_add_example(convert)
qt_internal_add_example(savegame)
+if(TARGET Qt6::Network AND TARGET Qt6::Widgets)
+ qt_internal_add_example(rsslisting)
+endif()
+if(TARGET Qt6::Widgets)
+ qt_internal_add_example(streambookmarks)
+endif()
diff --git a/examples/corelib/serialization/cbordump/CMakeLists.txt b/examples/corelib/serialization/cbordump/CMakeLists.txt
index b64ec2524c..813b02b9c0 100644
--- a/examples/corelib/serialization/cbordump/CMakeLists.txt
+++ b/examples/corelib/serialization/cbordump/CMakeLists.txt
@@ -1,8 +1,9 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(cbordump LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
@@ -11,12 +12,14 @@ set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/corelib/serialization/cbordump")
find_package(Qt6 REQUIRED COMPONENTS Core)
+qt_standard_project_setup()
+
qt_add_executable(cbordump
main.cpp
)
-target_link_libraries(cbordump PUBLIC
- Qt::Core
+target_link_libraries(cbordump PRIVATE
+ Qt6::Core
)
install(TARGETS cbordump
diff --git a/examples/corelib/serialization/cbordump/cbortag.py b/examples/corelib/serialization/cbordump/cbortag.py
new file mode 100755
index 0000000000..8634dcdc20
--- /dev/null
+++ b/examples/corelib/serialization/cbordump/cbortag.py
@@ -0,0 +1,188 @@
+#!/bin/env python3
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+"""Digest cbor-tags.xml file into code for insertion into main.cpp
+
+See main.cpp's comment on how to regenerate its GENERATED CODE.
+See ./cbortag.py --help for further details on how to invoke.
+You can import this is a module without invoking the script.
+"""
+
+def firstChild(parent, tag):
+ """Return parent's first child element with the given tag."""
+ return next(node for node in parent.childNodes
+ if node.nodeType == parent.ELEMENT_NODE and node.nodeName == tag)
+
+def nodeAttrIs(node, attr, seek):
+ """Checks whether the node has a given value for an attribute
+
+ Takes the node to check, the name of the attribute and the value
+ to check against. Returns true if the node does have that value
+ for the named attribute."""
+ if node.nodeType != node.ELEMENT_NODE:
+ return False
+ if node.attributes is None or attr not in node.attributes:
+ return False
+ return node.attributes[attr].value == seek
+
+def getRfcValue(node):
+ """Extract RFC reference from an <xref type="rfc" ...> element
+
+ Some of these have a reference including section details as the
+ body of the element, otherwise the data attribute should identify
+ the RFC. If neither is found, an empty string is returned."""
+ if node.childNodes:
+ return node.childNodes[0].nodeValue # Maybe accumulate several children ?
+ if node.attributes is None or 'data' not in node.attributes:
+ return ''
+ return node.attributes['data'].value
+
+def readRegistry(filename):
+ """Handles the XML parsing and returns the relevant parts.
+
+ Single argument is the path to the cbor-tags.xml file; returns a
+ twople of the title element's text and an interator over the
+ record nodes. Checks some things are as expected while doing so."""
+ from xml.dom.minidom import parse
+ doc = parse(filename).documentElement
+ assert nodeAttrIs(doc, 'id', 'cbor-tags')
+ title = firstChild(doc, 'title').childNodes[0].nodeValue
+ registry = firstChild(doc, 'registry')
+ assert nodeAttrIs(registry, 'id', 'tags')
+ records = (node for node in registry.childNodes if node.nodeName == 'record')
+ return title, records
+
+def digest(record):
+ """Digest a single record from cbor-tags.xml
+
+ If the record is not of interest, returns the twople (None, None).
+ For records of interest, returns (n, t) where n is the numeric tag
+ code of the record and t is a text describing it. If the record,
+ or its semantics field, has an xref child with type="rfc", the RFC
+ mentioned there is included with the text of the semantics; such a
+ record is of interest, provided it has a semantics field and no
+ dash in its value. Records with a value field containing a dash
+ (indicating a range) are not of interest. Records with a value of
+ 256 or above are only of interest if they include an RFC."""
+ data = {}
+ for kid in record.childNodes:
+ if kid.nodeName == 'xref':
+ if not nodeAttrIs(kid, 'type', 'rfc'):
+ continue
+ rfc = getRfcValue(kid)
+ if rfc:
+ # Potentially stomping one taken from semantics
+ data['rfc'] = rfc
+ elif kid.nodeName == 'semantics':
+ text = rfc = ''
+ for part in kid.childNodes:
+ if part.nodeType == kid.TEXT_NODE:
+ text += part.nodeValue
+ elif part.nodeType == kid.ELEMENT_NODE:
+ if part.nodeName != 'xref' or not nodeAttrIs(part, 'type', 'rfc'):
+ continue # potentially append content to text
+ assert not rfc, ('Duplicate RFC ?', rfc, part)
+ rfc = getRfcValue(part)
+ if rfc:
+ if text.endswith('()'):
+ text = text[:-2].rstrip()
+ if 'rfc' not in data:
+ data['rfc'] = rfc
+ data['semantics'] = ' '.join(text.split())
+ elif kid.nodeName == 'value':
+ data['value'] = kid.childNodes[0].nodeValue
+ text = data.get('semantics')
+ if not text or 'value' not in data or '-' in data['value']:
+ return None, None
+ value = int(data['value'])
+ if 'rfc' in data:
+ rfc = data["rfc"].replace('rfc', 'RFC')
+ text = f'{text} [{rfc}]'
+ elif value >= 256:
+ return None, None
+ return value, text
+
+def entries(records):
+ """Digest each record of interest into a value and text.
+
+ The value and text form the raw material of the tagDescriptions
+ array in main.cpp; see digest for which records are retained."""
+ for record in records:
+ value, text = digest(record)
+ if value is not None:
+ yield value, text
+
+def marginBound(text, prior, left, right):
+ """Split up a string literal for tidy display.
+
+ The first parameter, text, is the content of the string literal;
+ quotes shall be added. It may be split into several fragments,
+ each quoted, so as to abide by line length constraints.
+
+ The remaining parameters are integers: prior is the text already
+ present on the line before text is to be added; left is the width
+ of the left margin for all subsequent lines; and right is the
+ right margin to stay within, where possible. The returned string
+ is either a space with the whole quoted text following, to fit on
+ the line already started to length prior, or a sequence of quoted
+ strings, each preceded by a newline and indent of width left."""
+ if prior + 3 + len(text) < right: # 1 for space, 2 for quotes
+ return f' "{text}"'
+ width = right - left - 2 # 2 for the quotes
+ words = iter(text.split(' '))
+ lines, current = [''], [next(words)]
+ for word in words:
+ if len(word) + sum(len(w) + 1 for w in current) > width:
+ line = ' '.join(current)
+ lines.append(f'"{line}"')
+ current = ['', word]
+ else:
+ current.append(word)
+ line = ' '.join(current)
+ lines.append(f'"{line}"')
+ return ('\n' + ' ' * left).join(lines)
+
+def main(argv, speak):
+ """Takes care of driving the process.
+
+ Takes the command-line argument list (whose first entry is the
+ name of this script) and standard output (or compatible stream of
+ your choosing) to which to write data. If the --out option is
+ specified in the arguments, the file it names is used in place of
+ this output stream."""
+ from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter
+ parser = ArgumentParser(
+ description='Digest cbor-tags.xml into code to insert in main.cpp',
+ formatter_class=ArgumentDefaultsHelpFormatter)
+ parser.add_argument('path', help='path of the cbor-tags.xml file',
+ default='cbor-tags.xml')
+ parser.add_argument('--out', help='file to write instead of standard output')
+ args = parser.parse_args(argv[1:])
+ emit = (open(args.out) if args.out else speak).write
+
+ title, records = readRegistry(args.path)
+ emit(f"""\
+struct CborTagDescription
+{{
+ QCborTag tag;
+ const char *description; // with space and parentheses
+}};
+
+// {title}
+static const CborTagDescription tagDescriptions[] = {{
+ // from https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml
+""")
+
+ for value, text in sorted(entries(records)):
+ prior = f' {{ QCborTag({value}),'
+ body = marginBound(f' ({text})', len(prior), 6, 96)
+ emit(f"{prior}{body} }},\n")
+
+ emit("""\
+ { QCborTag(-1), nullptr }
+};
+""")
+
+if __name__ == '__main__':
+ import sys
+ sys.exit(main(sys.argv, sys.stdout))
diff --git a/examples/corelib/serialization/cbordump/doc/images/cbordump.png b/examples/corelib/serialization/cbordump/doc/images/cbordump.png
new file mode 100644
index 0000000000..d5ff1da0bf
--- /dev/null
+++ b/examples/corelib/serialization/cbordump/doc/images/cbordump.png
Binary files differ
diff --git a/examples/corelib/serialization/cbordump/doc/src/cbordump.qdoc b/examples/corelib/serialization/cbordump/doc/src/cbordump.qdoc
new file mode 100644
index 0000000000..bfb19768d8
--- /dev/null
+++ b/examples/corelib/serialization/cbordump/doc/src/cbordump.qdoc
@@ -0,0 +1,55 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \example serialization/cbordump
+ \examplecategory {Input/Output}
+ \meta tag {network}
+ \title Parsing and displaying CBOR data
+
+ \brief A demonstration of how to parse files in CBOR format.
+
+ This example shows how to use the QCborStreamReader class directly to parse
+ CBOR content. The \c cbordump program reads content in CBOR format from
+ files or standard input and dumps the decoded content to stdout in a
+ human-readable format. It can output in CBOR diagnostic notation (which is
+ similar to JSON), or it can produce a verbose output where each byte input
+ is displayed with its encoding beside it.
+
+ \sa QCborStreamReader
+
+ \image cbordump.png
+
+ \section1 The CborDumper Class
+
+ The CborDumper class contains a QCborStreamReader object that is initialized
+ using the QFile object argument passed to the CborDumper constructor. Based
+ on the arguments the dump function calls either dumpOne() or
+ dumpOneDetailed() to dump the contents to standard output,
+
+ \snippet serialization/cbordump/main.cpp 0
+
+ \section2 The dumpOne() Function
+
+ Switching on QCborStreamReader::type() enables printing appropriate to the
+ type of the current value in the stream. If the type is an array or map, the
+ value's content is iterated over, and for each entry the dumpOne() function
+ is called recursively with a higher indentation argument. If the type is a
+ tag, it is printed out and dumpOne() is called once without increasing the
+ indentation argument.
+
+ \section2 The dumpOneDetailed() Function
+
+ This function dumps out both the incoming bytes and the decoded contents
+ on the same line. It uses lambda functions to print out the bytes and
+ decoded content, but otherwise has a similar structure as dumpOne().
+
+ \section1 CborTagDescription
+
+ The \c tagDescriptions table, describing the CBOR tags available, is
+ automatically generated from an XML file available from the iana.org
+ website. When \c dumpOneDetailed() reports a tag, it uses its description
+ from this table.
+
+ \sa {CBOR Support in Qt}
+*/
diff --git a/examples/corelib/serialization/cbordump/main.cpp b/examples/corelib/serialization/cbordump/main.cpp
index 126a5c5833..4c02abd304 100644
--- a/examples/corelib/serialization/cbordump/main.cpp
+++ b/examples/corelib/serialization/cbordump/main.cpp
@@ -17,7 +17,10 @@
/*
* To regenerate:
* curl -O https://www.iana.org/assignments/cbor-tags/cbor-tags.xml
- * xsltproc tag-transform.xslt cbor-tags.xml
+ * ./cbortag.py cbor-tags.xml
+ *
+ * The XHTML URL mentioned in the comment below is a human-readable version of
+ * the same resource.
*/
// GENERATED CODE
@@ -27,52 +30,101 @@ struct CborTagDescription
const char *description; // with space and parentheses
};
-// CBOR Tags
+// Concise Binary Object Representation (CBOR) Tags
static const CborTagDescription tagDescriptions[] = {
// from https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml
- { QCborTag(0), " (Standard date/time string; see Section 2.4.1 [RFC7049])" },
- { QCborTag(1), " (Epoch-based date/time; see Section 2.4.1 [RFC7049])" },
- { QCborTag(2), " (Positive bignum; see Section 2.4.2 [RFC7049])" },
- { QCborTag(3), " (Negative bignum; see Section 2.4.2 [RFC7049])" },
- { QCborTag(4), " (Decimal fraction; see Section 2.4.3 [RFC7049])" },
- { QCborTag(5), " (Bigfloat; see Section 2.4.3 [RFC7049])" },
- { QCborTag(16), " (COSE Single Recipient Encrypted Data Object [RFC8152])" },
- { QCborTag(17), " (COSE Mac w/o Recipients Object [RFC8152])" },
- { QCborTag(18), " (COSE Single Signer Data Object [RFC8152])" },
- { QCborTag(21), " (Expected conversion to base64url encoding; see Section 2.4.4.2 [RFC7049])" },
- { QCborTag(22), " (Expected conversion to base64 encoding; see Section 2.4.4.2 [RFC7049])" },
- { QCborTag(23), " (Expected conversion to base16 encoding; see Section 2.4.4.2 [RFC7049])" },
- { QCborTag(24), " (Encoded CBOR data item; see Section 2.4.4.1 [RFC7049])" },
+ { QCborTag(0), " (Standard date/time string; see Section 3.4.1 [RFC8949])" },
+ { QCborTag(1), " (Epoch-based date/time; see Section 3.4.2 [RFC8949])" },
+ { QCborTag(2), " (Positive bignum; see Section 3.4.3 [RFC8949])" },
+ { QCborTag(3), " (Negative bignum; see Section 3.4.3 [RFC8949])" },
+ { QCborTag(4), " (Decimal fraction; see Section 3.4.4 [RFC8949])" },
+ { QCborTag(5), " (Bigfloat; see Section 3.4.4 [RFC8949])" },
+ { QCborTag(16), " (COSE Single Recipient Encrypted Data Object [RFC9052])" },
+ { QCborTag(17), " (COSE Mac w/o Recipients Object [RFC9052])" },
+ { QCborTag(18), " (COSE Single Signer Data Object [RFC9052])" },
+ { QCborTag(19), " (COSE standalone V2 countersignature [RFC9338])" },
+ { QCborTag(21),
+ " (Expected conversion to base64url encoding; see Section 3.4.5.2 [RFC8949])" },
+ { QCborTag(22), " (Expected conversion to base64 encoding; see Section 3.4.5.2 [RFC8949])" },
+ { QCborTag(23), " (Expected conversion to base16 encoding; see Section 3.4.5.2 [RFC8949])" },
+ { QCborTag(24), " (Encoded CBOR data item; see Section 3.4.5.1 [RFC8949])" },
{ QCborTag(25), " (reference the nth previously seen string)" },
{ QCborTag(26), " (Serialised Perl object with classname and constructor arguments)" },
- { QCborTag(27), " (Serialised language-independent object with type name and constructor arguments)" },
+ { QCborTag(27),
+ " (Serialised language-independent object with type name and constructor arguments)" },
{ QCborTag(28), " (mark value as (potentially) shared)" },
{ QCborTag(29), " (reference nth marked value)" },
{ QCborTag(30), " (Rational number)" },
- { QCborTag(32), " (URI; see Section 2.4.4.3 [RFC7049])" },
- { QCborTag(33), " (base64url; see Section 2.4.4.3 [RFC7049])" },
- { QCborTag(34), " (base64; see Section 2.4.4.3 [RFC7049])" },
+ { QCborTag(31), " (Absent value in a CBOR Array)" },
+ { QCborTag(32), " (URI; see Section 3.4.5.3 [RFC8949])" },
+ { QCborTag(33), " (base64url; see Section 3.4.5.3 [RFC8949])" },
+ { QCborTag(34), " (base64; see Section 3.4.5.3 [RFC8949])" },
{ QCborTag(35), " (Regular expression; see Section 2.4.4.3 [RFC7049])" },
- { QCborTag(36), " (MIME message; see Section 2.4.4.3 [RFC7049])" },
- { QCborTag(37), " (Binary UUID ( section 4.1.2))" },
- { QCborTag(38), " (Language-tagged string)" },
+ { QCborTag(36), " (MIME message; see Section 3.4.5.3 [RFC8949])" },
+ { QCborTag(37), " (Binary UUID [RFC4122, Section 4.1.2])" },
+ { QCborTag(38), " (Language-tagged string [RFC9290, Appendix A])" },
{ QCborTag(39), " (Identifier)" },
- { QCborTag(61), " (CBOR Web Token (CWT))" },
- { QCborTag(96), " (COSE Encrypted Data Object [RFC8152])" },
- { QCborTag(97), " (COSE MACed Data Object [RFC8152])" },
- { QCborTag(98), " (COSE Signed Data Object [RFC8152])" },
- { QCborTag(256), " (mark value as having string references)" },
- { QCborTag(257), " (Binary MIME message)" },
- { QCborTag(258), " (Mathematical finite set)" },
- { QCborTag(260), " (Network Address (IPv4 or IPv6 or MAC Address))" },
- { QCborTag(264), " (Decimal fraction with arbitrary exponent)" },
- { QCborTag(265), " (Bigfloat with arbitrary exponent)" },
- { QCborTag(1001), " (extended time)" },
- { QCborTag(1002), " (duration)" },
- { QCborTag(1003), " (period)" },
- { QCborTag(22098), " (hint that indicates an additional level of indirection)" },
- { QCborTag(55799), " (Self-describe CBOR; see Section 2.4.5 [RFC7049])" },
- { QCborTag(15309736), " (RAINS Message)" },
+ { QCborTag(40), " (Multi-dimensional Array, row-major order [RFC8746])" },
+ { QCborTag(41), " (Homogeneous Array [RFC8746])" },
+ { QCborTag(42), " (IPLD content identifier)" },
+ { QCborTag(43), " (YANG bits datatype; see Section 6.7. [RFC9254])" },
+ { QCborTag(44), " (YANG enumeration datatype; see Section 6.6. [RFC9254])" },
+ { QCborTag(45), " (YANG identityref datatype; see Section 6.10. [RFC9254])" },
+ { QCborTag(46), " (YANG instance-identifier datatype; see Section 6.13. [RFC9254])" },
+ { QCborTag(47), " (YANG Schema Item iDentifier (sid); see Section 3.2. [RFC9254])" },
+ { QCborTag(52), " (IPv4, [prefixlen,IPv4], [IPv4,prefixpart] [RFC9164])" },
+ { QCborTag(54), " (IPv6, [prefixlen,IPv6], [IPv6,prefixpart] [RFC9164])" },
+ { QCborTag(61), " (CBOR Web Token (CWT) [RFC8392])" },
+ { QCborTag(63), " (Encoded CBOR Sequence [RFC8742])" },
+ { QCborTag(64), " (uint8 Typed Array [RFC8746])" },
+ { QCborTag(65), " (uint16, big endian, Typed Array [RFC8746])" },
+ { QCborTag(66), " (uint32, big endian, Typed Array [RFC8746])" },
+ { QCborTag(67), " (uint64, big endian, Typed Array [RFC8746])" },
+ { QCborTag(68), " (uint8 Typed Array, clamped arithmetic [RFC8746])" },
+ { QCborTag(69), " (uint16, little endian, Typed Array [RFC8746])" },
+ { QCborTag(70), " (uint32, little endian, Typed Array [RFC8746])" },
+ { QCborTag(71), " (uint64, little endian, Typed Array [RFC8746])" },
+ { QCborTag(72), " (sint8 Typed Array [RFC8746])" },
+ { QCborTag(73), " (sint16, big endian, Typed Array [RFC8746])" },
+ { QCborTag(74), " (sint32, big endian, Typed Array [RFC8746])" },
+ { QCborTag(75), " (sint64, big endian, Typed Array [RFC8746])" },
+ { QCborTag(76), " ((reserved) [RFC8746])" },
+ { QCborTag(77), " (sint16, little endian, Typed Array [RFC8746])" },
+ { QCborTag(78), " (sint32, little endian, Typed Array [RFC8746])" },
+ { QCborTag(79), " (sint64, little endian, Typed Array [RFC8746])" },
+ { QCborTag(80), " (IEEE 754 binary16, big endian, Typed Array [RFC8746])" },
+ { QCborTag(81), " (IEEE 754 binary32, big endian, Typed Array [RFC8746])" },
+ { QCborTag(82), " (IEEE 754 binary64, big endian, Typed Array [RFC8746])" },
+ { QCborTag(83), " (IEEE 754 binary128, big endian, Typed Array [RFC8746])" },
+ { QCborTag(84), " (IEEE 754 binary16, little endian, Typed Array [RFC8746])" },
+ { QCborTag(85), " (IEEE 754 binary32, little endian, Typed Array [RFC8746])" },
+ { QCborTag(86), " (IEEE 754 binary64, little endian, Typed Array [RFC8746])" },
+ { QCborTag(87), " (IEEE 754 binary128, little endian, Typed Array [RFC8746])" },
+ { QCborTag(96), " (COSE Encrypted Data Object [RFC9052])" },
+ { QCborTag(97), " (COSE MACed Data Object [RFC9052])" },
+ { QCborTag(98), " (COSE Signed Data Object [RFC9052])" },
+ { QCborTag(100), " (Number of days since the epoch date 1970-01-01 [RFC8943])" },
+ { QCborTag(101), " (alternatives as given by the uint + 128; see Section 9.1)" },
+ { QCborTag(103), " (Geographic Coordinates)" },
+ { QCborTag(104), " (Geographic Coordinate Reference System WKT or EPSG number)" },
+ { QCborTag(110), " (relative object identifier (BER encoding); SDNV sequence [RFC9090])" },
+ { QCborTag(111), " (object identifier (BER encoding) [RFC9090])" },
+ { QCborTag(112), " (object identifier (BER encoding), relative to 1.3.6.1.4.1 [RFC9090])" },
+ { QCborTag(120), " (Internet of Things Data Point)" },
+ { QCborTag(260),
+ " (Network Address (IPv4 or IPv6 or MAC Address) (DEPRECATED in favor of 52 and 54 for IP"
+ " addresses) [RFC9164])" },
+ { QCborTag(261),
+ " (Network Address Prefix (IPv4 or IPv6 Address + Mask Length) (DEPRECATED in favor of 52"
+ " and 54 for IP addresses) [RFC9164])" },
+ { QCborTag(271),
+ " (DDoS Open Threat Signaling (DOTS) signal channel object, as defined in [RFC9132])" },
+ { QCborTag(1004), " (full-date string [RFC8943])" },
+ { QCborTag(1040), " (Multi-dimensional Array, column-major order [RFC8746])" },
+ { QCborTag(55799), " (Self-described CBOR; see Section 3.4.6 [RFC8949])" },
+ { QCborTag(55800), " (indicates that the file contains CBOR Sequences [RFC9277])" },
+ { QCborTag(55801),
+ " (indicates that the file starts with a CBOR-Labeled Non-CBOR Data label. [RFC9277])" },
{ QCborTag(-1), nullptr }
};
// END GENERATED CODE
@@ -87,6 +139,7 @@ enum {
Value64Bit = 27
};
+//! [0]
struct CborDumper
{
enum DumpOption {
@@ -113,6 +166,7 @@ private:
qint64 offset = 0;
DumpOptions opts;
};
+//! [0]
Q_DECLARE_OPERATORS_FOR_FLAGS(CborDumper::DumpOptions)
static int cborNumberSize(quint64 value)
@@ -179,18 +233,19 @@ QCborError CborDumper::dump()
template <typename T> static inline bool canConvertTo(double v)
{
+ using TypeInfo = std::numeric_limits<T>;
// The [conv.fpint] (7.10 Floating-integral conversions) section of the
// standard says only exact conversions are guaranteed. Converting
// integrals to floating-point with loss of precision has implementation-
// defined behavior whether the next higher or next lower is returned;
// converting FP to integral is UB if it can't be represented.;
- static_assert(std::numeric_limits<T>::is_integer);
+ static_assert(TypeInfo::is_integer);
- double supremum = ldexp(1, std::numeric_limits<T>::digits);
+ double supremum = ldexp(1, TypeInfo::digits);
if (v >= supremum)
return false;
- if (v < std::numeric_limits<T>::min()) // either zero or a power of two, so it's exact
+ if (v < TypeInfo::min()) // either zero or a power of two, so it's exact
return false;
// we're in range
@@ -426,6 +481,7 @@ void CborDumper::dumpOneDetailed(int nestingLevel)
};
auto printString = [=](const char *descr) {
+ constexpr qsizetype ChunkSizeLimit = std::numeric_limits<int>::max();
QByteArray indent(nestingLevel * 2, ' ');
const char *chunkStr = (reader.isLengthKnown() ? "" : "chunk ");
int width = 48 - indent.size();
@@ -434,7 +490,7 @@ void CborDumper::dumpOneDetailed(int nestingLevel)
qsizetype size = reader.currentStringChunkSize();
if (size < 0)
return; // error
- if (size >= std::numeric_limits<int>::max()) {
+ if (size >= ChunkSizeLimit) {
fprintf(stderr, "String length too big, %lli\n", qint64(size));
exit(EXIT_FAILURE);
}
@@ -491,7 +547,7 @@ void CborDumper::dumpOneDetailed(int nestingLevel)
size = reader.currentStringChunkSize();
if (size < 0)
return; // error
- if (size >= std::numeric_limits<int>::max()) {
+ if (size >= ChunkSizeLimit) {
fprintf(stderr, "String length too big, %lli\n", qint64(size));
exit(EXIT_FAILURE);
}
@@ -701,7 +757,7 @@ int main(int argc, char *argv[])
QStringList files = parser.positionalArguments();
if (files.isEmpty())
files << "-";
- for (const QString &file : qAsConst(files)) {
+ for (const QString &file : std::as_const(files)) {
QFile f(file);
if (file == "-" ? f.open(stdin, QIODevice::ReadOnly) : f.open(QIODevice::ReadOnly)) {
if (files.size() > 1)
diff --git a/examples/corelib/serialization/cbordump/tag-transform.xslt b/examples/corelib/serialization/cbordump/tag-transform.xslt
deleted file mode 100644
index 3cc1b9b293..0000000000
--- a/examples/corelib/serialization/cbordump/tag-transform.xslt
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0"?>
-<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:a="http://www.iana.org/assignments" xmlns="http://www.iana.org/assignments" xmlns:_="http://www.iana.org/assignments" xmlns:DEFAULT="http://www.iana.org/assignments" version="1.0">
-<xsl:output omit-xml-declaration="yes" indent="no" method="text"/>
-<xsl:template match="/a:registry[@id='cbor-tags']">struct CborTagDescription
-{
- QCborTag tag;
- const char *description; // with space and parentheses
-};
-
-// <xsl:value-of select="a:registry/a:title"/>
-static const CborTagDescription tagDescriptions[] = {
- // from https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml
-<xsl:for-each select="a:registry/a:record">
- <xsl:sort select="a:value" data-type="number"/>
- <xsl:if test="a:semantics != ''">
- <xsl:call-template name="row"/>
- </xsl:if>
- </xsl:for-each> { QCborTag(-1), nullptr }
-};
-</xsl:template>
-<xsl:template name="row"> { QCborTag(<xsl:value-of select="a:value"/>), " (<xsl:value-of select="a:semantics"/> <xsl:call-template name="xref"/>)" },
-</xsl:template>
-<xsl:template name="xref"><xsl:if test="a:xref/@type = 'rfc'"> [<xsl:value-of select="translate(a:xref/@data,'rfc','RFC')"/>]</xsl:if>
-</xsl:template>
-</xsl:stylesheet>
diff --git a/examples/corelib/serialization/convert/CMakeLists.txt b/examples/corelib/serialization/convert/CMakeLists.txt
index b8476253e6..5a10a78a5a 100644
--- a/examples/corelib/serialization/convert/CMakeLists.txt
+++ b/examples/corelib/serialization/convert/CMakeLists.txt
@@ -1,8 +1,9 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(convert LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
@@ -11,6 +12,8 @@ set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/corelib/serialization/convert")
find_package(Qt6 REQUIRED COMPONENTS Core)
+qt_standard_project_setup()
+
qt_add_executable(convert
cborconverter.cpp cborconverter.h
converter.h
@@ -22,8 +25,8 @@ qt_add_executable(convert
xmlconverter.cpp xmlconverter.h
)
-target_link_libraries(convert PUBLIC
- Qt::Core
+target_link_libraries(convert PRIVATE
+ Qt6::Core
)
install(TARGETS convert
diff --git a/examples/corelib/serialization/convert/cborconverter.cpp b/examples/corelib/serialization/convert/cborconverter.cpp
index 0f49de2551..85ca8c12ed 100644
--- a/examples/corelib/serialization/convert/cborconverter.cpp
+++ b/examples/corelib/serialization/convert/cborconverter.cpp
@@ -19,7 +19,7 @@
static CborConverter cborConverter;
static CborDiagnosticDumper cborDiagnosticDumper;
-static const char optionHelp[] =
+static const char cborOptionHelp[] =
"convert-float-to-int=yes|no Write integers instead of floating point, if no\n"
" loss of precision occurs on conversion.\n"
"float16=yes|always|no Write using half-precision floating point.\n"
@@ -57,6 +57,7 @@ QT_END_NAMESPACE
static QVariant convertCborValue(const QCborValue &value);
+//! [0]
static QVariant convertCborMap(const QCborMap &map)
{
VariantOrderedMap result;
@@ -83,8 +84,9 @@ static QVariant convertCborValue(const QCborValue &value)
return convertCborMap(value.toMap());
return value.toVariant();
}
-
+//! [0]
enum TrimFloatingPoint { Double, Float, Float16 };
+//! [1]
static QCborValue convertFromVariant(const QVariant &v, TrimFloatingPoint fpTrimming)
{
if (v.userType() == QMetaType::QVariantList) {
@@ -114,6 +116,7 @@ static QCborValue convertFromVariant(const QVariant &v, TrimFloatingPoint fpTrim
return QCborValue::fromVariant(v);
}
+//! [1]
QString CborDiagnosticDumper::name()
{
@@ -204,7 +207,7 @@ Converter::Options CborConverter::outputOptions()
const char *CborConverter::optionsHelp()
{
- return optionHelp;
+ return cborOptionHelp;
}
bool CborConverter::probeFile(QIODevice *f)
@@ -216,6 +219,7 @@ bool CborConverter::probeFile(QIODevice *f)
return f->isReadable() && f->peek(3) == QByteArray("\xd9\xd9\xf7", 3);
}
+//! [2]
QVariant CborConverter::loadFile(QIODevice *f, Converter *&outputConverter)
{
const char *ptr = nullptr;
@@ -250,9 +254,11 @@ QVariant CborConverter::loadFile(QIODevice *f, Converter *&outputConverter)
return contents.toVariant();
return convertCborValue(contents);
}
-
+//! [2]
+//! [3]
void CborConverter::saveFile(QIODevice *f, const QVariant &contents, const QStringList &options)
{
+ //! [3]
bool useSignature = true;
bool useIntegers = true;
enum { Yes, No, Always } useFloat16 = Yes, useFloat = Yes;
@@ -308,10 +314,10 @@ void CborConverter::saveFile(QIODevice *f, const QVariant &contents, const QStri
}
fprintf(stderr, "Unknown CBOR format option '%s'. Valid options are:\n%s",
- qPrintable(s), optionHelp);
+ qPrintable(s), cborOptionHelp);
exit(EXIT_FAILURE);
}
-
+ //! [4]
QCborValue v = convertFromVariant(contents,
useFloat16 == Always ? Float16 : useFloat == Always ? Float : Double);
QCborStreamWriter writer(f);
@@ -327,4 +333,4 @@ void CborConverter::saveFile(QIODevice *f, const QVariant &contents, const QStri
opts |= QCborValue::UseFloat16;
v.toCbor(writer, opts);
}
-
+//! [4]
diff --git a/examples/corelib/serialization/convert/datastreamconverter.cpp b/examples/corelib/serialization/convert/datastreamconverter.cpp
index 9322d97fef..451688e378 100644
--- a/examples/corelib/serialization/convert/datastreamconverter.cpp
+++ b/examples/corelib/serialization/convert/datastreamconverter.cpp
@@ -7,7 +7,7 @@
#include <QDebug>
#include <QTextStream>
-static const char optionHelp[] =
+static const char dataStreamOptionHelp[] =
"byteorder=host|big|little Byte order to use.\n"
"version=<n> QDataStream version (default: Qt 5.0).\n"
;
@@ -143,7 +143,7 @@ Converter::Options DataStreamConverter::outputOptions()
const char *DataStreamConverter::optionsHelp()
{
- return optionHelp;
+ return dataStreamOptionHelp;
}
bool DataStreamConverter::probeFile(QIODevice *f)
@@ -209,7 +209,7 @@ void DataStreamConverter::saveFile(QIODevice *f, const QVariant &contents, const
}
fprintf(stderr, "Unknown QDataStream formatting option '%s'. Available options are:\n%s",
- qPrintable(option), optionHelp);
+ qPrintable(option), dataStreamOptionHelp);
exit(EXIT_FAILURE);
}
diff --git a/examples/corelib/serialization/convert/doc/images/convert.png b/examples/corelib/serialization/convert/doc/images/convert.png
new file mode 100644
index 0000000000..8d6816a626
--- /dev/null
+++ b/examples/corelib/serialization/convert/doc/images/convert.png
Binary files differ
diff --git a/examples/corelib/serialization/convert/doc/src/convert.qdoc b/examples/corelib/serialization/convert/doc/src/convert.qdoc
new file mode 100644
index 0000000000..7baef83de2
--- /dev/null
+++ b/examples/corelib/serialization/convert/doc/src/convert.qdoc
@@ -0,0 +1,82 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \example serialization/convert
+ \examplecategory {Input/Output}
+ \meta tag {network}
+ \title Convert Example
+
+ \brief The Convert example demonstrates how to convert between different
+ serialization formats.
+
+ The Convert example converts between the serialization formats JSON, CBOR,
+ XML, QDataStream and text. It can also auto detect the format being used.
+ Not all formats support both input and output, and they have different
+ sets of which types they support. QDataStream and XML are the richest,
+ followed by CBOR, then JSON, and then the plain text one.
+
+ \image convert.png
+
+ \section1 The Converter Class
+
+ The Converter class is the abstract superclass for all the converters to
+ and from all the formats. They all convert to and from the QVariant class,
+ which is used to represent all the datastructures internally.
+ The name() function returns the name of the converter. The directions()
+ function is used to determine if a converter can be used for input, output,
+ or both. The outputOptions() and optionsHelp() functions are used to get
+ and query which options are used by the different converters. The
+ probeFile() function is used to determine if a file has the same file
+ format as the converter. The loadFile() function deserializes the given
+ file, while the saveFile() serializes to the given file.
+
+ \section1 The CborConverter Class
+
+ The CborConverter class shows how to serialize to and from the CBOR-format.
+ There is also a CborDiagnosticDumper class to output in CBOR diagnostic
+ notation. That is similar to JSON, but not exactly, because it allows
+ displaying the contents of a CBOR stream losslessly, while a conversion
+ to JSON is lossy.
+
+ The convertCborValue() function is used to convert a QCborValue to a
+ QVariant. It uses the helper functions convertCborMap() and
+ convertCborArray().
+ \snippet serialization/convert/cborconverter.cpp 0
+
+ A CBOR-file is read using loadFile() function.
+ \snippet serialization/convert/cborconverter.cpp 2
+
+ The convertFromVariant() function is used to convert a QVariant to a
+ QCborValue.
+ \snippet serialization/convert/cborconverter.cpp 1
+
+ A CBOR-file is written using the saveFile() function.
+ \snippet serialization/convert/cborconverter.cpp 3
+ \snippet serialization/convert/cborconverter.cpp 4
+
+ \sa {CBOR Support in Qt}
+
+ \section1 The DataStreamConverter Class
+
+ The DataStreamConverter class is used to serialize to and from the
+ QDataStream format. There is also the DataStreamDumper class for outputting
+ the data lossless in a non-standardized human readable format.
+
+ \section1 The JsonConverter Class
+
+ The JsonConverter class is used to serialize to and from the JSON-format.
+ \sa {JSON Support in Qt}
+
+ \section1 The XmlConverter Class
+
+ The XmlConverter class is used to serialize to and from the XML-format.
+
+ \section1 The TextConverter Class
+
+ The TextConverter class is used to serialize to and from a text format.
+
+ \section1 The NullConverter Class
+
+ The NullConverter class is an output serializer that does nothing.
+*/
diff --git a/examples/corelib/serialization/convert/jsonconverter.cpp b/examples/corelib/serialization/convert/jsonconverter.cpp
index 26f48661a9..f52c9db554 100644
--- a/examples/corelib/serialization/convert/jsonconverter.cpp
+++ b/examples/corelib/serialization/convert/jsonconverter.cpp
@@ -11,7 +11,7 @@
static JsonConverter jsonConverter;
-static const char optionHelp[] =
+static const char jsonOptionHelp[] =
"compact=no|yes Use compact JSON form.\n";
static QJsonDocument convertFromVariant(const QVariant &v)
@@ -45,7 +45,7 @@ Converter::Options JsonConverter::outputOptions()
const char *JsonConverter::optionsHelp()
{
- return optionHelp;
+ return jsonOptionHelp;
}
bool JsonConverter::probeFile(QIODevice *f)
@@ -96,7 +96,8 @@ void JsonConverter::saveFile(QIODevice *f, const QVariant &contents, const QStri
} else if (s == QLatin1String("compact=yes")) {
format = QJsonDocument::Compact;
} else {
- fprintf(stderr, "Unknown option '%s' to JSON output. Valid options are:\n%s", qPrintable(s), optionHelp);
+ fprintf(stderr, "Unknown option '%s' to JSON output. Valid options are:\n%s",
+ qPrintable(s), jsonOptionHelp);
exit(EXIT_FAILURE);
}
}
diff --git a/examples/corelib/serialization/convert/main.cpp b/examples/corelib/serialization/convert/main.cpp
index c234a28f1b..00c626e1c8 100644
--- a/examples/corelib/serialization/convert/main.cpp
+++ b/examples/corelib/serialization/convert/main.cpp
@@ -31,7 +31,7 @@ int main(int argc, char *argv[])
QStringList inputFormats;
QStringList outputFormats;
- for (Converter *conv : qAsConst(*availableConverters)) {
+ for (Converter *conv : std::as_const(*availableConverters)) {
auto direction = conv->directions();
QString name = conv->name();
if (direction & Converter::In)
@@ -82,7 +82,7 @@ int main(int argc, char *argv[])
if (parser.isSet(formatOptionsOption)) {
QString format = parser.value(formatOptionsOption);
- for (Converter *conv : qAsConst(*availableConverters)) {
+ for (Converter *conv : std::as_const(*availableConverters)) {
if (conv->name() == format) {
const char *help = conv->optionsHelp();
if (help)
@@ -100,7 +100,7 @@ int main(int argc, char *argv[])
Converter *inconv = nullptr;
QString format = parser.value(inputFormatOption);
if (format != "auto") {
- for (Converter *conv : qAsConst(*availableConverters)) {
+ for (Converter *conv : std::as_const(*availableConverters)) {
if (conv->name() == format) {
inconv = conv;
break;
@@ -116,7 +116,7 @@ int main(int argc, char *argv[])
Converter *outconv = nullptr;
format = parser.value(outputFormatOption);
if (format != "auto") {
- for (Converter *conv : qAsConst(*availableConverters)) {
+ for (Converter *conv : std::as_const(*availableConverters)) {
if (conv->name() == format) {
outconv = conv;
break;
@@ -155,7 +155,7 @@ int main(int argc, char *argv[])
if (!inconv) {
// probe the input to find a file format
- for (Converter *conv : qAsConst(*availableConverters)) {
+ for (Converter *conv : std::as_const(*availableConverters)) {
if (conv->directions() & Converter::In && conv->probeFile(&input)) {
inconv = conv;
break;
@@ -170,7 +170,7 @@ int main(int argc, char *argv[])
if (!outconv) {
// probe the output to find a file format
- for (Converter *conv : qAsConst(*availableConverters)) {
+ for (Converter *conv : std::as_const(*availableConverters)) {
if (conv->directions() & Converter::Out && conv->probeFile(&output)) {
outconv = conv;
break;
diff --git a/examples/corelib/serialization/convert/xmlconverter.cpp b/examples/corelib/serialization/convert/xmlconverter.cpp
index d4a11257c6..080528f678 100644
--- a/examples/corelib/serialization/convert/xmlconverter.cpp
+++ b/examples/corelib/serialization/convert/xmlconverter.cpp
@@ -13,7 +13,7 @@
#include <QXmlStreamReader>
#include <QXmlStreamWriter>
-static const char optionHelp[] =
+static const char xmlOptionHelp[] =
"compact=no|yes Use compact XML form.\n";
static XmlConverter xmlConverter;
@@ -416,7 +416,7 @@ Converter::Options XmlConverter::outputOptions()
const char *XmlConverter::optionsHelp()
{
- return optionHelp;
+ return xmlOptionHelp;
}
bool XmlConverter::probeFile(QIODevice *f)
@@ -454,7 +454,8 @@ void XmlConverter::saveFile(QIODevice *f, const QVariant &contents, const QStrin
} else if (s == QLatin1String("compact=yes")) {
compact = true;
} else {
- fprintf(stderr, "Unknown option '%s' to XML output. Valid options are:\n%s", qPrintable(s), optionHelp);
+ fprintf(stderr, "Unknown option '%s' to XML output. Valid options are:\n%s",
+ qPrintable(s), xmlOptionHelp);
exit(EXIT_FAILURE);
}
}
diff --git a/examples/xml/rsslisting/CMakeLists.txt b/examples/corelib/serialization/rsslisting/CMakeLists.txt
index eef679069c..405a01ce56 100644
--- a/examples/xml/rsslisting/CMakeLists.txt
+++ b/examples/corelib/serialization/rsslisting/CMakeLists.txt
@@ -1,15 +1,18 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(rsslisting LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/xml/rsslisting")
+set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/corelib/serialization/rsslisting")
+
+find_package(Qt6 REQUIRED COMPONENTS Core Gui Network Widgets)
-find_package(Qt6 REQUIRED COMPONENTS Core Gui Network Widgets Xml)
+qt_standard_project_setup()
qt_add_executable(rsslisting
main.cpp
@@ -21,12 +24,11 @@ set_target_properties(rsslisting PROPERTIES
MACOSX_BUNDLE TRUE
)
-target_link_libraries(rsslisting PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Network
- Qt::Widgets
- Qt::Xml
+target_link_libraries(rsslisting PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Network
+ Qt6::Widgets
)
install(TARGETS rsslisting
diff --git a/examples/corelib/serialization/rsslisting/doc/images/rsslisting.png b/examples/corelib/serialization/rsslisting/doc/images/rsslisting.png
new file mode 100644
index 0000000000..0b05375f93
--- /dev/null
+++ b/examples/corelib/serialization/rsslisting/doc/images/rsslisting.png
Binary files differ
diff --git a/examples/corelib/serialization/rsslisting/doc/src/rsslisting.qdoc b/examples/corelib/serialization/rsslisting/doc/src/rsslisting.qdoc
new file mode 100644
index 0000000000..b86fab1e1b
--- /dev/null
+++ b/examples/corelib/serialization/rsslisting/doc/src/rsslisting.qdoc
@@ -0,0 +1,129 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \example serialization/rsslisting
+ \examplecategory {Networking}
+ \meta tag {serialization}
+ \title A minimal RSS listing application
+
+ \brief A demonstration of how to fetch and display a network resource.
+
+ This example shows how to fetch a resource the user has requested and
+ display data contained in the response, illustrated by an RSS listing
+ application. (RDF Site Summary, or Really Simple Syndication, is a standard
+ format for communicating updates to web sites. See
+ https://www.rssboard.org/rss-specification for details.) The user inferface
+ in the illustration is simple, as the focus of this example is on how to use
+ networking, but naturally a more sophisticated interface would be wanted for
+ a serious RSS reader.
+
+ The example also illustrates how to do asynchronous parsing of data as it is
+ received, preserving state in member variables so that an incremental parser
+ can consume chunks of data as they arrive over the network. Constituents of
+ the parsed content may start in one chunk of data but not be completed until
+ a later chunk, requiring the parser to retain state between calls.
+
+ \image rsslisting.cpp
+
+ The main program is fairly minimal. It simply instantiates a \l QApplication
+ and the \c RSSListing widget, shows the latter and hands over control to the
+ former. For the sake of illustration, it gives the widget the Qt blog's URL
+ as default value for the resource to check.
+
+ \snippet serialization/rsslisting/main.cpp 0
+
+ \section1 The RSSListing class
+
+ \snippet serialization/rsslisting/rsslisting.h 0
+
+ The widget itself provides a simple user interface for specifying the URL to
+ fetch and, once available updates are displayed, controlling the downloading
+ of updated items. A \l QLineEdit provides for input of the URL, and a
+ \l QTreeWidget for display of the results once fetched.
+
+ The widget downloads and parses the RSS (a form of XML) asynchronously,
+ feeding the data to an XML reader as it arrives. This supports reading of
+ very large data sources. Because the data is streamed from the network
+ through the XML reader, there is no need to retain the full text of the XML
+ in memory. In other context, a similar approach can allow the user to
+ interrupt such incremental loading.
+
+ \section2 Construction
+
+ \snippet serialization/rsslisting/rsslisting.cpp setup
+
+ The constructor sets up the assorted components of the widget and connects
+ their various signals to the slots it shall use to handle them.
+
+ The user interface consists of a line edit, a push button, and a list view
+ widget. The line edit is used for entering the URL to fetch; the push button
+ starts the process of fetching updates. The line edit is empty by default,
+ but the constructor's caller can override that, as our \c main() has done.
+ In any case, the user can replace the default with the URL of another RSS
+ feed.
+
+ The list view shows the updated items reported in the RSS feed.
+ Double-clicking on one of these sends its URL to the user's browser or other
+ user agent using \l QDesktopServices::openUrl().
+
+ \section2 The slots
+
+ \snippet serialization/rsslisting/rsslisting.cpp slots
+
+ All slots are kept simple by delegating any hard work to private methods.
+
+ When the user completes input of a URL, either by clicking the "Fetch"
+ button or by pressing the return key in the line edit, the \c fetch() slot
+ disables the "Fetch" button and disables further editing of the line edit.
+ It clears the display of available updates and delegates to \c get() the
+ initiating of an HTTP GET request.
+
+ When data is received, the network reply triggers its \l {QNetworkReply::}
+ {readyRead()} signal, which \c get() connects to the \c consumeData()
+ slot. This checks the response got a successful status code and, if it did,
+ calls \c parseXml() to consume the data.
+
+ If the network reply gets an error, this is delivered to the \c error()
+ slot, which reports the error, clears the XML stream reader then disconnects
+ from the reply and deletes it.
+
+ On completion (whether successful or otherwise) of a network reply, the \c
+ finished() slot restores the UI to be ready to accept a new URL to fetch by
+ re-enabling the line edit and "Fetch" button.
+
+ \section2 The get() method
+
+ \snippet serialization/rsslisting/rsslisting.cpp get
+
+ The private \c get() method is used by the \c fetch() slot to initiate an
+ HTTP GET request. It first clears the XML stream reader and, if a reply is
+ currently active, disconnects and deletes it. If the URL it has been passed
+ is valid, it asks the network access manager to GET it. It connects its
+ relevant slots to signals of the resulting reply (if any) and sets up its
+ XML stream reader to read data from the reply - a network reply object is
+ also a \c QIODevice, from which data can be read.
+
+ \section2 The parseXml() method
+
+ \snippet serialization/rsslisting/rsslisting.cpp parse
+
+ When data is received, and thus made available to the XML stream reader, \c
+ parseXml() reads from the XML stream, checking for \c item elements and,
+ within them, \c title and \c link elements. It will use the \c{rss:about}
+ attribute of an \c item as URL in the Link column of the tree-view, failing
+ that the content of its \c link element; and it uses the content of the \c
+ title element in the Title column of the tree-view. As each \c item element
+ closes, its details are turned into a new row in the tree widget, with the
+ extracted title and URL in the Title and Link columns.
+
+ The variables that keep track of the parsing state - \c linkString, \c
+ titleString and \c currentTag - are member variables of the \c RSSListing
+ class, even though they are only accessed from this method, because this
+ method may be called repeatedly, as new data arrives, and one chunk of
+ received data may start an element that isn't completed until a later chunk
+ arrives. This enables the parser to operate asynchronously as the data
+ arrives, instead of having to wait until all the data has arrived.
+
+ \sa QNetworkReply, QXmlStreamReader
+*/
diff --git a/examples/widgets/tools/undo/main.cpp b/examples/corelib/serialization/rsslisting/main.cpp
index ce28152f75..7a64db8a0c 100644
--- a/examples/widgets/tools/undo/main.cpp
+++ b/examples/corelib/serialization/rsslisting/main.cpp
@@ -1,18 +1,16 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-#include <QApplication>
-#include "mainwindow.h"
+#include "rsslisting.h"
+#include <QtWidgets>
+using namespace Qt::StringLiterals;
+//! [0]
int main(int argc, char **argv)
{
- Q_INIT_RESOURCE(undo);
-
QApplication app(argc, argv);
-
- MainWindow win;
- win.resize(800, 600);
- win.show();
-
+ RSSListing rsslisting(u"https://www.qt.io/blog/rss.xml"_s);
+ rsslisting.show();
return app.exec();
}
+//! [0]
diff --git a/examples/corelib/serialization/rsslisting/rsslisting.cpp b/examples/corelib/serialization/rsslisting/rsslisting.cpp
new file mode 100644
index 0000000000..ed7c163c76
--- /dev/null
+++ b/examples/corelib/serialization/rsslisting/rsslisting.cpp
@@ -0,0 +1,126 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "rsslisting.h"
+
+#include <QtCore>
+#include <QtWidgets>
+#include <QtNetwork>
+
+//! [setup]
+RSSListing::RSSListing(const QString &url, QWidget *parent)
+ : QWidget(parent), currentReply(0)
+{
+ connect(&manager, &QNetworkAccessManager::finished, this, &RSSListing::finished);
+
+ lineEdit = new QLineEdit(this);
+ lineEdit->setText(url);
+ connect(lineEdit, &QLineEdit::returnPressed, this, &RSSListing::fetch);
+
+ fetchButton = new QPushButton(tr("Fetch"), this);
+ connect(fetchButton, &QPushButton::clicked, this, &RSSListing::fetch);
+
+ treeWidget = new QTreeWidget(this);
+ connect(treeWidget, &QTreeWidget::itemActivated,
+ // Open the link in the browser:
+ this, [](QTreeWidgetItem *item) { QDesktopServices::openUrl(QUrl(item->text(1))); });
+ treeWidget->setHeaderLabels(QStringList { tr("Title"), tr("Link") });
+ treeWidget->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
+
+ QHBoxLayout *hboxLayout = new QHBoxLayout;
+ hboxLayout->addWidget(lineEdit);
+ hboxLayout->addWidget(fetchButton);
+
+ QVBoxLayout *layout = new QVBoxLayout(this);
+ layout->addLayout(hboxLayout);
+ layout->addWidget(treeWidget);
+
+ setWindowTitle(tr("RSS listing example"));
+ resize(640, 480);
+}
+//! [setup]
+
+//! [slots]
+void RSSListing::fetch()
+{
+ lineEdit->setReadOnly(true);
+ fetchButton->setEnabled(false);
+ treeWidget->clear();
+
+ get(QUrl(lineEdit->text()));
+}
+
+void RSSListing::consumeData()
+{
+ int statusCode = currentReply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
+ if (statusCode >= 200 && statusCode < 300)
+ parseXml();
+}
+
+void RSSListing::error(QNetworkReply::NetworkError)
+{
+ qWarning("error retrieving RSS feed");
+ xml.clear();
+ currentReply->disconnect(this);
+ currentReply->deleteLater();
+ currentReply = nullptr;
+}
+
+void RSSListing::finished(QNetworkReply *reply)
+{
+ Q_UNUSED(reply);
+ lineEdit->setReadOnly(false);
+ fetchButton->setEnabled(true);
+}
+//! [slots]
+
+// Private methods
+
+//! [get]
+void RSSListing::get(const QUrl &url)
+{
+ if (currentReply) {
+ currentReply->disconnect(this);
+ currentReply->deleteLater();
+ }
+ currentReply = url.isValid() ? manager.get(QNetworkRequest(url)) : nullptr;
+ if (currentReply) {
+ connect(currentReply, &QNetworkReply::readyRead, this, &RSSListing::consumeData);
+ connect(currentReply, &QNetworkReply::errorOccurred, this, &RSSListing::error);
+
+ }
+ xml.setDevice(currentReply); // Equivalent to clear() if currentReply is null.
+}
+//! [get]
+
+// TODO: this is a candidate for showing how to use coroutines, once available.
+//! [parse]
+void RSSListing::parseXml()
+{
+ while (!xml.atEnd()) {
+ xml.readNext();
+ if (xml.isStartElement()) {
+ if (xml.name() == u"item") {
+ linkString = xml.attributes().value("rss:about").toString();
+ titleString.clear();
+ }
+ currentTag = xml.name().toString();
+ } else if (xml.isEndElement()) {
+ if (xml.name() == u"item") {
+
+ QTreeWidgetItem *item = new QTreeWidgetItem;
+ item->setText(0, titleString);
+ item->setText(1, linkString);
+ treeWidget->addTopLevelItem(item);
+ }
+ } else if (xml.isCharacters() && !xml.isWhitespace()) {
+ if (currentTag == "title")
+ titleString += xml.text();
+ else if (currentTag == "link")
+ linkString += xml.text();
+ }
+ }
+ if (xml.error() && xml.error() != QXmlStreamReader::PrematureEndOfDocumentError)
+ qWarning() << "XML ERROR:" << xml.lineNumber() << ": " << xml.errorString();
+}
+//! [parse]
diff --git a/examples/xml/rsslisting/rsslisting.h b/examples/corelib/serialization/rsslisting/rsslisting.h
index 81c655f677..499bc5d1d4 100644
--- a/examples/xml/rsslisting/rsslisting.h
+++ b/examples/corelib/serialization/rsslisting/rsslisting.h
@@ -7,49 +7,48 @@
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QWidget>
-#include <QBuffer>
#include <QXmlStreamReader>
-#include <QUrl>
-
QT_BEGIN_NAMESPACE
class QLineEdit;
+class QPushButton;
class QTreeWidget;
class QTreeWidgetItem;
-class QPushButton;
+class QUrl;
QT_END_NAMESPACE
+//! [0]
class RSSListing : public QWidget
{
Q_OBJECT
public:
- RSSListing(QWidget *widget = nullptr);
+ explicit RSSListing(const QString &url = QString(), QWidget *widget = nullptr);
public slots:
void fetch();
void finished(QNetworkReply *reply);
- void readyRead();
- void metaDataChanged();
- void itemActivated(QTreeWidgetItem * item);
+ void consumeData();
void error(QNetworkReply::NetworkError);
private:
void parseXml();
void get(const QUrl &url);
+ // Parser state:
QXmlStreamReader xml;
QString currentTag;
QString linkString;
QString titleString;
+ // Network state:
QNetworkAccessManager manager;
QNetworkReply *currentReply;
+ // UI elements:
QLineEdit *lineEdit;
QTreeWidget *treeWidget;
QPushButton *fetchButton;
-
};
+//! [0]
#endif
-
diff --git a/examples/xml/rsslisting/rsslisting.pro b/examples/corelib/serialization/rsslisting/rsslisting.pro
index b6a00aa0c6..7619755b8f 100644
--- a/examples/xml/rsslisting/rsslisting.pro
+++ b/examples/corelib/serialization/rsslisting/rsslisting.pro
@@ -1,8 +1,8 @@
HEADERS += rsslisting.h
SOURCES += main.cpp rsslisting.cpp
-QT += network xml widgets
+QT += network widgets
requires(qtConfig(treewidget))
# install
-target.path = $$[QT_INSTALL_EXAMPLES]/xml/rsslisting
+target.path = $$[QT_INSTALL_EXAMPLES]/corelib/serialization/rsslisting
INSTALLS += target
diff --git a/examples/corelib/serialization/savegame/CMakeLists.txt b/examples/corelib/serialization/savegame/CMakeLists.txt
index f757d1359b..8871a9d687 100644
--- a/examples/corelib/serialization/savegame/CMakeLists.txt
+++ b/examples/corelib/serialization/savegame/CMakeLists.txt
@@ -1,8 +1,9 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(savegame LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
@@ -11,6 +12,8 @@ set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/corelib/serialization/savegame")
find_package(Qt6 REQUIRED COMPONENTS Core)
+qt_standard_project_setup()
+
qt_add_executable(savegame
character.cpp character.h
game.cpp game.h
@@ -18,8 +21,8 @@ qt_add_executable(savegame
main.cpp
)
-target_link_libraries(savegame PUBLIC
- Qt::Core
+target_link_libraries(savegame PRIVATE
+ Qt6::Core
)
install(TARGETS savegame
diff --git a/examples/corelib/serialization/savegame/character.cpp b/examples/corelib/serialization/savegame/character.cpp
index 43be084d3e..039aa1fa94 100644
--- a/examples/corelib/serialization/savegame/character.cpp
+++ b/examples/corelib/serialization/savegame/character.cpp
@@ -6,10 +6,8 @@
#include <QMetaEnum>
#include <QTextStream>
-Character::Character() :
- mLevel(0),
- mClassType(Warrior) {
-}
+Character::Character()
+ = default;
Character::Character(const QString &name,
int level,
@@ -50,35 +48,41 @@ void Character::setClassType(Character::ClassType classType)
mClassType = classType;
}
-//! [0]
-void Character::read(const QJsonObject &json)
+//! [fromJson]
+Character Character::fromJson(const QJsonObject &json)
{
- if (json.contains("name") && json["name"].isString())
- mName = json["name"].toString();
+ Character result;
+
+ if (const QJsonValue v = json["name"]; v.isString())
+ result.mName = v.toString();
+
+ if (const QJsonValue v = json["level"]; v.isDouble())
+ result.mLevel = v.toInt();
- if (json.contains("level") && json["level"].isDouble())
- mLevel = json["level"].toInt();
+ if (const QJsonValue v = json["classType"]; v.isDouble())
+ result.mClassType = ClassType(v.toInt());
- if (json.contains("classType") && json["classType"].isDouble())
- mClassType = ClassType(json["classType"].toInt());
+ return result;
}
-//! [0]
+//! [fromJson]
-//! [1]
-void Character::write(QJsonObject &json) const
+//! [toJson]
+QJsonObject Character::toJson() const
{
+ QJsonObject json;
json["name"] = mName;
json["level"] = mLevel;
json["classType"] = mClassType;
+ return json;
}
-//! [1]
+//! [toJson]
-void Character::print(int indentation) const
+void Character::print(QTextStream &s, int indentation) const
{
const QString indent(indentation * 2, ' ');
- QTextStream(stdout) << indent << "Name:\t" << mName << "\n";
- QTextStream(stdout) << indent << "Level:\t" << mLevel << "\n";
+ const QString className = QMetaEnum::fromType<ClassType>().valueToKey(mClassType);
- QString className = QMetaEnum::fromType<ClassType>().valueToKey(mClassType);
- QTextStream(stdout) << indent << "Class:\t" << className << "\n";
+ s << indent << "Name:\t" << mName << "\n"
+ << indent << "Level:\t" << mLevel << "\n"
+ << indent << "Class:\t" << className << "\n";
}
diff --git a/examples/corelib/serialization/savegame/character.h b/examples/corelib/serialization/savegame/character.h
index dfb3837331..cffa5fa659 100644
--- a/examples/corelib/serialization/savegame/character.h
+++ b/examples/corelib/serialization/savegame/character.h
@@ -8,10 +8,12 @@
#include <QObject>
#include <QString>
+QT_FORWARD_DECLARE_CLASS(QTextStream)
+
//! [0]
class Character
{
- Q_GADGET;
+ Q_GADGET
public:
enum ClassType {
@@ -31,14 +33,14 @@ public:
ClassType classType() const;
void setClassType(ClassType classType);
- void read(const QJsonObject &json);
- void write(QJsonObject &json) const;
+ static Character fromJson(const QJsonObject &json);
+ QJsonObject toJson() const;
- void print(int indentation = 0) const;
+ void print(QTextStream &s, int indentation = 0) const;
private:
QString mName;
- int mLevel;
- ClassType mClassType;
+ int mLevel = 0;
+ ClassType mClassType = Warrior;
};
//! [0]
diff --git a/examples/corelib/serialization/savegame/doc/src/savegame.qdoc b/examples/corelib/serialization/savegame/doc/src/savegame.qdoc
index 0246ae48bb..37a461d7bd 100644
--- a/examples/corelib/serialization/savegame/doc/src/savegame.qdoc
+++ b/examples/corelib/serialization/savegame/doc/src/savegame.qdoc
@@ -3,6 +3,7 @@
/*!
\example serialization/savegame
+ \examplecategory {Input/Output}
\title JSON Save Game Example
\brief The JSON Save Game example demonstrates how to save and load a
@@ -10,11 +11,12 @@
Many games provide save functionality, so that the player's progress through
the game can be saved and loaded at a later time. The process of saving a
- game generally involves serializing each game object's member variables
- to a file. Many formats can be used for this purpose, one of which is JSON.
- With QJsonDocument, you also have the ability to serialize a document in a
- \l {RFC 7049} {CBOR} format, which is great if you
- don't want the save file to be readable, or if you need to keep the file size down.
+ game generally involves serializing each game object's member variables to a
+ file. Many formats can be used for this purpose, one of which is JSON. With
+ QJsonDocument, you also have the ability to serialize a document in a \l
+ {RFC 7049} {CBOR} format, which is great if you don't want the save file to
+ be easy to read (but see \l {Parsing and displaying CBOR data} for how it \e
+ can be read), or if you need to keep the file size down.
In this example, we'll demonstrate how to save and load a simple game to
and from JSON and binary formats.
@@ -24,45 +26,83 @@
The Character class represents a non-player character (NPC) in our game, and
stores the player's name, level, and class type.
- It provides read() and write() functions to serialise its member variables.
+ It provides static fromJson() and non-static toJson() functions to
+ serialise itself.
+
+ \note This pattern (fromJson()/toJson()) works because QJsonObjects can be
+ constructed independent of an owning QJsonDocument, and because the data
+ types being (de)serialized here are value types, so can be copied. When
+ serializing to another format — for example XML or QDataStream, which require passing
+ a document-like object — or when the object identity is important (QObject
+ subclasses, for example), other patterns may be more suitable. See the
+ \l{dombookmarks} example for XML, and the implementation of
+ \l QListWidgetItem::read() and \l QListWidgetItem::write()
+ for idiomatic QDataStream serialization. The \c{print()} functions in this example
+ are good examples of QTextStream serialization, even though they, of course, lack
+ the deserialization side.
\snippet serialization/savegame/character.h 0
- Of particular interest to us are the read and write function
+ Of particular interest to us are the fromJson() and toJson() function
implementations:
- \snippet serialization/savegame/character.cpp 0
+ \snippet serialization/savegame/character.cpp fromJson
- In the read() function, we assign Character's members values from the
- QJsonObject argument. You can use either \l QJsonObject::operator[]() or
- QJsonObject::value() to access values within the JSON object; both are
- const functions and return QJsonValue::Undefined if the key is invalid. We
- check if the keys are valid before attempting to read them with
- QJsonObject::contains().
+ In the fromJson() function, we construct a local \c result Character object
+ and assign \c{result}'s members values from the QJsonObject argument. You
+ can use either \l QJsonObject::operator[]() or QJsonObject::value() to
+ access values within the JSON object; both are const functions and return
+ QJsonValue::Undefined if the key is invalid. In particular, the \c{is...}
+ functions (for example \l QJsonValue::isString(), \l
+ QJsonValue::isDouble()) return \c false for QJsonValue::Undefined, so we
+ can check for existence as well as the correct type in a single lookup.
- \snippet serialization/savegame/character.cpp 1
+ If a value does not exist in the JSON object, or has the wrong type, we
+ don't write to the corresponding \c result member, either, thereby
+ preserving any values the default constructor may have set. This means
+ default values are centrally defined in one location (the default
+ constructor) and need not be repeated in serialisation code
+ (\l{https://en.wikipedia.org/wiki/Don%27t_repeat_yourself}{DRY}).
- In the write() function, we do the reverse of the read() function; assign
- values from the Character object to the JSON object. As with accessing
- values, there are two ways to set values on a QJsonObject:
- \l QJsonObject::operator[]() and QJsonObject::insert(). Both will override
- any existing value at the given key.
+ Observe the use of
+ \l{https://en.cppreference.com/w/cpp/language/if#If_statements_with_initializer}
+ {C++17 if-with-initializer} to separate scoping and checking of the variable \c v.
+ This means we can keep the variable name short, because its scope is limited.
- Next up is the Level class:
+ Compare that to the naïve approach using \c QJsonObject::contains():
+
+ \badcode
+ if (json.contains("name") && json["name"].isString())
+ result.mName = json["name"].toString();
+ \endcode
+
+ which, beside being less readable, requires a total of three lookups (no,
+ the compiler will \e not optimize these into one), so is three times
+ slower and repeats \c{"name"} three times (violating the DRY principle).
+
+ \snippet serialization/savegame/character.cpp toJson
+
+ In the toJson() function, we do the reverse of the fromJson() function;
+ assign values from the Character object to a new JSON object we then
+ return. As with accessing values, there are two ways to set values on a
+ QJsonObject: \l QJsonObject::operator[]() and \l QJsonObject::insert().
+ Both will override any existing value at the given key.
+
+ \section1 The Level Class
\snippet serialization/savegame/level.h 0
- We want to have several levels in our game, each with several NPCs, so we
- keep a QList of Character objects. We also provide the familiar read() and
- write() functions.
+ We want the levels in our game to each each have several NPCs, so we keep a QList
+ of Character objects. We also provide the familiar fromJson() and toJson()
+ functions.
- \snippet serialization/savegame/level.cpp 0
+ \snippet serialization/savegame/level.cpp fromJson
- Containers can be written and read to and from JSON using QJsonArray. In our
+ Containers can be written to and read from JSON using QJsonArray. In our
case, we construct a QJsonArray from the value associated with the key
\c "npcs". Then, for each QJsonValue element in the array, we call
- toObject() to get the Character's JSON object. The Character object can then
- read their JSON and be appended to our NPC array.
+ toObject() to get the Character's JSON object. Character::fromJson() can
+ then turn that QJSonObject into a Character object to append to our NPC array.
\note \l{Container Classes}{Associate containers} can be written by storing
the key in each value object (if it's not already). With this approach, the
@@ -70,11 +110,13 @@
element is used as the key to construct the container when reading it back
in.
- \snippet serialization/savegame/level.cpp 1
+ \snippet serialization/savegame/level.cpp toJson
- Again, the write() function is similar to the read() function, except
+ Again, the toJson() function is similar to the fromJson() function, except
reversed.
+ \section1 The Game Class
+
Having established the Character and Level classes, we can move on to
the Game class:
@@ -86,26 +128,43 @@
Next, we provide accessors for the player and levels. We then expose three
functions: newGame(), saveGame() and loadGame().
- The read() and write() functions are used by saveGame() and loadGame().
+ The read() and toJson() functions are used by saveGame() and loadGame().
+
+ \div{class="admonition note"}\b{Note:}
+ Despite \c Game being a value class, we assume that the author wants a game to have
+ identity, much like your main window would have. We therefore don't use a
+ static fromJson() function, which would create a new object, but a read()
+ function we can call on existing objects. There's a 1:1 correspondence
+ between read() and fromJson(), in that one can be implemented in terms of
+ the other:
+
+ \code
+ void read(const QJsonObject &json) { *this = fromJson(json); }
+ static Game fromObject(const QJsonObject &json) { Game g; g.read(json); return g; }
+ \endcode
- \snippet serialization/savegame/game.cpp 0
+ We just use what's more convenient for callers of the functions.
+ \enddiv
+
+ \snippet serialization/savegame/game.cpp newGame
To setup a new game, we create the player and populate the levels and their
NPCs.
- \snippet serialization/savegame/game.cpp 1
+ \snippet serialization/savegame/game.cpp read
- The first thing we do in the read() function is tell the player to read
- itself. We then clear the level array so that calling loadGame() on the
- same Game object twice doesn't result in old levels hanging around.
+ The read() function starts by replacing the player with the
+ one read from JSON. We then clear() the level array so that calling
+ loadGame() on the same Game object twice doesn't result in old levels
+ hanging around.
We then populate the level array by reading each Level from a QJsonArray.
- \snippet serialization/savegame/game.cpp 2
+ \snippet serialization/savegame/game.cpp toJson
- We write the game to JSON similarly to how we write Level.
+ Writing the game to JSON is similar to writing a level.
- \snippet serialization/savegame/game.cpp 3
+ \snippet serialization/savegame/game.cpp loadGame
When loading a saved game in loadGame(), the first thing we do is open the
save file based on which format it was saved to; \c "save.json" for JSON,
@@ -119,14 +178,16 @@
After constructing the QJsonDocument, we instruct the Game object to read
itself and then return \c true to indicate success.
- \snippet serialization/savegame/game.cpp 4
+ \snippet serialization/savegame/game.cpp saveGame
Not surprisingly, saveGame() looks very much like loadGame(). We determine
the file extension based on the format, print a warning and return \c false
if the opening of the file fails. We then write the Game object to a
- QJsonDocument, and call either QJsonDocument::toJson() or to
- QJsonDocument::toBinaryData() to save the game, depending on which format
- was specified.
+ QJsonObject. To save the game in the format that was specified, we
+ convert the JSON object into either a QJsonDocument for a subsequent
+ QJsonDocument::toJson() call, or a QCborValue for QCborValue::toCbor().
+
+ \section1 Tying It All Together
We are now ready to enter main():
@@ -158,5 +219,5 @@
human-readable JSON files, but you also have the option to use a binary
format if it's required, \e without rewriting any code.
- \sa {JSON Support in Qt}, {Data Storage}
+ \sa {JSON Support in Qt}, {CBOR Support in Qt}, {Data Input Output}
*/
diff --git a/examples/corelib/serialization/savegame/game.cpp b/examples/corelib/serialization/savegame/game.cpp
index 111fbfc6ea..85a2619b42 100644
--- a/examples/corelib/serialization/savegame/game.cpp
+++ b/examples/corelib/serialization/savegame/game.cpp
@@ -21,7 +21,7 @@ QList<Level> Game::levels() const
return mLevels;
}
-//! [0]
+//! [newGame]
void Game::newGame()
{
mPlayer = Character();
@@ -59,9 +59,9 @@ void Game::newGame()
dungeon.setNpcs(dungeonNpcs);
mLevels.append(dungeon);
}
-//! [0]
+//! [newGame]
-//! [3]
+//! [loadGame]
bool Game::loadGame(Game::SaveFormat saveFormat)
{
QFile loadFile(saveFormat == Json
@@ -87,9 +87,9 @@ bool Game::loadGame(Game::SaveFormat saveFormat)
<< (saveFormat != Json ? "CBOR" : "JSON") << "...\n";
return true;
}
-//! [3]
+//! [loadGame]
-//! [4]
+//! [saveGame]
bool Game::saveGame(Game::SaveFormat saveFormat) const
{
QFile saveFile(saveFormat == Json
@@ -101,60 +101,52 @@ bool Game::saveGame(Game::SaveFormat saveFormat) const
return false;
}
- QJsonObject gameObject;
- write(gameObject);
+ QJsonObject gameObject = toJson();
saveFile.write(saveFormat == Json
? QJsonDocument(gameObject).toJson()
: QCborValue::fromJsonValue(gameObject).toCbor());
return true;
}
-//! [4]
+//! [saveGame]
-//! [1]
+//! [read]
void Game::read(const QJsonObject &json)
{
- if (json.contains("player") && json["player"].isObject())
- mPlayer.read(json["player"].toObject());
+ if (const QJsonValue v = json["player"]; v.isObject())
+ mPlayer = Character::fromJson(v.toObject());
- if (json.contains("levels") && json["levels"].isArray()) {
- QJsonArray levelArray = json["levels"].toArray();
+ if (const QJsonValue v = json["levels"]; v.isArray()) {
+ const QJsonArray levels = v.toArray();
mLevels.clear();
- mLevels.reserve(levelArray.size());
- for (int levelIndex = 0; levelIndex < levelArray.size(); ++levelIndex) {
- QJsonObject levelObject = levelArray[levelIndex].toObject();
- Level level;
- level.read(levelObject);
- mLevels.append(level);
- }
+ mLevels.reserve(levels.size());
+ for (const QJsonValue &level : levels)
+ mLevels.append(Level::fromJson(level.toObject()));
}
}
-//! [1]
+//! [read]
-//! [2]
-void Game::write(QJsonObject &json) const
+//! [toJson]
+QJsonObject Game::toJson() const
{
- QJsonObject playerObject;
- mPlayer.write(playerObject);
- json["player"] = playerObject;
-
- QJsonArray levelArray;
- for (const Level &level : mLevels) {
- QJsonObject levelObject;
- level.write(levelObject);
- levelArray.append(levelObject);
- }
- json["levels"] = levelArray;
+ QJsonObject json;
+ json["player"] = mPlayer.toJson();
+
+ QJsonArray levels;
+ for (const Level &level : mLevels)
+ levels.append(level.toJson());
+ json["levels"] = levels;
+ return json;
}
-//! [2]
+//! [toJson]
-void Game::print(int indentation) const
+void Game::print(QTextStream &s, int indentation) const
{
const QString indent(indentation * 2, ' ');
- QTextStream(stdout) << indent << "Player\n";
- mPlayer.print(indentation + 1);
+ s << indent << "Player\n";
+ mPlayer.print(s, indentation + 1);
- QTextStream(stdout) << indent << "Levels\n";
- for (Level level : mLevels)
- level.print(indentation + 1);
+ s << indent << "Levels\n";
+ for (const Level &level : mLevels)
+ level.print(s, indentation + 1);
}
diff --git a/examples/corelib/serialization/savegame/game.h b/examples/corelib/serialization/savegame/game.h
index 266e764a80..2d7630c7df 100644
--- a/examples/corelib/serialization/savegame/game.h
+++ b/examples/corelib/serialization/savegame/game.h
@@ -4,11 +4,13 @@
#ifndef GAME_H
#define GAME_H
+#include "character.h"
+#include "level.h"
+
#include <QJsonObject>
#include <QList>
-#include "character.h"
-#include "level.h"
+QT_FORWARD_DECLARE_CLASS(QTextStream)
//! [0]
class Game
@@ -26,9 +28,9 @@ public:
bool saveGame(SaveFormat saveFormat) const;
void read(const QJsonObject &json);
- void write(QJsonObject &json) const;
+ QJsonObject toJson() const;
- void print(int indentation = 0) const;
+ void print(QTextStream &s, int indentation = 0) const;
private:
Character mPlayer;
QList<Level> mLevels;
diff --git a/examples/corelib/serialization/savegame/level.cpp b/examples/corelib/serialization/savegame/level.cpp
index 04edadf7f6..489a25e204 100644
--- a/examples/corelib/serialization/savegame/level.cpp
+++ b/examples/corelib/serialization/savegame/level.cpp
@@ -25,46 +25,44 @@ void Level::setNpcs(const QList<Character> &npcs)
mNpcs = npcs;
}
-//! [0]
-void Level::read(const QJsonObject &json)
+//! [fromJson]
+Level Level::fromJson(const QJsonObject &json)
{
- if (json.contains("name") && json["name"].isString())
- mName = json["name"].toString();
+ Level result;
- if (json.contains("npcs") && json["npcs"].isArray()) {
- QJsonArray npcArray = json["npcs"].toArray();
- mNpcs.clear();
- mNpcs.reserve(npcArray.size());
- for (int npcIndex = 0; npcIndex < npcArray.size(); ++npcIndex) {
- QJsonObject npcObject = npcArray[npcIndex].toObject();
- Character npc;
- npc.read(npcObject);
- mNpcs.append(npc);
- }
+ if (const QJsonValue v = json["name"]; v.isString())
+ result.mName = v.toString();
+
+ if (const QJsonValue v = json["npcs"]; v.isArray()) {
+ const QJsonArray npcs = v.toArray();
+ result.mNpcs.reserve(npcs.size());
+ for (const QJsonValue &npc : npcs)
+ result.mNpcs.append(Character::fromJson(npc.toObject()));
}
+
+ return result;
}
-//! [0]
+//! [fromJson]
-//! [1]
-void Level::write(QJsonObject &json) const
+//! [toJson]
+QJsonObject Level::toJson() const
{
+ QJsonObject json;
json["name"] = mName;
QJsonArray npcArray;
- for (const Character &npc : mNpcs) {
- QJsonObject npcObject;
- npc.write(npcObject);
- npcArray.append(npcObject);
- }
+ for (const Character &npc : mNpcs)
+ npcArray.append(npc.toJson());
json["npcs"] = npcArray;
+ return json;
}
-//! [1]
+//! [toJson]
-void Level::print(int indentation) const
+void Level::print(QTextStream &s, int indentation) const
{
const QString indent(indentation * 2, ' ');
- QTextStream(stdout) << indent << "Name:\t" << mName << "\n";
- QTextStream(stdout) << indent << "NPCs:\n";
+ s << indent << "Name:\t" << mName << "\n"
+ << indent << "NPCs:\n";
for (const Character &character : mNpcs)
- character.print(2);
+ character.print(s, indentation + 1);
}
diff --git a/examples/corelib/serialization/savegame/level.h b/examples/corelib/serialization/savegame/level.h
index 4c0a8aed89..ad8d0fd593 100644
--- a/examples/corelib/serialization/savegame/level.h
+++ b/examples/corelib/serialization/savegame/level.h
@@ -4,27 +4,29 @@
#ifndef LEVEL_H
#define LEVEL_H
+#include "character.h"
+
#include <QJsonObject>
#include <QList>
-#include "character.h"
+QT_FORWARD_DECLARE_CLASS(QTextStream)
//! [0]
class Level
{
public:
Level() = default;
- Level(const QString &name);
+ explicit Level(const QString &name);
QString name() const;
QList<Character> npcs() const;
void setNpcs(const QList<Character> &npcs);
- void read(const QJsonObject &json);
- void write(QJsonObject &json) const;
+ static Level fromJson(const QJsonObject &json);
+ QJsonObject toJson() const;
- void print(int indentation = 0) const;
+ void print(QTextStream &s, int indentation = 0) const;
private:
QString mName;
QList<Character> mNpcs;
diff --git a/examples/corelib/serialization/savegame/main.cpp b/examples/corelib/serialization/savegame/main.cpp
index c9e713c126..3fc0f3af10 100644
--- a/examples/corelib/serialization/savegame/main.cpp
+++ b/examples/corelib/serialization/savegame/main.cpp
@@ -1,32 +1,37 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+#include "game.h"
+
#include <QCoreApplication>
+#include <QStringList>
+#include <QString>
#include <QTextStream>
-#include "game.h"
+using namespace Qt::StringLiterals; // for _L1
+
//! [0]
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
- QStringList args = QCoreApplication::arguments();
- bool newGame = true;
- if (args.length() > 1)
- newGame = (args[1].toLower() != QStringLiteral("load"));
- bool json = true;
- if (args.length() > 2)
- json = (args[2].toLower() != QStringLiteral("binary"));
+
+ const QStringList args = QCoreApplication::arguments();
+ const bool newGame
+ = args.size() <= 1 || QString::compare(args[1], "load"_L1, Qt::CaseInsensitive) != 0;
+ const bool json
+ = args.size() <= 2 || QString::compare(args[2], "binary"_L1, Qt::CaseInsensitive) != 0;
Game game;
if (newGame)
game.newGame();
else if (!game.loadGame(json ? Game::Json : Game::Binary))
- return 1;
+ return 1;
// Game is played; changes are made...
//! [0]
//! [1]
- QTextStream(stdout) << "Game ended in the following state:\n";
- game.print();
+ QTextStream s(stdout);
+ s << "Game ended in the following state:\n";
+ game.print(s);
if (!game.saveGame(json ? Game::Json : Game::Binary))
return 1;
diff --git a/examples/corelib/serialization/serialization.pro b/examples/corelib/serialization/serialization.pro
index 7651444f19..9f0ced0282 100644
--- a/examples/corelib/serialization/serialization.pro
+++ b/examples/corelib/serialization/serialization.pro
@@ -3,3 +3,9 @@ SUBDIRS = \
cbordump \
convert \
savegame
+
+qtHaveModule(widgets) {
+ SUBDIRS += streambookmarks
+ qtHaveModule(network): SUBDIRS += \
+ rsslisting
+}
diff --git a/examples/xml/streambookmarks/CMakeLists.txt b/examples/corelib/serialization/streambookmarks/CMakeLists.txt
index 891272ef7f..1d0ab8690b 100644
--- a/examples/xml/streambookmarks/CMakeLists.txt
+++ b/examples/corelib/serialization/streambookmarks/CMakeLists.txt
@@ -1,15 +1,18 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(streambookmarks LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/xml/streambookmarks")
+set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/corelib/serialization/streambookmarks")
+
+find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
-find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets Xml)
+qt_standard_project_setup()
qt_add_executable(streambookmarks
main.cpp
@@ -23,11 +26,10 @@ set_target_properties(streambookmarks PROPERTIES
MACOSX_BUNDLE TRUE
)
-target_link_libraries(streambookmarks PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Widgets
- Qt::Xml
+target_link_libraries(streambookmarks PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Widgets
)
install(TARGETS streambookmarks
diff --git a/examples/xml/streambookmarks/doc/images/xmlstreamexample-filemenu.png b/examples/corelib/serialization/streambookmarks/doc/images/xmlstreamexample-filemenu.png
index e074fb7c41..e074fb7c41 100644
--- a/examples/xml/streambookmarks/doc/images/xmlstreamexample-filemenu.png
+++ b/examples/corelib/serialization/streambookmarks/doc/images/xmlstreamexample-filemenu.png
Binary files differ
diff --git a/examples/xml/streambookmarks/doc/images/xmlstreamexample-helpmenu.png b/examples/corelib/serialization/streambookmarks/doc/images/xmlstreamexample-helpmenu.png
index 0dc4392b94..0dc4392b94 100644
--- a/examples/xml/streambookmarks/doc/images/xmlstreamexample-helpmenu.png
+++ b/examples/corelib/serialization/streambookmarks/doc/images/xmlstreamexample-helpmenu.png
Binary files differ
diff --git a/examples/xml/streambookmarks/doc/images/xmlstreamexample-screenshot.png b/examples/corelib/serialization/streambookmarks/doc/images/xmlstreamexample-screenshot.png
index bbaa423061..bbaa423061 100644
--- a/examples/xml/streambookmarks/doc/images/xmlstreamexample-screenshot.png
+++ b/examples/corelib/serialization/streambookmarks/doc/images/xmlstreamexample-screenshot.png
Binary files differ
diff --git a/examples/xml/streambookmarks/doc/src/qxmlstreambookmarks.qdoc b/examples/corelib/serialization/streambookmarks/doc/src/qxmlstreambookmarks.qdoc
index 546962162f..a1498f0ff5 100644
--- a/examples/xml/streambookmarks/doc/src/qxmlstreambookmarks.qdoc
+++ b/examples/corelib/serialization/streambookmarks/doc/src/qxmlstreambookmarks.qdoc
@@ -2,7 +2,9 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
- \example streambookmarks
+ \example serialization/streambookmarks
+ \examplecategory {Input/Output}
+ \meta tag {network}
\title QXmlStream Bookmarks Example
\brief Demonstrates how to read and write to XBEL files.
\ingroup xml-examples
@@ -20,7 +22,7 @@
has a reference to the QTreeWidget instance where the bookmark hierarchy
is stored.
- \snippet streambookmarks/xbelwriter.h 0
+ \snippet serialization/streambookmarks/xbelwriter.h 0
\section1 XbelWriter Class Implementation
@@ -30,20 +32,20 @@
sections between elements, increasing readability as the data is split into
several lines.
- \snippet streambookmarks/xbelwriter.cpp 0
+ \snippet serialization/streambookmarks/xbelwriter.cpp 0
The \c writeFile() function accepts a QIODevice object and sets it using
\c setDevice(). This function then writes the document type
definition(DTD), the start element, the version, and \c{treeWidget}'s
top-level items.
- \snippet streambookmarks/xbelwriter.cpp 1
+ \snippet serialization/streambookmarks/xbelwriter.cpp 1
The \c writeItem() function accepts a QTreeWidgetItem object and writes it
to the stream, depending on its \c tagName, which can either be a "folder",
"bookmark", or "separator".
- \snippet streambookmarks/xbelwriter.cpp 2
+ \snippet serialization/streambookmarks/xbelwriter.cpp 2
\section1 XbelReader Class Definition
@@ -52,7 +54,7 @@
reference to the QTreeWidget that is used to group the bookmarks according
to their hierarchy.
- \snippet streambookmarks/xbelreader.h 0
+ \snippet serialization/streambookmarks/xbelreader.h 0
\section1 XbelReader Class Implementation
@@ -64,7 +66,7 @@
QStyle::SP_FileIcon correspond to standard pixmaps that follow the style
of your GUI.
- \snippet streambookmarks/xbelreader.cpp 0
+ \snippet serialization/streambookmarks/xbelreader.cpp 0
The \c read() function accepts a QIODevice and sets it using
\l{QXmlStreamReader::}{setDevice()}. The actual process of reading only
@@ -75,13 +77,13 @@
it makes extensive use of the \l{QXmlStreamReader::}{readNextStartElement()}
convenience function.
- \snippet streambookmarks/xbelreader.cpp 1
+ \snippet serialization/streambookmarks/xbelreader.cpp 1
The \c errorString() function is used if an error occurred, in order to
obtain a description of the error complete with line and column number
information.
- \snippet streambookmarks/xbelreader.cpp 2
+ \snippet serialization/streambookmarks/xbelreader.cpp 2
The \c readXBEL() function reads the name of a startElement and calls
the appropriate function to read it, depending on whether if its a
@@ -89,24 +91,24 @@
\l{QXmlStreamReader::}{skipCurrentElement()}. The Q_ASSERT() macro is used
to provide a pre-condition for the function.
- \snippet streambookmarks/xbelreader.cpp 3
+ \snippet serialization/streambookmarks/xbelreader.cpp 3
The \c readTitle() function reads the bookmark's title.
- \snippet streambookmarks/xbelreader.cpp 4
+ \snippet serialization/streambookmarks/xbelreader.cpp 4
The \c readSeparator() function creates a separator and sets its flags.
The text is set to 30 "0xB7", the HEX equivalent for period. The element
is then skipped using \l{QXmlStreamReader::}{skipCurrentElement()}.
- \snippet streambookmarks/xbelreader.cpp 5
+ \snippet serialization/streambookmarks/xbelreader.cpp 5
\section1 MainWindow Class Definition
The \c MainWindow class is a subclass of QMainWindow, with a
\c File menu and a \c Help menu.
- \snippet streambookmarks/mainwindow.h 0
+ \snippet serialization/streambookmarks/mainwindow.h 0
\section1 MainWindow Class Implementation
@@ -117,33 +119,33 @@
is used to display the message "Ready" and the window's size is fixed
to 480x320 pixels.
- \snippet streambookmarks/mainwindow.cpp 0
+ \snippet serialization/streambookmarks/mainwindow.cpp 0
The \c open() function enables the user to open an XBEL file using
QFileDialog::getOpenFileName(). A warning message is displayed along
with the \c fileName and \c errorString if the file cannot be read or
if there is a parse error.
- \snippet streambookmarks/mainwindow.cpp 1
+ \snippet serialization/streambookmarks/mainwindow.cpp 1
The \c saveAs() function displays a QFileDialog, prompting the user for
a \c fileName using QFileDialog::getSaveFileName(). Similar to the
\c open() function, this function also displays a warning message if
the file cannot be written to.
- \snippet streambookmarks/mainwindow.cpp 2
+ \snippet serialization/streambookmarks/mainwindow.cpp 2
The \c about() function displays a QMessageBox with a brief description
of the example.
- \snippet streambookmarks/mainwindow.cpp 3
+ \snippet serialization/streambookmarks/mainwindow.cpp 3
In order to implement the \c open(), \c saveAs(), \c exit(), \c about()
and \c aboutQt() functions, we connect them to QAction objects and
add them to the \c fileMenu and \c helpMenu. The connections are as shown
below:
- \snippet streambookmarks/mainwindow.cpp 5
+ \snippet serialization/streambookmarks/mainwindow.cpp 5
The \c createMenus() function creates the \c fileMenu and \c helpMenu
and adds the QAction objects to them in order to create the menu shown
@@ -155,14 +157,14 @@
\li \inlineimage xmlstreamexample-helpmenu.png
\endtable
- \snippet streambookmarks/mainwindow.cpp 5
+ \snippet serialization/streambookmarks/mainwindow.cpp 5
\section1 \c{main()} Function
The \c main() function instantiates \c MainWindow and invokes the \c show()
function.
- \snippet streambookmarks/main.cpp 0
+ \snippet serialization/streambookmarks/main.cpp 0
See the \l{http://pyxml.sourceforge.net/topics/xbel/}
{XML Bookmark Exchange Language Resource Page} for more information
diff --git a/examples/xml/streambookmarks/jennifer.xbel b/examples/corelib/serialization/streambookmarks/jennifer.xbel
index 2501c118af..2501c118af 100644
--- a/examples/xml/streambookmarks/jennifer.xbel
+++ b/examples/corelib/serialization/streambookmarks/jennifer.xbel
diff --git a/examples/xml/streambookmarks/main.cpp b/examples/corelib/serialization/streambookmarks/main.cpp
index 75b5d646c6..75b5d646c6 100644
--- a/examples/xml/streambookmarks/main.cpp
+++ b/examples/corelib/serialization/streambookmarks/main.cpp
diff --git a/examples/xml/streambookmarks/mainwindow.cpp b/examples/corelib/serialization/streambookmarks/mainwindow.cpp
index 644681d706..644681d706 100644
--- a/examples/xml/streambookmarks/mainwindow.cpp
+++ b/examples/corelib/serialization/streambookmarks/mainwindow.cpp
diff --git a/examples/xml/streambookmarks/mainwindow.h b/examples/corelib/serialization/streambookmarks/mainwindow.h
index 7a4a922e43..7a4a922e43 100644
--- a/examples/xml/streambookmarks/mainwindow.h
+++ b/examples/corelib/serialization/streambookmarks/mainwindow.h
diff --git a/examples/xml/streambookmarks/streambookmarks.pro b/examples/corelib/serialization/streambookmarks/streambookmarks.pro
index 8c2fc3fa19..9b067c7bba 100644
--- a/examples/xml/streambookmarks/streambookmarks.pro
+++ b/examples/corelib/serialization/streambookmarks/streambookmarks.pro
@@ -5,11 +5,11 @@ SOURCES = main.cpp \
mainwindow.cpp \
xbelreader.cpp \
xbelwriter.cpp
-QT += xml widgets
+QT += widgets
requires(qtConfig(filedialog))
EXAMPLE_FILES = frank.xbel jennifer.xbel
# install
-target.path = $$[QT_INSTALL_EXAMPLES]/xml/streambookmarks
+target.path = $$[QT_INSTALL_EXAMPLES]/corelib/serialization/streambookmarks
INSTALLS += target
diff --git a/examples/xml/streambookmarks/xbelreader.cpp b/examples/corelib/serialization/streambookmarks/xbelreader.cpp
index 74e25f12a8..74e25f12a8 100644
--- a/examples/xml/streambookmarks/xbelreader.cpp
+++ b/examples/corelib/serialization/streambookmarks/xbelreader.cpp
diff --git a/examples/xml/streambookmarks/xbelreader.h b/examples/corelib/serialization/streambookmarks/xbelreader.h
index 81a59b32b5..81a59b32b5 100644
--- a/examples/xml/streambookmarks/xbelreader.h
+++ b/examples/corelib/serialization/streambookmarks/xbelreader.h
diff --git a/examples/xml/streambookmarks/xbelwriter.cpp b/examples/corelib/serialization/streambookmarks/xbelwriter.cpp
index 6cfcd2bc1a..6cfcd2bc1a 100644
--- a/examples/xml/streambookmarks/xbelwriter.cpp
+++ b/examples/corelib/serialization/streambookmarks/xbelwriter.cpp
diff --git a/examples/xml/streambookmarks/xbelwriter.h b/examples/corelib/serialization/streambookmarks/xbelwriter.h
index ec95315c4b..ec95315c4b 100644
--- a/examples/xml/streambookmarks/xbelwriter.h
+++ b/examples/corelib/serialization/streambookmarks/xbelwriter.h
diff --git a/examples/corelib/threads/CMakeLists.txt b/examples/corelib/threads/CMakeLists.txt
index fab084385f..4ced9a50e5 100644
--- a/examples/corelib/threads/CMakeLists.txt
+++ b/examples/corelib/threads/CMakeLists.txt
@@ -1,6 +1,9 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
qt_internal_add_example(semaphores)
qt_internal_add_example(waitconditions)
-if(TARGET Qt::Widgets)
+if(TARGET Qt6::Widgets)
qt_internal_add_example(mandelbrot)
qt_internal_add_example(queuedcustomtype)
endif()
diff --git a/examples/corelib/threads/doc/src/mandelbrot.qdoc b/examples/corelib/threads/doc/src/mandelbrot.qdoc
index aaa6356a2c..fa9a7fc3f6 100644
--- a/examples/corelib/threads/doc/src/mandelbrot.qdoc
+++ b/examples/corelib/threads/doc/src/mandelbrot.qdoc
@@ -13,17 +13,17 @@
\image mandelbrot-example.png Screenshot of the Mandelbrot example
- The heavy computation here is the Mandelbrot set, probably the
- world's most famous fractal. These days, while sophisticated
- programs such as \l{http://matek.hu/xaos/doku.php}{XaoS} that provide real-time zooming in the
- Mandelbrot set, the standard Mandelbrot algorithm is just slow
- enough for our purposes.
+ The heavy computation here is the Mandelbrot set, probably the world's most
+ famous fractal. These days, while sophisticated programs, such as
+ \l{https://xaos-project.github.io/}{XaoS}, provide real-time zooming in
+ the Mandelbrot set, the standard Mandelbrot algorithm is just slow enough
+ for our purposes.
In real life, the approach described here is applicable to a
large set of problems, including synchronous network I/O and
database access, where the user interface must remain responsive
while some heavy operation is taking place. The \l
- {Blocking Fortune Client Example} shows the same principle at
+ {Blocking Fortune Client} example shows the same principle at
work in a TCP client.
The Mandelbrot application supports zooming and scrolling using
@@ -303,6 +303,11 @@
\snippet threads/mandelbrot/mandelbrotwidget.cpp 13
+ Pinch to zoom has been implemented with QGesture as outlined in
+ \l{Gestures in Widgets and Graphics View}.
+
+ \snippet threads/mandelbrot/mandelbrotwidget.cpp gesture1
+
When the user presses the left mouse button, we store the mouse
pointer position in \c lastDragPos.
diff --git a/examples/corelib/threads/doc/src/waitconditions.qdoc b/examples/corelib/threads/doc/src/waitconditions.qdoc
index 90f911aab3..ae9e767c13 100644
--- a/examples/corelib/threads/doc/src/waitconditions.qdoc
+++ b/examples/corelib/threads/doc/src/waitconditions.qdoc
@@ -109,7 +109,7 @@
thread is the only one that can do anything; the consumer is
blocked waiting for the \c bufferNotEmpty condition to be
signalled (\c numUsedBytes is 0). Once the producer has put one
- byte in the buffer, \c numUsedBytes is \c BufferSize - 1 and the
+ byte in the buffer, \c numUsedBytes is strictly greater than 0, and the
\c bufferNotEmpty condition is signalled. At that point, two
things can happen: Either the consumer thread takes over and
reads that byte, or the producer gets to produce a second byte.
diff --git a/examples/corelib/threads/mandelbrot/CMakeLists.txt b/examples/corelib/threads/mandelbrot/CMakeLists.txt
index 7fd70ebbd6..9c5a553966 100644
--- a/examples/corelib/threads/mandelbrot/CMakeLists.txt
+++ b/examples/corelib/threads/mandelbrot/CMakeLists.txt
@@ -1,8 +1,9 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(mandelbrot LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
@@ -11,6 +12,8 @@ set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/corelib/threads/mandelbrot")
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
+qt_standard_project_setup()
+
qt_add_executable(mandelbrot
main.cpp
mandelbrotwidget.cpp mandelbrotwidget.h
@@ -22,10 +25,10 @@ set_target_properties(mandelbrot PROPERTIES
MACOSX_BUNDLE TRUE
)
-target_link_libraries(mandelbrot PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Widgets
+target_link_libraries(mandelbrot PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Widgets
)
install(TARGETS mandelbrot
diff --git a/examples/corelib/threads/mandelbrot/main.cpp b/examples/corelib/threads/mandelbrot/main.cpp
index d73adb0193..d0d4680978 100644
--- a/examples/corelib/threads/mandelbrot/main.cpp
+++ b/examples/corelib/threads/mandelbrot/main.cpp
@@ -37,11 +37,7 @@ int main(int argc, char *argv[])
}
MandelbrotWidget widget;
- const auto geometry = widget.screen()->availableGeometry();
- widget.resize((2 * geometry.size()) / 3);
- const auto pos = (geometry.size() - widget.size()) / 2;
- widget.move(geometry.topLeft() + QPoint(pos.width(), pos.height()));
-
+ widget.grabGesture(Qt::PinchGesture);
widget.show();
return app.exec();
}
diff --git a/examples/corelib/threads/mandelbrot/mandelbrotwidget.cpp b/examples/corelib/threads/mandelbrot/mandelbrotwidget.cpp
index 9ab8936c85..e0f33a2b0b 100644
--- a/examples/corelib/threads/mandelbrot/mandelbrotwidget.cpp
+++ b/examples/corelib/threads/mandelbrot/mandelbrotwidget.cpp
@@ -3,8 +3,9 @@
#include "mandelbrotwidget.h"
-#include <QPainter>
+#include <QGesture>
#include <QKeyEvent>
+#include <QPainter>
#include <math.h>
@@ -26,8 +27,7 @@ MandelbrotWidget::MandelbrotWidget(QWidget *parent) :
pixmapScale(DefaultScale),
curScale(DefaultScale)
{
- help = tr("Use mouse wheel or the '+' and '-' keys to zoom. "
- "Press and hold left mouse button to scroll.");
+ help = tr("Zoom with mouse wheel, +/- keys or pinch. Scroll with arrow keys or by dragging.");
connect(&thread, &RenderThread::renderedImage,
this, &MandelbrotWidget::updatePixmap);
@@ -46,7 +46,7 @@ void MandelbrotWidget::paintEvent(QPaintEvent * /* event */)
if (pixmap.isNull()) {
painter.setPen(Qt::white);
- painter.drawText(rect(), Qt::AlignCenter, tr("Rendering initial image, please wait..."));
+ painter.drawText(rect(), Qt::AlignCenter|Qt::TextWordWrap, tr("Rendering initial image, please wait..."));
//! [2] //! [3]
return;
//! [3] //! [4]
@@ -80,17 +80,31 @@ void MandelbrotWidget::paintEvent(QPaintEvent * /* event */)
}
//! [8] //! [9]
- QString text = help;
- if (!info.isEmpty())
- text += ' ' + info;
QFontMetrics metrics = painter.fontMetrics();
- int textWidth = metrics.horizontalAdvance(text);
+ if (!info.isEmpty()){
+ int infoWidth = metrics.horizontalAdvance(info);
+ int infoHeight = metrics.height();
+
+ painter.setPen(Qt::NoPen);
+ painter.setBrush(QColor(0, 0, 0, 127));
+ infoHeight = (infoWidth/width()+1) * (infoHeight + 5);
+ painter.drawRect((width() - infoWidth) / 2 - 5, 0, infoWidth + 10, infoHeight);
+
+ painter.setPen(Qt::white);
+ painter.drawText(rect(), Qt::AlignHCenter|Qt::AlignTop|Qt::TextWordWrap, info);
+ }
+
+ int helpWidth = metrics.horizontalAdvance(help);
+ int helpHeight = metrics.height();
painter.setPen(Qt::NoPen);
painter.setBrush(QColor(0, 0, 0, 127));
- painter.drawRect((width() - textWidth) / 2 - 5, 0, textWidth + 10, metrics.lineSpacing() + 5);
+ helpHeight = (helpWidth/width()+1) * (helpHeight + 5);
+ painter.drawRect((width() - helpWidth) / 2 - 5, height()-helpHeight, helpWidth + 10, helpHeight);
+
painter.setPen(Qt::white);
- painter.drawText((width() - textWidth) / 2, metrics.leading() + metrics.ascent(), text);
+ painter.drawText(rect(), Qt::AlignHCenter|Qt::AlignBottom|Qt::TextWordWrap, help);
+
}
//! [9]
@@ -211,3 +225,24 @@ void MandelbrotWidget::scroll(int deltaX, int deltaY)
thread.render(centerX, centerY, curScale, size(), devicePixelRatio());
}
//! [18]
+
+//! [gesture1]
+#ifndef QT_NO_GESTURES
+bool MandelbrotWidget::gestureEvent(QGestureEvent *event)
+{
+ if (auto *pinch = static_cast<QPinchGesture *>(event->gesture(Qt::PinchGesture))) {
+ if (pinch->changeFlags().testFlag(QPinchGesture::ScaleFactorChanged))
+ zoom(1.0 / pinch->scaleFactor());
+ return true;
+ }
+ return false;
+}
+
+bool MandelbrotWidget::event(QEvent *event)
+{
+ if (event->type() == QEvent::Gesture)
+ return gestureEvent(static_cast<QGestureEvent*>(event));
+ return QWidget::event(event);
+}
+#endif
+//! [gesture1]
diff --git a/examples/corelib/threads/mandelbrot/mandelbrotwidget.h b/examples/corelib/threads/mandelbrot/mandelbrotwidget.h
index 68c4a6f4f7..23c3a2bf40 100644
--- a/examples/corelib/threads/mandelbrot/mandelbrotwidget.h
+++ b/examples/corelib/threads/mandelbrot/mandelbrotwidget.h
@@ -4,6 +4,7 @@
#ifndef MANDELBROTWIDGET_H
#define MANDELBROTWIDGET_H
+#include <QGestureEvent>
#include <QPixmap>
#include <QWidget>
#include "renderthread.h"
@@ -18,6 +19,7 @@ public:
MandelbrotWidget(QWidget *parent = nullptr);
protected:
+ QSize sizeHint() const override { return {1024, 768}; };
void paintEvent(QPaintEvent *event) override;
void resizeEvent(QResizeEvent *event) override;
void keyPressEvent(QKeyEvent *event) override;
@@ -27,6 +29,9 @@ protected:
void mousePressEvent(QMouseEvent *event) override;
void mouseMoveEvent(QMouseEvent *event) override;
void mouseReleaseEvent(QMouseEvent *event) override;
+#ifndef QT_NO_GESTURES
+ bool event(QEvent *event) override;
+#endif
private slots:
void updatePixmap(const QImage &image, double scaleFactor);
@@ -34,6 +39,9 @@ private slots:
private:
void scroll(int deltaX, int deltaY);
+#ifndef QT_NO_GESTURES
+ bool gestureEvent(QGestureEvent *event);
+#endif
RenderThread thread;
QPixmap pixmap;
diff --git a/examples/corelib/threads/queuedcustomtype/CMakeLists.txt b/examples/corelib/threads/queuedcustomtype/CMakeLists.txt
index 2086b83492..5a247bacc9 100644
--- a/examples/corelib/threads/queuedcustomtype/CMakeLists.txt
+++ b/examples/corelib/threads/queuedcustomtype/CMakeLists.txt
@@ -1,8 +1,9 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(queuedcustomtype LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
@@ -11,6 +12,8 @@ set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/corelib/threads/queuedcustomtype"
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
+qt_standard_project_setup()
+
qt_add_executable(queuedcustomtype
block.cpp block.h
main.cpp
@@ -23,10 +26,10 @@ set_target_properties(queuedcustomtype PROPERTIES
MACOSX_BUNDLE TRUE
)
-target_link_libraries(queuedcustomtype PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Widgets
+target_link_libraries(queuedcustomtype PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Widgets
)
install(TARGETS queuedcustomtype
diff --git a/examples/corelib/threads/semaphores/CMakeLists.txt b/examples/corelib/threads/semaphores/CMakeLists.txt
index 49169583a3..bccf6e1e37 100644
--- a/examples/corelib/threads/semaphores/CMakeLists.txt
+++ b/examples/corelib/threads/semaphores/CMakeLists.txt
@@ -1,8 +1,9 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(semaphores LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
@@ -11,12 +12,14 @@ set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/corelib/threads/semaphores")
find_package(Qt6 REQUIRED COMPONENTS Core)
+qt_standard_project_setup()
+
qt_add_executable(semaphores
semaphores.cpp
)
-target_link_libraries(semaphores PUBLIC
- Qt::Core
+target_link_libraries(semaphores PRIVATE
+ Qt6::Core
)
install(TARGETS semaphores
diff --git a/examples/corelib/threads/semaphores/semaphores.cpp b/examples/corelib/threads/semaphores/semaphores.cpp
index 2d9d169138..5a49555110 100644
--- a/examples/corelib/threads/semaphores/semaphores.cpp
+++ b/examples/corelib/threads/semaphores/semaphores.cpp
@@ -36,7 +36,6 @@ public:
class Consumer : public QThread
//! [3] //! [4]
{
- Q_OBJECT
public:
void run() override
{
@@ -64,5 +63,3 @@ int main(int argc, char *argv[])
return 0;
}
//! [6]
-
-#include "semaphores.moc"
diff --git a/examples/corelib/threads/waitconditions/CMakeLists.txt b/examples/corelib/threads/waitconditions/CMakeLists.txt
index c15dc19551..45818e2bfc 100644
--- a/examples/corelib/threads/waitconditions/CMakeLists.txt
+++ b/examples/corelib/threads/waitconditions/CMakeLists.txt
@@ -1,8 +1,9 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(waitconditions LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
@@ -11,12 +12,14 @@ set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/corelib/threads/waitconditions")
find_package(Qt6 REQUIRED COMPONENTS Core)
+qt_standard_project_setup()
+
qt_add_executable(waitconditions
waitconditions.cpp
)
-target_link_libraries(waitconditions PUBLIC
- Qt::Core
+target_link_libraries(waitconditions PRIVATE
+ Qt6::Core
)
install(TARGETS waitconditions
diff --git a/examples/corelib/threads/waitconditions/waitconditions.cpp b/examples/corelib/threads/waitconditions/waitconditions.cpp
index 72b9ed39a5..bdc24acd8c 100644
--- a/examples/corelib/threads/waitconditions/waitconditions.cpp
+++ b/examples/corelib/threads/waitconditions/waitconditions.cpp
@@ -1,21 +1,28 @@
// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2022 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-#include <QtCore>
+#include <QCoreApplication>
+#include <QMutex>
+#include <QMutexLocker>
+#include <QObject>
+#include <QRandomGenerator>
+#include <QThread>
+#include <QWaitCondition>
#include <stdio.h>
#include <stdlib.h>
//! [0]
-const int DataSize = 100000;
+constexpr int DataSize = 100000;
+constexpr int BufferSize = 8192;
-const int BufferSize = 8192;
+QMutex mutex; // protects the buffer and the counter
char buffer[BufferSize];
+int numUsedBytes;
QWaitCondition bufferNotEmpty;
QWaitCondition bufferNotFull;
-QMutex mutex;
-int numUsedBytes = 0;
//! [0]
//! [1]
@@ -23,24 +30,28 @@ class Producer : public QThread
//! [1] //! [2]
{
public:
- Producer(QObject *parent = NULL) : QThread(parent)
+ explicit Producer(QObject *parent = nullptr)
+ : QThread(parent)
{
}
+private:
void run() override
{
for (int i = 0; i < DataSize; ++i) {
- mutex.lock();
- if (numUsedBytes == BufferSize)
- bufferNotFull.wait(&mutex);
- mutex.unlock();
+ {
+ const QMutexLocker locker(&mutex);
+ while (numUsedBytes == BufferSize)
+ bufferNotFull.wait(&mutex);
+ }
buffer[i % BufferSize] = "ACGT"[QRandomGenerator::global()->bounded(4)];
- mutex.lock();
- ++numUsedBytes;
- bufferNotEmpty.wakeAll();
- mutex.unlock();
+ {
+ const QMutexLocker locker(&mutex);
+ ++numUsedBytes;
+ bufferNotEmpty.wakeAll();
+ }
}
}
};
@@ -50,32 +61,32 @@ public:
class Consumer : public QThread
//! [3] //! [4]
{
- Q_OBJECT
public:
- Consumer(QObject *parent = NULL) : QThread(parent)
+ explicit Consumer(QObject *parent = nullptr)
+ : QThread(parent)
{
}
+private:
void run() override
{
for (int i = 0; i < DataSize; ++i) {
- mutex.lock();
- if (numUsedBytes == 0)
- bufferNotEmpty.wait(&mutex);
- mutex.unlock();
+ {
+ const QMutexLocker locker(&mutex);
+ while (numUsedBytes == 0)
+ bufferNotEmpty.wait(&mutex);
+ }
fprintf(stderr, "%c", buffer[i % BufferSize]);
- mutex.lock();
- --numUsedBytes;
- bufferNotFull.wakeAll();
- mutex.unlock();
+ {
+ const QMutexLocker locker(&mutex);
+ --numUsedBytes;
+ bufferNotFull.wakeAll();
+ }
}
fprintf(stderr, "\n");
}
-
-signals:
- void stringConsumed(const QString &text);
};
//! [4]
@@ -95,4 +106,3 @@ int main(int argc, char *argv[])
}
//! [6]
-#include "waitconditions.moc"
diff --git a/examples/corelib/tools/CMakeLists.txt b/examples/corelib/tools/CMakeLists.txt
index a8db41edee..0ec145da29 100644
--- a/examples/corelib/tools/CMakeLists.txt
+++ b/examples/corelib/tools/CMakeLists.txt
@@ -1,4 +1,7 @@
-if(NOT TARGET Qt::Widgets)
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT TARGET Qt6::Widgets)
return()
endif()
qt_internal_add_example(contiguouscache)
diff --git a/examples/corelib/tools/contiguouscache/CMakeLists.txt b/examples/corelib/tools/contiguouscache/CMakeLists.txt
index 5c5f8a0b89..1a23099968 100644
--- a/examples/corelib/tools/contiguouscache/CMakeLists.txt
+++ b/examples/corelib/tools/contiguouscache/CMakeLists.txt
@@ -1,8 +1,9 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(contiguouscache LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
@@ -11,6 +12,8 @@ set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/corelib/tools/contiguouscache")
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
+qt_standard_project_setup()
+
qt_add_executable(contiguouscache
main.cpp
randomlistmodel.cpp randomlistmodel.h
@@ -21,10 +24,10 @@ set_target_properties(contiguouscache PROPERTIES
MACOSX_BUNDLE TRUE
)
-target_link_libraries(contiguouscache PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Widgets
+target_link_libraries(contiguouscache PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Widgets
)
install(TARGETS contiguouscache
diff --git a/examples/corelib/tools/customtype/CMakeLists.txt b/examples/corelib/tools/customtype/CMakeLists.txt
index 2d8a0c0f4c..21c9003f56 100644
--- a/examples/corelib/tools/customtype/CMakeLists.txt
+++ b/examples/corelib/tools/customtype/CMakeLists.txt
@@ -1,8 +1,9 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(customtype LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
@@ -11,6 +12,8 @@ set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/corelib/tools/customtype")
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
+qt_standard_project_setup()
+
qt_add_executable(customtype
main.cpp
message.cpp message.h
@@ -21,10 +24,10 @@ set_target_properties(customtype PROPERTIES
MACOSX_BUNDLE TRUE
)
-target_link_libraries(customtype PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Widgets
+target_link_libraries(customtype PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Widgets
)
install(TARGETS customtype
diff --git a/examples/corelib/tools/customtypesending/CMakeLists.txt b/examples/corelib/tools/customtypesending/CMakeLists.txt
index 22e4dd0518..a993d81160 100644
--- a/examples/corelib/tools/customtypesending/CMakeLists.txt
+++ b/examples/corelib/tools/customtypesending/CMakeLists.txt
@@ -1,8 +1,9 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(customtypesending LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
@@ -11,6 +12,8 @@ set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/corelib/tools/customtypesending")
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
+qt_standard_project_setup()
+
qt_add_executable(customtypesending
main.cpp
message.cpp message.h
@@ -22,10 +25,10 @@ set_target_properties(customtypesending PROPERTIES
MACOSX_BUNDLE TRUE
)
-target_link_libraries(customtypesending PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Widgets
+target_link_libraries(customtypesending PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Widgets
)
install(TARGETS customtypesending
diff --git a/examples/dbus/CMakeLists.txt b/examples/dbus/CMakeLists.txt
index d61f1db460..738d1e47f7 100644
--- a/examples/dbus/CMakeLists.txt
+++ b/examples/dbus/CMakeLists.txt
@@ -1,12 +1,14 @@
-if(NOT TARGET Qt::DBus)
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT TARGET Qt6::DBus)
return()
endif()
-qt_internal_add_example(listnames)
qt_internal_add_example(pingpong)
if(QT_FEATURE_process)
qt_internal_add_example(complexpingpong)
endif()
-if(TARGET Qt::Widgets)
+if(TARGET Qt6::Widgets)
qt_internal_add_example(chat)
- add_subdirectory(remotecontrolledcar)
+ qt_internal_add_example(remotecontrolledcar)
endif()
diff --git a/examples/dbus/chat/CMakeLists.txt b/examples/dbus/chat/CMakeLists.txt
index de58094758..b6b17e294d 100644
--- a/examples/dbus/chat/CMakeLists.txt
+++ b/examples/dbus/chat/CMakeLists.txt
@@ -1,11 +1,11 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(chat LANGUAGES CXX)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
-set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTOUIC ON)
-
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
@@ -14,6 +14,8 @@ set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/dbus/chat")
find_package(Qt6 REQUIRED COMPONENTS Core DBus Gui Widgets)
+qt_standard_project_setup()
+
set(chat_SRCS)
qt_add_dbus_interface(chat_SRCS
org.example.chat.xml
@@ -30,7 +32,6 @@ qt_add_dbus_adaptor(chat_SRCS
qt_add_executable(chat
chat.cpp chat.h
chatmainwindow.ui
- chatsetnickname.ui
${chat_SRCS}
)
@@ -39,11 +40,11 @@ set_target_properties(chat PROPERTIES
MACOSX_BUNDLE TRUE
)
-target_link_libraries(chat PUBLIC
- Qt::Core
- Qt::DBus
- Qt::Gui
- Qt::Widgets
+target_link_libraries(chat PRIVATE
+ Qt6::Core
+ Qt6::DBus
+ Qt6::Gui
+ Qt6::Widgets
)
install(TARGETS chat
diff --git a/examples/dbus/chat/chat.cpp b/examples/dbus/chat/chat.cpp
index 41a9f55120..cced911955 100644
--- a/examples/dbus/chat/chat.cpp
+++ b/examples/dbus/chat/chat.cpp
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include <QApplication>
+#include <QInputDialog>
#include <QMessageBox>
#include "chat.h"
@@ -9,105 +10,69 @@
#include "chat_interface.h"
ChatMainWindow::ChatMainWindow()
- : m_nickname(QLatin1String("nickname"))
{
setupUi(this);
- sendButton->setEnabled(false);
- connect(messageLineEdit, SIGNAL(textChanged(QString)),
- this, SLOT(textChangedSlot(QString)));
- connect(sendButton, SIGNAL(clicked(bool)), this, SLOT(sendClickedSlot()));
- connect(actionChangeNickname, SIGNAL(triggered(bool)), this, SLOT(changeNickname()));
- connect(actionAboutQt, SIGNAL(triggered(bool)), this, SLOT(aboutQt()));
- connect(qApp, SIGNAL(lastWindowClosed()), this, SLOT(exiting()));
+ connect(messageLineEdit, &QLineEdit::textChanged, this,
+ [this](const QString &newText) { sendButton->setEnabled(!newText.isEmpty()); });
+ connect(sendButton, &QPushButton::clicked, this, [this]() {
+ emit message(m_nickname, messageLineEdit->text());
+ messageLineEdit->clear();
+ });
+ connect(actionChangeNickname, &QAction::triggered,
+ this, &ChatMainWindow::changeNickname);
+ connect(actionAboutQt, &QAction::triggered, this, [this]() { QMessageBox::aboutQt(this); });
+ connect(qApp, &QApplication::lastWindowClosed, this,
+ [this]() { emit action(m_nickname, tr("leaves the chat")); });
// add our D-Bus interface and connect to D-Bus
new ChatAdaptor(this);
- QDBusConnection::sessionBus().registerObject("/", this);
-
- org::example::chat *iface;
- iface = new org::example::chat(QString(), QString(), QDBusConnection::sessionBus(), this);
- //connect(iface, SIGNAL(message(QString,QString)), this, SLOT(messageSlot(QString,QString)));
- QDBusConnection::sessionBus().connect(QString(), QString(), "org.example.chat", "message", this, SLOT(messageSlot(QString,QString)));
- connect(iface, SIGNAL(action(QString,QString)), this, SLOT(actionSlot(QString,QString)));
-
- NicknameDialog dialog;
- dialog.cancelButton->setVisible(false);
- dialog.exec();
- m_nickname = dialog.nickname->text().trimmed();
- emit action(m_nickname, QLatin1String("joins the chat"));
-}
-ChatMainWindow::~ChatMainWindow()
-{
-}
+ auto connection = QDBusConnection::sessionBus();
+ connection.registerObject("/", this);
-void ChatMainWindow::rebuildHistory()
-{
- QString history = m_messages.join( QLatin1String("\n" ) );
- chatHistory->setPlainText(history);
-}
+ using org::example::chat;
-void ChatMainWindow::messageSlot(const QString &nickname, const QString &text)
-{
- QString msg( QLatin1String("<%1> %2") );
- msg = msg.arg(nickname, text);
- m_messages.append(msg);
+ auto *iface = new chat({}, {}, connection, this);
+ connect(iface, &chat::message, this, [this](const QString &nickname, const QString &text) {
+ displayMessage(tr("<%1> %2").arg(nickname, text));
+ });
+ connect(iface, &chat::action, this, [this](const QString &nickname, const QString &text) {
+ displayMessage(tr("* %1 %2").arg(nickname, text));
+ });
- if (m_messages.count() > 100)
- m_messages.removeFirst();
- rebuildHistory();
+ if (!changeNickname(true))
+ QMetaObject::invokeMethod(qApp, &QApplication::quit, Qt::QueuedConnection);
}
-void ChatMainWindow::actionSlot(const QString &nickname, const QString &text)
+void ChatMainWindow::displayMessage(const QString &message)
{
- QString msg( QLatin1String("* %1 %2") );
- msg = msg.arg(nickname, text);
- m_messages.append(msg);
+ m_messages.append(message);
if (m_messages.count() > 100)
m_messages.removeFirst();
- rebuildHistory();
-}
-
-void ChatMainWindow::textChangedSlot(const QString &newText)
-{
- sendButton->setEnabled(!newText.isEmpty());
-}
-void ChatMainWindow::sendClickedSlot()
-{
- //emit message(m_nickname, messageLineEdit->text());
- QDBusMessage msg = QDBusMessage::createSignal("/", "org.example.chat", "message");
- msg << m_nickname << messageLineEdit->text();
- QDBusConnection::sessionBus().send(msg);
- messageLineEdit->setText(QString());
+ auto history = m_messages.join(QLatin1String("\n"));
+ chatHistory->setPlainText(history);
}
-void ChatMainWindow::changeNickname()
+bool ChatMainWindow::changeNickname(bool initial)
{
- NicknameDialog dialog(this);
- if (dialog.exec() == QDialog::Accepted) {
- QString old = m_nickname;
- m_nickname = dialog.nickname->text().trimmed();
- emit action(old, QString("is now known as %1").arg(m_nickname));
+ auto newNickname = QInputDialog::getText(this, tr("Set nickname"), tr("New nickname:"));
+ newNickname = newNickname.trimmed();
+
+ if (!newNickname.isEmpty()) {
+ auto old = m_nickname;
+ m_nickname = newNickname;
+
+ if (initial)
+ emit action(m_nickname, tr("joins the chat"));
+ else
+ emit action(old, tr("is now known as %1").arg(m_nickname));
+ return true;
}
-}
-
-void ChatMainWindow::aboutQt()
-{
- QMessageBox::aboutQt(this);
-}
-
-void ChatMainWindow::exiting()
-{
- emit action(m_nickname, QLatin1String("leaves the chat"));
-}
-NicknameDialog::NicknameDialog(QWidget *parent)
- : QDialog(parent)
-{
- setupUi(this);
+ return false;
}
int main(int argc, char **argv)
diff --git a/examples/dbus/chat/chat.h b/examples/dbus/chat/chat.h
index aabafcdc95..f7706eeeba 100644
--- a/examples/dbus/chat/chat.h
+++ b/examples/dbus/chat/chat.h
@@ -7,7 +7,6 @@
#include <QStringList>
#include "ui_chatmainwindow.h"
-#include "ui_chatsetnickname.h"
class ChatMainWindow: public QMainWindow, Ui::ChatMainWindow
{
@@ -16,29 +15,16 @@ class ChatMainWindow: public QMainWindow, Ui::ChatMainWindow
QStringList m_messages;
public:
ChatMainWindow();
- ~ChatMainWindow();
- void rebuildHistory();
+private:
+ void displayMessage(const QString &message);
signals:
void message(const QString &nickname, const QString &text);
void action(const QString &nickname, const QString &text);
private slots:
- void messageSlot(const QString &nickname, const QString &text);
- void actionSlot(const QString &nickname, const QString &text);
- void textChangedSlot(const QString &newText);
- void sendClickedSlot();
- void changeNickname();
- void aboutQt();
- void exiting();
-};
-
-class NicknameDialog: public QDialog, public Ui::NicknameDialog
-{
- Q_OBJECT
-public:
- NicknameDialog(QWidget *parent = nullptr);
+ bool changeNickname(bool initial = false);
};
#endif // CHAT_H
diff --git a/examples/dbus/chat/chat.pro b/examples/dbus/chat/chat.pro
index 93d3178177..2b4630d5f1 100644
--- a/examples/dbus/chat/chat.pro
+++ b/examples/dbus/chat/chat.pro
@@ -2,7 +2,7 @@ QT += dbus widgets
HEADERS += chat.h
SOURCES += chat.cpp
-FORMS += chatmainwindow.ui chatsetnickname.ui
+FORMS += chatmainwindow.ui
DBUS_ADAPTORS += org.example.chat.xml
DBUS_INTERFACES += org.example.chat.xml
diff --git a/examples/dbus/chat/chatsetnickname.ui b/examples/dbus/chat/chatsetnickname.ui
deleted file mode 100644
index fb9894e09f..0000000000
--- a/examples/dbus/chat/chatsetnickname.ui
+++ /dev/null
@@ -1,149 +0,0 @@
-<ui version="4.0" >
- <author></author>
- <comment></comment>
- <exportmacro></exportmacro>
- <class>NicknameDialog</class>
- <widget class="QDialog" name="NicknameDialog" >
- <property name="geometry" >
- <rect>
- <x>0</x>
- <y>0</y>
- <width>396</width>
- <height>105</height>
- </rect>
- </property>
- <property name="sizePolicy" >
- <sizepolicy>
- <hsizetype>1</hsizetype>
- <vsizetype>1</vsizetype>
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="windowTitle" >
- <string>Set nickname</string>
- </property>
- <layout class="QVBoxLayout" >
- <property name="margin" >
- <number>9</number>
- </property>
- <property name="spacing" >
- <number>6</number>
- </property>
- <item>
- <layout class="QVBoxLayout" >
- <property name="margin" >
- <number>0</number>
- </property>
- <property name="spacing" >
- <number>6</number>
- </property>
- <item>
- <widget class="QLabel" name="label" >
- <property name="sizePolicy" >
- <sizepolicy>
- <hsizetype>1</hsizetype>
- <vsizetype>1</vsizetype>
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text" >
- <string>New nickname:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLineEdit" name="nickname" />
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" >
- <property name="margin" >
- <number>0</number>
- </property>
- <property name="spacing" >
- <number>6</number>
- </property>
- <item>
- <spacer>
- <property name="orientation" >
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" >
- <size>
- <width>131</width>
- <height>31</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QPushButton" name="okButton" >
- <property name="text" >
- <string>OK</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="cancelButton" >
- <property name="text" >
- <string>Cancel</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer>
- <property name="orientation" >
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" >
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- <pixmapfunction></pixmapfunction>
- <resources/>
- <connections>
- <connection>
- <sender>okButton</sender>
- <signal>clicked()</signal>
- <receiver>NicknameDialog</receiver>
- <slot>accept()</slot>
- <hints>
- <hint type="sourcelabel" >
- <x>278</x>
- <y>253</y>
- </hint>
- <hint type="destinationlabel" >
- <x>96</x>
- <y>254</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>cancelButton</sender>
- <signal>clicked()</signal>
- <receiver>NicknameDialog</receiver>
- <slot>reject()</slot>
- <hints>
- <hint type="sourcelabel" >
- <x>369</x>
- <y>253</y>
- </hint>
- <hint type="destinationlabel" >
- <x>179</x>
- <y>282</y>
- </hint>
- </hints>
- </connection>
- </connections>
-</ui>
diff --git a/examples/dbus/complexpingpong/CMakeLists.txt b/examples/dbus/complexpingpong/CMakeLists.txt
index 88a7764a51..377b56b1ab 100644
--- a/examples/dbus/complexpingpong/CMakeLists.txt
+++ b/examples/dbus/complexpingpong/CMakeLists.txt
@@ -1,8 +1,9 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(complexpingpong LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
@@ -11,6 +12,8 @@ set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/dbus/complexpingpong")
find_package(Qt6 REQUIRED COMPONENTS Core DBus)
+qt_standard_project_setup()
+
qt_add_executable(complexping
complexping.cpp complexping.h
ping-common.h
diff --git a/examples/dbus/complexpingpong/complexping.cpp b/examples/dbus/complexpingpong/complexping.cpp
index 71e3e41b01..9651183c92 100644
--- a/examples/dbus/complexpingpong/complexping.cpp
+++ b/examples/dbus/complexpingpong/complexping.cpp
@@ -5,54 +5,58 @@
#include "complexping.h"
#include <QCoreApplication>
+#include <QDBusInterface>
#include <QDBusReply>
#include <QDBusServiceWatcher>
-#include <QFile>
#include <QDebug>
#include <QProcess>
-#include <stdio.h>
+#include <iostream>
+#include <string>
void Ping::start(const QString &name)
{
if (name != SERVICE_NAME)
return;
- // open stdin for reading
- qstdin.open(stdin, QIODevice::ReadOnly);
-
+ auto connection = QDBusConnection::sessionBus();
// find our remote
- iface = new QDBusInterface(SERVICE_NAME, "/", "org.example.QtDBus.ComplexPong.Pong",
- QDBusConnection::sessionBus(), this);
+ auto iface = new QDBusInterface(SERVICE_NAME, "/", "org.example.QtDBus.ComplexPong.Pong",
+ connection, this);
if (!iface->isValid()) {
- fprintf(stderr, "%s\n",
- qPrintable(QDBusConnection::sessionBus().lastError().message()));
+ qWarning().noquote() << connection.lastError().message();
QCoreApplication::instance()->quit();
}
connect(iface, SIGNAL(aboutToQuit()), QCoreApplication::instance(), SLOT(quit()));
+ std::string s;
+
while (true) {
- printf("Ask your question: ");
+ std::cout << qPrintable(tr("Ask your question: ")) << std::flush;
+
+ std::getline(std::cin, s);
+ auto line = QString::fromStdString(s).trimmed();
- QString line = QString::fromLocal8Bit(qstdin.readLine()).trimmed();
if (line.isEmpty()) {
iface->call("quit");
return;
} else if (line == "value") {
QVariant reply = iface->property("value");
if (!reply.isNull())
- printf("value = %s\n", qPrintable(reply.toString()));
+ std::cout << "value = " << qPrintable(reply.toString()) << std::endl;
} else if (line.startsWith("value=")) {
iface->setProperty("value", line.mid(6));
} else {
QDBusReply<QDBusVariant> reply = iface->call("query", line);
- if (reply.isValid())
- printf("Reply was: %s\n", qPrintable(reply.value().variant().toString()));
+ if (reply.isValid()) {
+ std::cout << qPrintable(tr("Reply was: %1").arg(reply.value().variant().toString()))
+ << std::endl;
+ }
}
if (iface->lastError().isValid())
- fprintf(stderr, "Call failed: %s\n", qPrintable(iface->lastError().message()));
+ qWarning().noquote() << tr("Call failed: %1").arg(iface->lastError().message());
}
}
@@ -61,9 +65,11 @@ int main(int argc, char **argv)
QCoreApplication app(argc, argv);
if (!QDBusConnection::sessionBus().isConnected()) {
- fprintf(stderr, "Cannot connect to the D-Bus session bus.\n"
+ qWarning().noquote() << QCoreApplication::translate(
+ "complexping",
+ "Cannot connect to the D-Bus session bus.\n"
"To start it, run:\n"
- "\teval `dbus-launch --auto-syntax`\n");
+ "\teval `dbus-launch --auto-syntax`");
return 1;
}
diff --git a/examples/dbus/complexpingpong/complexping.h b/examples/dbus/complexpingpong/complexping.h
index cb067993d3..fd566a9bab 100644
--- a/examples/dbus/complexpingpong/complexping.h
+++ b/examples/dbus/complexpingpong/complexping.h
@@ -5,17 +5,12 @@
#define COMPLEXPING_H
#include <QtCore/QObject>
-#include <QtCore/QFile>
-#include <QtDBus/QDBusInterface>
-class Ping: public QObject
+class Ping : public QObject
{
Q_OBJECT
public slots:
- void start(const QString &);
-public:
- QFile qstdin;
- QDBusInterface *iface;
+ void start(const QString &name);
};
#endif
diff --git a/examples/dbus/complexpingpong/complexpong.cpp b/examples/dbus/complexpingpong/complexpong.cpp
index 059153ba36..088b452b30 100644
--- a/examples/dbus/complexpingpong/complexpong.cpp
+++ b/examples/dbus/complexpingpong/complexpong.cpp
@@ -7,12 +7,8 @@
#include <QCoreApplication>
#include <QDBusConnection>
#include <QDBusError>
-#include <QTimer>
+#include <QDebug>
-#include <stdio.h>
-#include <stdlib.h>
-
-// the property
QString Pong::value() const
{
return m_value;
@@ -25,7 +21,8 @@ void Pong::setValue(const QString &newValue)
void Pong::quit()
{
- QTimer::singleShot(0, QCoreApplication::instance(), &QCoreApplication::quit);
+ QMetaObject::invokeMethod(QCoreApplication::instance(), &QCoreApplication::quit,
+ Qt::QueuedConnection);
}
QDBusVariant Pong::query(const QString &query)
@@ -54,12 +51,13 @@ int main(int argc, char **argv)
Pong *pong = new Pong(&obj);
QObject::connect(&app, &QCoreApplication::aboutToQuit, pong, &Pong::aboutToQuit);
pong->setProperty("value", "initial value");
- QDBusConnection::sessionBus().registerObject("/", &obj);
- if (!QDBusConnection::sessionBus().registerService(SERVICE_NAME)) {
- fprintf(stderr, "%s\n",
- qPrintable(QDBusConnection::sessionBus().lastError().message()));
- exit(1);
+ auto connection = QDBusConnection::sessionBus();
+ connection.registerObject("/", &obj);
+
+ if (!connection.registerService(SERVICE_NAME)) {
+ qWarning().noquote() << connection.lastError().message();
+ return 1;
}
app.exec();
diff --git a/examples/dbus/complexpingpong/complexpong.h b/examples/dbus/complexpingpong/complexpong.h
index 56d0badc22..b9328c399e 100644
--- a/examples/dbus/complexpingpong/complexpong.h
+++ b/examples/dbus/complexpingpong/complexpong.h
@@ -8,23 +8,26 @@
#include <QtDBus/QDBusAbstractAdaptor>
#include <QtDBus/QDBusVariant>
-class Pong: public QDBusAbstractAdaptor
+class Pong : public QDBusAbstractAdaptor
{
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "org.example.QtDBus.ComplexPong.Pong")
Q_PROPERTY(QString value READ value WRITE setValue)
public:
- QString m_value;
QString value() const;
void setValue(const QString &newValue);
- Pong(QObject *obj) : QDBusAbstractAdaptor(obj)
- { }
+ Pong(QObject *obj) : QDBusAbstractAdaptor(obj) { }
+
signals:
void aboutToQuit();
+
public slots:
QDBusVariant query(const QString &query);
Q_NOREPLY void quit();
+
+private:
+ QString m_value;
};
#endif
diff --git a/examples/dbus/dbus.pro b/examples/dbus/dbus.pro
index 1b2164c4ae..627f362b38 100644
--- a/examples/dbus/dbus.pro
+++ b/examples/dbus/dbus.pro
@@ -1,8 +1,7 @@
requires(qtHaveModule(dbus))
TEMPLATE = subdirs
-SUBDIRS = listnames \
- pingpong
+SUBDIRS = pingpong
qtConfig(process): SUBDIRS += complexpingpong
diff --git a/examples/dbus/doc/images/dbus-chat-example.png b/examples/dbus/doc/images/dbus-chat-example.png
deleted file mode 100644
index ad66d08950..0000000000
--- a/examples/dbus/doc/images/dbus-chat-example.png
+++ /dev/null
Binary files differ
diff --git a/examples/dbus/doc/images/dbus-chat-example.webp b/examples/dbus/doc/images/dbus-chat-example.webp
new file mode 100644
index 0000000000..82f651a50c
--- /dev/null
+++ b/examples/dbus/doc/images/dbus-chat-example.webp
Binary files differ
diff --git a/examples/dbus/doc/src/chat.qdoc b/examples/dbus/doc/src/chat.qdoc
index a39cf85367..12bd498ac9 100644
--- a/examples/dbus/doc/src/chat.qdoc
+++ b/examples/dbus/doc/src/chat.qdoc
@@ -3,7 +3,7 @@
/*!
\example chat
- \title D-Bus Chat Example
+ \title D-Bus Chat
\ingroup examples-dbus
\brief Demonstrates communication among instances of an application.
@@ -11,7 +11,7 @@
among instances of an application. Users connect and send message to
each other.
- \image dbus-chat-example.png
+ \image dbus-chat-example.webp
\include examples-run.qdocinc
*/
diff --git a/examples/dbus/doc/src/complexpingpong.qdoc b/examples/dbus/doc/src/complexpingpong.qdoc
index 9c8379ad54..0521eafb19 100644
--- a/examples/dbus/doc/src/complexpingpong.qdoc
+++ b/examples/dbus/doc/src/complexpingpong.qdoc
@@ -3,11 +3,11 @@
/*!
\example complexpingpong
- \title D-Bus Complex Ping Pong Example
+ \title D-Bus Complex Ping Pong
\ingroup examples-dbus
\brief Demonstrates usage of the Qt D-Bus typesystem.
- \e{Complex Ping Pong Example} demonstrates the use of \l{Qt D-Bus}
+ \e{Complex Ping Pong} example demonstrates the use of \l{Qt D-Bus}
typesystem with QDBusVariant and QDBusReply. The example consists of the
main application \c complexping which starts the other application, \c
complexpong. Entering keywords such as \c hello and \c ping is handled by
diff --git a/examples/dbus/doc/src/listnames.qdoc b/examples/dbus/doc/src/listnames.qdoc
deleted file mode 100644
index afff9bd920..0000000000
--- a/examples/dbus/doc/src/listnames.qdoc
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
-
-/*!
- \example listnames
- \title D-Bus List Names Example
- \ingroup examples-dbus
- \brief Shows how to access the D-Bus bus daemon service.
-
- \e{List Names} is a command-line example which shows how to
- access the \l{Qt D-Bus} bus daemon service. The example prints various
- information about the bus daemon service.
-
- \include examples-run.qdocinc
-*/
diff --git a/examples/dbus/doc/src/pingpong.qdoc b/examples/dbus/doc/src/pingpong.qdoc
index 29c06adcf3..1e2b114a0e 100644
--- a/examples/dbus/doc/src/pingpong.qdoc
+++ b/examples/dbus/doc/src/pingpong.qdoc
@@ -3,7 +3,7 @@
/*!
\example pingpong
- \title D-Bus Ping Pong Example
+ \title D-Bus Ping Pong
\ingroup examples-dbus
\brief Demonstrates a simple message system using D-Bus.
diff --git a/examples/dbus/listnames/CMakeLists.txt b/examples/dbus/listnames/CMakeLists.txt
deleted file mode 100644
index f646762fd1..0000000000
--- a/examples/dbus/listnames/CMakeLists.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-cmake_minimum_required(VERSION 3.16)
-project(listnames LANGUAGES CXX)
-
-set(CMAKE_AUTOMOC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/dbus/listnames")
-
-find_package(Qt6 REQUIRED COMPONENTS Core DBus)
-
-qt_add_executable(listnames
- listnames.cpp
-)
-
-target_link_libraries(listnames PUBLIC
- Qt::Core
- Qt::DBus
-)
-
-install(TARGETS listnames
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
-)
diff --git a/examples/dbus/listnames/listnames.cpp b/examples/dbus/listnames/listnames.cpp
deleted file mode 100644
index 789b3e941e..0000000000
--- a/examples/dbus/listnames/listnames.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#include <QCoreApplication>
-#include <QDBusConnection>
-#include <QDBusConnectionInterface>
-#include <QDBusInterface>
-#include <QDBusReply>
-#include <QDebug>
-#include <QStringList>
-
-void method1()
-{
- qDebug() << "Method 1:";
-
- QDBusReply<QStringList> reply = QDBusConnection::sessionBus().interface()->registeredServiceNames();
- if (!reply.isValid()) {
- qDebug() << "Error:" << reply.error().message();
- exit(1);
- }
- const QStringList values = reply.value();
- for (const QString &name : values)
- qDebug() << name;
-}
-
-void method2()
-{
- qDebug() << "Method 2:";
-
- QDBusConnection bus = QDBusConnection::sessionBus();
- QDBusInterface dbus_iface("org.freedesktop.DBus", "/org/freedesktop/DBus",
- "org.freedesktop.DBus", bus);
- qDebug() << dbus_iface.call("ListNames").arguments().at(0);
-}
-
-void method3()
-{
- qDebug() << "Method 3:";
- qDebug() << QDBusConnection::sessionBus().interface()->registeredServiceNames().value();
-}
-
-int main(int argc, char **argv)
-{
- QCoreApplication app(argc, argv);
-
- if (!QDBusConnection::sessionBus().isConnected()) {
- fprintf(stderr, "Cannot connect to the D-Bus session bus.\n"
- "To start it, run:\n"
- "\teval `dbus-launch --auto-syntax`\n");
- return 1;
- }
-
- method1();
- method2();
- method3();
-
- return 0;
-}
diff --git a/examples/dbus/listnames/listnames.pro b/examples/dbus/listnames/listnames.pro
deleted file mode 100644
index ed130f7374..0000000000
--- a/examples/dbus/listnames/listnames.pro
+++ /dev/null
@@ -1,8 +0,0 @@
-QT -= gui
-QT += dbus
-win32:CONFIG += console
-
-SOURCES += listnames.cpp
-
-target.path = $$[QT_INSTALL_EXAMPLES]/dbus/listnames
-INSTALLS += target
diff --git a/examples/dbus/pingpong/CMakeLists.txt b/examples/dbus/pingpong/CMakeLists.txt
index 3003a53db1..5d59813784 100644
--- a/examples/dbus/pingpong/CMakeLists.txt
+++ b/examples/dbus/pingpong/CMakeLists.txt
@@ -1,8 +1,9 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(pingpong LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
@@ -11,22 +12,24 @@ set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/dbus/pingpong")
find_package(Qt6 REQUIRED COMPONENTS Core DBus)
+qt_standard_project_setup()
+
qt_add_executable(ping
ping.cpp
ping-common.h
)
-target_link_libraries(ping PUBLIC
+target_link_libraries(ping PRIVATE
Qt6::Core
Qt6::DBus
)
qt_add_executable(pong
ping-common.h
- pong.cpp pong.h
+ pong.cpp
)
-target_link_libraries(pong PUBLIC
+target_link_libraries(pong PRIVATE
Qt6::Core
Qt6::DBus
)
diff --git a/examples/dbus/pingpong/ping.cpp b/examples/dbus/pingpong/ping.cpp
index 17f6b0e3cb..a217107835 100644
--- a/examples/dbus/pingpong/ping.cpp
+++ b/examples/dbus/pingpong/ping.cpp
@@ -8,32 +8,33 @@
#include <QDBusInterface>
#include <QDBusReply>
-#include <stdio.h>
+#include <iostream>
int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);
- if (!QDBusConnection::sessionBus().isConnected()) {
- fprintf(stderr, "Cannot connect to the D-Bus session bus.\n"
- "To start it, run:\n"
- "\teval `dbus-launch --auto-syntax`\n");
+ auto connection = QDBusConnection::sessionBus();
+
+ if (!connection.isConnected()) {
+ qWarning("Cannot connect to the D-Bus session bus.\n"
+ "To start it, run:\n"
+ "\teval `dbus-launch --auto-syntax`\n");
return 1;
}
- QDBusInterface iface(SERVICE_NAME, "/", "", QDBusConnection::sessionBus());
+ QDBusInterface iface(SERVICE_NAME, "/");
if (iface.isValid()) {
QDBusReply<QString> reply = iface.call("ping", argc > 1 ? argv[1] : "");
if (reply.isValid()) {
- printf("Reply was: %s\n", qPrintable(reply.value()));
+ std::cout << "Reply was: " << qPrintable(reply.value()) << std::endl;
return 0;
}
- fprintf(stderr, "Call failed: %s\n", qPrintable(reply.error().message()));
+ qWarning("Call failed: %s\n", qPrintable(reply.error().message()));
return 1;
}
- fprintf(stderr, "%s\n",
- qPrintable(QDBusConnection::sessionBus().lastError().message()));
+ qWarning("%s\n", qPrintable(connection.lastError().message()));
return 1;
}
diff --git a/examples/dbus/pingpong/pong.cpp b/examples/dbus/pingpong/pong.cpp
index 2aad1f10f7..ed8c90195e 100644
--- a/examples/dbus/pingpong/pong.cpp
+++ b/examples/dbus/pingpong/pong.cpp
@@ -2,19 +2,22 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "ping-common.h"
-#include "pong.h"
+#include <QObject>
#include <QCoreApplication>
#include <QDBusConnection>
#include <QDBusError>
-#include <QTimer>
-#include <stdio.h>
-#include <stdlib.h>
+class Pong : public QObject
+{
+ Q_OBJECT
+public slots:
+ QString ping(const QString &arg);
+};
QString Pong::ping(const QString &arg)
{
- QMetaObject::invokeMethod(QCoreApplication::instance(), "quit");
+ QMetaObject::invokeMethod(QCoreApplication::instance(), &QCoreApplication::quit);
return QString("ping(\"%1\") got called").arg(arg);
}
@@ -22,22 +25,25 @@ int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);
- if (!QDBusConnection::sessionBus().isConnected()) {
- fprintf(stderr, "Cannot connect to the D-Bus session bus.\n"
- "To start it, run:\n"
- "\teval `dbus-launch --auto-syntax`\n");
+ auto connection = QDBusConnection::sessionBus();
+
+ if (!connection.isConnected()) {
+ qWarning("Cannot connect to the D-Bus session bus.\n"
+ "To start it, run:\n"
+ "\teval `dbus-launch --auto-syntax`\n");
return 1;
}
- if (!QDBusConnection::sessionBus().registerService(SERVICE_NAME)) {
- fprintf(stderr, "%s\n",
- qPrintable(QDBusConnection::sessionBus().lastError().message()));
+ if (!connection.registerService(SERVICE_NAME)) {
+ qWarning("%s\n", qPrintable(connection.lastError().message()));
exit(1);
}
Pong pong;
- QDBusConnection::sessionBus().registerObject("/", &pong, QDBusConnection::ExportAllSlots);
+ connection.registerObject("/", &pong, QDBusConnection::ExportAllSlots);
app.exec();
return 0;
}
+
+#include "pong.moc"
diff --git a/examples/dbus/pingpong/pong.h b/examples/dbus/pingpong/pong.h
deleted file mode 100644
index f683ec3dfb..0000000000
--- a/examples/dbus/pingpong/pong.h
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#ifndef PONG_H
-#define PONG_H
-
-#include <QtCore/QObject>
-
-class Pong: public QObject
-{
- Q_OBJECT
-public slots:
- Q_SCRIPTABLE QString ping(const QString &arg);
-};
-
-#endif
diff --git a/examples/dbus/pingpong/pong.pro b/examples/dbus/pingpong/pong.pro
index bc78730534..1307e70805 100644
--- a/examples/dbus/pingpong/pong.pro
+++ b/examples/dbus/pingpong/pong.pro
@@ -1,7 +1,7 @@
QT -= gui
QT += dbus
-HEADERS += ping-common.h pong.h
+HEADERS += ping-common.h
SOURCES += pong.cpp
target.path = $$[QT_INSTALL_EXAMPLES]/dbus/pingpong
diff --git a/examples/dbus/remotecontrolledcar/CMakeLists.txt b/examples/dbus/remotecontrolledcar/CMakeLists.txt
index 259d3a0470..1704591026 100644
--- a/examples/dbus/remotecontrolledcar/CMakeLists.txt
+++ b/examples/dbus/remotecontrolledcar/CMakeLists.txt
@@ -1,2 +1,12 @@
-qt_internal_add_example(car)
-qt_internal_add_example(controller)
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+cmake_minimum_required(VERSION 3.16)
+project(remotecontrolledcar LANGUAGES CXX)
+
+find_package(Qt6 REQUIRED COMPONENTS Core DBus Gui Widgets)
+
+qt_standard_project_setup()
+
+add_subdirectory(car)
+add_subdirectory(controller)
diff --git a/examples/dbus/remotecontrolledcar/car/CMakeLists.txt b/examples/dbus/remotecontrolledcar/car/CMakeLists.txt
index 6d2ba75abd..3b95730625 100644
--- a/examples/dbus/remotecontrolledcar/car/CMakeLists.txt
+++ b/examples/dbus/remotecontrolledcar/car/CMakeLists.txt
@@ -1,21 +1,17 @@
-cmake_minimum_required(VERSION 3.16)
-project(car LANGUAGES CXX)
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
set(CMAKE_INCLUDE_CURRENT_DIR ON)
-set(CMAKE_AUTOMOC ON)
-
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/dbus/remotecontrolledcar/car")
-find_package(Qt6 REQUIRED COMPONENTS Core DBus Gui Widgets)
-
set(car_SRCS)
qt_add_dbus_adaptor(car_SRCS
- car.xml
+ ../common/car.xml
qobject.h
"" # empty parent_class value on purpose to not pass -l flag
car_adaptor
@@ -32,11 +28,11 @@ set_target_properties(car PROPERTIES
MACOSX_BUNDLE TRUE
)
-target_link_libraries(car PUBLIC
- Qt::Core
- Qt::DBus
- Qt::Gui
- Qt::Widgets
+target_link_libraries(car PRIVATE
+ Qt6::Core
+ Qt6::DBus
+ Qt6::Gui
+ Qt6::Widgets
)
install(TARGETS car
diff --git a/examples/dbus/remotecontrolledcar/car/car.cpp b/examples/dbus/remotecontrolledcar/car/car.cpp
index 0c1ea3e2d7..7d12e54071 100644
--- a/examples/dbus/remotecontrolledcar/car/car.cpp
+++ b/examples/dbus/remotecontrolledcar/car/car.cpp
@@ -3,18 +3,17 @@
#include "car.h"
#include <QtWidgets/QtWidgets>
-#include <qmath.h>
+#include <cmath>
QRectF Car::boundingRect() const
{
return QRectF(-35, -81, 70, 115);
}
-Car::Car() : color(Qt::green), wheelsAngle(0), speed(0)
+Car::Car()
{
startTimer(1000 / 33);
- setFlag(QGraphicsItem::ItemIsMovable, true);
- setFlag(QGraphicsItem::ItemIsFocusable, true);
+ setFlags(ItemIsMovable | ItemIsFocusable);
}
void Car::accelerate()
@@ -87,7 +86,7 @@ void Car::timerEvent(QTimerEvent *event)
const qreal axelDistance = 54;
qreal wheelsAngleRads = qDegreesToRadians(wheelsAngle);
- qreal turnDistance = ::cos(wheelsAngleRads) * axelDistance * 2;
+ qreal turnDistance = std::cos(wheelsAngleRads) * axelDistance * 2;
qreal turnRateRads = wheelsAngleRads / turnDistance; // rough estimate
qreal turnRate = qRadiansToDegrees(turnRateRads);
qreal rotation = speed * turnRate;
diff --git a/examples/dbus/remotecontrolledcar/car/car.h b/examples/dbus/remotecontrolledcar/car/car.h
index 44654f6647..5a1e199ae0 100644
--- a/examples/dbus/remotecontrolledcar/car/car.h
+++ b/examples/dbus/remotecontrolledcar/car/car.h
@@ -12,25 +12,23 @@ class Car : public QGraphicsObject
Q_OBJECT
public:
Car();
- QRectF boundingRect() const;
+ QRectF boundingRect() const override;
-public Q_SLOTS:
+public slots:
void accelerate();
void decelerate();
void turnLeft();
void turnRight();
-Q_SIGNALS:
- void crashed();
-
protected:
- void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr);
- void timerEvent(QTimerEvent *event);
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
+ QWidget *widget = nullptr) override;
+ void timerEvent(QTimerEvent *event) override;
private:
- QBrush color;
- qreal wheelsAngle; // used when applying rotation
- qreal speed; // delta movement along the body axis
+ QBrush color = Qt::green;
+ qreal wheelsAngle = 0; // used when applying rotation
+ qreal speed = 0; // delta movement along the body axis
};
#endif // CAR_H
diff --git a/examples/dbus/remotecontrolledcar/car/car.pro b/examples/dbus/remotecontrolledcar/car/car.pro
index 5e354e3d0b..4c0f2a1eb9 100644
--- a/examples/dbus/remotecontrolledcar/car/car.pro
+++ b/examples/dbus/remotecontrolledcar/car/car.pro
@@ -1,6 +1,6 @@
QT += dbus widgets
-DBUS_ADAPTORS += car.xml
+DBUS_ADAPTORS += ../common/car.xml
HEADERS += car.h
SOURCES += car.cpp main.cpp
diff --git a/examples/dbus/remotecontrolledcar/car/car.xml b/examples/dbus/remotecontrolledcar/car/car.xml
deleted file mode 100644
index 6d8c9d19f2..0000000000
--- a/examples/dbus/remotecontrolledcar/car/car.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
- "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
-<node name="/com/trollech/examples/car">
- <interface name="org.example.Examples.CarInterface">
- <method name="accelerate"/>
- <method name="decelerate"/>
- <method name="turnLeft"/>
- <method name="turnRight"/>
- <signal name="crashed"/>
- </interface>
-</node> \ No newline at end of file
diff --git a/examples/dbus/remotecontrolledcar/car/main.cpp b/examples/dbus/remotecontrolledcar/car/main.cpp
index c7be72b275..9c732fed5e 100644
--- a/examples/dbus/remotecontrolledcar/car/main.cpp
+++ b/examples/dbus/remotecontrolledcar/car/main.cpp
@@ -16,7 +16,7 @@ int main(int argc, char *argv[])
scene.setSceneRect(-500, -500, 1000, 1000);
scene.setItemIndexMethod(QGraphicsScene::NoIndex);
- Car *car = new Car();
+ auto car = new Car();
scene.addItem(car);
QGraphicsView view(&scene);
@@ -27,7 +27,7 @@ int main(int argc, char *argv[])
view.show();
new CarInterfaceAdaptor(car);
- QDBusConnection connection = QDBusConnection::sessionBus();
+ auto connection = QDBusConnection::sessionBus();
connection.registerObject("/Car", car);
connection.registerService("org.example.CarExample");
diff --git a/examples/dbus/remotecontrolledcar/controller/car.xml b/examples/dbus/remotecontrolledcar/common/car.xml
index 6d8c9d19f2..ea9a000bb8 100644
--- a/examples/dbus/remotecontrolledcar/controller/car.xml
+++ b/examples/dbus/remotecontrolledcar/common/car.xml
@@ -6,6 +6,5 @@
<method name="decelerate"/>
<method name="turnLeft"/>
<method name="turnRight"/>
- <signal name="crashed"/>
</interface>
-</node> \ No newline at end of file
+</node>
diff --git a/examples/dbus/remotecontrolledcar/controller/CMakeLists.txt b/examples/dbus/remotecontrolledcar/controller/CMakeLists.txt
index d150f4a599..e94d79a634 100644
--- a/examples/dbus/remotecontrolledcar/controller/CMakeLists.txt
+++ b/examples/dbus/remotecontrolledcar/controller/CMakeLists.txt
@@ -1,22 +1,17 @@
-cmake_minimum_required(VERSION 3.16)
-project(controller LANGUAGES CXX)
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
set(CMAKE_INCLUDE_CURRENT_DIR ON)
-set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTOUIC ON)
-
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/dbus/remotecontrolledcar/controller")
-find_package(Qt6 REQUIRED COMPONENTS Core DBus Gui Widgets)
-
set(controller_SRCS)
qt_add_dbus_interface(controller_SRCS
- car.xml
+ ../common/car.xml
car_interface
)
@@ -31,11 +26,11 @@ set_target_properties(controller PROPERTIES
MACOSX_BUNDLE TRUE
)
-target_link_libraries(controller PUBLIC
- Qt::Core
- Qt::DBus
- Qt::Gui
- Qt::Widgets
+target_link_libraries(controller PRIVATE
+ Qt6::Core
+ Qt6::DBus
+ Qt6::Gui
+ Qt6::Widgets
)
install(TARGETS controller
diff --git a/examples/dbus/remotecontrolledcar/controller/controller.cpp b/examples/dbus/remotecontrolledcar/controller/controller.cpp
index ab0ec20d22..f5f0fa8866 100644
--- a/examples/dbus/remotecontrolledcar/controller/controller.cpp
+++ b/examples/dbus/remotecontrolledcar/controller/controller.cpp
@@ -1,45 +1,25 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-#include <QtWidgets>
-
#include "controller.h"
-#include "car_interface.h"
-Controller::Controller(QWidget *parent)
- : QWidget(parent)
+using org::example::Examples::CarInterface;
+
+Controller::Controller(QWidget *parent) : QWidget(parent)
{
ui.setupUi(this);
- car = new org::example::Examples::CarInterface("org.example.CarExample", "/Car",
- QDBusConnection::sessionBus(), this);
+ car = new CarInterface("org.example.CarExample", "/Car", QDBusConnection::sessionBus(), this);
+
+ connect(ui.accelerate, &QPushButton::clicked, car, &CarInterface::accelerate);
+ connect(ui.decelerate, &QPushButton::clicked, car, &CarInterface::decelerate);
+ connect(ui.left, &QPushButton::clicked, car, &CarInterface::turnLeft);
+ connect(ui.right, &QPushButton::clicked, car, &CarInterface::turnRight);
+
startTimer(1000);
}
void Controller::timerEvent(QTimerEvent *event)
{
Q_UNUSED(event);
- if (car->isValid())
- ui.label->setText("connected");
- else
- ui.label->setText("disconnected");
-}
-
-void Controller::on_accelerate_clicked()
-{
- car->accelerate();
-}
-
-void Controller::on_decelerate_clicked()
-{
- car->decelerate();
-}
-
-void Controller::on_left_clicked()
-{
- car->turnLeft();
-}
-
-void Controller::on_right_clicked()
-{
- car->turnRight();
+ ui.label->setText(car->isValid() ? tr("connected") : tr("disconnected"));
}
diff --git a/examples/dbus/remotecontrolledcar/controller/controller.h b/examples/dbus/remotecontrolledcar/controller/controller.h
index c4d2838bfc..4fd1833330 100644
--- a/examples/dbus/remotecontrolledcar/controller/controller.h
+++ b/examples/dbus/remotecontrolledcar/controller/controller.h
@@ -12,16 +12,10 @@ class Controller : public QWidget
Q_OBJECT
public:
- Controller(QWidget *parent = nullptr);
+ explicit Controller(QWidget *parent = nullptr);
protected:
- void timerEvent(QTimerEvent *event);
-
-private slots:
- void on_accelerate_clicked();
- void on_decelerate_clicked();
- void on_left_clicked();
- void on_right_clicked();
+ void timerEvent(QTimerEvent *event) override;
private:
Ui::Controller ui;
diff --git a/examples/dbus/remotecontrolledcar/controller/controller.pro b/examples/dbus/remotecontrolledcar/controller/controller.pro
index 07767141f4..eddcbdefdf 100644
--- a/examples/dbus/remotecontrolledcar/controller/controller.pro
+++ b/examples/dbus/remotecontrolledcar/controller/controller.pro
@@ -1,6 +1,6 @@
QT += dbus widgets
-DBUS_INTERFACES += car.xml
+DBUS_INTERFACES += ../common/car.xml
FORMS += controller.ui
HEADERS += controller.h
SOURCES += main.cpp controller.cpp
diff --git a/examples/dbus/remotecontrolledcar/doc/images/remotecontrolledcar-car-example.png b/examples/dbus/remotecontrolledcar/doc/images/remotecontrolledcar-car-example.png
deleted file mode 100644
index 7e08340c80..0000000000
--- a/examples/dbus/remotecontrolledcar/doc/images/remotecontrolledcar-car-example.png
+++ /dev/null
Binary files differ
diff --git a/examples/dbus/remotecontrolledcar/doc/images/remotecontrolledcar-car-example.webp b/examples/dbus/remotecontrolledcar/doc/images/remotecontrolledcar-car-example.webp
new file mode 100644
index 0000000000..cc2f1de3dc
--- /dev/null
+++ b/examples/dbus/remotecontrolledcar/doc/images/remotecontrolledcar-car-example.webp
Binary files differ
diff --git a/examples/dbus/remotecontrolledcar/doc/src/dbus-remotecontrolledcar.qdoc b/examples/dbus/remotecontrolledcar/doc/src/dbus-remotecontrolledcar.qdoc
index 073bf3e435..a9c04e821a 100644
--- a/examples/dbus/remotecontrolledcar/doc/src/dbus-remotecontrolledcar.qdoc
+++ b/examples/dbus/remotecontrolledcar/doc/src/dbus-remotecontrolledcar.qdoc
@@ -3,14 +3,14 @@
/*!
\example remotecontrolledcar
- \title D-Bus Remote Controlled Car Example
+ \title D-Bus Remote Controlled Car
\ingroup examples-dbus
\brief Shows how to use Qt D-Bus to control a car from another application.
The Remote Controlled Car example shows how to use \l{Qt D-Bus} to control
one application from another.
- \image remotecontrolledcar-car-example.png
+ \image remotecontrolledcar-car-example.webp
\include examples-run.qdocinc
*/
diff --git a/examples/embedded/CMakeLists.txt b/examples/embedded/CMakeLists.txt
index 143f40cbcb..1eb8bc7537 100644
--- a/examples/embedded/CMakeLists.txt
+++ b/examples/embedded/CMakeLists.txt
@@ -1,4 +1,7 @@
-if(NOT TARGET Qt::Gui OR (NOT embedded AND NOT x11))
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT TARGET Qt6::Gui OR (NOT embedded AND NOT x11))
return()
endif()
qt_internal_add_example(styleexample)
diff --git a/examples/embedded/digiflip/CMakeLists.txt b/examples/embedded/digiflip/CMakeLists.txt
index c24e42e124..9678c74772 100644
--- a/examples/embedded/digiflip/CMakeLists.txt
+++ b/examples/embedded/digiflip/CMakeLists.txt
@@ -1,8 +1,9 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(digiflip LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
@@ -11,6 +12,8 @@ set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/embedded/digiflip")
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
+qt_standard_project_setup()
+
qt_add_executable(digiflip
digiflip.cpp
)
@@ -20,10 +23,10 @@ set_target_properties(digiflip PROPERTIES
MACOSX_BUNDLE TRUE
)
-target_link_libraries(digiflip PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Widgets
+target_link_libraries(digiflip PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Widgets
)
install(TARGETS digiflip
diff --git a/examples/embedded/digiflip/digiflip.cpp b/examples/embedded/digiflip/digiflip.cpp
index 7497f04e6c..ab5075a4ec 100644
--- a/examples/embedded/digiflip/digiflip.cpp
+++ b/examples/embedded/digiflip/digiflip.cpp
@@ -23,7 +23,8 @@ public:
{
setAttribute(Qt::WA_OpaquePaintEvent, true);
setAttribute(Qt::WA_NoSystemBackground, true);
- connect(&m_animator, SIGNAL(frameChanged(int)), SLOT(update()));
+ connect(&m_animator, &QTimeLine::frameChanged,
+ this, qOverload<>(&Digits::update));
m_animator.setFrameRange(0, 100);
m_animator.setDuration(600);
m_animator.setEasingCurve(QEasingCurve::InOutSine);
@@ -272,9 +273,9 @@ public:
QAction *slideAction = new QAction("&Slide", this);
QAction *flipAction = new QAction("&Flip", this);
QAction *rotateAction = new QAction("&Rotate", this);
- connect(slideAction, SIGNAL(triggered()), SLOT(chooseSlide()));
- connect(flipAction, SIGNAL(triggered()), SLOT(chooseFlip()));
- connect(rotateAction, SIGNAL(triggered()), SLOT(chooseRotate()));
+ connect(slideAction, &QAction::triggered, this, &DigiFlip::chooseSlide);
+ connect(flipAction, &QAction::triggered, this, &DigiFlip::chooseFlip);
+ connect(rotateAction, &QAction::triggered, this, &DigiFlip::chooseRotate);
addAction(slideAction);
addAction(flipAction);
addAction(rotateAction);
diff --git a/examples/embedded/flickable/CMakeLists.txt b/examples/embedded/flickable/CMakeLists.txt
index 0dc5051eec..835d4ec77a 100644
--- a/examples/embedded/flickable/CMakeLists.txt
+++ b/examples/embedded/flickable/CMakeLists.txt
@@ -1,8 +1,9 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(flickable LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
@@ -11,6 +12,8 @@ set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/embedded/flickable")
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
+qt_standard_project_setup()
+
qt_add_executable(flickable
flickable.cpp flickable.h
main.cpp
@@ -21,10 +24,10 @@ set_target_properties(flickable PROPERTIES
MACOSX_BUNDLE TRUE
)
-target_link_libraries(flickable PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Widgets
+target_link_libraries(flickable PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Widgets
)
install(TARGETS flickable
diff --git a/examples/embedded/flightinfo/CMakeLists.txt b/examples/embedded/flightinfo/CMakeLists.txt
index 25309199b3..8e31aedd49 100644
--- a/examples/embedded/flightinfo/CMakeLists.txt
+++ b/examples/embedded/flightinfo/CMakeLists.txt
@@ -1,9 +1,9 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(flightinfo LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTOUIC ON)
-
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
@@ -12,6 +12,8 @@ set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/embedded/flightinfo")
find_package(Qt6 REQUIRED COMPONENTS Core Gui Network Widgets)
+qt_standard_project_setup()
+
qt_add_executable(flightinfo
flightinfo.cpp
form.ui
@@ -22,11 +24,11 @@ set_target_properties(flightinfo PROPERTIES
MACOSX_BUNDLE TRUE
)
-target_link_libraries(flightinfo PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Network
- Qt::Widgets
+target_link_libraries(flightinfo PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Network
+ Qt6::Widgets
)
# Resources:
diff --git a/examples/embedded/flightinfo/flightinfo.cpp b/examples/embedded/flightinfo/flightinfo.cpp
index c4d81177e7..6a5eb55d99 100644
--- a/examples/embedded/flightinfo/flightinfo.cpp
+++ b/examples/embedded/flightinfo/flightinfo.cpp
@@ -71,8 +71,8 @@ public:
ui.searchBar->hide();
ui.infoBox->hide();
- connect(ui.searchButton, SIGNAL(clicked()), SLOT(startSearch()));
- connect(ui.flightEdit, SIGNAL(returnPressed()), SLOT(startSearch()));
+ connect(ui.searchButton, &QPushButton::clicked, this, &FlightInfo::startSearch);
+ connect(ui.flightEdit, &QLineEdit::returnPressed, this, &FlightInfo::startSearch);
setWindowTitle("Flight Info");
@@ -83,11 +83,11 @@ public:
QAction *searchTodayAction = new QAction("Today's Flight", this);
QAction *searchYesterdayAction = new QAction("Yesterday's Flight", this);
QAction *randomAction = new QAction("Random Flight", this);
- connect(searchTodayAction, SIGNAL(triggered()), SLOT(today()));
- connect(searchYesterdayAction, SIGNAL(triggered()), SLOT(yesterday()));
- connect(randomAction, SIGNAL(triggered()), SLOT(randomFlight()));
- connect(&m_manager, SIGNAL(finished(QNetworkReply*)),
- this, SLOT(handleNetworkData(QNetworkReply*)));
+ connect(searchTodayAction, &QAction::triggered, this, &FlightInfo::today);
+ connect(searchYesterdayAction, &QAction::triggered, this, &FlightInfo::yesterday);
+ connect(randomAction, &QAction::triggered, this, &FlightInfo::randomFlight);
+ connect(&m_manager, &QNetworkAccessManager::finished,
+ this, &FlightInfo::handleNetworkData);
addAction(searchTodayAction);
addAction(searchYesterdayAction);
addAction(randomAction);
diff --git a/examples/embedded/lightmaps/CMakeLists.txt b/examples/embedded/lightmaps/CMakeLists.txt
index e7feccab7d..c637aa705c 100644
--- a/examples/embedded/lightmaps/CMakeLists.txt
+++ b/examples/embedded/lightmaps/CMakeLists.txt
@@ -1,8 +1,9 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(lightmaps LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
@@ -11,6 +12,8 @@ set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/embedded/lightmaps")
find_package(Qt6 REQUIRED COMPONENTS Core Gui Network Widgets)
+qt_standard_project_setup()
+
qt_add_executable(lightmaps
lightmaps.cpp lightmaps.h
main.cpp
@@ -23,11 +26,11 @@ set_target_properties(lightmaps PROPERTIES
MACOSX_BUNDLE TRUE
)
-target_link_libraries(lightmaps PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Network
- Qt::Widgets
+target_link_libraries(lightmaps PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Network
+ Qt6::Widgets
)
install(TARGETS lightmaps
diff --git a/examples/embedded/lightmaps/lightmaps.cpp b/examples/embedded/lightmaps/lightmaps.cpp
index 5f62f926b4..566ba243ee 100644
--- a/examples/embedded/lightmaps/lightmaps.cpp
+++ b/examples/embedded/lightmaps/lightmaps.cpp
@@ -24,8 +24,8 @@ LightMaps::LightMaps(QWidget *parent)
{
m_normalMap = new SlippyMap(this);
m_largeMap = new SlippyMap(this);
- connect(m_normalMap, SIGNAL(updated(QRect)), SLOT(updateMap(QRect)));
- connect(m_largeMap, SIGNAL(updated(QRect)), SLOT(update()));
+ connect(m_normalMap, &SlippyMap::updated, this, &LightMaps::updateMap);
+ connect(m_largeMap, &SlippyMap::updated, this, &LightMaps::updateMap);
}
void LightMaps::setCenter(qreal lat, qreal lng)
diff --git a/examples/embedded/raycasting/CMakeLists.txt b/examples/embedded/raycasting/CMakeLists.txt
index b2e66c2442..7186fddb8f 100644
--- a/examples/embedded/raycasting/CMakeLists.txt
+++ b/examples/embedded/raycasting/CMakeLists.txt
@@ -1,8 +1,9 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(raycasting LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
@@ -11,6 +12,8 @@ set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/embedded/raycasting")
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
+qt_standard_project_setup()
+
qt_add_executable(raycasting
raycasting.cpp
)
@@ -20,10 +23,10 @@ set_target_properties(raycasting PROPERTIES
MACOSX_BUNDLE TRUE
)
-target_link_libraries(raycasting PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Widgets
+target_link_libraries(raycasting PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Widgets
)
# Resources:
diff --git a/examples/embedded/styleexample/CMakeLists.txt b/examples/embedded/styleexample/CMakeLists.txt
index 2d1547ab9c..becc8dbb84 100644
--- a/examples/embedded/styleexample/CMakeLists.txt
+++ b/examples/embedded/styleexample/CMakeLists.txt
@@ -1,9 +1,9 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(styleexample LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTOUIC ON)
-
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
@@ -12,6 +12,8 @@ set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/embedded/styleexample")
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
+qt_standard_project_setup()
+
qt_add_executable(styleexample
main.cpp
stylewidget.cpp stylewidget.h stylewidget.ui
@@ -22,10 +24,10 @@ set_target_properties(styleexample PROPERTIES
MACOSX_BUNDLE TRUE
)
-target_link_libraries(styleexample PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Widgets
+target_link_libraries(styleexample PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Widgets
)
# Resources:
diff --git a/examples/gui/CMakeLists.txt b/examples/gui/CMakeLists.txt
index 0abfb9ba86..8eda006a11 100644
--- a/examples/gui/CMakeLists.txt
+++ b/examples/gui/CMakeLists.txt
@@ -1,5 +1,8 @@
-if(NOT TARGET Qt::Gui)
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT TARGET Qt6::Gui)
return()
endif()
-qt_internal_add_example(analogclock)
qt_internal_add_example(rasterwindow)
+qt_internal_add_example(rhiwindow)
diff --git a/examples/gui/analogclock/CMakeLists.txt b/examples/gui/analogclock/CMakeLists.txt
deleted file mode 100644
index a5f6eac377..0000000000
--- a/examples/gui/analogclock/CMakeLists.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-cmake_minimum_required(VERSION 3.16)
-project(analogclock LANGUAGES CXX)
-
-set(CMAKE_AUTOMOC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/gui/gui_analogclock")
-
-find_package(Qt6 REQUIRED COMPONENTS Core Gui)
-
-qt_add_executable(gui_analogclock
- ../rasterwindow/rasterwindow.cpp ../rasterwindow/rasterwindow.h
- main.cpp
-)
-
-set_target_properties(gui_analogclock PROPERTIES
- WIN32_EXECUTABLE TRUE
- MACOSX_BUNDLE TRUE
-)
-
-target_include_directories(gui_analogclock PUBLIC
- ../rasterwindow
-)
-
-target_link_libraries(gui_analogclock PUBLIC
- Qt::Core
- Qt::Gui
-)
-
-install(TARGETS gui_analogclock
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
-)
diff --git a/examples/gui/analogclock/analogclock.pro b/examples/gui/analogclock/analogclock.pro
deleted file mode 100644
index eef17274f5..0000000000
--- a/examples/gui/analogclock/analogclock.pro
+++ /dev/null
@@ -1,10 +0,0 @@
-include(../rasterwindow/rasterwindow.pri)
-
-# work-around for QTBUG-13496
-CONFIG += no_batch
-
-SOURCES += \
- main.cpp
-
-target.path = $$[QT_INSTALL_EXAMPLES]/gui/analogclock
-INSTALLS += target
diff --git a/examples/gui/analogclock/main.cpp b/examples/gui/analogclock/main.cpp
deleted file mode 100644
index 8e0a061057..0000000000
--- a/examples/gui/analogclock/main.cpp
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#include <QtGui>
-
-#include "rasterwindow.h"
-
-//! [5]
-class AnalogClockWindow : public RasterWindow
-{
-public:
- AnalogClockWindow();
-
-protected:
- void timerEvent(QTimerEvent *) override;
- void render(QPainter *p) override;
-
-private:
- int m_timerId;
-};
-//! [5]
-
-
-//! [6]
-AnalogClockWindow::AnalogClockWindow()
-{
- setTitle("Analog Clock");
- resize(200, 200);
-
- m_timerId = startTimer(1000);
-}
-//! [6]
-
-//! [7]
-void AnalogClockWindow::timerEvent(QTimerEvent *event)
-{
- if (event->timerId() == m_timerId)
- renderLater();
-}
-//! [7]
-
-//! [1] //! [14]
-void AnalogClockWindow::render(QPainter *p)
-{
-//! [14]
-//! [8]
- static const QPoint hourHand[3] = {
- QPoint(7, 8),
- QPoint(-7, 8),
- QPoint(0, -40)
- };
- static const QPoint minuteHand[3] = {
- QPoint(7, 8),
- QPoint(-7, 8),
- QPoint(0, -70)
- };
-
- QColor hourColor(127, 0, 127);
- QColor minuteColor(0, 127, 127, 191);
-//! [8]
-
-//! [9]
- p->setRenderHint(QPainter::Antialiasing);
-//! [9] //! [10]
- p->translate(width() / 2, height() / 2);
-
- int side = qMin(width(), height());
- p->scale(side / 200.0, side / 200.0);
-//! [1] //! [10]
-
-//! [11]
- p->setPen(Qt::NoPen);
- p->setBrush(hourColor);
-//! [11]
-
-//! [2]
- QTime time = QTime::currentTime();
-
- p->save();
- p->rotate(30.0 * ((time.hour() + time.minute() / 60.0)));
- p->drawConvexPolygon(hourHand, 3);
- p->restore();
-//! [2]
-
-//! [12]
- p->setPen(hourColor);
-
- for (int i = 0; i < 12; ++i) {
- p->drawLine(88, 0, 96, 0);
- p->rotate(30.0);
- }
-//! [12] //! [13]
- p->setPen(Qt::NoPen);
- p->setBrush(minuteColor);
-//! [13]
-
-//! [3]
- p->save();
- p->rotate(6.0 * (time.minute() + time.second() / 60.0));
- p->drawConvexPolygon(minuteHand, 3);
- p->restore();
-//! [3]
-
-//! [4]
- p->setPen(minuteColor);
-
- for (int j = 0; j < 60; ++j) {
- if ((j % 5) != 0)
- p->drawLine(92, 0, 96, 0);
- p->rotate(6.0);
- }
-//! [4]
-}
-
-int main(int argc, char **argv)
-{
- QGuiApplication app(argc, argv);
-
- AnalogClockWindow clock;
- clock.show();
-
- return app.exec();
-}
diff --git a/examples/gui/doc/images/analogclock-window-example.png b/examples/gui/doc/images/analogclock-window-example.png
deleted file mode 100644
index f5e92e400a..0000000000
--- a/examples/gui/doc/images/analogclock-window-example.png
+++ /dev/null
Binary files differ
diff --git a/examples/gui/doc/images/analogclockwindow-viewport.png b/examples/gui/doc/images/analogclockwindow-viewport.png
deleted file mode 100644
index 31ce0c3c6e..0000000000
--- a/examples/gui/doc/images/analogclockwindow-viewport.png
+++ /dev/null
Binary files differ
diff --git a/examples/gui/doc/images/rhiwindow_example.jpg b/examples/gui/doc/images/rhiwindow_example.jpg
new file mode 100644
index 0000000000..ca1e44bada
--- /dev/null
+++ b/examples/gui/doc/images/rhiwindow_example.jpg
Binary files differ
diff --git a/examples/gui/doc/src/analogclockwindow.qdoc b/examples/gui/doc/src/analogclockwindow.qdoc
deleted file mode 100644
index 7ae13821dd..0000000000
--- a/examples/gui/doc/src/analogclockwindow.qdoc
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
-
-/*!
- \example analogclock
- \title Analog Clock Window Example
-
- \brief The Analog Clock Window example shows how to draw the contents of
- a custom window.
-
- \image analogclock-window-example.png Screenshot of the Analog
- Clock Window example
-
- This example demonstrates how the transformation and scaling
- features of QPainter can be used to make drawing easier.
-
- \section1 AnalogClockWindow Class Definition
-
- The \c AnalogClockWindow class provides a clock with hour and
- minute hands that is automatically updated every few seconds. We
- make use of the RasterWindow from the \l {Raster Window Example}
- and reimplement the \c render function to draw the clock face:
-
- \snippet analogclock/main.cpp 5
-
- \section1 AnalogClock Class Implementation
-
- \snippet analogclock/main.cpp 6
-
- We set a title on the window and resize to a reasonable size. Then
- we start a timer which we will use to redraw the clock every
- second.
-
- \snippet analogclock/main.cpp 7
-
- The timerEvent function is called every second as a result of
- our startTimer call. Making use of the convenience in the base
- class, we schedule the window to be repainted.
-
- Checking the timer's id is not strictly needed as we only have
- one active timer in this instance, but it is good practice to do
- so.
-
- \snippet analogclock/main.cpp 14
- \snippet analogclock/main.cpp 8
-
- Before we set up the painter and draw the clock, we first define
- two lists of \l {QPoint}s and two \l{QColor}s that will be used
- for the hour and minute hands. The minute hand's color has an
- alpha component of 191, meaning that it's 75% opaque.
-
- \snippet analogclock/main.cpp 9
-
- We call QPainter::setRenderHint() with QPainter::Antialiasing to
- turn on antialiasing. This makes drawing of diagonal lines much
- smoother.
-
- \snippet analogclock/main.cpp 10
-
- The translation moves the origin to the center of the window, and
- the scale operation ensures that the following drawing operations
- are scaled to fit within the window. We use a scale factor that
- let's us use x and y coordinates between -100 and 100, and that
- ensures that these lie within the length of the window's shortest
- side.
-
- To make our code simpler, we will draw a fixed size clock face that will
- be positioned and scaled so that it lies in the center of the window.
-
- We also determine the length of the window's shortest side so that we
- can fit the clock face inside the window.
-
- The painter takes care of all the transformations made during the
- rendering, and ensures that everything is drawn correctly. Letting
- the painter handle transformations is often easier than performing
- manual calculations.
-
- \image analogclockwindow-viewport.png
-
- We draw the hour hand first, using a formula that rotates the coordinate
- system counterclockwise by a number of degrees determined by the current
- hour and minute. This means that the hand will be shown rotated clockwise
- by the required amount.
-
- \snippet analogclock/main.cpp 11
-
- We set the pen to be Qt::NoPen because we don't want any outline,
- and we use a solid brush with the color appropriate for
- displaying hours. Brushes are used when filling in polygons and
- other geometric shapes.
-
- \snippet analogclock/main.cpp 2
-
- We save and restore the transformation matrix before and after the
- rotation because we want to place the minute hand without having to
- take into account any previous rotations.
-
- \snippet analogclock/main.cpp 12
-
- We draw markers around the edge of the clock for each hour. We
- draw each marker then rotate the coordinate system so that the
- painter is ready for the next one.
-
- \snippet analogclock/main.cpp 13
- \snippet analogclock/main.cpp 3
-
- The minute hand is rotated in a similar way to the hour hand.
-
- \snippet analogclock/main.cpp 4
-
- Again, we draw markers around the edge of the clock, but this
- time to indicate minutes. We skip multiples of 5 to avoid drawing
- minute markers on top of hour markers.
-*/
diff --git a/examples/gui/doc/src/rhiwindow.qdoc b/examples/gui/doc/src/rhiwindow.qdoc
new file mode 100644
index 0000000000..478ac8a1b4
--- /dev/null
+++ b/examples/gui/doc/src/rhiwindow.qdoc
@@ -0,0 +1,439 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \example rhiwindow
+ \title RHI Window Example
+
+ \brief This example shows how to create a minimal QWindow-based
+ application using QRhi.
+
+ \image rhiwindow_example.jpg
+
+ Qt 6.6 starts offering its accelerated 3D API and shader abstraction layer
+ for application use as well. Applications can now use the same 3D graphics
+ classes Qt itself uses to implement the Qt Quick scenegraph or the Qt Quick
+ 3D engine. In earlier Qt versions QRhi and the related classes were all
+ private APIs. From 6.6 on these classes are in a similar category as QPA
+ family of classes: neither fully public nor private, but something
+ in-between, with a more limited compatibility promise compared to public
+ APIs. On the other hand, QRhi and the related classes now come with full
+ documentation similarly to public APIs.
+
+ There are multiple ways to use QRhi, the example here shows the most
+ low-level approach: targeting a QWindow, while not using Qt Quick, Qt Quick
+ 3D, or Widgets in any form, and setting up all the rendering and windowing
+ infrastructure in the application.
+
+ In contrast, when writing a QML application with Qt Quick or Qt Quick 3D,
+ and wanting to add QRhi-based rendering to it, such an application is going
+ to rely on the window and rendering infrastructure Qt Quick has already
+ initialized, and it is likely going to query an existing QRhi instance from
+ the QQuickWindow. There dealing with QRhi::create(), platform/API specifics
+ such as \l{QVulkanInstance}{Vulkan instances}, or correctly handling
+ \l{QExposeEvent}{expose} and resize events for the window are all managed
+ by Qt Quick. Whereas in this example, all that is managed and taken care
+ of by the application itself.
+
+ \note For QWidget-based applications in particular, it should be noted that
+ QWidget::createWindowContainer() allows embedding a QWindow (backed by a
+ native window) into the widget-based user interface. Therefore, the \c
+ HelloWindow class from this example is reusable in QWidget-based
+ applications, assuming the necessary initialization from \c main() is in
+ place as well.
+
+ \section1 3D API Support
+
+ The application supports all the current \l{QRhi::Implementation}{QRhi
+ backends}. When no command-line arguments are specified, platform-specific
+ defaults are used: Direct 3D 11 on Windows, OpenGL on Linux, Metal on
+ macOS/iOS.
+
+ Running with \c{--help} shows the available command-line options:
+
+ \list
+ \li -d or --d3d11 for Direct 3D 11
+ \li -D or --d3d12 for Direct 3D 12
+ \li -m or --metal for Metal
+ \li -v or --vulkan for Vulkan
+ \li -g or --opengl for OpenGL or OpenGL ES
+ \li -n or --null for the \l{QRhi::Null}{Null backend}
+ \endlist
+
+ \section1 Build System Notes
+
+ This application relies solely on the Qt GUI module. It does not use Qt
+ Widgets or Qt Quick.
+
+ In order to access the RHI APIs, which are available to all Qt applications
+ but come with a limited compatibility promise, the \c target_link_libraries
+ CMake command lists \c{Qt6::GuiPrivate}. This is what enables the
+ \c{#include <rhi/qrhi.h>} include statement to compile successfully.
+
+ \section1 Features
+
+ The application features:
+
+ \list
+
+ \li A resizable QWindow,
+
+ \li a swapchain and depth-stencil buffer that properly follows the size of
+ the window,
+
+ \li logic to initialize, render, and tear down at the appropriate time
+ based on events such as \l QExposeEvent and \l QPlatformSurfaceEvent,
+
+ \li rendering a fullscreen textured quad, using a texture the contents of
+ which is generated in a QImage via QPainter (using the raster paint engine,
+ i.e. the generating of the image's pixel data is all CPU-based, that data
+ is then uploaded into a GPU texture),
+
+ \li rendering a triangle with blending and depth testing enabled, using a
+ perspective projection, while applying a model transform that changes on
+ every frame,
+
+ \li an efficient, cross-platform render loop using
+ \l{QWindow::requestUpdate()}{requestUpdate()}.
+
+ \endlist
+
+ \section1 Shaders
+
+ The application uses two sets of vertex and fragment shader pairs:
+
+ \list
+
+ \li one for the fullscreen quad, which uses no vertex inputs and the
+ fragment shader samples a texture (\c quad.vert, \c quad.frag),
+
+ \li and another pair for the triangle, where vertex positions and colors
+ are provided in a vertex buffer and a modelview-projection matrix is
+ provided in a uniform buffer (\c color.vert, \c color.frag).
+
+ \endlist
+
+ The shaders are written as Vulkan-compatible GLSL source code.
+
+ Due to being a Qt GUI module example, this example cannot have a dependency
+ on the \l{Qt Shader Tools} module. This means that CMake helper functions
+ such as \c{qt_add_shaders} are not available for use. Therefore, the
+ example has the pre-processed \c{.qsb} files included in the
+ \c{shaders/prebuilt} folder, and they are simply included within the
+ executable via \c{qt_add_resources}. This approach is not generally
+ recommended for applications, consider rather using \l{Qt Shader Tools
+ Build System Integration}{qt_add_shaders}, which avoids the need to
+ manually generate and manage the \c{.qsb} files.
+
+ To generate the \c{.qsb} files for this example, the command \c{qsb --qt6
+ color.vert -o prebuilt/color.vert.qsb} etc. was used. This leads to
+ compiling to \l{https://www.khronos.org/spir/}{SPIR-V} and than transpiling
+ into GLSL (\c{100 es} and \c 120), HLSL (5.0), and MSL (1.2). All the
+ shader versions are then packed together into a QShader and serialized to
+ disk.
+
+ \section1 API-specific Initialization
+
+ For some of the 3D APIs the main() function has to perform the appropriate
+ API-specific initialiation, e.g. to create a QVulkanInstance when using
+ Vulkan. For OpenGL we have to ensure a depth buffer is available, this is
+ done via QSurfaceFormat. These steps are not in the scope of QRhi since
+ QRhi backends for OpenGL or Vulkan build on the existing Qt facilities such
+ as QOpenGLContext or QVulkanInstance.
+
+ \snippet rhiwindow/main.cpp api-setup
+
+ \note For Vulkan, note how
+ QRhiVulkanInitParams::preferredInstanceExtensions() is taken into account
+ to ensure the appropriate extensions are enabled.
+
+ \c HelloWindow is a subclass of \c RhiWindow, which in turn is a QWindow.
+ \c RhiWindow contains everything needed to manage a resizable window with
+ a\ swapchain (and depth-stencil buffer), and is potentially reusable in
+ other applications as well. \c HelloWindow contains the rendering logic
+ specific to this particular example application.
+
+ In the QWindow subclass constructor the surface type is set based on the
+ selected 3D API.
+
+ \snippet rhiwindow/rhiwindow.cpp rhiwindow-ctor
+
+ Creating and initializing a QRhi object is implemented in
+ RhiWindow::init(). Note that this is invoked only when the window is
+ \c renderable, which is indicated by an \l{QExposeEvent}{expose event}.
+
+ Depending on which 3D API we use, the appropriate InitParams struct needs
+ to be passed to QRhi::create(). With OpenGL for example, a
+ QOffscreenSurface (or some other QSurface) must be created by the
+ application and provided for use to the QRhi. With Vulkan, a successfully
+ initialized QVulkanInstance is required. Others, such as Direct 3D or Metal
+ need no additional information to be able to initialize.
+
+ \snippet rhiwindow/rhiwindow.cpp rhi-init
+
+ Apart from this, everything else, all the rendering code, is fully
+ cross-platform and has no branching or conditions specific to any of the 3D
+ API.
+
+ \section1 Expose Events
+
+ What \c renderable exactly means is platform-specific. For example, on
+ macOS a window that is fully obscured (fully behind some other window) is
+ not renderable, whereas on Windows obscuring has no significance.
+ Fortunately, the application needs no special knowledge about this: Qt's
+ platform plugins abstract the differences behind the expose event. However,
+ the \l{QWindow::exposeEvent()}{exposeEvent()} reimplementation also needs
+ to be aware that an empty output size (e.g. width and height of 0) is also
+ something that should be treated as a non-renderable situation. On Windows
+ for example, this is what is going to happen when minimizing the window.
+ Hence the check based on QRhiSwapChain::surfacePixelSize().
+
+ This implementation of expose event handling attempts to be robust, safe,
+ and portable. Qt Quick itself also implements a very similar logic in its
+ render loops.
+
+ \snippet rhiwindow/rhiwindow.cpp expose
+
+ In RhiWindow::render(), which is invoked in response to the
+ \l{QEvent::UpdateRequest}{UpdateRequest} event generated by
+ \l{QWindow::requestUpdate()}{requestUpdate()}, the following check is in
+ place, to prevent attempting to render when the swapchain initialization
+ failed, or when the window became non-renderable.
+
+ \snippet rhiwindow/rhiwindow.cpp render-precheck
+
+ \section1 Swapchain, Depth-Stencil buffer, and Resizing
+
+ To render to the QWindow, a QRhiSwapChain is needed. In addition, a
+ QRhiRenderBuffer acting as the depth-stencil buffer is created as well
+ since the application demonstrates how depth testing can be enabled in a
+ graphics pipeline. With some legacy 3D APIs managing the depth/stencil
+ buffer for a window is part of the corresponding windowing system interface
+ API (EGL, WGL, GLX, etc., meaning the depth/stencil buffer is implicitly
+ managed together with the \c{window surface}), whereas with modern APIs
+ managing the depth-stencil buffer for a window-based render target is no
+ different from offscreen render targets. QRhi abstracts this, but for best
+ performance it still needs to be indicated that the QRhiRenderBuffer is
+ \l{QRhiRenderBuffer::UsedWithSwapChainOnly}{used with together with a
+ QRhiSwapChain}.
+
+ The QRhiSwapChain is associated with the QWindow and the depth/stencil
+ buffer.
+
+ \snippet rhiwindow/rhiwindow.cpp swapchain-data
+
+ \snippet rhiwindow/rhiwindow.cpp swapchain-init
+
+ When the window size changes, the swapchain needs to be resized as well.
+ This is implemented in resizeSwapChain().
+
+ \snippet rhiwindow/rhiwindow.cpp swapchain-resize
+
+ Unlike other QRhiResource subclasses, QRhiSwapChain features slightly
+ different semantics when it comes to its create-function. As the name,
+ \l{QRhiSwapChain::createOrResize()}{createOrResize()}, suggests, this needs
+ to be called whenever it is known that the output window size may be out of
+ sync with what the swapchain was last initialized. The associated
+ QRhiRenderBuffer for depth-stencil gets its
+ \l{QRhiRenderBuffer::pixelSize()}{size} set automatically, and
+ \l{QRhiRenderBuffer::create()}{create()} is called on it implicitly from the
+ swapchain's createOrResize().
+
+ This is also a convenient place to (re)calculate the projection and view
+ matrices since the perspective projection we set up depends on the output
+ aspect ratio.
+
+ \note To eliminate coordinate system differences, the
+ \l{QRhi::clipSpaceCorrMatrix()}{a backend/API-specific "correction" matrix}
+ is queried from QRhi and baked in to the projection matrix. This is what
+ allows the application to work with OpenGL-style vertex data, assuming a
+ coordinate system with the origin at the bottom-left.
+
+ The resizeSwapChain() function is called from RhiWindow::render() when it
+ is discovered that the currently reported size is not the same anymore as
+ what the swapchain was last initialized with.
+
+ See QRhiSwapChain::currentPixelSize() and QRhiSwapChain::surfacePixelSize()
+ for further details.
+
+ High DPI support is built-in: the sizes, as the naming indicates, are
+ always in pixels, taking the window-specific
+ \l{QWindow::devicePixelRatio()}{scale factor} into account. On the QRhi
+ (and 3D API) level there is no concept of high DPI scaling, everything is
+ always in pixels. This means that a QWindow with a size() of 1280x720 and
+ a devicePixelRatio() of 2 is a render target (swapchain) with a (pixel) size
+ of 2560x1440.
+
+ \snippet rhiwindow/rhiwindow.cpp render-resize
+
+ \section1 Render Loop
+
+ The application renders continuously, throttled by the presentation rate
+ (vsync). This is ensured by calling
+ \l{QWindow::requestUpdate()}{requestUpdate()} from RhiWindow::render() when
+ the currently recorded frame has been submitted.
+
+ \snippet rhiwindow/rhiwindow.cpp request-update
+
+ This eventually leads to getting a \l{QEvent::UpdateRequest}{UpdateRequest}
+ event. This is handled in the reimplementation of event().
+
+ \snippet rhiwindow/rhiwindow.cpp event
+
+ \section1 Resource and Pipeline Setup
+
+ The application records a single render pass that issues two draw calls,
+ with two different graphics pipelines. One is the "background", with the
+ texture containing the QPainter-generated image, then a single triangle is
+ rendered on top with blending enabled.
+
+ The vertex and uniform buffer used with the triangle is created like this.
+ The size of the uniform buffer is 68 bytes since the shader specific a \c
+ mat4 and a \c float member in the uniform block. Watch out for the
+ \l{https://registry.khronos.org/OpenGL/specs/gl/glspec45.core.pdf#page=159}{std140
+ layout rules}. This presents no surprises in this example since the \c
+ float member that follows the \c mat4 has the correct alignment without any
+ additional padding, but it may become relevant in other applications,
+ especially when working with types such as \c vec2 or \c vec3. When in
+ doubt, consider checking the QShaderDescription for the
+ \l{QShader::description()}{QShader}, or, what is often more convenient, run
+ the \c qsb tool on the \c{.qsb} file with the \c{-d} argument to inspect
+ the metadata in human-readable form. The printed information includes,
+ among other things, the uniform block member offsets, sizes, and the total
+ size in bytes of each uniform block.
+
+ \snippet rhiwindow/rhiwindow.cpp render-init-1
+
+ The vertex and fragment shaders both need a uniform buffer at binding point
+ 0. This is ensured by the QRhiShaderResourceBindings object. The graphics
+ pipeline is then setup with the shaders and a number of additional
+ information. The example also relies on a number of convenient defaults,
+ e.g. the primitive topology is
+ \l{QRhiGraphicsPipeline::Triangles}{Triangles}, but that is the default,
+ and therefore it is not explicitly set. See QRhiGraphicsPipeline for
+ further details.
+
+ In addition to specifying the topology and various state, the pipeline must
+ also be associated with:
+
+ \list
+
+ \li The vertex input layout in form of a QRhiVertexInputLayout. This
+ specifies the type and component count for each vertex input location, the
+ total stride in bytes per vertex, and other related data.
+ QRhiVertexInputLayout only holds data, not actual native resources, and is
+ copiable.
+
+ \li A valid and successfully initialized QRhiShaderResourceBindings object.
+ This describes the layout of the resource bindings (uniform buffers,
+ textures, samplers) the shaders expect. This must either by the
+ QRhiShaderResourceBindings used when recording the draw calls, or another
+ that is
+ \l{QRhiShaderResourceBindings::isLayoutCompatible()}{layout-compatible with it}.
+ This simple application takes the former approach.
+
+ \li A valid QRhiRenderPassDescriptor object. This must be retrieved from,
+ or \l{QRhiRenderPassDescriptor::isCompatible()}{be compatible with} the
+ render target. The example uses the former, by creating a
+ QRhiRenderPassDescriptor object via
+ QRhiSwapChain::newCompatibleRenderPassDescriptor().
+
+ \endlist
+
+ \snippet rhiwindow/rhiwindow.cpp render-init-2
+
+ getShader() is a helper function that loads a \c{.qsb} file and
+ deserializes a QShader from it.
+
+ \snippet rhiwindow/rhiwindow.cpp getshader
+
+ The \c{color.vert} shader specifies the following as the vertex inputs:
+
+ \badcode
+ layout(location = 0) in vec4 position;
+ layout(location = 1) in vec3 color;
+ \endcode
+
+ The C++ code however provides vertex data as 2 floats for position, with 3
+ floats for the color interleaved. (\c x, \c y, \c r, \c g, \c b for each
+ vertex) This is why the stride is \c{5 * sizeof(float)} and the inputs for
+ locations 0 and 1 are specified as \c Float2 and \c Float3, respectively.
+ This is valid, and the \c z and \c w of the \c vec4 position will get set
+ automatically.
+
+ \section1 Rendering
+
+ Recording a frame is started by calling \l{QRhi::beginFrame()} and finished
+ by calling \l{QRhi::endFrame()}.
+
+ \snippet rhiwindow/rhiwindow.cpp beginframe
+
+ Some of the resources (buffers, textures) have static data in the
+ application, meaning the content never changes. The vertex buffer's content
+ is provided in the initialization step for example, and is not changed
+ afterwards. These data update operations are recorded in \c
+ m_initialUpdates. When not yet done, the commands on this resource update
+ batch are merged into the per-frame batch.
+
+ \snippet rhiwindow/rhiwindow.cpp render-1
+
+ Having a per-frame resource update batch is necessary since the uniform
+ buffer contents with the modelview-projection matrix and the opacity
+ changes on every frame.
+
+ \snippet rhiwindow/rhiwindow.cpp render-rotation
+
+ \snippet rhiwindow/rhiwindow.cpp render-opacity
+
+ To begin recording the render pass, a QRhiCommandBuffer is queried, and the
+ output size is determined, which will be useful for setting up the viewport
+ and resizing our fullscreen texture, if needed.
+
+ \snippet rhiwindow/rhiwindow.cpp render-cb
+
+ Starting a render pass implies clearing the render target's color and
+ depth-stencil buffers (unless the render target flags indicate otherwise,
+ but that is only an option for texture-based render targets). Here we
+ specify black for color, 1.0f for depth, and 0 for stencil (unused). The
+ last argument, \c resourceUpdates, is what ensures that the data update
+ commands recorded on the batch get committed. Alternatively, we could have
+ used QRhiCommandBuffer::resourceUpdate() instead. The render pass targets a
+ swapchain, hence calling
+ \l{QRhiSwapChain::currentFrameRenderTarget()}{currentFrameRenderTarget()}
+ to get a valid QRhiRenderTarget.
+
+ \snippet rhiwindow/rhiwindow.cpp render-pass
+
+ Recording the draw call for the triangle is straightforward: set the
+ pipeline, set the shader resources, set the vertex/index buffer(s), and
+ record the draw call. Here we use a non-indexed draw with just 3 vertices.
+
+ \snippet rhiwindow/rhiwindow.cpp render-pass-record
+
+ The \l{QRhiCommandBuffer::setShaderResources()}{setShaderResources()} call
+ has no arguments given, which implies using \c m_colorTriSrb since that was
+ associated with the active QRhiGraphicsPipeline (\c m_colorPipeline).
+
+ We will not dive into the details of the rendering of the fullscreen
+ background image. See the example source code for that. It is however worth
+ noting a common pattern for "resizing" a texture or buffer resource. There
+ is no such thing as changing the size of an existing native resource, so
+ changing a texture or buffer size must be followed by a call to create(),
+ to release and recreate the underlying native resources. To ensure that the
+ QRhiTexture always has the required size, the application implements the
+ following logic. Note that \c m_texture stays valid for the entire lifetime
+ of the window, which means object references to it, e.g. in a
+ QRhiShaderResourceBindings, continue to be valid all the time. It is only
+ the underlying native resources that come and go over time.
+
+ \snippet rhiwindow/rhiwindow.cpp ensure-texture
+
+ Once a QImage is generated and the QPainter-based drawing into it has
+ finished, we use
+ \l{QRhiResourceUpdateBatch::uploadTexture()}{uploadTexture()} to record a
+ texture upload on the resource update batch:
+
+ \snippet rhiwindow/rhiwindow.cpp ensure-texture-2
+
+ \sa QRhi, QRhiSwapChain, QWindow, QRhiCommandBuffer, QRhiResourceUpdateBatch, QRhiBuffer, QRhiTexture
+ */
diff --git a/examples/gui/gui.pro b/examples/gui/gui.pro
index 275adc804d..0696458db1 100644
--- a/examples/gui/gui.pro
+++ b/examples/gui/gui.pro
@@ -4,5 +4,5 @@ TEMPLATE = subdirs
QT_FOR_CONFIG += gui
CONFIG += no_docs_target
-SUBDIRS += analogclock
-SUBDIRS += rasterwindow
+SUBDIRS += rasterwindow \
+ rhiwindow
diff --git a/examples/gui/rasterwindow/CMakeLists.txt b/examples/gui/rasterwindow/CMakeLists.txt
index dec3e25eb6..1a7878cc0a 100644
--- a/examples/gui/rasterwindow/CMakeLists.txt
+++ b/examples/gui/rasterwindow/CMakeLists.txt
@@ -1,8 +1,9 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(rasterwindow LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
@@ -11,6 +12,8 @@ set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/gui/rasterwindow")
find_package(Qt6 REQUIRED COMPONENTS Core Gui)
+qt_standard_project_setup()
+
qt_add_executable(rasterwindow
main.cpp
rasterwindow.cpp rasterwindow.h
@@ -21,9 +24,9 @@ set_target_properties(rasterwindow PROPERTIES
MACOSX_BUNDLE TRUE
)
-target_link_libraries(rasterwindow PUBLIC
- Qt::Core
- Qt::Gui
+target_link_libraries(rasterwindow PRIVATE
+ Qt6::Core
+ Qt6::Gui
)
install(TARGETS rasterwindow
diff --git a/examples/gui/rhiwindow/CMakeLists.txt b/examples/gui/rhiwindow/CMakeLists.txt
new file mode 100644
index 0000000000..3c50add134
--- /dev/null
+++ b/examples/gui/rhiwindow/CMakeLists.txt
@@ -0,0 +1,59 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+cmake_minimum_required(VERSION 3.16)
+project(rhiwindow LANGUAGES CXX)
+
+if(NOT DEFINED INSTALL_EXAMPLESDIR)
+ set(INSTALL_EXAMPLESDIR "examples")
+endif()
+
+set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/gui/rhiwindow")
+
+find_package(Qt6 REQUIRED COMPONENTS Core Gui)
+
+qt_standard_project_setup()
+
+qt_add_executable(rhiwindow
+ main.cpp
+ rhiwindow.cpp rhiwindow.h
+)
+
+set_target_properties(rhiwindow PROPERTIES
+ WIN32_EXECUTABLE TRUE
+ MACOSX_BUNDLE TRUE
+)
+
+target_link_libraries(rhiwindow PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::GuiPrivate
+)
+
+set_source_files_properties("shaders/prebuilt/color.vert.qsb"
+ PROPERTIES QT_RESOURCE_ALIAS "color.vert.qsb"
+)
+set_source_files_properties("shaders/prebuilt/color.frag.qsb"
+ PROPERTIES QT_RESOURCE_ALIAS "color.frag.qsb"
+)
+set_source_files_properties("shaders/prebuilt/quad.vert.qsb"
+ PROPERTIES QT_RESOURCE_ALIAS "quad.vert.qsb"
+)
+set_source_files_properties("shaders/prebuilt/quad.frag.qsb"
+ PROPERTIES QT_RESOURCE_ALIAS "quad.frag.qsb"
+)
+qt_add_resources(rhiwindow "rhiwindow"
+ PREFIX
+ "/"
+ FILES
+ "shaders/prebuilt/color.vert.qsb"
+ "shaders/prebuilt/color.frag.qsb"
+ "shaders/prebuilt/quad.vert.qsb"
+ "shaders/prebuilt/quad.frag.qsb"
+)
+
+install(TARGETS rhiwindow
+ RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
+ BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
+ LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+)
diff --git a/examples/gui/rhiwindow/main.cpp b/examples/gui/rhiwindow/main.cpp
new file mode 100644
index 0000000000..c6d9ce5669
--- /dev/null
+++ b/examples/gui/rhiwindow/main.cpp
@@ -0,0 +1,100 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include <QGuiApplication>
+#include <QCommandLineParser>
+#include "rhiwindow.h"
+
+int main(int argc, char **argv)
+{
+ QGuiApplication app(argc, argv);
+
+ QRhi::Implementation graphicsApi;
+
+ // Use platform-specific defaults when no command-line arguments given.
+#if defined(Q_OS_WIN)
+ graphicsApi = QRhi::D3D11;
+#elif defined(Q_OS_MACOS) || defined(Q_OS_IOS)
+ graphicsApi = QRhi::Metal;
+#elif QT_CONFIG(vulkan)
+ graphicsApi = QRhi::Vulkan;
+#else
+ graphicsApi = QRhi::OpenGLES2;
+#endif
+
+ QCommandLineParser cmdLineParser;
+ cmdLineParser.addHelpOption();
+ QCommandLineOption nullOption({ "n", "null" }, QLatin1String("Null"));
+ cmdLineParser.addOption(nullOption);
+ QCommandLineOption glOption({ "g", "opengl" }, QLatin1String("OpenGL"));
+ cmdLineParser.addOption(glOption);
+ QCommandLineOption vkOption({ "v", "vulkan" }, QLatin1String("Vulkan"));
+ cmdLineParser.addOption(vkOption);
+ QCommandLineOption d3d11Option({ "d", "d3d11" }, QLatin1String("Direct3D 11"));
+ cmdLineParser.addOption(d3d11Option);
+ QCommandLineOption d3d12Option({ "D", "d3d12" }, QLatin1String("Direct3D 12"));
+ cmdLineParser.addOption(d3d12Option);
+ QCommandLineOption mtlOption({ "m", "metal" }, QLatin1String("Metal"));
+ cmdLineParser.addOption(mtlOption);
+
+ cmdLineParser.process(app);
+ if (cmdLineParser.isSet(nullOption))
+ graphicsApi = QRhi::Null;
+ if (cmdLineParser.isSet(glOption))
+ graphicsApi = QRhi::OpenGLES2;
+ if (cmdLineParser.isSet(vkOption))
+ graphicsApi = QRhi::Vulkan;
+ if (cmdLineParser.isSet(d3d11Option))
+ graphicsApi = QRhi::D3D11;
+ if (cmdLineParser.isSet(d3d12Option))
+ graphicsApi = QRhi::D3D12;
+ if (cmdLineParser.isSet(mtlOption))
+ graphicsApi = QRhi::Metal;
+
+ //! [api-setup]
+ // For OpenGL.
+ QSurfaceFormat fmt;
+ fmt.setDepthBufferSize(24);
+ fmt.setStencilBufferSize(8);
+ QSurfaceFormat::setDefaultFormat(fmt);
+
+ // For Vulkan.
+#if QT_CONFIG(vulkan)
+ QVulkanInstance inst;
+ if (graphicsApi == QRhi::Vulkan) {
+ // Request validation, if available. This is completely optional
+ // and has a performance impact, and should be avoided in production use.
+ inst.setLayers({ "VK_LAYER_KHRONOS_validation" });
+ // Play nice with QRhi.
+ inst.setExtensions(QRhiVulkanInitParams::preferredInstanceExtensions());
+ if (!inst.create()) {
+ qWarning("Failed to create Vulkan instance, switching to OpenGL");
+ graphicsApi = QRhi::OpenGLES2;
+ }
+ }
+#endif
+//! [api-setup]
+
+ HelloWindow window(graphicsApi);
+
+#if QT_CONFIG(vulkan)
+ if (graphicsApi == QRhi::Vulkan)
+ window.setVulkanInstance(&inst);
+#endif
+ window.resize(1280, 720);
+ window.setTitle(QCoreApplication::applicationName() + QLatin1String(" - ") + window.graphicsApiName());
+ window.show();
+
+ int ret = app.exec();
+
+ // RhiWindow::event() will not get invoked when the
+ // PlatformSurfaceAboutToBeDestroyed event is sent during the QWindow
+ // destruction. That happens only when exiting via app::quit() instead of
+ // the more common QWindow::close(). Take care of it: if the QPlatformWindow
+ // is still around (there was no close() yet), get rid of the swapchain
+ // while it's not too late.
+ if (window.handle())
+ window.releaseSwapChain();
+
+ return ret;
+}
diff --git a/examples/gui/rhiwindow/rhiwindow.cpp b/examples/gui/rhiwindow/rhiwindow.cpp
new file mode 100644
index 0000000000..5022244b86
--- /dev/null
+++ b/examples/gui/rhiwindow/rhiwindow.cpp
@@ -0,0 +1,435 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "rhiwindow.h"
+#include <QPlatformSurfaceEvent>
+#include <QPainter>
+#include <QFile>
+#include <rhi/qshader.h>
+
+//! [rhiwindow-ctor]
+RhiWindow::RhiWindow(QRhi::Implementation graphicsApi)
+ : m_graphicsApi(graphicsApi)
+{
+ switch (graphicsApi) {
+ case QRhi::OpenGLES2:
+ setSurfaceType(OpenGLSurface);
+ break;
+ case QRhi::Vulkan:
+ setSurfaceType(VulkanSurface);
+ break;
+ case QRhi::D3D11:
+ case QRhi::D3D12:
+ setSurfaceType(Direct3DSurface);
+ break;
+ case QRhi::Metal:
+ setSurfaceType(MetalSurface);
+ break;
+ case QRhi::Null:
+ break; // RasterSurface
+ }
+}
+//! [rhiwindow-ctor]
+
+QString RhiWindow::graphicsApiName() const
+{
+ switch (m_graphicsApi) {
+ case QRhi::Null:
+ return QLatin1String("Null (no output)");
+ case QRhi::OpenGLES2:
+ return QLatin1String("OpenGL");
+ case QRhi::Vulkan:
+ return QLatin1String("Vulkan");
+ case QRhi::D3D11:
+ return QLatin1String("Direct3D 11");
+ case QRhi::D3D12:
+ return QLatin1String("Direct3D 12");
+ case QRhi::Metal:
+ return QLatin1String("Metal");
+ }
+ return QString();
+}
+
+//! [expose]
+void RhiWindow::exposeEvent(QExposeEvent *)
+{
+ // initialize and start rendering when the window becomes usable for graphics purposes
+ if (isExposed() && !m_initialized) {
+ init();
+ resizeSwapChain();
+ m_initialized = true;
+ }
+
+ const QSize surfaceSize = m_hasSwapChain ? m_sc->surfacePixelSize() : QSize();
+
+ // stop pushing frames when not exposed (or size is 0)
+ if ((!isExposed() || (m_hasSwapChain && surfaceSize.isEmpty())) && m_initialized && !m_notExposed)
+ m_notExposed = true;
+
+ // Continue when exposed again and the surface has a valid size. Note that
+ // surfaceSize can be (0, 0) even though size() reports a valid one, hence
+ // trusting surfacePixelSize() and not QWindow.
+ if (isExposed() && m_initialized && m_notExposed && !surfaceSize.isEmpty()) {
+ m_notExposed = false;
+ m_newlyExposed = true;
+ }
+
+ // always render a frame on exposeEvent() (when exposed) in order to update
+ // immediately on window resize.
+ if (isExposed() && !surfaceSize.isEmpty())
+ render();
+}
+//! [expose]
+
+//! [event]
+bool RhiWindow::event(QEvent *e)
+{
+ switch (e->type()) {
+ case QEvent::UpdateRequest:
+ render();
+ break;
+
+ case QEvent::PlatformSurface:
+ // this is the proper time to tear down the swapchain (while the native window and surface are still around)
+ if (static_cast<QPlatformSurfaceEvent *>(e)->surfaceEventType() == QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed)
+ releaseSwapChain();
+ break;
+
+ default:
+ break;
+ }
+
+ return QWindow::event(e);
+}
+//! [event]
+
+//! [rhi-init]
+void RhiWindow::init()
+{
+ if (m_graphicsApi == QRhi::Null) {
+ QRhiNullInitParams params;
+ m_rhi.reset(QRhi::create(QRhi::Null, &params));
+ }
+
+#if QT_CONFIG(opengl)
+ if (m_graphicsApi == QRhi::OpenGLES2) {
+ m_fallbackSurface.reset(QRhiGles2InitParams::newFallbackSurface());
+ QRhiGles2InitParams params;
+ params.fallbackSurface = m_fallbackSurface.get();
+ params.window = this;
+ m_rhi.reset(QRhi::create(QRhi::OpenGLES2, &params));
+ }
+#endif
+
+#if QT_CONFIG(vulkan)
+ if (m_graphicsApi == QRhi::Vulkan) {
+ QRhiVulkanInitParams params;
+ params.inst = vulkanInstance();
+ params.window = this;
+ m_rhi.reset(QRhi::create(QRhi::Vulkan, &params));
+ }
+#endif
+
+#ifdef Q_OS_WIN
+ if (m_graphicsApi == QRhi::D3D11) {
+ QRhiD3D11InitParams params;
+ // Enable the debug layer, if available. This is optional
+ // and should be avoided in production builds.
+ params.enableDebugLayer = true;
+ m_rhi.reset(QRhi::create(QRhi::D3D11, &params));
+ } else if (m_graphicsApi == QRhi::D3D12) {
+ QRhiD3D12InitParams params;
+ // Enable the debug layer, if available. This is optional
+ // and should be avoided in production builds.
+ params.enableDebugLayer = true;
+ m_rhi.reset(QRhi::create(QRhi::D3D12, &params));
+ }
+#endif
+
+#if defined(Q_OS_MACOS) || defined(Q_OS_IOS)
+ if (m_graphicsApi == QRhi::Metal) {
+ QRhiMetalInitParams params;
+ m_rhi.reset(QRhi::create(QRhi::Metal, &params));
+ }
+#endif
+
+ if (!m_rhi)
+ qFatal("Failed to create RHI backend");
+//! [rhi-init]
+
+//! [swapchain-init]
+ m_sc.reset(m_rhi->newSwapChain());
+ m_ds.reset(m_rhi->newRenderBuffer(QRhiRenderBuffer::DepthStencil,
+ QSize(), // no need to set the size here, due to UsedWithSwapChainOnly
+ 1,
+ QRhiRenderBuffer::UsedWithSwapChainOnly));
+ m_sc->setWindow(this);
+ m_sc->setDepthStencil(m_ds.get());
+ m_rp.reset(m_sc->newCompatibleRenderPassDescriptor());
+ m_sc->setRenderPassDescriptor(m_rp.get());
+//! [swapchain-init]
+
+ customInit();
+}
+
+//! [swapchain-resize]
+void RhiWindow::resizeSwapChain()
+{
+ m_hasSwapChain = m_sc->createOrResize(); // also handles m_ds
+
+ const QSize outputSize = m_sc->currentPixelSize();
+ m_viewProjection = m_rhi->clipSpaceCorrMatrix();
+ m_viewProjection.perspective(45.0f, outputSize.width() / (float) outputSize.height(), 0.01f, 1000.0f);
+ m_viewProjection.translate(0, 0, -4);
+}
+//! [swapchain-resize]
+
+void RhiWindow::releaseSwapChain()
+{
+ if (m_hasSwapChain) {
+ m_hasSwapChain = false;
+ m_sc->destroy();
+ }
+}
+
+//! [render-precheck]
+void RhiWindow::render()
+{
+ if (!m_hasSwapChain || m_notExposed)
+ return;
+//! [render-precheck]
+
+//! [render-resize]
+ // If the window got resized or newly exposed, resize the swapchain. (the
+ // newly-exposed case is not actually required by some platforms, but is
+ // here for robustness and portability)
+ //
+ // This (exposeEvent + the logic here) is the only safe way to perform
+ // resize handling. Note the usage of the RHI's surfacePixelSize(), and
+ // never QWindow::size(). (the two may or may not be the same under the hood,
+ // depending on the backend and platform)
+ //
+ if (m_sc->currentPixelSize() != m_sc->surfacePixelSize() || m_newlyExposed) {
+ resizeSwapChain();
+ if (!m_hasSwapChain)
+ return;
+ m_newlyExposed = false;
+ }
+//! [render-resize]
+
+//! [beginframe]
+ QRhi::FrameOpResult result = m_rhi->beginFrame(m_sc.get());
+ if (result == QRhi::FrameOpSwapChainOutOfDate) {
+ resizeSwapChain();
+ if (!m_hasSwapChain)
+ return;
+ result = m_rhi->beginFrame(m_sc.get());
+ }
+ if (result != QRhi::FrameOpSuccess) {
+ qWarning("beginFrame failed with %d, will retry", result);
+ requestUpdate();
+ return;
+ }
+
+ customRender();
+//! [beginframe]
+
+//! [request-update]
+ m_rhi->endFrame(m_sc.get());
+
+ // Always request the next frame via requestUpdate(). On some platforms this is backed
+ // by a platform-specific solution, e.g. CVDisplayLink on macOS, which is potentially
+ // more efficient than a timer, queued metacalls, etc.
+ requestUpdate();
+}
+//! [request-update]
+
+static float vertexData[] = {
+ // Y up (note clipSpaceCorrMatrix in m_viewProjection), CCW
+ 0.0f, 0.5f, 1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ 0.5f, -0.5f, 0.0f, 0.0f, 1.0f,
+};
+
+//! [getshader]
+static QShader getShader(const QString &name)
+{
+ QFile f(name);
+ if (f.open(QIODevice::ReadOnly))
+ return QShader::fromSerialized(f.readAll());
+
+ return QShader();
+}
+//! [getshader]
+
+HelloWindow::HelloWindow(QRhi::Implementation graphicsApi)
+ : RhiWindow(graphicsApi)
+{
+}
+
+//! [ensure-texture]
+void HelloWindow::ensureFullscreenTexture(const QSize &pixelSize, QRhiResourceUpdateBatch *u)
+{
+ if (m_texture && m_texture->pixelSize() == pixelSize)
+ return;
+
+ if (!m_texture)
+ m_texture.reset(m_rhi->newTexture(QRhiTexture::RGBA8, pixelSize));
+ else
+ m_texture->setPixelSize(pixelSize);
+
+ m_texture->create();
+
+ QImage image(pixelSize, QImage::Format_RGBA8888_Premultiplied);
+//! [ensure-texture]
+ QPainter painter(&image);
+ painter.fillRect(QRectF(QPointF(0, 0), pixelSize), QColor::fromRgbF(0.4f, 0.7f, 0.0f, 1.0f));
+ painter.setPen(Qt::transparent);
+ painter.setBrush({ QGradient(QGradient::DeepBlue) });
+ painter.drawRoundedRect(QRectF(QPointF(20, 20), pixelSize - QSize(40, 40)), 16, 16);
+ painter.setPen(Qt::black);
+ QFont font;
+ font.setPixelSize(0.05 * qMin(pixelSize.width(), pixelSize.height()));
+ painter.setFont(font);
+ painter.drawText(QRectF(QPointF(60, 60), pixelSize - QSize(120, 120)), 0,
+ QLatin1String("Rendering with QRhi to a resizable QWindow.\nThe 3D API is %1.\nUse the command-line options to choose a different API.")
+ .arg(graphicsApiName()));
+ painter.end();
+
+ if (m_rhi->isYUpInNDC())
+ image = image.mirrored();
+
+//! [ensure-texture-2]
+ u->uploadTexture(m_texture.get(), image);
+//! [ensure-texture-2]
+}
+
+//! [render-init-1]
+void HelloWindow::customInit()
+{
+ m_initialUpdates = m_rhi->nextResourceUpdateBatch();
+
+ m_vbuf.reset(m_rhi->newBuffer(QRhiBuffer::Immutable, QRhiBuffer::VertexBuffer, sizeof(vertexData)));
+ m_vbuf->create();
+ m_initialUpdates->uploadStaticBuffer(m_vbuf.get(), vertexData);
+
+ static const quint32 UBUF_SIZE = 68;
+ m_ubuf.reset(m_rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, UBUF_SIZE));
+ m_ubuf->create();
+//! [render-init-1]
+
+ ensureFullscreenTexture(m_sc->surfacePixelSize(), m_initialUpdates);
+
+ m_sampler.reset(m_rhi->newSampler(QRhiSampler::Linear, QRhiSampler::Linear, QRhiSampler::None,
+ QRhiSampler::ClampToEdge, QRhiSampler::ClampToEdge));
+ m_sampler->create();
+
+ //! [render-init-2]
+ m_colorTriSrb.reset(m_rhi->newShaderResourceBindings());
+ static const QRhiShaderResourceBinding::StageFlags visibility =
+ QRhiShaderResourceBinding::VertexStage | QRhiShaderResourceBinding::FragmentStage;
+ m_colorTriSrb->setBindings({
+ QRhiShaderResourceBinding::uniformBuffer(0, visibility, m_ubuf.get())
+ });
+ m_colorTriSrb->create();
+
+ m_colorPipeline.reset(m_rhi->newGraphicsPipeline());
+ // Enable depth testing; not quite needed for a simple triangle, but we
+ // have a depth-stencil buffer so why not.
+ m_colorPipeline->setDepthTest(true);
+ m_colorPipeline->setDepthWrite(true);
+ // Blend factors default to One, OneOneMinusSrcAlpha, which is convenient.
+ QRhiGraphicsPipeline::TargetBlend premulAlphaBlend;
+ premulAlphaBlend.enable = true;
+ m_colorPipeline->setTargetBlends({ premulAlphaBlend });
+ m_colorPipeline->setShaderStages({
+ { QRhiShaderStage::Vertex, getShader(QLatin1String(":/color.vert.qsb")) },
+ { QRhiShaderStage::Fragment, getShader(QLatin1String(":/color.frag.qsb")) }
+ });
+ QRhiVertexInputLayout inputLayout;
+ inputLayout.setBindings({
+ { 5 * sizeof(float) }
+ });
+ inputLayout.setAttributes({
+ { 0, 0, QRhiVertexInputAttribute::Float2, 0 },
+ { 0, 1, QRhiVertexInputAttribute::Float3, 2 * sizeof(float) }
+ });
+ m_colorPipeline->setVertexInputLayout(inputLayout);
+ m_colorPipeline->setShaderResourceBindings(m_colorTriSrb.get());
+ m_colorPipeline->setRenderPassDescriptor(m_rp.get());
+ m_colorPipeline->create();
+//! [render-init-2]
+
+ m_fullscreenQuadSrb.reset(m_rhi->newShaderResourceBindings());
+ m_fullscreenQuadSrb->setBindings({
+ QRhiShaderResourceBinding::sampledTexture(0, QRhiShaderResourceBinding::FragmentStage,
+ m_texture.get(), m_sampler.get())
+ });
+ m_fullscreenQuadSrb->create();
+
+ m_fullscreenQuadPipeline.reset(m_rhi->newGraphicsPipeline());
+ m_fullscreenQuadPipeline->setShaderStages({
+ { QRhiShaderStage::Vertex, getShader(QLatin1String(":/quad.vert.qsb")) },
+ { QRhiShaderStage::Fragment, getShader(QLatin1String(":/quad.frag.qsb")) }
+ });
+ m_fullscreenQuadPipeline->setVertexInputLayout({});
+ m_fullscreenQuadPipeline->setShaderResourceBindings(m_fullscreenQuadSrb.get());
+ m_fullscreenQuadPipeline->setRenderPassDescriptor(m_rp.get());
+ m_fullscreenQuadPipeline->create();
+}
+
+//! [render-1]
+void HelloWindow::customRender()
+{
+ QRhiResourceUpdateBatch *resourceUpdates = m_rhi->nextResourceUpdateBatch();
+
+ if (m_initialUpdates) {
+ resourceUpdates->merge(m_initialUpdates);
+ m_initialUpdates->release();
+ m_initialUpdates = nullptr;
+ }
+//! [render-1]
+
+//! [render-rotation]
+ m_rotation += 1.0f;
+ QMatrix4x4 modelViewProjection = m_viewProjection;
+ modelViewProjection.rotate(m_rotation, 0, 1, 0);
+ resourceUpdates->updateDynamicBuffer(m_ubuf.get(), 0, 64, modelViewProjection.constData());
+//! [render-rotation]
+
+//! [render-opacity]
+ m_opacity += m_opacityDir * 0.005f;
+ if (m_opacity < 0.0f || m_opacity > 1.0f) {
+ m_opacityDir *= -1;
+ m_opacity = qBound(0.0f, m_opacity, 1.0f);
+ }
+ resourceUpdates->updateDynamicBuffer(m_ubuf.get(), 64, 4, &m_opacity);
+//! [render-opacity]
+
+//! [render-cb]
+ QRhiCommandBuffer *cb = m_sc->currentFrameCommandBuffer();
+ const QSize outputSizeInPixels = m_sc->currentPixelSize();
+//! [render-cb]
+
+ // (re)create the texture with a size matching the output surface size, when necessary.
+ ensureFullscreenTexture(outputSizeInPixels, resourceUpdates);
+
+//! [render-pass]
+ cb->beginPass(m_sc->currentFrameRenderTarget(), Qt::black, { 1.0f, 0 }, resourceUpdates);
+//! [render-pass]
+
+ cb->setGraphicsPipeline(m_fullscreenQuadPipeline.get());
+ cb->setViewport({ 0, 0, float(outputSizeInPixels.width()), float(outputSizeInPixels.height()) });
+ cb->setShaderResources();
+ cb->draw(3);
+
+//! [render-pass-record]
+ cb->setGraphicsPipeline(m_colorPipeline.get());
+ cb->setShaderResources();
+ const QRhiCommandBuffer::VertexInput vbufBinding(m_vbuf.get(), 0);
+ cb->setVertexInput(0, 1, &vbufBinding);
+ cb->draw(3);
+
+ cb->endPass();
+//! [render-pass-record]
+}
diff --git a/examples/gui/rhiwindow/rhiwindow.h b/examples/gui/rhiwindow/rhiwindow.h
new file mode 100644
index 0000000000..520c3e8c0a
--- /dev/null
+++ b/examples/gui/rhiwindow/rhiwindow.h
@@ -0,0 +1,78 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#ifndef WINDOW_H
+#define WINDOW_H
+
+#include <QWindow>
+#include <QOffscreenSurface>
+#include <rhi/qrhi.h>
+
+class RhiWindow : public QWindow
+{
+public:
+ RhiWindow(QRhi::Implementation graphicsApi);
+ QString graphicsApiName() const;
+ void releaseSwapChain();
+
+protected:
+ virtual void customInit() = 0;
+ virtual void customRender() = 0;
+
+ // destruction order matters to a certain degree: the fallbackSurface must
+ // outlive the rhi, the rhi must outlive all other resources. The resources
+ // need no special order when destroying.
+#if QT_CONFIG(opengl)
+ std::unique_ptr<QOffscreenSurface> m_fallbackSurface;
+#endif
+ std::unique_ptr<QRhi> m_rhi;
+//! [swapchain-data]
+ std::unique_ptr<QRhiSwapChain> m_sc;
+ std::unique_ptr<QRhiRenderBuffer> m_ds;
+ std::unique_ptr<QRhiRenderPassDescriptor> m_rp;
+//! [swapchain-data]
+ bool m_hasSwapChain = false;
+ QMatrix4x4 m_viewProjection;
+
+private:
+ void init();
+ void resizeSwapChain();
+ void render();
+
+ void exposeEvent(QExposeEvent *) override;
+ bool event(QEvent *) override;
+
+ QRhi::Implementation m_graphicsApi;
+ bool m_initialized = false;
+ bool m_notExposed = false;
+ bool m_newlyExposed = false;
+};
+
+class HelloWindow : public RhiWindow
+{
+public:
+ HelloWindow(QRhi::Implementation graphicsApi);
+
+ void customInit() override;
+ void customRender() override;
+
+private:
+ void ensureFullscreenTexture(const QSize &pixelSize, QRhiResourceUpdateBatch *u);
+
+ std::unique_ptr<QRhiBuffer> m_vbuf;
+ std::unique_ptr<QRhiBuffer> m_ubuf;
+ std::unique_ptr<QRhiTexture> m_texture;
+ std::unique_ptr<QRhiSampler> m_sampler;
+ std::unique_ptr<QRhiShaderResourceBindings> m_colorTriSrb;
+ std::unique_ptr<QRhiGraphicsPipeline> m_colorPipeline;
+ std::unique_ptr<QRhiShaderResourceBindings> m_fullscreenQuadSrb;
+ std::unique_ptr<QRhiGraphicsPipeline> m_fullscreenQuadPipeline;
+
+ QRhiResourceUpdateBatch *m_initialUpdates = nullptr;
+
+ float m_rotation = 0;
+ float m_opacity = 1;
+ int m_opacityDir = -1;
+};
+
+#endif
diff --git a/examples/gui/rhiwindow/rhiwindow.pri b/examples/gui/rhiwindow/rhiwindow.pri
new file mode 100644
index 0000000000..d0ef7a2699
--- /dev/null
+++ b/examples/gui/rhiwindow/rhiwindow.pri
@@ -0,0 +1,4 @@
+INCLUDEPATH += $$PWD
+SOURCES += $$PWD/rhiwindow.cpp
+HEADERS += $$PWD/rhiwindow.h
+RESOURCES += $$PWD/rhiwindow.qrc
diff --git a/examples/gui/rhiwindow/rhiwindow.pro b/examples/gui/rhiwindow/rhiwindow.pro
new file mode 100644
index 0000000000..18f259aaf6
--- /dev/null
+++ b/examples/gui/rhiwindow/rhiwindow.pro
@@ -0,0 +1,9 @@
+include(rhiwindow.pri)
+
+QT += gui-private
+
+SOURCES += \
+ main.cpp
+
+target.path = $$[QT_INSTALL_EXAMPLES]/gui/rhiwindow
+INSTALLS += target
diff --git a/examples/gui/rhiwindow/rhiwindow.qrc b/examples/gui/rhiwindow/rhiwindow.qrc
new file mode 100644
index 0000000000..1009ec5dda
--- /dev/null
+++ b/examples/gui/rhiwindow/rhiwindow.qrc
@@ -0,0 +1,8 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file alias="color.vert.qsb">shaders/prebuilt/color.vert.qsb</file>
+ <file alias="color.frag.qsb">shaders/prebuilt/color.frag.qsb</file>
+ <file alias="quad.vert.qsb">shaders/prebuilt/quad.vert.qsb</file>
+ <file alias="quad.frag.qsb">shaders/prebuilt/quad.frag.qsb</file>
+</qresource>
+</RCC>
diff --git a/examples/gui/rhiwindow/shaders/color.frag b/examples/gui/rhiwindow/shaders/color.frag
new file mode 100644
index 0000000000..6e0a3bc91f
--- /dev/null
+++ b/examples/gui/rhiwindow/shaders/color.frag
@@ -0,0 +1,15 @@
+#version 440
+
+layout(location = 0) in vec3 v_color;
+
+layout(location = 0) out vec4 fragColor;
+
+layout(std140, binding = 0) uniform buf {
+ mat4 mvp;
+ float opacity;
+};
+
+void main()
+{
+ fragColor = vec4(v_color * opacity, opacity);
+}
diff --git a/examples/gui/rhiwindow/shaders/color.vert b/examples/gui/rhiwindow/shaders/color.vert
new file mode 100644
index 0000000000..70852ab86c
--- /dev/null
+++ b/examples/gui/rhiwindow/shaders/color.vert
@@ -0,0 +1,17 @@
+#version 440
+
+layout(location = 0) in vec4 position;
+layout(location = 1) in vec3 color;
+
+layout(location = 0) out vec3 v_color;
+
+layout(std140, binding = 0) uniform buf {
+ mat4 mvp;
+ float opacity;
+};
+
+void main()
+{
+ v_color = color;
+ gl_Position = mvp * position;
+}
diff --git a/examples/gui/rhiwindow/shaders/prebuilt/color.frag.qsb b/examples/gui/rhiwindow/shaders/prebuilt/color.frag.qsb
new file mode 100644
index 0000000000..b4db470e5b
--- /dev/null
+++ b/examples/gui/rhiwindow/shaders/prebuilt/color.frag.qsb
Binary files differ
diff --git a/examples/gui/rhiwindow/shaders/prebuilt/color.vert.qsb b/examples/gui/rhiwindow/shaders/prebuilt/color.vert.qsb
new file mode 100644
index 0000000000..ab046b77f8
--- /dev/null
+++ b/examples/gui/rhiwindow/shaders/prebuilt/color.vert.qsb
Binary files differ
diff --git a/examples/gui/rhiwindow/shaders/prebuilt/quad.frag.qsb b/examples/gui/rhiwindow/shaders/prebuilt/quad.frag.qsb
new file mode 100644
index 0000000000..c2ea3cf251
--- /dev/null
+++ b/examples/gui/rhiwindow/shaders/prebuilt/quad.frag.qsb
Binary files differ
diff --git a/examples/gui/rhiwindow/shaders/prebuilt/quad.vert.qsb b/examples/gui/rhiwindow/shaders/prebuilt/quad.vert.qsb
new file mode 100644
index 0000000000..f0b64f7500
--- /dev/null
+++ b/examples/gui/rhiwindow/shaders/prebuilt/quad.vert.qsb
Binary files differ
diff --git a/examples/gui/rhiwindow/shaders/quad.frag b/examples/gui/rhiwindow/shaders/quad.frag
new file mode 100644
index 0000000000..65882a4292
--- /dev/null
+++ b/examples/gui/rhiwindow/shaders/quad.frag
@@ -0,0 +1,11 @@
+#version 440
+
+layout(location = 0) in vec2 v_uv;
+layout(location = 0) out vec4 fragColor;
+layout(binding = 0) uniform sampler2D tex;
+
+void main()
+{
+ vec4 c = texture(tex, v_uv);
+ fragColor = vec4(c.rgb * c.a, c.a);
+}
diff --git a/examples/gui/rhiwindow/shaders/quad.vert b/examples/gui/rhiwindow/shaders/quad.vert
new file mode 100644
index 0000000000..359896d080
--- /dev/null
+++ b/examples/gui/rhiwindow/shaders/quad.vert
@@ -0,0 +1,10 @@
+#version 440
+
+layout (location = 0) out vec2 v_uv;
+
+void main()
+{
+ // https://www.saschawillems.de/blog/2016/08/13/vulkan-tutorial-on-rendering-a-fullscreen-quad-without-buffers/
+ v_uv = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2);
+ gl_Position = vec4(v_uv * 2.0 - 1.0, 0.0, 1.0);
+}
diff --git a/examples/network/CMakeLists.txt b/examples/network/CMakeLists.txt
index df65fad19c..4e19a2dffd 100644
--- a/examples/network/CMakeLists.txt
+++ b/examples/network/CMakeLists.txt
@@ -1,36 +1,35 @@
-if(NOT TARGET Qt::Network)
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT TARGET Qt6::Network)
return()
endif()
-qt_internal_add_example(download)
-qt_internal_add_example(downloadmanager)
if(NOT INTEGRITY)
qt_internal_add_example(dnslookup)
endif()
-if(TARGET Qt::Widgets)
+if(TARGET Qt6::Widgets)
qt_internal_add_example(blockingfortuneclient)
qt_internal_add_example(broadcastreceiver)
qt_internal_add_example(broadcastsender)
qt_internal_add_example(http)
- qt_internal_add_example(loopback)
qt_internal_add_example(threadedfortuneserver)
- qt_internal_add_example(googlesuggest)
qt_internal_add_example(torrent)
qt_internal_add_example(multicastreceiver)
qt_internal_add_example(multicastsender)
qt_internal_add_example(fortuneclient)
qt_internal_add_example(fortuneserver)
endif()
-if(QT_FEATURE_processenvironment AND TARGET Qt::Widgets)
+if(QT_FEATURE_processenvironment AND TARGET Qt6::Widgets)
qt_internal_add_example(network-chat)
endif()
-if(QT_FEATURE_ssl AND TARGET Qt::Widgets)
+if(QT_FEATURE_ssl AND TARGET Qt6::Widgets)
qt_internal_add_example(securesocketclient)
endif()
-if(QT_FEATURE_dtls AND TARGET Qt::Widgets)
+if(QT_FEATURE_dtls AND TARGET Qt6::Widgets)
qt_internal_add_example(secureudpserver)
qt_internal_add_example(secureudpclient)
endif()
-if(QT_FEATURE_sctp AND TARGET Qt::Widgets)
+if(QT_FEATURE_sctp AND TARGET Qt6::Widgets)
qt_internal_add_example(multistreamserver)
qt_internal_add_example(multistreamclient)
endif()
diff --git a/examples/network/blockingfortuneclient/CMakeLists.txt b/examples/network/blockingfortuneclient/CMakeLists.txt
index 346a014abe..cfcb03af2d 100644
--- a/examples/network/blockingfortuneclient/CMakeLists.txt
+++ b/examples/network/blockingfortuneclient/CMakeLists.txt
@@ -1,8 +1,9 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(blockingfortuneclient LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
@@ -11,6 +12,8 @@ set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/network/blockingfortuneclient")
find_package(Qt6 REQUIRED COMPONENTS Core Gui Network Widgets)
+qt_standard_project_setup()
+
qt_add_executable(blockingfortuneclient
blockingclient.cpp blockingclient.h
fortunethread.cpp fortunethread.h
@@ -22,11 +25,11 @@ set_target_properties(blockingfortuneclient PROPERTIES
MACOSX_BUNDLE TRUE
)
-target_link_libraries(blockingfortuneclient PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Network
- Qt::Widgets
+target_link_libraries(blockingfortuneclient PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Network
+ Qt6::Widgets
)
install(TARGETS blockingfortuneclient
diff --git a/examples/network/blockingfortuneclient/blockingclient.cpp b/examples/network/blockingfortuneclient/blockingclient.cpp
index ef059b2e5f..b530e052f6 100644
--- a/examples/network/blockingfortuneclient/blockingclient.cpp
+++ b/examples/network/blockingfortuneclient/blockingclient.cpp
@@ -14,12 +14,11 @@ BlockingClient::BlockingClient(QWidget *parent)
// find out which IP to connect to
QString ipAddress;
- QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();
+ const QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();
// use the first non-localhost IPv4 address
- for (int i = 0; i < ipAddressesList.size(); ++i) {
- if (ipAddressesList.at(i) != QHostAddress::LocalHost &&
- ipAddressesList.at(i).toIPv4Address()) {
- ipAddress = ipAddressesList.at(i).toString();
+ for (const QHostAddress &entry : ipAddressesList) {
+ if (entry != QHostAddress::LocalHost && entry.toIPv4Address()) {
+ ipAddress = entry.toString();
break;
}
}
diff --git a/examples/network/blockingfortuneclient/fortunethread.cpp b/examples/network/blockingfortuneclient/fortunethread.cpp
index 8e8df8cf8e..464482e17b 100644
--- a/examples/network/blockingfortuneclient/fortunethread.cpp
+++ b/examples/network/blockingfortuneclient/fortunethread.cpp
@@ -62,7 +62,7 @@ void FortuneThread::run()
//! [8] //! [11]
QDataStream in(&socket);
- in.setVersion(QDataStream::Qt_4_0);
+ in.setVersion(QDataStream::Qt_6_5);
QString fortune;
//! [11] //! [12]
diff --git a/examples/network/broadcastreceiver/CMakeLists.txt b/examples/network/broadcastreceiver/CMakeLists.txt
index d1f3563a3c..2e694c7a3f 100644
--- a/examples/network/broadcastreceiver/CMakeLists.txt
+++ b/examples/network/broadcastreceiver/CMakeLists.txt
@@ -1,8 +1,9 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(broadcastreceiver LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
@@ -11,6 +12,8 @@ set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/network/broadcastreceiver")
find_package(Qt6 REQUIRED COMPONENTS Core Gui Network Widgets)
+qt_standard_project_setup()
+
qt_add_executable(broadcastreceiver
main.cpp
receiver.cpp receiver.h
@@ -21,11 +24,11 @@ set_target_properties(broadcastreceiver PROPERTIES
MACOSX_BUNDLE TRUE
)
-target_link_libraries(broadcastreceiver PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Network
- Qt::Widgets
+target_link_libraries(broadcastreceiver PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Network
+ Qt6::Widgets
)
install(TARGETS broadcastreceiver
diff --git a/examples/network/broadcastreceiver/receiver.cpp b/examples/network/broadcastreceiver/receiver.cpp
index caa05ac45a..ffade9992c 100644
--- a/examples/network/broadcastreceiver/receiver.cpp
+++ b/examples/network/broadcastreceiver/receiver.cpp
@@ -5,6 +5,7 @@
#include <QPushButton>
#include <QUdpSocket>
#include <QVBoxLayout>
+#include <QCoreApplication>
#include "receiver.h"
@@ -26,7 +27,7 @@ Receiver::Receiver(QWidget *parent)
this, &Receiver::processPendingDatagrams);
//! [1]
connect(quitButton, &QPushButton::clicked,
- this, &Receiver::close);
+ qApp, &QCoreApplication::quit);
auto buttonLayout = new QHBoxLayout;
buttonLayout->addStretch(1);
diff --git a/examples/network/broadcastsender/CMakeLists.txt b/examples/network/broadcastsender/CMakeLists.txt
index 0fb7b8d8e6..bf010463a8 100644
--- a/examples/network/broadcastsender/CMakeLists.txt
+++ b/examples/network/broadcastsender/CMakeLists.txt
@@ -1,8 +1,9 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(broadcastsender LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
@@ -11,6 +12,8 @@ set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/network/broadcastsender")
find_package(Qt6 REQUIRED COMPONENTS Core Gui Network Widgets)
+qt_standard_project_setup()
+
qt_add_executable(broadcastsender
main.cpp
sender.cpp sender.h
@@ -21,11 +24,11 @@ set_target_properties(broadcastsender PROPERTIES
MACOSX_BUNDLE TRUE
)
-target_link_libraries(broadcastsender PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Network
- Qt::Widgets
+target_link_libraries(broadcastsender PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Network
+ Qt6::Widgets
)
install(TARGETS broadcastsender
diff --git a/examples/network/broadcastsender/sender.cpp b/examples/network/broadcastsender/sender.cpp
index 7aa416ad6c..622d3f9616 100644
--- a/examples/network/broadcastsender/sender.cpp
+++ b/examples/network/broadcastsender/sender.cpp
@@ -25,7 +25,7 @@ Sender::Sender(QWidget *parent)
//! [0]
connect(startButton, &QPushButton::clicked, this, &Sender::startBroadcasting);
- connect(quitButton, &QPushButton::clicked, this, &Sender::close);
+ connect(quitButton, &QPushButton::clicked, qApp, &QCoreApplication::quit);
connect(&timer, &QTimer::timeout, this, &Sender::broadcastDatagram);
auto mainLayout = new QVBoxLayout;
diff --git a/examples/network/dnslookup/CMakeLists.txt b/examples/network/dnslookup/CMakeLists.txt
index a6c3681731..e90cdaff2d 100644
--- a/examples/network/dnslookup/CMakeLists.txt
+++ b/examples/network/dnslookup/CMakeLists.txt
@@ -1,8 +1,9 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(dnslookup LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
@@ -11,13 +12,15 @@ set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/network/dnslookup")
find_package(Qt6 REQUIRED COMPONENTS Core Network)
+qt_standard_project_setup()
+
qt_add_executable(dnslookup
dnslookup.cpp dnslookup.h
)
-target_link_libraries(dnslookup PUBLIC
- Qt::Core
- Qt::Network
+target_link_libraries(dnslookup PRIVATE
+ Qt6::Core
+ Qt6::Network
)
install(TARGETS dnslookup
diff --git a/examples/network/dnslookup/dnslookup.cpp b/examples/network/dnslookup/dnslookup.cpp
index 91311b26b8..bfcd60813b 100644
--- a/examples/network/dnslookup/dnslookup.cpp
+++ b/examples/network/dnslookup/dnslookup.cpp
@@ -11,43 +11,51 @@
#include <QCommandLineParser>
#include <QCommandLineOption>
-#include <stdio.h>
+#include <cstdio>
-static int typeFromParameter(const QString &type)
+using namespace Qt::StringLiterals;
+
+static std::optional<QDnsLookup::Type> typeFromParameter(QStringView type)
{
- if (type == "a")
+ if (type.compare(u"a", Qt::CaseInsensitive) == 0)
return QDnsLookup::A;
- if (type == "aaaa")
+ if (type.compare(u"aaaa", Qt::CaseInsensitive) == 0)
return QDnsLookup::AAAA;
- if (type == "any")
+ if (type.compare(u"any", Qt::CaseInsensitive) == 0)
return QDnsLookup::ANY;
- if (type == "cname")
+ if (type.compare(u"cname", Qt::CaseInsensitive) == 0)
return QDnsLookup::CNAME;
- if (type == "mx")
+ if (type.compare(u"mx", Qt::CaseInsensitive) == 0)
return QDnsLookup::MX;
- if (type == "ns")
+ if (type.compare(u"ns", Qt::CaseInsensitive) == 0)
return QDnsLookup::NS;
- if (type == "ptr")
+ if (type.compare(u"ptr", Qt::CaseInsensitive) == 0)
return QDnsLookup::PTR;
- if (type == "srv")
+ if (type.compare(u"srv", Qt::CaseInsensitive) == 0)
return QDnsLookup::SRV;
- if (type == "txt")
+ if (type.compare(u"txt", Qt::CaseInsensitive) == 0)
return QDnsLookup::TXT;
- return -1;
+ return std::nullopt;
}
//! [0]
-enum CommandLineParseResult
+struct CommandLineParseResult
{
- CommandLineOk,
- CommandLineError,
- CommandLineVersionRequested,
- CommandLineHelpRequested
+ enum class Status {
+ Ok,
+ Error,
+ VersionRequested,
+ HelpRequested
+ };
+ Status statusCode = Status::Ok;
+ std::optional<QString> errorString = std::nullopt;
};
-CommandLineParseResult parseCommandLine(QCommandLineParser &parser, DnsQuery *query, QString *errorMessage)
+CommandLineParseResult parseCommandLine(QCommandLineParser &parser, DnsQuery *query)
{
+ using Status = CommandLineParseResult::Status;
+
parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions);
const QCommandLineOption nameServerOption("n", "The name server to use.", "nameserver");
parser.addOption(nameServerOption);
@@ -57,48 +65,41 @@ CommandLineParseResult parseCommandLine(QCommandLineParser &parser, DnsQuery *qu
const QCommandLineOption helpOption = parser.addHelpOption();
const QCommandLineOption versionOption = parser.addVersionOption();
- if (!parser.parse(QCoreApplication::arguments())) {
- *errorMessage = parser.errorText();
- return CommandLineError;
- }
+ if (!parser.parse(QCoreApplication::arguments()))
+ return { Status::Error, parser.errorText() };
if (parser.isSet(versionOption))
- return CommandLineVersionRequested;
+ return { Status::VersionRequested };
if (parser.isSet(helpOption))
- return CommandLineHelpRequested;
+ return { Status::HelpRequested };
if (parser.isSet(nameServerOption)) {
const QString nameserver = parser.value(nameServerOption);
query->nameServer = QHostAddress(nameserver);
- if (query->nameServer.isNull() || query->nameServer.protocol() == QAbstractSocket::UnknownNetworkLayerProtocol) {
- *errorMessage = "Bad nameserver address: " + nameserver;
- return CommandLineError;
+ if (query->nameServer.isNull()
+ || query->nameServer.protocol() == QAbstractSocket::UnknownNetworkLayerProtocol) {
+ return { Status::Error,
+ u"Bad nameserver address: %1"_qs.arg(nameserver) };
}
}
if (parser.isSet(typeOption)) {
const QString typeParameter = parser.value(typeOption);
- const int type = typeFromParameter(typeParameter.toLower());
- if (type < 0) {
- *errorMessage = "Bad record type: " + typeParameter;
- return CommandLineError;
- }
- query->type = static_cast<QDnsLookup::Type>(type);
+ if (std::optional<QDnsLookup::Type> type = typeFromParameter(typeParameter))
+ query->type = *type;
+ else
+ return { Status::Error, u"Bad record type: %1"_qs.arg(typeParameter) };
}
const QStringList positionalArguments = parser.positionalArguments();
- if (positionalArguments.isEmpty()) {
- *errorMessage = "Argument 'name' missing.";
- return CommandLineError;
- }
- if (positionalArguments.size() > 1) {
- *errorMessage = "Several 'name' arguments specified.";
- return CommandLineError;
- }
+ if (positionalArguments.isEmpty())
+ return { Status::Error, u"Argument 'name' missing."_qs };
+ if (positionalArguments.size() > 1)
+ return { Status::Error, u"Several 'name' arguments specified."_qs };
query->name = positionalArguments.first();
- return CommandLineOk;
+ return { Status::Ok };
}
//! [0]
@@ -122,39 +123,52 @@ void DnsManager::execute()
void DnsManager::showResults()
{
if (dns->error() != QDnsLookup::NoError)
- printf("Error: %i (%s)\n", dns->error(), qPrintable(dns->errorString()));
+ std::printf("Error: %i (%s)\n", dns->error(), qPrintable(dns->errorString()));
// CNAME records
const QList<QDnsDomainNameRecord> cnameRecords = dns->canonicalNameRecords();
- for (const QDnsDomainNameRecord &record : cnameRecords)
- printf("%s\t%i\tIN\tCNAME\t%s\n", qPrintable(record.name()), record.timeToLive(), qPrintable(record.value()));
+ for (const QDnsDomainNameRecord &record : cnameRecords) {
+ std::printf("%s\t%i\tIN\tCNAME\t%s\n", qPrintable(record.name()), record.timeToLive(),
+ qPrintable(record.value()));
+ }
// A and AAAA records
const QList<QDnsHostAddressRecord> aRecords = dns->hostAddressRecords();
for (const QDnsHostAddressRecord &record : aRecords) {
- const char *type = (record.value().protocol() == QAbstractSocket::IPv6Protocol) ? "AAAA" : "A";
- printf("%s\t%i\tIN\t%s\t%s\n", qPrintable(record.name()), record.timeToLive(), type, qPrintable(record.value().toString()));
+ const char *type =
+ (record.value().protocol() == QAbstractSocket::IPv6Protocol) ? "AAAA" : "A";
+ std::printf("%s\t%i\tIN\t%s\t%s\n", qPrintable(record.name()), record.timeToLive(), type,
+ qPrintable(record.value().toString()));
}
// MX records
const QList<QDnsMailExchangeRecord> mxRecords = dns->mailExchangeRecords();
- for (const QDnsMailExchangeRecord &record : mxRecords)
- printf("%s\t%i\tIN\tMX\t%u %s\n", qPrintable(record.name()), record.timeToLive(), record.preference(), qPrintable(record.exchange()));
+ for (const QDnsMailExchangeRecord &record : mxRecords) {
+ std::printf("%s\t%i\tIN\tMX\t%u %s\n", qPrintable(record.name()), record.timeToLive(),
+ record.preference(), qPrintable(record.exchange()));
+ }
// NS records
const QList<QDnsDomainNameRecord> nsRecords = dns->nameServerRecords();
- for (const QDnsDomainNameRecord &record : nsRecords)
- printf("%s\t%i\tIN\tNS\t%s\n", qPrintable(record.name()), record.timeToLive(), qPrintable(record.value()));
+ for (const QDnsDomainNameRecord &record : nsRecords) {
+ std::printf("%s\t%i\tIN\tNS\t%s\n", qPrintable(record.name()), record.timeToLive(),
+ qPrintable(record.value()));
+ }
// PTR records
const QList<QDnsDomainNameRecord> ptrRecords = dns->pointerRecords();
- for (const QDnsDomainNameRecord &record : ptrRecords)
- printf("%s\t%i\tIN\tPTR\t%s\n", qPrintable(record.name()), record.timeToLive(), qPrintable(record.value()));
+ for (const QDnsDomainNameRecord &record : ptrRecords) {
+ std::printf("%s\t%i\tIN\tPTR\t%s\n", qPrintable(record.name()), record.timeToLive(),
+ qPrintable(record.value()));
+ }
// SRV records
const QList<QDnsServiceRecord> srvRecords = dns->serviceRecords();
- for (const QDnsServiceRecord &record : srvRecords)
- printf("%s\t%i\tIN\tSRV\t%u %u %u %s\n", qPrintable(record.name()), record.timeToLive(), record.priority(), record.weight(), record.port(), qPrintable(record.target()));
+ for (const QDnsServiceRecord &record : srvRecords) {
+ std::printf("%s\t%i\tIN\tSRV\t%u %u %u %s\n", qPrintable(record.name()),
+ record.timeToLive(), record.priority(), record.weight(), record.port(),
+ qPrintable(record.target()));
+ }
// TXT records
const QList<QDnsTextRecord> txtRecords = dns->textRecords();
@@ -163,7 +177,8 @@ void DnsManager::showResults()
const QList<QByteArray> dnsRecords = record.values();
for (const QByteArray &ba : dnsRecords)
values << "\"" + QString::fromLatin1(ba) + "\"";
- printf("%s\t%i\tIN\tTXT\t%s\n", qPrintable(record.name()), record.timeToLive(), qPrintable(values.join(' ')));
+ std::printf("%s\t%i\tIN\tTXT\t%s\n", qPrintable(record.name()), record.timeToLive(),
+ qPrintable(values.join(' ')));
}
QCoreApplication::instance()->quit();
@@ -175,32 +190,36 @@ int main(int argc, char *argv[])
//! [1]
QCoreApplication::setApplicationVersion(QT_VERSION_STR);
- QCoreApplication::setApplicationName(QCoreApplication::translate("QDnsLookupExample", "DNS Lookup Example"));
+ QCoreApplication::setApplicationName(QCoreApplication::translate("QDnsLookupExample",
+ "DNS Lookup Example"));
QCommandLineParser parser;
- parser.setApplicationDescription(QCoreApplication::translate("QDnsLookupExample", "An example demonstrating the class QDnsLookup."));
+ parser.setApplicationDescription(QCoreApplication::translate("QDnsLookupExample",
+ "An example demonstrating the "
+ "class QDnsLookup."));
DnsQuery query;
- QString errorMessage;
- switch (parseCommandLine(parser, &query, &errorMessage)) {
- case CommandLineOk:
+ using Status = CommandLineParseResult::Status;
+ CommandLineParseResult parseResult = parseCommandLine(parser, &query);
+ switch (parseResult.statusCode) {
+ case Status::Ok:
break;
- case CommandLineError:
- fputs(qPrintable(errorMessage), stderr);
- fputs("\n\n", stderr);
- fputs(qPrintable(parser.helpText()), stderr);
+ case Status::Error:
+ std::fputs(qPrintable(parseResult.errorString.value_or(u"Unknown error occurred"_qs)),
+ stderr);
+ std::fputs("\n\n", stderr);
+ std::fputs(qPrintable(parser.helpText()), stderr);
return 1;
- case CommandLineVersionRequested:
- printf("%s %s\n", qPrintable(QCoreApplication::applicationName()),
- qPrintable(QCoreApplication::applicationVersion()));
- return 0;
- case CommandLineHelpRequested:
+ case Status::VersionRequested:
+ parser.showVersion();
+ Q_UNREACHABLE_RETURN(0);
+ case Status::HelpRequested:
parser.showHelp();
- Q_UNREACHABLE();
+ Q_UNREACHABLE_RETURN(0);
}
//! [1]
DnsManager manager;
manager.setQuery(query);
- QTimer::singleShot(0, &manager, SLOT(execute()));
+ QTimer::singleShot(0, &manager, &DnsManager::execute);
return app.exec();
}
diff --git a/examples/network/doc/images/blockingfortuneclient-example.png b/examples/network/doc/images/blockingfortuneclient-example.png
index cdb7cac0d3..ab918e791d 100644
--- a/examples/network/doc/images/blockingfortuneclient-example.png
+++ b/examples/network/doc/images/blockingfortuneclient-example.png
Binary files differ
diff --git a/examples/network/doc/images/fortuneclient-example.png b/examples/network/doc/images/fortuneclient-example.png
index b34a98736d..cae0b066dc 100644
--- a/examples/network/doc/images/fortuneclient-example.png
+++ b/examples/network/doc/images/fortuneclient-example.png
Binary files differ
diff --git a/examples/network/doc/images/fortuneserver-example.png b/examples/network/doc/images/fortuneserver-example.png
index 73f27d5653..55ea8b1c29 100644
--- a/examples/network/doc/images/fortuneserver-example.png
+++ b/examples/network/doc/images/fortuneserver-example.png
Binary files differ
diff --git a/examples/network/doc/images/googlesuggest-example.png b/examples/network/doc/images/googlesuggest-example.png
deleted file mode 100644
index c704f5b2b4..0000000000
--- a/examples/network/doc/images/googlesuggest-example.png
+++ /dev/null
Binary files differ
diff --git a/examples/network/doc/images/http-example.png b/examples/network/doc/images/http-example.png
deleted file mode 100644
index c5f3ef1649..0000000000
--- a/examples/network/doc/images/http-example.png
+++ /dev/null
Binary files differ
diff --git a/examples/network/doc/images/http-example.webp b/examples/network/doc/images/http-example.webp
new file mode 100644
index 0000000000..4f6269ec8b
--- /dev/null
+++ b/examples/network/doc/images/http-example.webp
Binary files differ
diff --git a/examples/network/doc/images/loopback-example.png b/examples/network/doc/images/loopback-example.png
deleted file mode 100644
index 2b1bd4a0f2..0000000000
--- a/examples/network/doc/images/loopback-example.png
+++ /dev/null
Binary files differ
diff --git a/examples/network/doc/images/multicastreceiver-example.png b/examples/network/doc/images/multicastreceiver-example.png
deleted file mode 100644
index 8de11cda63..0000000000
--- a/examples/network/doc/images/multicastreceiver-example.png
+++ /dev/null
Binary files differ
diff --git a/examples/network/doc/images/multicastreceiver-example.webp b/examples/network/doc/images/multicastreceiver-example.webp
new file mode 100644
index 0000000000..2dd0c28036
--- /dev/null
+++ b/examples/network/doc/images/multicastreceiver-example.webp
Binary files differ
diff --git a/examples/network/doc/images/multicastsender-example.png b/examples/network/doc/images/multicastsender-example.png
deleted file mode 100644
index a619b047e3..0000000000
--- a/examples/network/doc/images/multicastsender-example.png
+++ /dev/null
Binary files differ
diff --git a/examples/network/doc/images/multicastsender-example.webp b/examples/network/doc/images/multicastsender-example.webp
new file mode 100644
index 0000000000..b06da08351
--- /dev/null
+++ b/examples/network/doc/images/multicastsender-example.webp
Binary files differ
diff --git a/examples/network/doc/images/threadedfortuneserver-example.png b/examples/network/doc/images/threadedfortuneserver-example.png
index 701a0ca035..72315e0b79 100644
--- a/examples/network/doc/images/threadedfortuneserver-example.png
+++ b/examples/network/doc/images/threadedfortuneserver-example.png
Binary files differ
diff --git a/examples/network/doc/src/blockingfortuneclient.qdoc b/examples/network/doc/src/blockingfortuneclient.qdoc
index 931391567d..cd7a8e4c9a 100644
--- a/examples/network/doc/src/blockingfortuneclient.qdoc
+++ b/examples/network/doc/src/blockingfortuneclient.qdoc
@@ -3,7 +3,9 @@
/*!
\example blockingfortuneclient
- \title Blocking Fortune Client Example
+ \title Blocking Fortune Client
+ \examplecategory {Networking}
+ \meta tags {tcp,network,threading,synchronous-io}
\ingroup examples-network
\brief Demonstrates how to create a client for a network service.
@@ -123,7 +125,7 @@
The final part of our loop is that we acquire the mutex so that we can
safely read from our member data. We then let the thread go to sleep by
calling QWaitCondition::wait(). At this point, we can go back to
- requestNewFortune() and look closed at the call to wakeOne():
+ requestNewFortune() and look closely at the call to wakeOne():
\snippet blockingfortuneclient/fortunethread.cpp 1
\dots
@@ -169,5 +171,5 @@
Here, we simply display the fortune we received as the argument.
- \sa {Fortune Client Example}, {Fortune Server Example}
+ \sa {Fortune Client}, {Fortune Server}
*/
diff --git a/examples/network/doc/src/fortuneclient.qdoc b/examples/network/doc/src/fortuneclient.qdoc
index 2e5c976ecc..c22641940c 100644
--- a/examples/network/doc/src/fortuneclient.qdoc
+++ b/examples/network/doc/src/fortuneclient.qdoc
@@ -3,7 +3,9 @@
/*!
\example fortuneclient
- \title Fortune Client Example
+ \title Fortune Client
+ \examplecategory {Networking}
+ \meta tags {tcp,network}
\ingroup examples-network
\brief Demonstrates how to create a client for a network service.
@@ -38,7 +40,7 @@
\endlist
In this example, we will demonstrate the asynchronous approach. The
- \l{blockingfortuneclient}{Blocking Fortune Client Example}
+ \l{blockingfortuneclient}{Blocking Fortune Client} example
illustrates the synchronous approach.
Our class contains some data and a few private slots:
@@ -132,5 +134,5 @@
After a successful read transaction, we call QLabel::setText() to display
the fortune.
- \sa {Fortune Server Example}, {Blocking Fortune Client Example}
+ \sa {Fortune Server}, {Blocking Fortune Client}
*/
diff --git a/examples/network/doc/src/fortuneserver.qdoc b/examples/network/doc/src/fortuneserver.qdoc
index a24804ffda..1973f372ce 100644
--- a/examples/network/doc/src/fortuneserver.qdoc
+++ b/examples/network/doc/src/fortuneserver.qdoc
@@ -3,13 +3,15 @@
/*!
\example fortuneserver
- \title Fortune Server Example
+ \title Fortune Server
+ \examplecategory {Networking}
+ \meta tags {tcp,network,server}
\ingroup examples-network
\brief Demonstrates how to create a server for a network service.
This example is intended to be run alongside the
\l{fortuneclient}{Fortune Client} example or the
- \l{blockingfortuneclient}{Blocking Fortune Client Example}.
+ \l{blockingfortuneclient}{Blocking Fortune Client} example.
\image fortuneserver-example.png Screenshot of the Fortune Server example
@@ -48,7 +50,7 @@
to the connecting socket. This is a common way to transfer binary data
using QTcpSocket. First we create a QByteArray and a QDataStream object,
passing the bytearray to QDataStream's constructor. We then explicitly set
- the protocol version of QDataStream to QDataStream::Qt_4_0 to ensure that
+ the protocol version of QDataStream to QDataStream::Qt_5_10 to ensure that
we can communicate with clients from future versions of Qt (see
QDataStream::setVersion()). We continue by streaming in a random fortune.
@@ -69,5 +71,5 @@
will then close, which in turn will cause QObject::deleteLater() to delete
it.
- \sa {Fortune Client Example}, {Threaded Fortune Server Example}
+ \sa {Fortune Client}, {Threaded Fortune Server}
*/
diff --git a/examples/network/doc/src/googlesuggest.qdoc b/examples/network/doc/src/googlesuggest.qdoc
deleted file mode 100644
index 0cd1b6d868..0000000000
--- a/examples/network/doc/src/googlesuggest.qdoc
+++ /dev/null
@@ -1,153 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
-
-/*!
- \example googlesuggest
- \title Google Suggest Example
- \ingroup examples-network
- \brief Obtains the list of search recommendations by the Google search engine.
-
- The example uses the QNetworkAccessManager to obtain the list of search
- recommendations by Google as the user types into a QLineEdit.
-
- \image googlesuggest-example.png
-
- The application makes use of the \c get function in
- QNetworkAccessManager to post a request and obtain the result of the search
- query sent to the Google search engine. The results returned are listed as
- clickable links appearing below the search box as a drop-down menu.
-
- The widget is built up by a QLineEdit as the search box, and a QTreeView
- used as a popup menu below the search box.
-
- \section1 GSuggestCompletion Class Declaration
-
- This class implements an event filter and a number of functions to display
- the search results and to determent when and how to perform the search.
-
- \snippet googlesuggest/googlesuggest.h 1
-
- The class connects to a QLineEdit and uses a QTreeWidget to display the
- results. A QTimer controls the start of the network requests that are
- executed using a QNetworkAccessManager.
-
- \section1 GSuggestCompletion Class Implementation
-
- We start by defining a constant containing the URL to be used in the Google
- queries. This is the basis for the query. The letters typed into the search
- box will be added to the query to perform the search itself.
-
- \snippet googlesuggest/googlesuggest.cpp 1
-
- In the constructor, we set the parent of this GSuggestCompletion instance
- to be the QLineEdit passed in. For simplicity, the QLineEdit is also stored
- in the explicit \c editor member variable.
-
- We then create a QTreeWidget as a toplevel widget and configure the various
- properties to give it the look of a popup widget. The widget is populated
- with the results by Google Suggest API request.
-
- Furthermore, we install the GSuggestCompletion instance as an event filter
- on the QTreeWidget, and connect the \c itemClicked() signal with the \c
- doneCompletion() slot.
-
- A single-shot QTimer is used to start the request when the user has stopped
- typing for 500 ms.
-
- Finally, we connect the networkManagers \c finished() signal with the \c
- handleNetworkData() slot to handle the incoming data.
-
- \snippet googlesuggest/googlesuggest.cpp 2
-
- Since the QTreeWidget popup has been instantiated as a toplevel widget, the
- destructor has to delete it explicitly from memory to avoid a memory leak.
-
- \snippet googlesuggest/googlesuggest.cpp 3
-
- The event filter handles mouse press and key press events that are
- delivered to the popup. For mouse press events we just hide the popup and
- return focus to the editor widget, and then return true to prevent further
- event processing.
-
- Key event handling is implemented so that Enter and Return execute the
- selected link, while the Escape key hides the popup. Since we want to be
- able to navigate the list of suggestions using the different navigation
- keys on the keyboard we let Qt continue regular event processing for those
- by returning false from the eventFilter reimplementation.
-
- For all other keys, the event will be passed on to the editor widget and the
- popup is hidden. This way the user's typing will not be interrupted by the
- popping up of the completion list.
-
- \snippet googlesuggest/googlesuggest.cpp 4
-
- The \c showCompletion() function populates the QTreeWidget with the results
- returned from the query. It takes a QStringList of the suggested search
- terms.
-
- \snippet googlesuggest/googlesuggest.cpp 5
-
- A QTreeWidgetItem is created for each index in the list and inserted into
- the QTreeWidget. Finally, we adjust position and size of the popup to make
- sure that it pops up in the correct position below the editor, and show it.
-
- The \c doneCompletion() function, which is called by the event filter when
- either Enter or Return keys are pressed, stops the timer to prevent further
- requests and passes the text of the selected item to the editor. We then
- make the \c editor QLineEdit emit the returnPressed() signal, to which the
- application can connect to open the respective web page.
-
- \snippet googlesuggest/googlesuggest.cpp 6
-
- The \c autoSuggest() slot is called when the timer times out, and uses the
- text in the editor to build the complete search query. The query is then
- passed to the QNetworkAccessManager's \c get() function to start the
- request.
-
- \snippet googlesuggest/googlesuggest.cpp 7
-
- The function \c preventSuggest() stops the timer to prevent further
- requests from being started.
-
- \snippet googlesuggest/googlesuggest.cpp 8
-
- When the network request is finished, the QNetworkAccessManager delivers the
- data received from the server through the networkReply object.
-
- \snippet googlesuggest/googlesuggest.cpp 9
-
- To extract the data from the reply we use the \c readAll() function, which
- is inherited from QIODevice and returns a QByteArray. Since this data is
- encoded in XML we can use a QXmlStreamReader to traverse the data and
- extract the search result as QStrings, which we can stream into two
- QStringLists used to populate the popup.
-
- Finally, we schedule the QNetworkReply object for deletion using the \c
- deleteLater function.
-
- \section1 SearchBox Class Declaration
-
- The SearchBox class inherits QLineEdit and adds the protected slot \c
- doSearch().
-
- A \c GSuggestCompletion member provides the SearchBox with the request
- functionality and the suggestions returned from the Google search engine.
-
- \snippet googlesuggest/searchbox.h 1
-
- \section1 SearchBox Class Implementation
-
- The search box constructor instantiates the GSuggestCompletion object and
- connects the returnPressed() signal to the doSearch() slot.
-
- \snippet googlesuggest/searchbox.cpp 1
-
- The function \c doSearch() stops the completer from sending any further
- queries to the search engine.
-
- Further, the function extracts the selected search phrase and opens it
- in the default web browser using QDesktopServices.
-
- \snippet googlesuggest/searchbox.cpp 2
-
-*/
diff --git a/examples/network/doc/src/http.qdoc b/examples/network/doc/src/http.qdoc
index 0776b13a00..0dcaffd42b 100644
--- a/examples/network/doc/src/http.qdoc
+++ b/examples/network/doc/src/http.qdoc
@@ -3,14 +3,16 @@
/*!
\example http
- \title HTTP Example
+ \examplecategory {Networking}
+ \meta tags {http,network,https,proxy}
+ \title HTTP Client
\ingroup examples-network
\brief Demonstrates a simple HTTP client.
This example demonstrates how a simple HTTP client can fetch files
from remote hosts.
- \image http-example.png
+ \image http-example.webp
The main work of this example is done in the HttpWindow class.
Thus we will focus on that.
diff --git a/examples/network/doc/src/loopback.qdoc b/examples/network/doc/src/loopback.qdoc
deleted file mode 100644
index 657e2959bf..0000000000
--- a/examples/network/doc/src/loopback.qdoc
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
-
-/*!
- \example loopback
- \title Loopback Example
- \ingroup examples-network
- \brief Demonstrates the client-server communication on a local host.
-
- The example demonstrates how the clients and servers on a local host
- communicate with each other.
-
- \image loopback-example.png
-*/
diff --git a/examples/network/doc/src/multicastreceiver.qdoc b/examples/network/doc/src/multicastreceiver.qdoc
index 0003f04284..16c7235c17 100644
--- a/examples/network/doc/src/multicastreceiver.qdoc
+++ b/examples/network/doc/src/multicastreceiver.qdoc
@@ -3,10 +3,12 @@
/*!
\example multicastreceiver
- \title Multicast Receiver Example
+ \title Multicast Receiver
+ \examplecategory {Networking}
+ \meta tags {network,multicast,ipv6,ipv4,udp}
\ingroup examples-network
\brief Demonstrates how to receive information sent to a multicast group.
- This example demonstrates how to receive messages sent to a multicast group
- \image multicastreceiver-example.png
+ This example demonstrates how to receive messages sent to a multicast group.
+ \image multicastreceiver-example.webp
*/
diff --git a/examples/network/doc/src/multicastsender.qdoc b/examples/network/doc/src/multicastsender.qdoc
index c5305f271f..26e0d951fe 100644
--- a/examples/network/doc/src/multicastsender.qdoc
+++ b/examples/network/doc/src/multicastsender.qdoc
@@ -3,12 +3,14 @@
/*!
\example multicastsender
- \title Multicast Sender Example
+ \title Multicast Sender
+ \examplecategory {Networking}
+ \meta tags {network,multicast,ipv6,ipv4,udp}
\ingroup examples-network
\brief Demonstrates how to send messages to a multicast group.
This example demonstrates how to send messages to the clients of a
multicast group.
- \image multicastsender-example.png
+ \image multicastsender-example.webp
*/
diff --git a/examples/network/doc/src/network-download.qdoc b/examples/network/doc/src/network-download.qdoc
deleted file mode 100644
index 807cebada2..0000000000
--- a/examples/network/doc/src/network-download.qdoc
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
-
-/*!
- \example download
- \title Network Download Example
- \brief Demonstrates how to use networking APIs for multiple downloads.
- \ingroup examples-network
-
- The Network Download example shows how to perform multiple downloads in
- parallel using the QNetworkAccessManager class.
-
- This example is designed to be run from the command-line.
-
- The \l{Network Download Manager Example} implements a more complex system
- that places files in a queue for sequential downloading.
-*/
diff --git a/examples/network/doc/src/network-downloadmanager.qdoc b/examples/network/doc/src/network-downloadmanager.qdoc
deleted file mode 100644
index 6f5606b016..0000000000
--- a/examples/network/doc/src/network-downloadmanager.qdoc
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
-
-/*!
- \example downloadmanager
- \title Network Download Manager Example
- \brief Demonstrates how to use the networking APIs for multiple downloads.
- \ingroup examples-network
-
- The Network Download example shows how to implement a queue for multiple
- downloads using the QNetworkAccessManager class.
-
- This example is designed to be run from the command-line.
-
- See the \l{Network Download Example} for a simpler version of this example
- that obtains multiple files in parallel.
-*/
diff --git a/examples/network/doc/src/threadedfortuneserver.qdoc b/examples/network/doc/src/threadedfortuneserver.qdoc
index 86de36a4ef..51198061e6 100644
--- a/examples/network/doc/src/threadedfortuneserver.qdoc
+++ b/examples/network/doc/src/threadedfortuneserver.qdoc
@@ -3,7 +3,9 @@
/*!
\example threadedfortuneserver
- \title Threaded Fortune Server Example
+ \title Threaded Fortune Server
+ \examplecategory {Networking}
+ \meta tags {tcp,network,threading,server,synchronous-io}
\ingroup examples-network
\brief The Threaded Fortune Server example shows how to create a server for a
@@ -79,6 +81,5 @@
the socket has disconnected. Because we are running in a separate thread,
the GUI will remain responsive.
- \sa {Fortune Server Example}, {Fortune Client Example}, {Blocking Fortune
- Client Example}
+ \sa {Fortune Server}, {Fortune Client}, {Blocking Fortune Client}
*/
diff --git a/examples/network/download/CMakeLists.txt b/examples/network/download/CMakeLists.txt
deleted file mode 100644
index a258341ce1..0000000000
--- a/examples/network/download/CMakeLists.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-cmake_minimum_required(VERSION 3.16)
-project(download LANGUAGES CXX)
-
-set(CMAKE_AUTOMOC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/network/download")
-
-find_package(Qt6 REQUIRED COMPONENTS Core Network)
-
-qt_add_executable(download
- main.cpp
-)
-
-target_link_libraries(download PUBLIC
- Qt::Core
- Qt::Network
-)
-
-install(TARGETS download
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
-)
diff --git a/examples/network/download/download.pro b/examples/network/download/download.pro
deleted file mode 100644
index 63d80a0e7c..0000000000
--- a/examples/network/download/download.pro
+++ /dev/null
@@ -1,8 +0,0 @@
-QT = core network
-CONFIG += cmdline
-
-SOURCES += main.cpp
-
-# install
-target.path = $$[QT_INSTALL_EXAMPLES]/network/download
-INSTALLS += target
diff --git a/examples/network/download/main.cpp b/examples/network/download/main.cpp
deleted file mode 100644
index 32fccbad9c..0000000000
--- a/examples/network/download/main.cpp
+++ /dev/null
@@ -1,166 +0,0 @@
-// Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#include <QtCore>
-#include <QtNetwork>
-
-#include <cstdio>
-
-QT_BEGIN_NAMESPACE
-class QSslError;
-QT_END_NAMESPACE
-
-using namespace std;
-
-class DownloadManager: public QObject
-{
- Q_OBJECT
- QNetworkAccessManager manager;
- QList<QNetworkReply *> currentDownloads;
-
-public:
- DownloadManager();
- void doDownload(const QUrl &url);
- static QString saveFileName(const QUrl &url);
- bool saveToDisk(const QString &filename, QIODevice *data);
- static bool isHttpRedirect(QNetworkReply *reply);
-
-public slots:
- void execute();
- void downloadFinished(QNetworkReply *reply);
- void sslErrors(const QList<QSslError> &errors);
-};
-
-DownloadManager::DownloadManager()
-{
- connect(&manager, &QNetworkAccessManager::finished,
- this, &DownloadManager::downloadFinished);
-}
-
-void DownloadManager::doDownload(const QUrl &url)
-{
- QNetworkRequest request(url);
- QNetworkReply *reply = manager.get(request);
-
-#if QT_CONFIG(ssl)
- connect(reply, &QNetworkReply::sslErrors,
- this, &DownloadManager::sslErrors);
-#endif
-
- currentDownloads.append(reply);
-}
-
-QString DownloadManager::saveFileName(const QUrl &url)
-{
- QString path = url.path();
- QString basename = QFileInfo(path).fileName();
-
- if (basename.isEmpty())
- basename = "download";
-
- if (QFile::exists(basename)) {
- // already exists, don't overwrite
- int i = 0;
- basename += '.';
- while (QFile::exists(basename + QString::number(i)))
- ++i;
-
- basename += QString::number(i);
- }
-
- return basename;
-}
-
-bool DownloadManager::saveToDisk(const QString &filename, QIODevice *data)
-{
- QFile file(filename);
- if (!file.open(QIODevice::WriteOnly)) {
- fprintf(stderr, "Could not open %s for writing: %s\n",
- qPrintable(filename),
- qPrintable(file.errorString()));
- return false;
- }
-
- file.write(data->readAll());
- file.close();
-
- return true;
-}
-
-bool DownloadManager::isHttpRedirect(QNetworkReply *reply)
-{
- int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
- return statusCode == 301 || statusCode == 302 || statusCode == 303
- || statusCode == 305 || statusCode == 307 || statusCode == 308;
-}
-
-void DownloadManager::execute()
-{
- QStringList args = QCoreApplication::instance()->arguments();
- args.takeFirst(); // skip the first argument, which is the program's name
- if (args.isEmpty()) {
- printf("Qt Download example - downloads all URLs in parallel\n"
- "Usage: download url1 [url2... urlN]\n"
- "\n"
- "Downloads the URLs passed in the command-line to the local directory\n"
- "If the target file already exists, a .0, .1, .2, etc. is appended to\n"
- "differentiate.\n");
- QCoreApplication::instance()->quit();
- return;
- }
-
- for (const QString &arg : qAsConst(args)) {
- QUrl url = QUrl::fromEncoded(arg.toLocal8Bit());
- doDownload(url);
- }
-}
-
-void DownloadManager::sslErrors(const QList<QSslError> &sslErrors)
-{
-#if QT_CONFIG(ssl)
- for (const QSslError &error : sslErrors)
- fprintf(stderr, "SSL error: %s\n", qPrintable(error.errorString()));
-#else
- Q_UNUSED(sslErrors);
-#endif
-}
-
-void DownloadManager::downloadFinished(QNetworkReply *reply)
-{
- QUrl url = reply->url();
- if (reply->error()) {
- fprintf(stderr, "Download of %s failed: %s\n",
- url.toEncoded().constData(),
- qPrintable(reply->errorString()));
- } else {
- if (isHttpRedirect(reply)) {
- fputs("Request was redirected.\n", stderr);
- } else {
- QString filename = saveFileName(url);
- if (saveToDisk(filename, reply)) {
- printf("Download of %s succeeded (saved to %s)\n",
- url.toEncoded().constData(), qPrintable(filename));
- }
- }
- }
-
- currentDownloads.removeAll(reply);
- reply->deleteLater();
-
- if (currentDownloads.isEmpty()) {
- // all downloads finished
- QCoreApplication::instance()->quit();
- }
-}
-
-int main(int argc, char **argv)
-{
- QCoreApplication app(argc, argv);
-
- DownloadManager manager;
- QTimer::singleShot(0, &manager, SLOT(execute()));
-
- app.exec();
-}
-
-#include "main.moc"
diff --git a/examples/network/downloadmanager/CMakeLists.txt b/examples/network/downloadmanager/CMakeLists.txt
deleted file mode 100644
index a65ff74cdc..0000000000
--- a/examples/network/downloadmanager/CMakeLists.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-cmake_minimum_required(VERSION 3.16)
-project(downloadmanager LANGUAGES CXX)
-
-set(CMAKE_AUTOMOC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/network/downloadmanager")
-
-find_package(Qt6 REQUIRED COMPONENTS Core Network)
-
-qt_add_executable(downloadmanager
- downloadmanager.cpp downloadmanager.h
- main.cpp
- textprogressbar.cpp textprogressbar.h
-)
-
-target_link_libraries(downloadmanager PUBLIC
- Qt::Core
- Qt::Network
-)
-
-install(TARGETS downloadmanager
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
-)
diff --git a/examples/network/downloadmanager/downloadmanager.cpp b/examples/network/downloadmanager/downloadmanager.cpp
deleted file mode 100644
index ffb7362113..0000000000
--- a/examples/network/downloadmanager/downloadmanager.cpp
+++ /dev/null
@@ -1,165 +0,0 @@
-// Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#include "downloadmanager.h"
-
-#include <QTextStream>
-
-#include <cstdio>
-
-using namespace std;
-
-DownloadManager::DownloadManager(QObject *parent)
- : QObject(parent)
-{
-}
-
-void DownloadManager::append(const QStringList &urls)
-{
- for (const QString &urlAsString : urls)
- append(QUrl::fromEncoded(urlAsString.toLocal8Bit()));
-
- if (downloadQueue.isEmpty())
- QTimer::singleShot(0, this, &DownloadManager::finished);
-}
-
-void DownloadManager::append(const QUrl &url)
-{
- if (downloadQueue.isEmpty())
- QTimer::singleShot(0, this, &DownloadManager::startNextDownload);
-
- downloadQueue.enqueue(url);
- ++totalCount;
-}
-
-QString DownloadManager::saveFileName(const QUrl &url)
-{
- QString path = url.path();
- QString basename = QFileInfo(path).fileName();
-
- if (basename.isEmpty())
- basename = "download";
-
- if (QFile::exists(basename)) {
- // already exists, don't overwrite
- int i = 0;
- basename += '.';
- while (QFile::exists(basename + QString::number(i)))
- ++i;
-
- basename += QString::number(i);
- }
-
- return basename;
-}
-
-void DownloadManager::startNextDownload()
-{
- if (downloadQueue.isEmpty()) {
- printf("%d/%d files downloaded successfully\n", downloadedCount, totalCount);
- emit finished();
- return;
- }
-
- QUrl url = downloadQueue.dequeue();
-
- QString filename = saveFileName(url);
- output.setFileName(filename);
- if (!output.open(QIODevice::WriteOnly)) {
- fprintf(stderr, "Problem opening save file '%s' for download '%s': %s\n",
- qPrintable(filename), url.toEncoded().constData(),
- qPrintable(output.errorString()));
-
- startNextDownload();
- return; // skip this download
- }
-
- QNetworkRequest request(url);
- currentDownload = manager.get(request);
- connect(currentDownload, &QNetworkReply::downloadProgress,
- this, &DownloadManager::downloadProgress);
- connect(currentDownload, &QNetworkReply::finished,
- this, &DownloadManager::downloadFinished);
- connect(currentDownload, &QNetworkReply::readyRead,
- this, &DownloadManager::downloadReadyRead);
-
- // prepare the output
- printf("Downloading %s...\n", url.toEncoded().constData());
- downloadTimer.start();
-}
-
-void DownloadManager::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
-{
- progressBar.setStatus(bytesReceived, bytesTotal);
-
- // calculate the download speed
- double speed = bytesReceived * 1000.0 / downloadTimer.elapsed();
- QString unit;
- if (speed < 1024) {
- unit = "bytes/sec";
- } else if (speed < 1024*1024) {
- speed /= 1024;
- unit = "kB/s";
- } else {
- speed /= 1024*1024;
- unit = "MB/s";
- }
-
- progressBar.setMessage(QString::fromLatin1("%1 %2")
- .arg(speed, 3, 'f', 1).arg(unit));
- progressBar.update();
-}
-
-void DownloadManager::downloadFinished()
-{
- progressBar.clear();
- output.close();
-
- if (currentDownload->error()) {
- // download failed
- fprintf(stderr, "Failed: %s\n", qPrintable(currentDownload->errorString()));
- output.remove();
- } else {
- // let's check if it was actually a redirect
- if (isHttpRedirect()) {
- reportRedirect();
- output.remove();
- } else {
- printf("Succeeded.\n");
- ++downloadedCount;
- }
- }
-
- currentDownload->deleteLater();
- startNextDownload();
-}
-
-void DownloadManager::downloadReadyRead()
-{
- output.write(currentDownload->readAll());
-}
-
-bool DownloadManager::isHttpRedirect() const
-{
- int statusCode = currentDownload->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
- return statusCode == 301 || statusCode == 302 || statusCode == 303
- || statusCode == 305 || statusCode == 307 || statusCode == 308;
-}
-
-void DownloadManager::reportRedirect()
-{
- int statusCode = currentDownload->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
- QUrl requestUrl = currentDownload->request().url();
- QTextStream(stderr) << "Request: " << requestUrl.toDisplayString()
- << " was redirected with code: " << statusCode
- << '\n';
-
- QVariant target = currentDownload->attribute(QNetworkRequest::RedirectionTargetAttribute);
- if (!target.isValid())
- return;
- QUrl redirectUrl = target.toUrl();
- if (redirectUrl.isRelative())
- redirectUrl = requestUrl.resolved(redirectUrl);
- QTextStream(stderr) << "Redirected to: " << redirectUrl.toDisplayString()
- << '\n';
-}
diff --git a/examples/network/downloadmanager/downloadmanager.h b/examples/network/downloadmanager/downloadmanager.h
deleted file mode 100644
index 4293bce26b..0000000000
--- a/examples/network/downloadmanager/downloadmanager.h
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#ifndef DOWNLOADMANAGER_H
-#define DOWNLOADMANAGER_H
-
-#include <QtNetwork>
-#include <QtCore>
-
-#include "textprogressbar.h"
-
-class DownloadManager: public QObject
-{
- Q_OBJECT
-public:
- explicit DownloadManager(QObject *parent = nullptr);
-
- void append(const QUrl &url);
- void append(const QStringList &urls);
- static QString saveFileName(const QUrl &url);
-
-signals:
- void finished();
-
-private slots:
- void startNextDownload();
- void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);
- void downloadFinished();
- void downloadReadyRead();
-
-private:
- bool isHttpRedirect() const;
- void reportRedirect();
-
- QNetworkAccessManager manager;
- QQueue<QUrl> downloadQueue;
- QNetworkReply *currentDownload = nullptr;
- QFile output;
- QElapsedTimer downloadTimer;
- TextProgressBar progressBar;
-
- int downloadedCount = 0;
- int totalCount = 0;
-};
-
-#endif
diff --git a/examples/network/downloadmanager/downloadmanager.pro b/examples/network/downloadmanager/downloadmanager.pro
deleted file mode 100644
index cd1a977e5d..0000000000
--- a/examples/network/downloadmanager/downloadmanager.pro
+++ /dev/null
@@ -1,17 +0,0 @@
-QT = core network
-CONFIG += cmdline
-
-HEADERS += downloadmanager.h textprogressbar.h
-SOURCES += downloadmanager.cpp main.cpp textprogressbar.cpp
-
-# install
-target.path = $$[QT_INSTALL_EXAMPLES]/network/downloadmanager
-INSTALLS += target
-
-OTHER_FILES += \
- debian/changelog \
- debian/compat \
- debian/control \
- debian/copyright \
- debian/README \
- debian/rules
diff --git a/examples/network/downloadmanager/main.cpp b/examples/network/downloadmanager/main.cpp
deleted file mode 100644
index 6b99e38c63..0000000000
--- a/examples/network/downloadmanager/main.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#include <QCoreApplication>
-#include <QStringList>
-
-#include "downloadmanager.h"
-
-#include <cstdio>
-
-int main(int argc, char **argv)
-{
- using namespace std;
-
- QCoreApplication app(argc, argv);
- QStringList arguments = app.arguments();
- arguments.takeFirst(); // remove the first argument, which is the program's name
-
- if (arguments.isEmpty()) {
- printf("Qt Download example\n"
- "Usage: downloadmanager url1 [url2... urlN]\n"
- "\n"
- "Downloads the URLs passed in the command-line to the local directory\n"
- "If the target file already exists, a .0, .1, .2, etc. is appended to\n"
- "differentiate.\n");
- return 0;
- }
-
- DownloadManager manager;
- manager.append(arguments);
-
- QObject::connect(&manager, &DownloadManager::finished,
- &app, &QCoreApplication::quit);
- app.exec();
-}
diff --git a/examples/network/downloadmanager/textprogressbar.cpp b/examples/network/downloadmanager/textprogressbar.cpp
deleted file mode 100644
index 824b403cfc..0000000000
--- a/examples/network/downloadmanager/textprogressbar.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#include "textprogressbar.h"
-
-#include <QByteArray>
-
-#include <cstdio>
-
-using namespace std;
-
-void TextProgressBar::clear()
-{
- printf("\n");
- fflush(stdout);
-
- value = 0;
- maximum = -1;
- iteration = 0;
-}
-
-void TextProgressBar::update()
-{
- ++iteration;
-
- if (maximum > 0) {
- // we know the maximum
- // draw a progress bar
- int percent = value * 100 / maximum;
- int hashes = percent / 2;
-
- QByteArray progressbar(hashes, '#');
- if (percent % 2)
- progressbar += '>';
-
- printf("\r[%-50s] %3d%% %s ",
- progressbar.constData(),
- percent,
- qPrintable(message));
- } else {
- // we don't know the maximum, so we can't draw a progress bar
- int center = (iteration % 48) + 1; // 50 spaces, minus 2
- QByteArray before(qMax(center - 2, 0), ' ');
- QByteArray after(qMin(center + 2, 50), ' ');
-
- printf("\r[%s###%s] %s ",
- before.constData(), after.constData(), qPrintable(message));
- }
-}
-
-void TextProgressBar::setMessage(const QString &m)
-{
- message = m;
-}
-
-void TextProgressBar::setStatus(qint64 val, qint64 max)
-{
- value = val;
- maximum = max;
-}
diff --git a/examples/network/downloadmanager/textprogressbar.h b/examples/network/downloadmanager/textprogressbar.h
deleted file mode 100644
index 60ef0dfddc..0000000000
--- a/examples/network/downloadmanager/textprogressbar.h
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#ifndef TEXTPROGRESSBAR_H
-#define TEXTPROGRESSBAR_H
-
-#include <QString>
-
-class TextProgressBar
-{
-public:
- void clear();
- void update();
- void setMessage(const QString &message);
- void setStatus(qint64 value, qint64 maximum);
-
-private:
- QString message;
- qint64 value = 0;
- qint64 maximum = -1;
- int iteration = 0;
-};
-
-#endif
diff --git a/examples/network/fortuneclient/CMakeLists.txt b/examples/network/fortuneclient/CMakeLists.txt
index 05ab8c6fd7..3546aca929 100644
--- a/examples/network/fortuneclient/CMakeLists.txt
+++ b/examples/network/fortuneclient/CMakeLists.txt
@@ -1,8 +1,9 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(fortuneclient LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
@@ -11,6 +12,8 @@ set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/network/fortuneclient")
find_package(Qt6 REQUIRED COMPONENTS Core Gui Network Widgets)
+qt_standard_project_setup()
+
qt_add_executable(fortuneclient
client.cpp client.h
main.cpp
@@ -21,11 +24,11 @@ set_target_properties(fortuneclient PROPERTIES
MACOSX_BUNDLE TRUE
)
-target_link_libraries(fortuneclient PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Network
- Qt::Widgets
+target_link_libraries(fortuneclient PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Network
+ Qt6::Widgets
)
install(TARGETS fortuneclient
diff --git a/examples/network/fortuneclient/client.cpp b/examples/network/fortuneclient/client.cpp
index 68fbb68a4e..af7efbd9ed 100644
--- a/examples/network/fortuneclient/client.cpp
+++ b/examples/network/fortuneclient/client.cpp
@@ -14,7 +14,6 @@ Client::Client(QWidget *parent)
, getFortuneButton(new QPushButton(tr("Get Fortune")))
, tcpSocket(new QTcpSocket(this))
{
- setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
//! [0]
hostCombo->setEditable(true);
// find out name of this machine
@@ -28,16 +27,16 @@ Client::Client(QWidget *parent)
if (name != QLatin1String("localhost"))
hostCombo->addItem(QString("localhost"));
// find out IP addresses of this machine
- QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();
+ const QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();
// add non-localhost addresses
- for (int i = 0; i < ipAddressesList.size(); ++i) {
- if (!ipAddressesList.at(i).isLoopback())
- hostCombo->addItem(ipAddressesList.at(i).toString());
+ for (const QHostAddress &entry : ipAddressesList) {
+ if (!entry.isLoopback())
+ hostCombo->addItem(entry.toString());
}
// add localhost addresses
- for (int i = 0; i < ipAddressesList.size(); ++i) {
- if (ipAddressesList.at(i).isLoopback())
- hostCombo->addItem(ipAddressesList.at(i).toString());
+ for (const QHostAddress &entry : ipAddressesList) {
+ if (entry.isLoopback())
+ hostCombo->addItem(entry.toString());
}
portLineEdit->setValidator(new QIntValidator(1, 65535, this));
@@ -61,7 +60,7 @@ Client::Client(QWidget *parent)
//! [1]
in.setDevice(tcpSocket);
- in.setVersion(QDataStream::Qt_4_0);
+ in.setVersion(QDataStream::Qt_6_5);
//! [1]
connect(hostCombo, &QComboBox::editTextChanged,
diff --git a/examples/network/fortuneserver/CMakeLists.txt b/examples/network/fortuneserver/CMakeLists.txt
index 16be51f61c..8ed91f6bef 100644
--- a/examples/network/fortuneserver/CMakeLists.txt
+++ b/examples/network/fortuneserver/CMakeLists.txt
@@ -1,8 +1,9 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(fortuneserver LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
@@ -11,6 +12,8 @@ set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/network/fortuneserver")
find_package(Qt6 REQUIRED COMPONENTS Core Gui Network Widgets)
+qt_standard_project_setup()
+
qt_add_executable(fortuneserver
main.cpp
server.cpp server.h
@@ -21,11 +24,11 @@ set_target_properties(fortuneserver PROPERTIES
MACOSX_BUNDLE TRUE
)
-target_link_libraries(fortuneserver PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Network
- Qt::Widgets
+target_link_libraries(fortuneserver PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Network
+ Qt6::Widgets
)
install(TARGETS fortuneserver
diff --git a/examples/network/fortuneserver/server.cpp b/examples/network/fortuneserver/server.cpp
index 3a78429d31..67d6117566 100644
--- a/examples/network/fortuneserver/server.cpp
+++ b/examples/network/fortuneserver/server.cpp
@@ -11,7 +11,6 @@ Server::Server(QWidget *parent)
: QDialog(parent)
, statusLabel(new QLabel)
{
- setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
statusLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
initServer();
@@ -72,12 +71,11 @@ void Server::initServer()
}
//! [0]
QString ipAddress;
- QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();
+ const QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();
// use the first non-localhost IPv4 address
- for (int i = 0; i < ipAddressesList.size(); ++i) {
- if (ipAddressesList.at(i) != QHostAddress::LocalHost &&
- ipAddressesList.at(i).toIPv4Address()) {
- ipAddress = ipAddressesList.at(i).toString();
+ for (const QHostAddress &entry : ipAddressesList) {
+ if (entry != QHostAddress::LocalHost && entry.toIPv4Address()) {
+ ipAddress = entry.toString();
break;
}
}
@@ -96,7 +94,7 @@ void Server::sendFortune()
//! [5]
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
- out.setVersion(QDataStream::Qt_5_10);
+ out.setVersion(QDataStream::Qt_6_5);
out << fortunes[QRandomGenerator::global()->bounded(fortunes.size())];
//! [4] //! [7]
diff --git a/examples/network/googlesuggest/CMakeLists.txt b/examples/network/googlesuggest/CMakeLists.txt
deleted file mode 100644
index 27bc585eae..0000000000
--- a/examples/network/googlesuggest/CMakeLists.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-cmake_minimum_required(VERSION 3.16)
-project(googlesuggest LANGUAGES CXX)
-
-set(CMAKE_AUTOMOC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/network/googlesuggest")
-
-find_package(Qt6 REQUIRED COMPONENTS Core Gui Network Widgets)
-
-qt_add_executable(googlesuggest
- googlesuggest.cpp googlesuggest.h
- main.cpp
- searchbox.cpp searchbox.h
-)
-
-set_target_properties(googlesuggest PROPERTIES
- WIN32_EXECUTABLE TRUE
- MACOSX_BUNDLE TRUE
-)
-
-target_link_libraries(googlesuggest PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Network
- Qt::Widgets
-)
-
-install(TARGETS googlesuggest
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
-)
diff --git a/examples/network/googlesuggest/googlesuggest.cpp b/examples/network/googlesuggest/googlesuggest.cpp
deleted file mode 100644
index b8cb589262..0000000000
--- a/examples/network/googlesuggest/googlesuggest.cpp
+++ /dev/null
@@ -1,184 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#include "googlesuggest.h"
-
-//! [1]
-const QString gsuggestUrl(QStringLiteral("http://google.com/complete/search?output=toolbar&q=%1"));
-//! [1]
-
-//! [2]
-GSuggestCompletion::GSuggestCompletion(QLineEdit *parent): QObject(parent), editor(parent)
-{
- popup = new QTreeWidget;
- popup->setWindowFlags(Qt::Popup);
- popup->setFocusPolicy(Qt::NoFocus);
- popup->setFocusProxy(parent);
- popup->setMouseTracking(true);
-
- popup->setColumnCount(1);
- popup->setUniformRowHeights(true);
- popup->setRootIsDecorated(false);
- popup->setEditTriggers(QTreeWidget::NoEditTriggers);
- popup->setSelectionBehavior(QTreeWidget::SelectRows);
- popup->setFrameStyle(QFrame::Box | QFrame::Plain);
- popup->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- popup->header()->hide();
-
- popup->installEventFilter(this);
-
- connect(popup, &QTreeWidget::itemClicked,
- this, &GSuggestCompletion::doneCompletion);
-
- timer.setSingleShot(true);
- timer.setInterval(500);
- connect(&timer, &QTimer::timeout,
- this, &GSuggestCompletion::autoSuggest);
- connect(editor, &QLineEdit::textEdited,
- &timer, QOverload<>::of(&QTimer::start));
-
- connect(&networkManager, &QNetworkAccessManager::finished,
- this, &GSuggestCompletion::handleNetworkData);
-
-}
-//! [2]
-
-//! [3]
-GSuggestCompletion::~GSuggestCompletion()
-{
- delete popup;
-}
-//! [3]
-
-//! [4]
-bool GSuggestCompletion::eventFilter(QObject *obj, QEvent *ev)
-{
- if (obj != popup)
- return false;
-
- if (ev->type() == QEvent::MouseButtonPress) {
- popup->hide();
- editor->setFocus();
- return true;
- }
-
- if (ev->type() == QEvent::KeyPress) {
- bool consumed = false;
- int key = static_cast<QKeyEvent*>(ev)->key();
- switch (key) {
- case Qt::Key_Enter:
- case Qt::Key_Return:
- doneCompletion();
- consumed = true;
- break;
-
- case Qt::Key_Escape:
- editor->setFocus();
- popup->hide();
- consumed = true;
- break;
-
- case Qt::Key_Up:
- case Qt::Key_Down:
- case Qt::Key_Home:
- case Qt::Key_End:
- case Qt::Key_PageUp:
- case Qt::Key_PageDown:
- break;
-
- default:
- editor->setFocus();
- editor->event(ev);
- popup->hide();
- break;
- }
-
- return consumed;
- }
-
- return false;
-}
-//! [4]
-
-//! [5]
-void GSuggestCompletion::showCompletion(const QList<QString> &choices)
-{
- if (choices.isEmpty())
- return;
-
- const QPalette &pal = editor->palette();
- QColor color = pal.color(QPalette::Disabled, QPalette::WindowText);
-
- popup->setUpdatesEnabled(false);
- popup->clear();
-
- for (const auto &choice : choices) {
- auto item = new QTreeWidgetItem(popup);
- item->setText(0, choice);
- item->setForeground(0, color);
- }
-
- popup->setCurrentItem(popup->topLevelItem(0));
- popup->resizeColumnToContents(0);
- popup->setUpdatesEnabled(true);
-
- popup->move(editor->mapToGlobal(QPoint(0, editor->height())));
- popup->setFocus();
- popup->show();
-}
-//! [5]
-
-//! [6]
-void GSuggestCompletion::doneCompletion()
-{
- timer.stop();
- popup->hide();
- editor->setFocus();
- QTreeWidgetItem *item = popup->currentItem();
- if (item) {
- editor->setText(item->text(0));
- QMetaObject::invokeMethod(editor, "returnPressed");
- }
-}
-//! [6]
-
-//! [7]
-void GSuggestCompletion::autoSuggest()
-{
- QString str = editor->text();
- QString url = gsuggestUrl.arg(str);
- networkManager.get(QNetworkRequest(url));
-}
-//! [7]
-
-//! [8]
-void GSuggestCompletion::preventSuggest()
-{
- timer.stop();
-}
-//! [8]
-
-//! [9]
-void GSuggestCompletion::handleNetworkData(QNetworkReply *networkReply)
-{
- QUrl url = networkReply->url();
- if (networkReply->error() == QNetworkReply::NoError) {
- QList<QString> choices;
-
- QByteArray response(networkReply->readAll());
- QXmlStreamReader xml(response);
- while (!xml.atEnd()) {
- xml.readNext();
- if (xml.tokenType() == QXmlStreamReader::StartElement)
- if (xml.name() == u"suggestion") {
- auto str = xml.attributes().value("data");
- choices << str.toString();
- }
- }
-
- showCompletion(choices);
- }
-
- networkReply->deleteLater();
-}
-//! [9]
diff --git a/examples/network/googlesuggest/googlesuggest.h b/examples/network/googlesuggest/googlesuggest.h
deleted file mode 100644
index c46b58044b..0000000000
--- a/examples/network/googlesuggest/googlesuggest.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#ifndef GOOGLESUGGEST_H
-#define GOOGLESUGGEST_H
-
-#include <QtWidgets>
-#include <QtNetwork>
-#include <QtCore>
-
-//! [1]
-class GSuggestCompletion : public QObject
-{
- Q_OBJECT
-
-public:
- explicit GSuggestCompletion(QLineEdit *parent = nullptr);
- ~GSuggestCompletion();
- bool eventFilter(QObject *obj, QEvent *ev) override;
- void showCompletion(const QList<QString> &choices);
-
-public slots:
-
- void doneCompletion();
- void preventSuggest();
- void autoSuggest();
- void handleNetworkData(QNetworkReply *networkReply);
-
-private:
- QLineEdit *editor = nullptr;
- QTreeWidget *popup = nullptr;
- QTimer timer;
- QNetworkAccessManager networkManager;
-};
-//! [1]
-#endif // GOOGLESUGGEST_H
-
diff --git a/examples/network/googlesuggest/googlesuggest.pro b/examples/network/googlesuggest/googlesuggest.pro
deleted file mode 100644
index 6e73906303..0000000000
--- a/examples/network/googlesuggest/googlesuggest.pro
+++ /dev/null
@@ -1,8 +0,0 @@
-QT += network widgets
-requires(qtConfig(itemviews))
-SOURCES = main.cpp searchbox.cpp googlesuggest.cpp
-HEADERS = searchbox.h googlesuggest.h
-
-# install
-target.path = $$[QT_INSTALL_EXAMPLES]/network/googlesuggest
-INSTALLS += target
diff --git a/examples/network/googlesuggest/main.cpp b/examples/network/googlesuggest/main.cpp
deleted file mode 100644
index 0e927f3d23..0000000000
--- a/examples/network/googlesuggest/main.cpp
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#include <QApplication>
-
-#include "searchbox.h"
-
-int main(int argc, char * argv[])
-{
- QApplication app(argc, argv);
- SearchBox searchEdit;
- searchEdit.show();
- return app.exec();
-}
diff --git a/examples/network/googlesuggest/searchbox.cpp b/examples/network/googlesuggest/searchbox.cpp
deleted file mode 100644
index 56ca44dac4..0000000000
--- a/examples/network/googlesuggest/searchbox.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#include <QDesktopServices>
-#include <QUrl>
-
-#include "searchbox.h"
-#include "googlesuggest.h"
-
-const QString gsearchUrl = QStringLiteral("http://www.google.com/search?q=%1");
-
-//! [1]
-SearchBox::SearchBox(QWidget *parent)
- : QLineEdit(parent)
- , completer(new GSuggestCompletion(this))
-{
- connect(this, &SearchBox::returnPressed, this, &SearchBox::doSearch);
-
- setWindowTitle("Search with Google");
-
- adjustSize();
- resize(400, height());
- setFocus();
-}
-//! [1]
-
-//! [2]
-void SearchBox::doSearch()
-{
- completer->preventSuggest();
- QString url = gsearchUrl.arg(text());
- QDesktopServices::openUrl(url);
-}
-//! [2]
-
diff --git a/examples/network/googlesuggest/searchbox.h b/examples/network/googlesuggest/searchbox.h
deleted file mode 100644
index be9beba1bc..0000000000
--- a/examples/network/googlesuggest/searchbox.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#ifndef SEARCHBOX_H
-#define SEARCHBOX_H
-
-//! [1]
-#include <QLineEdit>
-
-class GSuggestCompletion;
-
-class SearchBox: public QLineEdit
-{
- Q_OBJECT
-
-public:
- explicit SearchBox(QWidget *parent = nullptr);
-
-protected slots:
- void doSearch();
-
-private:
- GSuggestCompletion *completer = nullptr;
-//! [1]
-};
-
-
-#endif // SEARCHBOX_H
diff --git a/examples/network/http/CMakeLists.txt b/examples/network/http/CMakeLists.txt
index 8be2d25bec..0592dfa8e2 100644
--- a/examples/network/http/CMakeLists.txt
+++ b/examples/network/http/CMakeLists.txt
@@ -1,9 +1,9 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(http LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTOUIC ON)
-
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
@@ -12,6 +12,8 @@ set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/network/http")
find_package(Qt6 REQUIRED COMPONENTS Core Gui Network Widgets)
+qt_standard_project_setup()
+
qt_add_executable(http
authenticationdialog.ui
httpwindow.cpp httpwindow.h
@@ -23,11 +25,11 @@ set_target_properties(http PROPERTIES
MACOSX_BUNDLE TRUE
)
-target_link_libraries(http PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Network
- Qt::Widgets
+target_link_libraries(http PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Network
+ Qt6::Widgets
)
install(TARGETS http
diff --git a/examples/network/http/httpwindow.cpp b/examples/network/http/httpwindow.cpp
index 9fa32da101..72f130734b 100644
--- a/examples/network/http/httpwindow.cpp
+++ b/examples/network/http/httpwindow.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2020 The Qt Company Ltd.
+// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "httpwindow.h"
@@ -23,7 +23,6 @@ ProgressDialog::ProgressDialog(const QUrl &url, QWidget *parent)
: QProgressDialog(parent)
{
setWindowTitle(tr("Download Progress"));
- setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
setLabelText(tr("Downloading %1.").arg(url.toDisplayString()));
setMinimum(0);
setValue(0);
@@ -42,17 +41,20 @@ HttpWindow::HttpWindow(QWidget *parent)
, statusLabel(new QLabel(tr("Please enter the URL of a file you want to download.\n\n"), this))
, urlLineEdit(new QLineEdit(defaultUrl))
, downloadButton(new QPushButton(tr("Download")))
- , launchCheckBox(new QCheckBox("Launch file"))
+ , launchCheckBox(new QCheckBox(tr("Launch file")))
, defaultFileLineEdit(new QLineEdit(defaultFileName))
, downloadDirectoryLineEdit(new QLineEdit)
{
- setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
- setWindowTitle(tr("HTTP"));
+ setWindowTitle(tr("HTTP Client"));
//! [qnam-auth-required-1]
connect(&qnam, &QNetworkAccessManager::authenticationRequired,
this, &HttpWindow::slotAuthenticationRequired);
//! [qnam-auth-required-1]
+#if QT_CONFIG(networkproxy)
+ connect(&qnam, &QNetworkAccessManager::proxyAuthenticationRequired,
+ this, &HttpWindow::slotProxyAuthenticationRequired);
+#endif
QFormLayout *formLayout = new QFormLayout;
urlLineEdit->setClearButtonEnabled(true);
@@ -142,19 +144,18 @@ void HttpWindow::downloadFile()
bool useDirectory = !downloadDirectory.isEmpty() && QFileInfo(downloadDirectory).isDir();
if (useDirectory)
fileName.prepend(downloadDirectory + '/');
+
if (QFile::exists(fileName)) {
- if (QMessageBox::question(this, tr("Overwrite Existing File"),
- tr("There already exists a file called %1%2."
- " Overwrite?")
- .arg(fileName,
- useDirectory
- ? QString()
- : QStringLiteral(" in the current directory")),
- QMessageBox::Yes | QMessageBox::No,
- QMessageBox::No)
- == QMessageBox::No) {
+ QString alreadyExists = useDirectory
+ ? tr("There already exists a file called %1. Overwrite?")
+ : tr("There already exists a file called %1 in the current directory. "
+ "Overwrite?");
+ QMessageBox::StandardButton response = QMessageBox::question(this,
+ tr("Overwrite Existing File"),
+ alreadyExists.arg(QDir::toNativeSeparators(fileName)),
+ QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
+ if (response == QMessageBox::No)
return;
- }
QFile::remove(fileName);
}
@@ -272,11 +273,34 @@ void HttpWindow::sslErrors(const QList<QSslError> &errors)
errorString += error.errorString();
}
- if (QMessageBox::warning(this, tr("SSL Errors"),
- tr("One or more SSL errors has occurred:\n%1").arg(errorString),
- QMessageBox::Ignore | QMessageBox::Abort) == QMessageBox::Ignore) {
+ if (QMessageBox::warning(this, tr("TLS Errors"),
+ tr("One or more TLS errors has occurred:\n%1").arg(errorString),
+ QMessageBox::Ignore | QMessageBox::Abort)
+ == QMessageBox::Ignore) {
reply->ignoreSslErrors();
}
}
//! [sslerrors-2]
#endif
+
+#if QT_CONFIG(networkproxy)
+void HttpWindow::slotProxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator)
+{
+ QDialog authenticationDialog;
+ Ui::Dialog ui;
+ ui.setupUi(&authenticationDialog);
+ authenticationDialog.adjustSize();
+ ui.siteDescription->setText(tr("A network proxy at %1 is requesting credentials for realm: %2")
+ .arg(proxy.hostName(), authenticator->realm()));
+
+ // If the user passed credentials in the URL to http_proxy or similar they may be available to
+ // us. Otherwise this will just leave the fields empty
+ ui.userEdit->setText(proxy.user());
+ ui.passwordEdit->setText(proxy.password());
+
+ if (authenticationDialog.exec() == QDialog::Accepted) {
+ authenticator->setUser(ui.userEdit->text());
+ authenticator->setPassword(ui.passwordEdit->text());
+ }
+}
+#endif
diff --git a/examples/network/http/httpwindow.h b/examples/network/http/httpwindow.h
index 64e9274288..ade0635e48 100644
--- a/examples/network/http/httpwindow.h
+++ b/examples/network/http/httpwindow.h
@@ -19,6 +19,9 @@ class QSslError;
class QAuthenticator;
class QNetworkReply;
class QCheckBox;
+#if QT_CONFIG(networkproxy)
+class QNetworkProxy;
+#endif
QT_END_NAMESPACE
@@ -52,6 +55,9 @@ private slots:
#if QT_CONFIG(ssl)
void sslErrors(const QList<QSslError> &errors);
#endif
+#if QT_CONFIG(networkproxy)
+ void slotProxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator);
+#endif
private:
std::unique_ptr<QFile> openFileForWrite(const QString &fileName);
diff --git a/examples/network/http/ma