Search icon CANCEL
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Qt 6 C++ GUI Programming Cookbook

You're reading from   Qt 6 C++ GUI Programming Cookbook Practical recipes for building cross-platform GUI applications, widgets, and animations with Qt 6

Arrow left icon
Product type Paperback
Published in Apr 2024
Publisher Packt
ISBN-13 9781805122630
Length 428 pages
Edition 3rd Edition
Languages
Tools
Arrow right icon
Author (1):
Arrow left icon
Lee Zhi Eng Lee Zhi Eng
Author Profile Icon Lee Zhi Eng
Lee Zhi Eng
Arrow right icon
View More author details
Toc

Table of Contents (17) Chapters Close

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

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.

You have been reading a chapter from
Qt 6 C++ GUI Programming Cookbook - Third Edition
Published in: Apr 2024
Publisher: Packt
ISBN-13: 9781805122630
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime