Search icon
Arrow left icon
All Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletters
Free Learning
Arrow right icon
Qt 6 C++ GUI Programming Cookbook - Third Edition
Qt 6 C++ GUI Programming Cookbook - Third Edition

Qt 6 C++ GUI Programming Cookbook: Practical recipes for building cross-platform GUI applications, widgets, and animations with Qt 6, Third Edition

By Lee Zhi Eng
€27.99 €18.99
Book Apr 2024 428 pages 3rd Edition
eBook
€27.99 €18.99
Print
€34.99
Subscription
€14.99 Monthly
eBook
€27.99 €18.99
Print
€34.99
Subscription
€14.99 Monthly

What do you get with eBook?

Product feature icon Instant access to your Digital eBook purchase
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Buy Now

Product Details


Publication date : Apr 12, 2024
Length 428 pages
Edition : 3rd Edition
Language : English
ISBN-13 : 9781805122630
Category :
Table of content icon View table of contents Preview book icon Preview Book

Qt 6 C++ GUI Programming Cookbook - Third Edition

Look-and-Feel Customization with Qt Designer

Qt 6 allows us to easily design our program’s user interface through a method most people are familiar with. Qt not only provides us with a powerful user interface toolkit, called Qt Designer, which enables us to design our user interface without writing a single line of code, but it also allows advanced users to customize their user interface components through a simple scripting language called Qt Style Sheet.

In this chapter, we’re going to cover the following recipes:

  • Using style sheets with Qt Designer
  • Customizing basic style sheets
  • Creating a login screen using style sheets
  • Using resources in style sheets
  • Customizing properties and sub-controls
  • Styling in Qt Modeling Language (QML)
  • Exposing the QML object pointer to C++

Technical requirements

The technical requirements for this chapter include having Qt 6.1.1 MinGW 64-bit and Qt Creator 12.0.2. The code that’s used in this chapter can be downloaded from this book’s GitHub repository: https://github.com/PacktPublishing/QT6-C-GUI-Programming-Cookbook---Third-Edition-/tree/main/Chapter01.

Using style sheets with Qt Designer

In this example, we will learn how to change the look and feel of our program and make it look more professional by using style sheets and resources. Qt allows you to decorate your graphical user interfaces (GUIs) using a style sheet language called Qt Style Sheets, which is very similar to Cascading Style Sheets (CSS), something that’s used by web designers to decorate their websites.

How to do it...

Let’s get started by learning how to create a new project and get ourselves familiar with Qt Designer:

  1. Open up Qt Creator and create a new project. If this is the first time you have used Qt Creator, you can either click the big button, which reads Create Project…, or simply go to File | New Project….
  2. Select Application (Qt) from the Projects window and select Qt Widgets Application.
  3. Click the Choose... button at the bottom. A window will pop out and ask you to insert the project’s name and its location.
  4. Click Next several times, then click the Finish button to create the project. We will stick with the default settings for now. Once the project has been created, the first thing you will see is a panel with tons of big icons on the left-hand side of the window, which is called the mode selector panel; we will discuss this in more detail in the Dissecting Qt Designer recipe.
  5. You will see all your source files listed on the sidebar panel, which is located next to the mode selector panel. This is where you can select which file you want to edit. In this case, this is mainwindow.ui, because we are about to start designing the program’s UI.
  6. Double-click the mainwindow.ui file; you will see an entirely different interface appear out of nowhere. Qt Creator helped you switch from the script editor to the UI editor (Qt Designer) because it detected the .ui extension on the file you’re trying to open.
  7. You will also notice that the highlighted button on the mode selector panel has changed from Edit to Design. You can switch back to the script editor or change to any other tools by clicking one of the buttons located in the upper half of the mode selector panel.
  8. Let’s go back to Qt Designer and look at the mainwindow.ui file. This is the main window of our program (as the filename implies) and it’s empty by default, without any widget on it. You can try to compile and run the program by pressing the Run button (the green arrow button) at the bottom of the mode selector panel; you will see an empty window pop up once the compilation is complete.
  9. Let’s add a push button to our program’s UI by clicking on the Push Button item in the Widget Box area (under the Buttons category) and dragging it to our main window in the form editor. Keep the push button selected; you will see all the properties of this button inside the Property Editor area on the right-hand side of your window. Scroll down to the middle and look for a property called styleSheet. This is where you will apply styles to your widget, which may or may not be inherited from its children or grandchildren recursively, depending on how you set your style sheet. Alternatively, you can right-click on any widget in your UI at the form editor and select Change styleSheet... from the pop-up menu.
  10. You can click on the input field of the styleSheet property to directly write the style sheet code, or click on the button beside the input field to open up the Edit Style Sheet window, which has a bigger space for writing longer code for style sheets. At the top of the window, you can find several buttons, such as Add Resource, Add Gradient, Add Color, and Add Font, that can help you kickstart your coding if you can’t remember the properties’ names. Let’s try to do some simple styling with the Edit Style Sheet window.
  11. Click Add Color and choose a color.
  12. Pick a random color from the color picker window – let’s say, a pure red color. Then, click OK.
  13. A line of code has been added to the text field in the Edit Style Sheet window, which in my case is as follows:
    color: rgb(255, 0, 0);
  14. Click the OK button; the text on your push button should change to red.

How it works...

Let’s take a bit of time to get familiar with Qt Designer’s interface before we start learning how to design our own UI:

Figure 1.1 – Overview of Qt Designer’s interface

Figure 1.1 – Overview of Qt Designer’s interface

The explanation for the preceding screenshot is as follows:

  1. Menu bar: The menu bar houses application-specific menus that provide easy access to essential functions, such as creating new projects, saving files, undoing, redoing, copying, and pasting. It also allows you to access development tools that come with Qt Creator, such as the compiler, debugger, and profiler.
  2. Widget Box: This is where you can find all the different types of widgets provided by Qt Designer. You can add a widget to your program’s UI by clicking one of the widgets from the Widget Box area and dragging it to the form editor.
  3. Mode selector: The mode selector is a side panel that places shortcut buttons for easy access to different tools. You can quickly switch between the script editor and form editor by clicking the Edit or Design button on the mode selector panel, which is very useful for multitasking. You can also easily navigate to the debugger and profiler tools at the same speed and manner.
  4. Build shortcuts: The build shortcuts are located at the bottom of the mode selector panel. You can build, run, and debug your project easily by pressing the shortcut buttons here.
  5. Form editor: The form editor is where you edit your program’s UI. You can add different widgets to your program by selecting a widget from the Widget Box area and dragging it to the form editor.
  6. Form toolbar: From here, you can quickly select a different form to edit. Click the drop-down box located at the top of the Widget Box area and select the file you want to open with Qt Designer. Beside the drop-down box are buttons to switch between the different modes of the form editor, and also buttons to change the layout of your UI.
  7. Object Inspector: The Object Inspector area lists all the widgets within your current .ui file. All the widgets are arranged according to their parent-child relationship in the hierarchy. You can select a widget from the Object Inspector area to display its properties in the Property Editor area.
  8. Property Editor: The Property Editor area will display all the properties of the widget you selected from either the Object Inspector area or the form editor window.
  9. Action Editor and Signals & Slots Editor: This window contains two editors: Action Editor and Signals & Slots Editor. Both can be accessed from the tabs beneath the window. Action Editor is where you create actions that can be added to a menu bar or toolbar in your program’s UI.
  10. Output panes: Output panes consist of several different windows that display information and output messages related to script compilation and debugging. You can switch between different output panes by pressing the buttons that carry a number before them, such as 1 Issues, 2 Search Results, or 3 Application Output.

There’s more...

In this recipe, we discussed how to apply style sheets to Qt widgets through C++ coding. Although that method works well, most of the time, the person who is in charge of designing the program’s UI is not the programmer, but rather a UI designer who specializes in designing user-friendly UI. In this case, it’s better to let the UI designer design the program’s layout and style sheet with a different tool and not mess around with the code. Qt provides an all-in-one editor called Qt Creator.

Qt Creator consists of several different tools, such as a script editor, compiler, debugger, profiler, and UI editor. The UI editor, which is also called Qt Designer, is the perfect tool for designers to design their program’s UI without writing any code. This is because Qt Designer adopted the what you see is what you get approach by providing an accurate visual representation of the final result, which means whatever you design with Qt Designer will turn out the same visually when the program is compiled and run.

The similarities between Qt Style Sheets and CSS are as follows:

  • This is how a typical piece of CSS code looks:
    h1 { color: red; background-color: white;}
  • This is how Qt Style Sheets look, which is almost the same as the preceding CSS:
    QLineEdit { color: red; background-color: white;}

As you can see, both of them contain a selector and a declaration block. Each declaration contains a property and a value, separated by a colon. In Qt, a style sheet can be applied to a single widget by calling the QObject::setStyleSheet() function in C++ code.

Consider the following, for example:

myPushButton->setStyleSheet("color : blue");

The preceding code will turn the text of a button with the myPushButton variable name to blue. You can achieve the same result by writing the declaration in the style sheet property field in Qt Designer. We will discuss Qt Designer more in the Customizing basic style sheets recipe.

Qt Style Sheets also supports all the different types of selectors defined in the CSS2 standard, including the universal selector, type selector, class selector, and ID selector, which allows us to apply styling to a very specific individual widget or group of widgets. For instance, if we want to change the background color of a specific line-edit widget with the usernameEdit object name, we can do this by using an ID selector to refer to it:

QLineEdit#usernameEdit { background-color: blue }

Note

To learn about all the selectors available in CSS2 (which are also supported by Qt Style Sheets), please refer to this document: http://www.w3.org/TR/REC-CSS2/selector.html.

Customizing basic style sheets

In the previous recipe, you learned how to apply a style sheet to a widget with Qt Designer. Let’s go crazy and push things further by creating a few other types of widgets and changing their style properties to something bizarre for the sake of learning.

This time, however, we will not apply the style to every single widget one by one; instead, we will learn to apply the style sheet to the main window and let it inherit down the hierarchy to all the other widgets so that the style sheet is easier to manage and maintain in the long run.

How to do it...

In the following example, we will format different types of widgets on the canvas and add some code to the style sheet to change its appearance:

  1. Remove the style sheet from PushButton by selecting it and clicking the small arrow button beside the styleSheet property. This button will revert the property to its default value, which in this case is the empty style sheet.
  2. Add a few more widgets to the UI by dragging them one by one from the Widget Box area to the form editor. I’ve added a line edit, combo box, horizontal slider, radio button, and a check box.
  3. For the sake of simplicity, delete menuBar, mainToolBar, and statusBar from your UI by selecting them in the Object Inspector area, right-clicking, and choosing Remove. Now, your UI should look similar to this:
Figure 1.2 – Dragging and dropping some widgets onto the form editor

Figure 1.2 – Dragging and dropping some widgets onto the form editor

  1. Select the main window from either the form editor or the Object Inspector area, then right-click and choose Change styleSheet... to open the Edit Style Sheet window. Insert the following into the style sheet:
    border: 2px solid gray;
    border-radius: 10px;
    padding: 0 8px;
    background: yellow;
  2. You will see a bizarre-looking UI with everything covered in yellow with a thick border. This is because the preceding style sheet does not have a selector, which means the style will apply to the children widgets of the main window down the hierarchy. To change that, let’s try something different:
    QPushButton {
         border: 2px solid gray;
         border-radius: 10px;
         padding: 0 8px;
         background: yellow;
    }
  3. This time, only PushButton will get the style described in the preceding code, and all the other widgets will return to the default styling. You can try to add a few more push buttons to your UI; they will all look the same:
Figure 1.3 – Changing the push buttons to yellow

Figure 1.3 – Changing the push buttons to yellow

  1. This happens because we specifically tell the selector to apply the style to all the widgets with the QPushButton class. We can also apply the style to just one of the push buttons by mentioning its name in the style sheet, as shown in the following code:
    QPushButton#pushButton_3 {
         border: 2px solid gray;
         border-radius: 10px;
         padding: 0 8px;
         background: yellow;
    }
  2. Once you understand this method, we can add the following code to the style sheet:
    QPushButton {
         color: red;
         border: 0px;
         padding: 0 8px;
         background: white;
    }
    QPushButton#pushButton_2 {
         border: 1px solid red;
         border-radius: 10px;
    }
  3. This code changes the style of all the push buttons, as well as some properties of the pushButton_2 button. We keep the style sheet of pushButton_3 as-is. Now, the buttons will look like this:
Figure 1.4 – Applying a different style to each button

