Qt5 C++ GUI Programming Cookbook
上QQ阅读APP看书,第一时间看更新

Styling in QML

Qt Meta Language or Qt Modeling Language (QML) is a Javascript-inspired user interface mark-up language used by Qt for designing 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 given in the following section.

How to do it…

  1. Create a new project by going to File | New File or Project. Select Application under Project category and choose Qt Quick Application.
  2. Press the Choose button, and that will bring you to the next window. Insert a name for your project and click the Next button again.
  3. Another window will now appear and ask you to choose a minimum required Qt version. Pick the latest version installed on your computer and click Next.
  4. After that, click Next again followed by Finish. Qt Creator will now create a new project for you.
  5. Once the project is being created, you will see there are some differences compare to a C++ Qt project. You will see two .qml files, namely main.qml and MainForm.ui.qml, inside the project resource. These two files are the UI description files using the QML mark-up language. If you double click main.qml file, Qt Creator will open up the script editor and you will see something like this:
    import QtQuick 2.5
    import QtQuick.Window 2.2
    
    Window {
      visible: true
      MainForm {
        anchors.fill: parent
        mouseArea.onClicked: {
          Qt.quit();
        }
      }
    }
  6. This file basically tells Qt to create a window and insert a set of UI called MainForm which is actually from the other .qml file called MainForm.ui.qml. It also tells Qt that when the user clicks on the mouseArea widget, the entire program should be terminated.
  7. Now, try to open the MainForm.ui.qml file by double-clicking on it. This time, Qt Designer (UI editor) will be opened instead, and you will see a completely different UI editor compared to the C++ project we did previously. This editor is also called the Qt Quick Designer, specially designed for editing QML-based UI only.
  8. If you open up the main.cpp file in your project, you will see this line of code:
    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
  9. The preceding code basically tells Qt's QML engine to load the main.qml file when the program starts. If you want to load the other .qml file instead of main.qml, you know where to look for the code.
  10. When main.qml is loaded by the QML engine, it will also import MainForm.ui.qml into the UI, since MainForm is being called in the main.qml file. Qt will check if MainForm is a valid UI by searching for its .qml file based on the naming convention. Basically the concept is similar to the C++ project we did in the previous section, whereby the main.qml file acts like the main.cpp file and MainForm.ui.qml acts like the MainWindow class. You can also create other UI templates and use them in main.qml. Hopefully this comparison will make it easier to understand how QML works.
  11. Now let's open up MainForm.ui.qml. You should see three items listed on the navigator window: Rectangle, mouseArea, and Text. When these items are interpreted by the QML engine, it produces the following result on the canvas:
  12. The Rectangle item is basically the base layout of the window, which cannot be deleted. It is similar to the centralWidget we used in the previous section. The mouseArea 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 is also used in a button component, which we will be using in a while. The Text component is self-explanatory: it is a label that displays a block of text on the application.
  13. On the Navigator window, we can hide or show an item by clicking on the icon besides the item which resembles an eye. When an item is hidden, it will not show on the canvas nor 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 children items will be placed below the parent item with an indented position. In our case, you can see the mouseArea and Text items are all positioned slightly to the right compared to the Rectangle item, because they are both the children of the Rectangle item. We can re-arrange 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 mouseArea. You will then see the Text item changes its position and is now located below the mouseArea with a wider indentation:
  14. We can also re-arrange them by using the arrow buttons located on 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, hide and show the parent item, and so on.

    Tip

    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.

  15. Next, delete both the mouseArea and Text items as we will be learning how to create a user interface from scratch using QML and Qt Quick.
  16. After you've done, let's set the Rectangle item's size to 800x600, as we're going to need a bigger space for the widgets.
  17. Open up main.qml and remove these lines of code:
    mouseArea.onClicked: {
      Qt.quit();
    }

    This is because the mouseArea item no longer exists and it will cause an error when compiling.

  18. After that, remove the following code from MainForm.ui.qml:
    property alias mouseArea: mousearea
  19. This is removed for the same reason as the previous code, because the mouseArea item no longer exists.
  20. Then, copy the images we used in the previous C++ project over to the QML project's folder, because we are going re-create the same login screen, with QML!
  21. Add the images to the resource file so that we can use them for our UI.
  22. Once you're done with that, open up Qt Quick Designer again and switch to the resource window. Click and drag the background image directly to the canvas. Then, switch over to the Layout tab on the properties pane and click the fill anchor button marked in red circle. This will make the background image always stick to the window size:
  23. Next, click and drag a Rectangle component from the library window to the canvas. We will use this as the top panel for our program.
  24. For the top panel, enable top anchor, left anchor, and right anchor so that it sticks to the top of the window and follow its width. Make sure all the margins are set to zero.
  25. Then, go to the Color property of the top panel and select Gradient mode. Set the first color to #805bcce9 and the second color to #80000000. This will create a half-transparent panel with a blue gradient.
  26. After that, 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, Monday, 26-10-2015 3:14 PM) for display purposes. Then, set the text color to white.
  27. Switch over to the Layout tab and enable top anchor and left anchor so that the text widget will always stick to the top left corner of the screen.
  28. Next, add a mouse area to the screen and set its size to 50x50. Then, make it a child of the top panel by dragging it on top of the top panel in the navigator window.
  29. Set the color of the mouse area to blue (#27a9e3) and set its radius to 2 to make its corners slightly rounded. Then, enable 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 right anchor's margin to 10 to give out some space.
  30. After that, open up the resources window and drag the shutdown icon to the canvas. Then, 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.
  31. Phew, that's a lot of steps! Now your items should be arranged like this on the Navigator window:
  32. 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.
  33. At this point, your top panel should look something like this:
  34. Next, we will be working on the login form. First, add a new rectangle to the canvas by dragging it from the Library window. Resize the rectangle to 360x200 and set its radius to 15.
  35. Then, set its color to #80000000, which will change it to black with 50% transparency.
  36. After that, enable the vertical center anchor and the horizontal center anchor to make it always align to 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 to give space to the logo. The following screenshot illustrates the settings of the anchors:
  37. Add the text widgets to the canvas. Make them the children of the login form (rectangle widget) and set their text property to Username: and Password: respectively. Then, 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.
  38. Next, add two text input widgets to the canvas and place them next to the text widgets we created just now. Make sure the text inputs are also the children of the login form. Since the text inputs don't contain any background color property, we need to add two rectangles to the canvas to use as their background.
  39. Add two rectangles to the canvas and make each of them a child of one of the text inputs we created just now. Then, 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.
  40. After that, we're going to create the login button below the password field. First, add a mouse area to the canvas and make it a child of the login form. Then, resize it to your preferred dimension and move it into place.
  41. Since the mouse area also 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.
  42. Next, add a text widget 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 to align it to the center of the button.
  43. You will now get a login form that looks pretty similar to the one we made in the C++ project:
  44. After we have done the login form, it's time to add the logo. It's actually very simple. First, open up the resources window and drag the logo image to the canvas.
  45. Make it a child of the login form and set its size to 512x200.
  46. Position it above the login form and you're done!
  47. This is what the entire UI look like when compiled. We have successfully re-created the login screen from the C++ project, but this time we did it with QML and Qt Quick!

How it works...

Qt Quick editor uses a very different approach for placing widgets in the application compared to the form editor. It's entirely up to the user which method is best suited for him/her.

The following screenshot shows what the Qt Quick Designer looks like:

We will now 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 previous section.
  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 it here.
  3. Resources: The Resources window displays all the resources in a list which can then be used in your UI design.
  4. Imports: The Imports window allows you to import different QML modules into your current QML file, such as a bluetooth module, webkit module, positioning module, and so on, to add additional functionality to your QML project.
  5. State pane: Stat pane displays the different states in the QML project which typically describe UI configurations, such as the UI controls, their properties and behavior, and the available actions.
  6. Properties pane: Similar to the property editor we used in previous section, this 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 as well.
  7. Canvas: Canvas is the working area where you create QML components and design applications.