Figure 1.4 – Applying a different style to each button

  1. The first set of style sheets will change all widgets of the QPushButton type to a white rectangular button with no border and red text. The second set of style sheets only changes the border of a specific QPushButton widget called pushButton_2. Notice that the background color and text color of pushButton_2 remain white and red, respectively, because we didn’t override them in the second set of style sheets, hence it will return to the style described in the first set of style sheets since it applies to all the QPushButton widgets. The text of the third button has also changed to red because we didn’t describe the Color property in the third set of style sheets.
  2. Create another set of style sheets that use the universal selector by using the following code:
    * {
         background: qradialgradient(cx: 0.3, cy: -0.4, fx: 0.3, fy: -0.4, radius: 1.35, stop: 0 #fff, stop: 1 #888);
         color: rgb(255, 255, 255);
         border: 1px solid #ffffff;
    }
  3. The universal selector will affect all the widgets, regardless of their type. Therefore, the preceding style sheet will apply a nice gradient color to all the widgets’ backgrounds and set their text to white with a one-pixel solid outline that is also white. Instead of writing the name of the color (that is, white), we can use the rgb function (rgb(255, 255, 255)) or hex code (#ffffff) to describe the color value.
  4. As before, the preceding style sheet will not affect the push buttons because we have already given them their own styles, which will override the general style described in the universal selector. Just remember that in Qt, the more specific style will ultimately be used when there is more than one style with an influence on a widget. This is how the UI will look now:
Figure 1.5 – Applying a gradient background to all the other widgets

Figure 1.5 – Applying a gradient background to all the other widgets

How it works…

If you are ever involved in web development using HTML and CSS, Qt’s style sheets work the same way as CSS. Style sheets provide the definitions to describe the presentation of the widgets – what the colors are for each element in the widget group, how thick the border should be, and so on. If you specify the name of the widget to the style sheet, it will change the style of the particular PushButton widget with the name you provide. None of the other widgets will be affected and will remain as the default style.

To change the name of a widget, select the widget from either the form editor or the Object Inspector area and change the objectName property in the property window. If you used the ID selector previously to change the style of the widget, changing its object name will break the style sheet and lose the style. To fix this problem, simply change the object name in the style sheet as well.

Creating a login screen using style sheets

Next, we will learn how to put all the knowledge we learned in the previous recipe together and create a fake graphical login screen for an imaginary operating system. Style sheets are not the only thing you need to master to design a good UI. You will also need to learn how to arrange the widgets neatly using the layout system in Qt Designer.

How to do it...

Let’s get started by following these steps:

  1. We need to design the layout of the graphical login screen before we start doing anything. Planning is very important to produce good software. The following is a sample layout design I made to show you how I imagine the login screen will look. Just a simple line drawing like this is sufficient, so long as it conveys the message clearly:
Figure 1.6 – A simple drawing depicting the login screen

Figure 1.6 – A simple drawing depicting the login screen

  1. Go back to Qt Designer again.
  2. We will be placing the widgets at the top panel first, then the logo and the login form beneath it.
  3. Select the main window and change its width and height from 400 and 300 to 800 and 600, respectively – we’ll need a bigger space in which to place all the widgets.
  4. Click and drag a label under the Display Widgets category from the Widget Box area to the form editor.
  5. Change the objectName property of the label to currentDateTime and change its text property to the current date and time for display purposes – for example, Wednesday, 25-10-2023 3:14 PM.
  6. Click and drag PushButton under the Buttons category to the form editor. Repeat this process once more because we have two buttons on the top panel. Rename the two buttons restartButton and shutdownButton.
  7. Select the main window and click the small icon button on the form toolbar that says Lay Out Vertically when you mouse over it. You will see that the widgets are automatically arranged on the main window, but that’s not exactly what we want yet.
  8. Click and drag a Horizontal Layout widget under the Layouts category to the main window.
  9. Click and drag the two push buttons and the text label into the horizontal layout. You will see the three widgets being arranged in a horizontal row, but vertically, they are located in the middle of the screen. The horizontal arrangement is almost correct, but the vertical position is off.
  10. Click and drag a Vertical Spacer widget from the Spacers category and place it beneath the Horizontal Layout widget we created in Step 9 (under the red rectangular outline). All the widgets will be pushed to the top by the spacer.
  11. Place a Horizontal Spacer widget between the text label and the two buttons to keep them apart. This will ensure the text label always sticks to the left and the buttons align to the right.
  12. Set both the Horizontal Policy and Vertical Policy properties of the two buttons to Fixed and set the minimumSize property to 55 x 55. Set the text property of the buttons to empty, as we will be using icons instead of text. We will learn how to place an icon in the button widgets in the Using resources in style sheets recipe.
  13. Your UI should look similar to this:
Figure 1.7 – Pushing apart the text and buttons using a horizontal spacer

Figure 1.7 – Pushing apart the text and buttons using a horizontal spacer

Next, we will be adding the logo. Follow these steps:

  1. Add a Horizontal Layout widget between the top panel and a Vertical Spacer widget to serve as a container for the logo.
  2. After adding the Horizontal Layout widget, you will find that the layout is way too thin in height (almost zero height) for you to add any widgets to it. This is because the layout is empty and it’s being pushed by the vertical spacer under it into zero height. To solve this problem, we can set its vertical margin (either layoutTopMargin or layoutBottomMargin) to be temporarily bigger until a widget is added to the layout.
  3. Add a Label value to the Horizontal Layout widget that you just created and rename it logo. We will learn more about how to insert an image into the label to use it as a logo in the Using resources in style sheets recipe. For now, just empty out the text property and set both its Horizontal Policy and Vertical Policy properties to Fixed. Set the minimumSize property to 150 x 150.
  4. Set the vertical margin of the layout back to zero if you haven’t already done so.
  5. The logo will now appear to be invisible, so we will just place a temporary style sheet to make it visible until we add an image to it in the Using resources in style sheets recipe. The style sheet is really simple:
    border: 1px solid;

    Your UI should look similar to this:

Figure 1.8 – Putting the placeholder logo in the middle

Figure 1.8 – Putting the placeholder logo in the middle

Now, let’s create the login form:

  1. Add a Horizontal Layout widget between the logo’s layout and the Vertical Spacer widget. Set the layoutTopMargin property to a large number (that is, 100) so that you can add a widget to it more easily.
  2. Add a Vertical Layout widget inside the Horizontal Layout widget you just created. This layout will be used as a container for the login form. Set its layoutTopMargin property to a number lower than that of the horizontal layout (that is, 20) so that we can place widgets in it.
  3. Right-click the Vertical Layout widget you just created and choose Morph into | QWidget. Here, Vertical Layout is converted into an empty widget. This step is essential because we will be adjusting the width and height of the container for the login form. A layout widget does not contain any properties for width and height, only margins, since a layout will expand toward the space surrounding it. This makes sense considering that it does not have any size properties. Once you have converted the layout into a QWidget object, it will automatically inherit all the properties from the widget class, which means we can now adjust its size to suit our needs.
  4. Rename the QWidget object, which we just converted from the layout, loginForm and change both its Horizontal Policy and Vertical Policy properties to Fixed. Set the minimumSize parameter to 350 x 200.
  5. Since we already placed the loginForm widget inside Horizontal Layout, we can set its layoutTopMargin property back to zero.
  6. Add the same style sheet that you did for the logo to the loginForm widget to make it visible temporarily. However, this time, we need to add an ID selector in front so that it will only apply the style to loginForm and not its children widgets:
    #loginForm { border: 1px solid; }

    Your UI should look something like this:

Figure 1.9 – Constructing the frame for the login form

Figure 1.9 – Constructing the frame for the login form

We are not done with the login form yet. Now that we have created the container for the login form, it’s time to put more widgets into the form:

  1. Place two horizontal layouts in the login form container. We need two layouts: one for the username field and another for the password field.
  2. Add Label and Line Edit properties to each of the layouts you just added. Change the text property of the upper label to Username: and the one beneath to Password:. Rename the two line edits to username and password, respectively.
  3. Add a push button beneath the password layout and change its text property to Login. Rename it loginButton.
  4. You can add a Vertical Spacer widget between the password layout and the Login button to distance them slightly. After the Vertical Spacer widget has been placed, change its sizeType property to Fixed and change its Height property to 5.
  5. Select the loginForm container and set all its margins to 35. This is to make the login form look better by adding some space to all its sides.
  6. Set the Height property of the Username, Password, and loginButton widgets to 25 so that they don’t look so cramped.

    Your UI should look something like this:

Figure 1.10 – Adding widgets to the login form

Figure 1.10 – Adding widgets to the login form

Note

Alternatively, you can use a grid layout for the Username and Password fields to keep their sizes uniform.

We’re not done yet! As you can see, the login form and the logo are both sticking to the top of the main window due to the Vertical Spacer widget beneath them. The logo and the login form should be placed at the center of the main window instead of the top. To fix this problem, follow these steps:

  1. Add another Vertical Spacer widget between the top panel and the logo’s layout. This will counter the spacer at the bottom to balance out the alignment.
  2. If you think that the logo is sticking too close to the login form, you can add a Vertical Spacer widget between the logo’s layout and the login form’s layout. Set its sizeType property to Fixed and its Height property to 10.
  3. Right-click the top panel’s layout and choose Morph into | QWidget. Rename it topPanel. The layout must be converted into QWidget because we cannot apply style sheets to a layout. This is because a layout doesn’t have any properties other than margins.
  4. There is a little bit of a margin around the edges of the main window – we don’t want that. To remove the margins, select the centralWidget object from the Object Inspector window, which is right under the MainWindow panel, and set all the margin values to zero.
  5. Run the project by clicking the Run button (with the green arrow icon) to see what your program looks like. If everything goes well, you should see something like this:
Figure 1.11 – We’re done with the layout – for now

Figure 1.11 – We’re done with the layout – for now

  1. Now, let’s decorate the UI using style sheets! Since all the important widgets have been given object names, it’s easier for us to apply the style sheets to them from the main window since we will only write the style sheets to the main window and let them inherit down the hierarchy tree.
  2. Right-click on MainWindow from the Object Inspector area and choose Change styleSheet....
  3. Add the following code to the style sheet:
    #centralWidget { background: rgba(32, 80, 96, 100); }
  4. The background of the main window will change color. We will learn how to use an image for the background in the Using resources in style sheets recipe. So, the color is just temporary.
  5. In Qt, if you want to apply styles to the main window itself, you must apply them to its centralWidget widget instead of the main window since the window is just a container.
  6. Add a nice gradient color to the top panel:
    #topPanel {
         background-color: qlineargradient(spread:reflect, x1:0.5, y1:0, x2:0, y2:0, stop:0 rgba(91, 204, 233, 100), stop:1 rgba(32, 80, 96, 100));
    }
  7. Apply the black color to the login form and make it look semi-transparent. We will also make the corners of the login form container slightly rounded by setting the border-radius property:
    #loginForm {
         background: rgba(0, 0, 0, 80);
         border-radius: 8px;
    }
  8. Apply styles to the general types of widgets:
    QLabel { color: white; }
    QLineEdit { border-radius: 3px; }
  9. The preceding style sheets will change all the labels’ texts to a white color; this includes the text on the widgets as well because, internally, Qt uses the same type of label on the widgets that have text on them. Also, we made the corners of the line edit widgets slightly rounded.
  10. Apply style sheets to all the push buttons on our UI:
    QPushButton {
         color: white;
         background-color: #27a9e3;
         border-width: 0px;
         border-radius: 3px;
    }
  11. The preceding style sheet changes the text of all the buttons to a white color, then sets its background color to blue, and makes its corners slightly rounded.
  12. To push things even further, we will make it so that the color of the push buttons changes when we mouse over it by using the hover keyword:
    QPushButton:hover { background-color: #66c011; }
  13. The preceding style sheet will change the background color of the push buttons to green when we mouse over them. We will talk more about this in the Customizing properties and sub-controls recipe.
  14. You can further adjust the size and margins of the widgets to make them look even better. Remember to remove the border line of the login form by removing the style sheet that we applied directly to it in step 6.
  15. Your login screen should look something like this:
Figure 1.12 – Applying colors and styles to the widgets

Figure 1.12 – Applying colors and styles to the widgets

How it works…

This example focused more on the layout system of Qt. Qt’s layout system allows our application GUI to automatically arrange itself within the given space by arranging the children objects of each widget. The spacer items that we used in this recipe help push the widgets contained in a layout outward to create spacing along the width of the spacer item.

To locate a widget in the middle of the layout, we must put two spacer items into the layout: one on the left-hand side of the widget and one on the right-hand side of the widget. The widget will then be pushed to the middle of the layout by the two spacers.

Using resources in style sheets

Qt provides us with a platform-independent resource system that allows us to store any type of file in our program’s executable for later use. There is no limit to the types of files we can store in our executable – images, audio, video, HTML, XML, text files, binary files, and so on are all permitted.

The resource system is really useful for embedding resource files (such as icons and translation files) into the executable so that it can be accessed by the application at any time. To achieve this, we must tell Qt which files we want to add to its resource system in the .qrc file; Qt will handle the rest during the build process.

How to do it…

To add a new .qrc file to our project, go to File | New File. Then, select Qt under the Files and Classes category and select Qt Resources File. After that, give it a name (that is, resources) and click the Next button, followed by the Finish button. The .qrc file will now be created and automatically opened by Qt Creator. You don’t have to edit the .qrc file directly in XML format as Qt Creator provides you with the user interface to manage your resources.

To add images and icons to your project, you need to make sure that the images and icons are being placed in your project’s directory. While the .qrc file is opened in Qt Creator, click the Add button, followed by the Add Prefix button. The prefix is used to categorize your resources so that they can be better managed when you have a ton of resources in your project:

  1. Rename the prefix you just created to /icons.
  2. Create another prefix by clicking Add, followed by Add Prefix.
  3. Rename the new prefix /images.
  4. Select the /icon prefix and click Add, followed by Add Files.
  5. A file selection window will appear; use that to select all the icon files. You can select multiple files at a time by holding the Ctrl key on your keyboard while clicking on the files to select them. Click Open once you’re done.
  6. Select the /images prefix and click the Add button, followed by the Add Files button. The file-selection window will pop up again; this time, we will select the background image.
  7. Repeat the preceding steps, but this time, we will add the logo image to the /images prefix. Don’t forget to save once you’re done by pressing Ctrl + S. Your .qrc file should now look like this:
Figure 1.13 – Showing the structure of the resource file

Figure 1.13 – Showing the structure of the resource file

  1. Go back to the mainwindow.ui file; let’s make use of the resources we have just added to our project. Select the restart button located on the top panel. Scroll down the Property Editor area until you see the icon property. Click the little button with a drop-down arrow icon and click Choose Resources from its menu.
  2. The Select Resource window will pop up. Click on the icons prefix on the left panel and select the restart icon on the right panel. Press OK.
  3. A tiny icon will appear on the button. This icon looks very tiny because the default icon size is set to 16 x 16. Change the iconSize property to 50 x 50; you will see that the icon appears bigger. Repeat the preceding steps for the shutdown button, except this time, choose the shutdown icon instead.
  4. The two buttons should now look like this:
Figure 1.14 – Applying icons to the push buttons

Figure 1.14 – Applying icons to the push buttons

  1. Let’s use the image we added to the resource file as our logo. Select the logo widget and remove the style sheet that we added earlier to render its outline.
  2. Scroll down the Property Editor area until you see the pixmap property.
  3. Click the little drop-down button behind the pixmap property and select Choose Resources from the menu. Select the logo image and click OK. The logo size no longer follows the dimension you set previously; it follows the actual dimension of the image instead. We cannot change its dimension because this is simply how the pixmap property works.
  4. If you want more control over the logo’s dimension, you can remove the image from the pixmap property and use a style sheet instead. You can use the following code to apply an image to the icon container:
    border-image: url(:/images/logo.png);
  5. To obtain the path of the image, right-click the image’s name in the file list window and choose Copy path. The path will be saved to your operating system’s clipboard; now, you can just paste it into the preceding style sheet. Using this method will ensure that the image fits the dimensions of the widget that you applied the style to. Your logo should now appear like what’s shown in the following screenshot:
Figure 1.15 – The logo is now appearing at the top of the login form

Figure 1.15 – The logo is now appearing at the top of the login form

  1. Apply the wallpaper image to the background using a style sheet. Since the background dimension will change according to the window size, we cannot use pixmap here. Instead, we will use the border-image property in a style sheet. Right-click the main window and select Change styleSheet... to open the Edit Style Sheet window. We will add a new line under the style sheet of the centralWidget widget:
    #centralWidget {
         background: rgba(32, 80, 96, 100);
         border-image: url(:/images/login_bg.png);
    }
  2. It’s really that simple and easy! Your login screen should now look like this:
Figure 1.16 – The final result looks neat

Figure 1.16 – The final result looks neat

How it works…

The resource system in Qt stores binary files, such as images and translation files, in the executable when it gets compiled. It reads the resource collection files (.qrc) in your project to locate the files that need to be stored in the executable and include them in the build process. A .qrc file looks something like this:

<!DOCTYPE RCC>
<RCC version="1.0">
     <qresource>
           <file>images/copy.png</file>
           <file>images/cut.png</file>
           <file>images/new.png</file>
           <file>images/open.png</file>
           <file>images/paste.png</file>
           <file>images/save.png</file>
     </qresource>
</RCC>

It uses XML format to store the paths of the resource files, which are relative to the directory that contains them. The listed resource files must be located in the same directory as the .qrc file, or one of its subdirectories.

Customizing properties and sub-controls

Qt’s style sheet system enables us to create stunning and professional-looking UIs with ease. In this example, we will learn how to set custom properties for our widgets and use them to switch between different styles.

How to do it…

Follow these steps to customize widget properties and sub-controls:

  1. Let’s create a new Qt project. I have prepared the UI for this purpose. The UI contains three buttons on the left-hand side and a tab widget with three pages located on the right-hand side, as shown in the following screenshot:
Figure 1.17 – Basic user interface with three tabs and buttons

Figure 1.17 – Basic user interface with three tabs and buttons

  1. The three buttons are blue because I’ve added the following style sheet to the main window (not to the individual button):
    QPushButton {
         color: white;
         background-color: #27a9e3;
         border-width: 0px;
         border-radius: 3px;
    }
  2. I will explain what pseudo-states are in Qt by adding the following style sheet to the main window. You might be familiar with this:
    QPushButton:hover {
         color: white;
         background-color: #66c011;
         border-width: 0px;
         border-radius: 3px;
    }
  3. We used the preceding style sheet in the Creating a login screen using style sheets recipe, to make the buttons change color when there is a mouse-over event. This is made possible by Qt Style Sheet’s pseudo-state, which in this case is the word hover separated from the QPushButton class by a colon. Every widget has a set of generic pseudo-states, such as active, disabled, and enabled, and also a set of pseudo-states that apply to their widget type. For example, states such as open and flat are available for QPushButton, but not for QLineEdit. Let’s add the pressed pseudo-state to change the buttons’ color to yellow when the user clicks on it:
    QPushButton:pressed {
         color: white;
         background-color: yellow;
         border-width: 0px;
         border-radius: 3px;
    }
  4. Pseudo-states allow the users to load a different set of style sheets based on the condition that applies to them. Qt pushes this concept further by implementing dynamic properties in Qt Style Sheets. This allows us to change the style sheet of a widget when a custom condition has been met. We can make use of this feature to change the style sheet of our buttons based on a custom condition that we can set using custom properties in Qt. First, we will add this style sheet to our main window:
    QPushButton[pagematches=true] {
         color: white;
         background-color: red;
         border-width: 0px;
         border-radius: 3px;
    }
  5. This changes the push button’s background color to red if the pagematches property returns true. This property does not exist in the QPushButton class. However, we can add it to our buttons using QObject::setProperty():
    • In your mainwindow.cpp source code, add the following code right after ui->setupUi(this):
      ui->button1->setProperty("pagematches", true);

    The preceding code will add a custom property called pagematches to the first button and set its value as true. This will make the first button turn red by default.

    • After that, right-click on Tab Widget and choose Go to slot…. A window will pop up; select the currentChanged(int) option from the list and click OK. Qt will generate a slot function for you, which looks something like this:
      private slots:
      void on_tabWidget_currentChanged(int index);
    • The slot function will be called whenever we change the page of Tab Widget. We can then decide what we want it to do by adding our code to the slot function. To do that, open mainwindow.cpp; you will see the function’s declaration there. Let’s add some code to the function:
      void MainWindow::on_tabWidget_currentChanged(int
      index) {
           // Set all buttons to false
           ui->button1->setProperty("pagematches", false);
           ui->button2->setProperty("pagematches", false);
           ui->button3->setProperty("pagematches", false);
           // Set one of the buttons to true
           if (0 == index)
                 ui->button1->setProperty("pagematches", true);
           else if (index == 1)
                 ui->button2->setProperty("pagematches", true);
           else
                 ui->button3->setProperty("pagematches", true);
           // Update buttons style
           ui->button1->style()->polish(ui->button1);
           ui->button2->style()->polish(ui->button2);
           ui->button3->style()->polish(ui->button3);
      }
  6. The preceding code sets the pagematches properties of all three buttons to false when Tab Widget switches its current page. Be sure to reset everything before we decide which button should change to red.
  7. Check the index variable supplied by the event signal; this will tell you the index number of the current page. Set the pagematches property of one of the buttons to true, based on the index number.
  8. Refresh the style of all three buttons by calling polish(). You may also want to add the following header to mainwindow.h:
    #include <QStyle>
  9. Build and run the project. You should now see the three buttons changing to red whenever you switch Tab Widget to a different page. Also, the buttons will change to green when there is a mouse-over, as well as change to yellow when you click on them:
Figure 1.18 – The final result looks like this

Figure 1.18 – The final result looks like this

How it works…

Qt provides users the freedom to add custom properties to any type of widget. Custom properties are very useful if you want to change a particular widget when a special condition is met, whereas Qt doesn’t provide such a context by default. This allows the user to extend the usability of Qt and makes it a flexible tool for customized solutions.

For example, if we have a row of buttons on our main window and we need one of them to change its color depending on which page Tab Widget is currently showing, there is no way the buttons would know when they should change their color because Qt itself has no built-in context for this type of situation. To solve this issue, Qt gives us a method to add our own properties to the widgets, which uses a generic function called QObject::setProperty(). To read the custom property, we can use another function called QObject::property().

Next, we will talk about sub-controls in Qt Style Sheets. Often, a widget is not just a single object, but a combination of more than one object or control, used to form a more complex widget. These objects are called sub-controls.

For example, a spin box widget contains an input field, a down button, an up button, an up arrow, and a down arrow, which is quite complicated compared to some other widgets. In this case, Qt grants us more flexibility by allowing us to change every sub-control using a style sheet if we want to. We can do so by specifying the name of the sub-control behind the widget’s class name, separated by a double colon. For instance, if I want to change the image of the down button to a spin box, I can write my style sheet as follows:

QSpinBox::down-button {
     image: url(:/images/spindown.png);
     subcontrol-origin: padding;
     subcontrol-position: right bottom;
}

This will only apply the image to the down button of my spin box, and not to any other parts of the widget. By combining custom properties, pseudo-states, and sub-controls, Qt provides us with a very flexible method to customize our user interface.

Note

Visit the following link to learn more about pseudo-states and subcontrols in Qt: http://doc.qt.io/qt-6/stylesheet-reference.html.

Styling in Qt Modeling Language (QML)

Qt Meta Language or Qt Modeling Language (QML) is a JavaScript-inspired user interface markup language that’s used by Qt to design user interfaces. Qt provides you with Qt Quick Components (widgets powered by the QML technology) to easily design touch-friendly UI without C++ programming. We will learn more about how to use QML and Qt Quick Components to design our program’s UI by following the steps provided in this recipe.

How to do it…

Follow these steps to learn about styling in QML:

  1. Since Qt 6, The Qt Company has released a separate program called Qt Design Studio for developing Qt Quick applications. It’s intended to separate the different tasks of designers and programmers. So, if you’re a GUI designer, you should use Qt Design Studio, while sticking to Qt Creator if you’re a programmer. Once you have installed and opened Qt Design Studio, create a new project by pressing on the big Create Project… button or by going to File | New Project… from the top menu:
Figure 1.19 – Creating a new QML project in Qt Design Studio

Figure 1.19 – Creating a new QML project in Qt Design Studio

  1. Once the New Project window appears, key in the default width and height of your project window and insert a name for your project. Then, select the directory where you want your project to be created, select a default GUI style, pick a target Qt version, and click the Create button. Your Qt Quick project will now be created by Qt Design Studio.
  2. There are some differences between a QML project and a C++ Qt project. You will see an App.qml file inside the project resource. This .qml file is the UI description file that’s written using the QML markup language. If you double-click the main.qml file, Qt Creator will open the script editor and you will see something like this:
    import QtQuick 6.2
    import QtQuick.Window 6.2
    import MyProject
    Window {
        width: mainScreen.width
        height: mainScreen.height
        visible: true
        title: "MyProject"
        Screen01 {
            id: mainScreen
        }
    }
  3. This file tells Qt to create a window that loads the Screen01 user interface and a window title with your project name. The Screen01 interface comes from another file called Screen01.ui.qml.
  4. If you open the main.cpp file located in the scr folder in your project, you will see the following line of code:
    QQmlApplicationEngine engine;
    const QUrl url(u"qrc:Main/main.qml"_qs);
  5. The preceding code tells Qt’s QML engine to load the main.qml file when the program starts. If you want to load the other .qml file, you know where to look for the code. The src folder is hidden from your Qt Design Studio project; you can look for it inside your project directory.
  6. If you build the project now, all you’ll get is a huge window with simple text and a push button that says Press me. The window’s background color and the text will change when you press the push button:
Figure 1.20 – Your first Qt Quick program

Figure 1.20 – Your first Qt Quick program

  1. To add UI elements, we’ll create a Qt Quick UI File by going to File | New File… and selecting Qt Quick UI File under the Files and Classes | Qt Quick Files category:
Figure 1.21 - Creating a new Qt Quick UI file

Figure 1.21 - Creating a new Qt Quick UI file

  1. Set Component name to Main, followed by clicking the Finish button:
Figure 1.22 – Giving your Qt Quick component a meaningful name

Figure 1.22 – Giving your Qt Quick component a meaningful name

  1. A new file called Main.ui.qml has been added to your project resources. Try to open the Main.ui.qml file by double-clicking on it, if it hasn’t been automatically opened by Qt Design Studio upon creation. You will see a completely different UI editor compared to what we had for the C++ project in the previous recipes.
  2. Let’s open App.qml and replace Screen01 with Main, like so:
    Main {
         id: mainScreen
    }
  3. When App.qml is loaded by the QML engine, it will also import Main.ui.qml into the UI since Main is now being called in the App.qml file. Qt will check whether Main is a valid UI by searching for its .qml file based on the naming convention. This concept is similar to the C++ project we completed in all our previous recipes; the App.qml file acts like the main.cpp file and Main.ui.qml acts like the MainWindow class. You can also create other UI templates and use them in App.qml. Hopefully, this comparison will make it easier to understand how QML works.
  4. Open Main.ui.qml. You should see only one item listed in the Navigator window: Item. This is the base layout of the window, which shouldn’t be deleted. It is similar to centralWidget, which we used in the previous recipe.
  5. The canvas is empty at the moment, so let’s drag a Mouse Area item and Text items to the canvas from the QML Types panel on the left. Resize Mouse Area so that it fills the entire canvas. Also, make sure that both Mouse Area and the Text items are being placed under the Item item in the Navigator panel, as shown in the following screenshot:
Figure 1.23 – Dragging and dropping a mouse area and text items onto the canvas

Figure 1.23 – Dragging and dropping a mouse area and text items onto the canvas

  1. The Mouse Area item is an invincible item that gets triggered when the mouse is clicking on it, or when a finger is touching it (for mobile platforms). The Mouse Area item is also used in a button component, which we will be using in a while. The Text item is self-explanatory: it is a label that displays a block of text in the application.
  2. On the Navigator window, we can hide or show an item by clicking on the icon that resembles an eye beside the item. When an item is hidden, it will not appear on the canvas or the compiled application. Just like the widgets in a C++ Qt project, Qt Quick Components are arranged in a hierarchy based on the parent-child relationship. All the child items will be placed under the parent item with an indented position. In our case, we can see that the Mouse Area and Text elements are positioned slightly to the right compared to the Item item because they are both children of the Item element. We can rearrange the parent-child relationship, as well as their position in the hierarchy, by using a click-and-drag method from the Navigator window. You can try clicking on the Text item and dragging it on top of the mouse area. You will then see that the Text item has changed its position and is now located beneath the mouse area with a wider indentation:
Figure 1.24 – Rearranging the parent-child relationship between items

Figure 1.24 – Rearranging the parent-child relationship between items

  1. We can rearrange them by using the arrow buttons located at the top of the Navigator window, as shown in the preceding screenshot. Anything that happens to the parent item will also affect all its children, such as moving the parent item, and hiding and showing the parent item.

Note

You can pan around the canvas view by holding the middle mouse button (or mouse scroll) while moving your mouse around. You can also zoom in and out by scrolling your mouse while holding the Ctrl key on your keyboard. By default, scrolling your mouse will move the canvas view up and down. However, if your mouse cursor is on top of the horizontal scroll bar of the canvas, scrolling the mouse will move the view to the left and right.

  1. Delete both the Mouse Area item and Text items as we will be learning how to create a user interface from scratch using QML and Qt Quick.
  2. Set the Item element’s size to 800 x 600 as we’re going to need a bigger space for the widgets.
  3. Copy the images we used in the previous C++ project, in the Using resources in style sheets recipe, over to the QML project’s folder since we are going to recreate the same login screen with QML.
  4. Add the images to the resource file so that we can use them for our UI.
  5. Open Qt Design Studio and switch to the Resources window. Click and drag the background image directly to the canvas. Switch over to the Layout tab on the Properties pane and click the fill anchor button, indicated here by a red circle. This will make the background image always stick to the window size:
Figure 1.25 – Selecting the fill anchor button to make the item follow the size of its parent object

Figure 1.25 – Selecting the fill anchor button to make the item follow the size of its parent object

  1. Click and drag a Rectangle component from the Library window to the canvas. We will use this as the top panel for our program.
  2. For the top panel, enable the top anchor, left anchor, and right anchor so that the panel sticks to the top of the window and follows its width. Make sure all the margins are set to zero.
  3. Go to the Color property of the top panel and select Gradient. Set the first color to #805bcce9 and the second color to #80000000. This will create a half-transparent panel with a blue gradient.
  4. Add a Text widget to the canvas and make it a child of the top panel. Set its text property to the current date and time (for example, Wednesday, 25-10-2023 3:14 PM) for display purposes. Then, set the text color to white.
  5. Switch over to the Layout tab and enable the top anchor and left anchor so that the text widget will always stick to the top-left corner of the screen.
  6. Add a Mouse Area item to the screen and set its size to 50 x 50. Then, make it a child of the top panel by dragging it on top of the top panel in the Navigator window.
  7. Set the color of the mouse area to blue (#27a9e3) and set its radius to 2 to make its corners slightly rounded. Enable the top anchor and right anchor to make it stick to the top-right corner of the window. Set the top anchor’s margin to 8 and the right anchor’s margin to 10 to create some space.
  8. Open the Resources window and drag the shutdown icon to the canvas. Make it a child of the Mouse Area item we created a moment ago. Then, enable the fill anchor to make it fit the size of the mouse area.
  9. Phew – that’s a lot of steps! Now, your items should be arranged as follows in the Navigator window:
Figure 1.26 – Be cautious about the parent-child relationship between items

Figure 1.26 – Be cautious about the parent-child relationship between items

  1. The parent-child relationship and the layout anchors are both very important to keep the widgets in the correct positions when the main window changes its size. Your top panel should look something like this:
Figure 1.27 – Completing the top banner design

Figure 1.27 – Completing the top banner design

  1. Let’s work on the login form. Add a new Rectangle to the canvas by dragging it from the Library window. Resize the rectangle to 360 x 200 and set its radius to 15.
  2. Set its color to #80000000; this will change it to black with 50% transparency.
  3. Enable the vertical center anchor and the horizontal center anchor to make the rectangle always align with the center of the window. Then, set the margin of the vertical center anchor to 100 so that it moves slightly lower to the bottom. This will ensure we have the space to place the logo. The following screenshot illustrates the settings for Anchors:
Figure 1.28 – Setting the alignment and margin

Figure 1.28 – Setting the alignment and margin

  1. Add the text objects to the canvas. Make them children of the login form (the Rectangle widget) and set their text properties to Username: and Password:. Change their text color to white and position them accordingly. We don’t need to set a margin this time because they will follow the rectangle’s position.
  2. Add two text input objects to the canvas and place them next to the text widgets we just created. Make sure the text input is also a child of the login form. Since the text input doesn’t contain any background color property, we need to add two rectangles to the canvas to use as their background.
  3. Add two rectangles to the canvas and make each of them a child of one of the text inputs we just created. Set the radius property to 5 to give them some rounded corners. After that, enable fill anchors on both of the rectangles so that they will follow the size of the text input widgets.
  4. Now, let’s create the login button beneath the password field. Add a mouse area to the canvas and make it a child of the login form. Resize it to your preferred dimension and move it into place.
  5. Since the mouse area does not contain any background color property, we need to add a Rectangle widget and make it a child of the mouse area. Set the color of the rectangle to blue (#27a9e3) and enable the fill anchor so that it fits nicely with the mouse area.
  6. Add a text object to the canvas and make it a child of the login button. Change its text color to white and set its text property to Login. Finally, enable the horizontal center anchor and the vertical center anchor so that they align with the center of the button.
  7. You will now get a login form that looks pretty similar to the one we made in the C++ project:
Figure 1.29 – Final design of the login form

Figure 1.29 – Final design of the login form

  1. Now, it’s time to add the logo, which is very simple. Open the Resources window and drag the logo image to the canvas.
  2. Make it a child of the login form and set its size to 512 x 200.
  3. Position it on top of the login form. With that, you’re done.
  4. This is what the entire UI looks like when compiled. We have successfully recreated the login screen from the C++ project, but this time, we did it with QML and Qt Quick:
Figure 1.30 – The final result

Figure 1.30 – The final result

How it works…

The Qt Quick editor uses a very different approach for placing widgets in the application compared to the form editor. The user can decide which method is best suited to their purposes. The following screenshot shows what the Qt Quick Designer looks like:

Figure 1.31 – Overview of Qt Design Studio’s user interface

Figure 1.31 – Overview of Qt Design Studio’s user interface

Let’s look at the various elements of the editor’s UI:

  1. Navigator: The Navigator window displays the items in the current QML file as a tree structure. It’s similar to the object operator window in the other Qt Designer we used in the Using style sheets with Qt Designer recipe.
  2. Library: The Library window displays all the Qt Quick Components or Qt Quick Controls available in QML. You can click and drag it to the canvas window to add to your UI. You can also create your own custom QML components and display them here.
  3. Assets: The Assets window displays all the resources in a list that can then be used in your UI design.
  4. Add Modules: The Add Modules button allows you to import different QML modules into your current QML file, such as a Bluetooth module, a WebKit module, or a positioning module, to add additional functionality to your QML project.
  5. Properties: Similar to the Property Editor area we used in the previous recipe, the Properties pane in QML Designer displays the properties of the selected item. You can also change the properties of the items in the code editor.
  6. Canvas: The canvas is the working area where you create QML components and design applications.
  7. Workspace selector: The workspace selector area displays the different layouts available in the Qt Design Studio editor, allowing the user to select the workspace that suits their needs.
  8. Style selector: This selector is where you can select a different style to preview how your application will look when running on a specific platform. This is very useful when developing cross-platform applications.

Exposing the QML object pointer to C++

Sometimes, we want to modify the properties of a QML object through C++ scripting, such as changing the text of a label, hiding/showing the widget, or changing its size. Qt’s QML engine allows you to register your QML objects to C++ types, which automatically exposes all its properties.

How to do it…

We want to create a label in QML and change its text occasionally. To expose the label object to C++, we can do the following:

  1. Create a C++ class called MyLabel that extends from the QObject class in mylabel.h:
    class MyLabel : public QObject {
    Q_OBJECT
    public:
         // Object pointer
         QObject* myObject;
         explicit MyLabel(QObject *parent = 0);
         // Must call Q_INVOKABLE so that this function can be used in QML
         Q_INVOKABLE void SetMyObject(QObject* obj);
    }
  2. In the mylabel.cpp source file, define a function called SetMyObject() to save the object pointer. This function will later be called in QML in mylabel.cpp:
    void MyLabel::SetMyObject(QObject* obj) {
         // Set the object pointer
         myObject = obj;
    }
  3. In main.cpp, include the MyLabel header and register it to the QML engine using the qmlRegisterType() function:
    include "mylabel.h"
    int main(int argc, char *argv[]) {
         // Register your class to QML
         qmlRegisterType<MyLabel>("MyLabelLib", 1, 0, "MyLabel");
    }
  4. Notice that there are four parameters you need to declare in qmlRegisterType(). Besides declaring your class name (MyLabel), you also need to declare your library name (MyLabelLib) and its version (1.0). This will be used to import your class into QML.
  5. Map the QML engine to our label object in QML and import the class library we defined earlier in Step 3 by calling import MyLabelLib 1.0 in our QML file. Notice that the library name and its version number have to match the one you declared in main.cpp; otherwise, it will throw an error. After declaring MyLabel in QML and setting its ID as mylabels, call mylabel.SetMyObject(myLabel) to expose its pointer to C/C++ right after the label is initialized:
    import MyLabelLib 1.0
    ApplicationWindow {
         id: mainWindow
         width: 480
         height: 640
         MyLabel {
               id: mylabel
         }
         Label {
               id: helloWorldLabel
               text: qsTr("Hello World!")
               Component.onCompleted: {
                   mylabel.SetMyObject(hellowWorldLabel);
               }
         }
    }
  6. Wait until the label is fully initiated before exposing its pointer to C/C++; otherwise, you may cause the program to crash. To make sure it’s fully initiated, call the SetMyObject() function within Component.onCompleted and not in any other functions or event callbacks. Now that the QML label has been exposed to C/C++, we can change any of its properties by calling the setProperty() function. For instance, we can set its visibility to true and change its text to Bye bye world!:
    // Qvariant automatically detects your data type
    myObject->setProperty("visible", Qvariant(true));
    myObject->setProperty("text", Qvariant("Bye bye world!"));
  7. Besides changing the properties, we can also call its functions by calling the following code:
    QVariant returnedValue;
    QVariant message = "Hello world!";
    QMetaObject::invokeMethod(myObject, "myQMLFunction",
    Q_RETURN_ARG(QVariant, returnedValue), Q_ARG(QVariant,
    message));
    qDebug() << "QML function returned:" <<
    returnedValue.toString();
  8. Or, simply, we can call the invokedMethod() function with only two parameters if we do not expect any values to be returned from it:
    QMetaObject::invokeMethod(myObject, "myQMLFunction");

How it works…

QML is designed in such a way that it can be expanded through C++ code. The classes in the Qt QML module permit QML objects to be used and operate from C++, and the capability of the QML engine united with Qt’s meta-object system allows C++ functionality to be called directly from QML. To add some C++ data or usage to QML, it should come forward from a QObject-derived class. QML object types could be instituted from C++ and supervised to access their properties, appeal their methods, and get their signal alerts. This is possible because all QML object types are executed using QObject-derived classes, allowing the QML engine to forcibly load and inspect objects through the Qt meta-object system.

There’s more…

Qt 6 comes with two different types of GUI kits – Qt Widgets and Qt Quick. Both have their strengths and advantages over the other, giving programmers the ability and freedom to design their application’s interface without having to worry about feature constraints and performance issues.

Qt 6 allows you to pick the best method and programming language that suits your working style and requirements for your project. By going through this chapter, you will be able to create a good-looking and functional cross-platform application using Qt 6 in no time.

Left arrow icon Right arrow icon
Download code icon Download Code

Key benefits

  • Learn to use Qt 6 to design and customize the look and feel of your applications
  • Improve the visual quality of an application by using graphics rendering and animation
  • Understand the balance of presentation and web content that will make an application appealing yet functional
  • Purchase of the print or Kindle book includes a free PDF eBook

Description

With the growing need to develop GUIs for multiple targets and multiple screens, improving the visual quality of your application has become pivotal in helping it stand out from your competitors. With its cross-platform ability and the latest UI paradigms, Qt makes it possible to build intuitive, interactive, and user-friendly UIs for your applications. The third edition of Qt 6 C++ GUI Programming Cookbook teaches you how to develop functional and appealing UIs using the latest version of Qt 6 and C++. This book will help you learn a variety of topics such as GUI customization and animation, graphics rendering, and implementing Google Maps. You’ll also be taken through advanced concepts such as asynchronous programming, event handling using signals and slots, network programming, and other aspects to optimize your application. By the end of this Qt book, you’ll have the confidence you need to design and customize GUI applications that meet your clients' expectations and have an understanding of best-practice solutions to common problems during the app development process.

What you will learn

Animate GUI elements using Qt 6's built-in animation system Draw vector shapes and bitmap images using Qt 6's powerful rendering system Implement an industry-standard OpenGL library in your project Build a mobile app that supports touch events and export it into devices Parse and extract data from an XML file and present it on your GUI Interact with web content by calling JavaScript functions from C++ Access MySQL and SQLite databases to retrieve data and display it on your GUI

What do you get with eBook?

Product feature icon Instant access to your Digital eBook purchase
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Buy Now

Product Details


Publication date : Apr 12, 2024
Length 428 pages
Edition : 3rd Edition
Language : English
ISBN-13 : 9781805122630
Category :

Table of Contents

17 Chapters
Preface Chevron down icon Chevron up icon
Chapter 1: Look-and-Feel Customization with Qt Designer Chevron down icon Chevron up icon
Chapter 2: Event Handling – Signals and Slots Chevron down icon Chevron up icon
Chapter 3: States and Animations with Qt and QML Chevron down icon Chevron up icon
Chapter 4: QPainter and 2D Graphics Chevron down icon Chevron up icon
Chapter 5: OpenGL Implementation Chevron down icon Chevron up icon
Chapter 6: Transitioning from Qt 5 to Qt 6 Chevron down icon Chevron up icon
Chapter 7: Using Network and Managing Large Documents Chevron down icon Chevron up icon
Chapter 8: Threading Basics –Asynchronous Programming Chevron down icon Chevron up icon
Chapter 9: Building a Touch Screen Application with Qt 6 Chevron down icon Chevron up icon
Chapter 10: JSON Parsing Made Easy Chevron down icon Chevron up icon
Chapter 11: Conversion Library Chevron down icon Chevron up icon
Chapter 12: Accessing Databases with SQL Driver and Qt Chevron down icon Chevron up icon
Chapter 13: Developing Web Applications Using Qt WebEngine Chevron down icon Chevron up icon
Chapter 14: Performance Optimization Chevron down icon Chevron up icon
Index Chevron down icon Chevron up icon
Other Books You May Enjoy Chevron down icon Chevron up icon

Customer reviews

Filter icon Filter
Top Reviews
Rating distribution
Empty star icon Empty star icon Empty star icon Empty star icon Empty star icon 0
(0 Ratings)
5 star 0%
4 star 0%
3 star 0%
2 star 0%
1 star 0%

Filter reviews by


No reviews found
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

How do I buy and download an eBook? Chevron down icon Chevron up icon

Where there is an eBook version of a title available, you can buy it from the book details for that title. Add either the standalone eBook or the eBook and print book bundle to your shopping cart. Your eBook will show in your cart as a product on its own. After completing checkout and payment in the normal way, you will receive your receipt on the screen containing a link to a personalised PDF download file. This link will remain active for 30 days. You can download backup copies of the file by logging in to your account at any time.

If you already have Adobe reader installed, then clicking on the link will download and open the PDF file directly. If you don't, then save the PDF file on your machine and download the Reader to view it.

Please Note: Packt eBooks are non-returnable and non-refundable.

Packt eBook and Licensing When you buy an eBook from Packt Publishing, completing your purchase means you accept the terms of our licence agreement. Please read the full text of the agreement. In it we have tried to balance the need for the ebook to be usable for you the reader with our needs to protect the rights of us as Publishers and of our authors. In summary, the agreement says:

  • You may make copies of your eBook for your own use onto any machine
  • You may not pass copies of the eBook on to anyone else
How can I make a purchase on your website? Chevron down icon Chevron up icon

If you want to purchase a video course, eBook or Bundle (Print+eBook) please follow below steps:

  1. Register on our website using your email address and the password.
  2. Search for the title by name or ISBN using the search option.
  3. Select the title you want to purchase.
  4. Choose the format you wish to purchase the title in; if you order the Print Book, you get a free eBook copy of the same title. 
  5. Proceed with the checkout process (payment to be made using Credit Card, Debit Cart, or PayPal)
Where can I access support around an eBook? Chevron down icon Chevron up icon
  • If you experience a problem with using or installing Adobe Reader, the contact Adobe directly.
  • To view the errata for the book, see www.packtpub.com/support and view the pages for the title you have.
  • To view your account details or to download a new copy of the book go to www.packtpub.com/account
  • To contact us directly if a problem is not resolved, use www.packtpub.com/contact-us
What eBook formats do Packt support? Chevron down icon Chevron up icon

Our eBooks are currently available in a variety of formats such as PDF and ePubs. In the future, this may well change with trends and development in technology, but please note that our PDFs are not Adobe eBook Reader format, which has greater restrictions on security.

You will need to use Adobe Reader v9 or later in order to read Packt's PDF eBooks.

What are the benefits of eBooks? Chevron down icon Chevron up icon
  • You can get the information you need immediately
  • You can easily take them with you on a laptop
  • You can download them an unlimited number of times
  • You can print them out
  • They are copy-paste enabled
  • They are searchable
  • There is no password protection
  • They are lower price than print
  • They save resources and space
What is an eBook? Chevron down icon Chevron up icon

Packt eBooks are a complete electronic version of the print edition, available in PDF and ePub formats. Every piece of content down to the page numbering is the same. Because we save the costs of printing and shipping the book to you, we are able to offer eBooks at a lower cost than print editions.

When you have purchased an eBook, simply login to your account and click on the link in Your Download Area. We recommend you saving the file to your hard drive before opening it.

For optimal viewing of our eBooks, we recommend you download and install the free Adobe Reader version 9.