End to End GUI Development with Qt5
上QQ阅读APP看书,第一时间看更新

Font Awesome

With our styling framework in place, let’s review what our navigation bar looks like and figure out what we want to achieve:

The buttons we want to display on our navigation bar are Dashboard View (the Home view), New Client View, and Find Client View, along with a toggle button at the top to expand and collapse the bar.

A common UI design pattern is to represent simple commands with icons. Further information about the command can be obtained by a variety of means; for example, when you hover over the button, information can be displayed in a tooltip or a status bar at the bottom of the screen. Our approach will be to have a collapsible bar. The default state of the bar will be collapsed and will display an icon representing each command. In expanded state, the bar will display both the icon and a textual description of the command. The user will be able to toggle the states with an additional button. This is a pattern particularly prevalent in mobile application development, where you want to consume as little screen space as possible by default.

There are a few options for displaying the icons for our buttons. Older desktop applications would more than likely use image files of some description. This gives you full artistic control over how your icons look, but carries several drawbacks. Image files tend to be comparatively large in size, and they are a fixed size. If you need to draw them at a different size, then they can look bad, particularly if they are scaled up or if the aspect ratio changes.

Scalable Vector Graphics (SVG) are much smaller files and scale very well. They are more difficult to create and can be a bit more limited artistically, but they can be very useful for the purpose of icons. However, from experience, they can be quite tricky to work with in Qt/QML.

The third option that gives you the small file size and scalability benefits of SVG but are much easier to work with are symbol font files. This is a very common solution in web development, and this is the approach we will take.

There are numerous symbol fonts available but perhaps the most popular for development is Font Awesome. It provides a wide range of terrific symbols and has a very helpful website; check out: http://fontawesome.io/.

Check any licensing applicable for fonts you choose to use, especially if you are using them commercially.

Download the kit and open up the archive file. The file we are interested in is fonts/fontawesome-webfont.ttf. Copy this file into our project folder in cm/cm-ui/assets.

In our cm-ui project, edit assets.qrc and add the font to our resources:

<file alias="fontawesome.ttf">assets/fontawesome-webfont.ttf</file>

Remember that our alias doesn’t have to be the same as the original filename, and we’ve taken the opportunity to shorten it a bit.

Next up, edit Style.qml and we'll wire the font up to our custom style for easy use. We first need the font to be loaded and made available for use, which we achieve using a FontLoader component. Add the following inside the root Item element:

FontLoader {
    id: fontAwesomeLoader
    source: "qrc:/assets/fontawesome.ttf"
}    

In the source property, we use the /assets prefix (or virtual folder) we defined in our assets.qrc file along with the fontawesome.ttf alias. Now, we have loaded the font but as it stands, we won’t be able to reference it from outside of Style.qml. This is because only properties at root component level are accessible outside of the file. Child components are deemed effectively private. The way we get around this is by creating a property alias for the element we want to expose:

Item {
    property alias fontAwesome: fontAwesomeLoader.name
    
    readonly property color colourBackground: "#efefef"
        
    FontLoader {
        id: fontAwesomeLoader
        source: "qrc:/assets/fontawesome.ttf"
    }    
}

This creates a publicly available property called fontAwesomewhich when called, simply redirects the caller to the name property of the internal fontAwesomeLoader element.

With the wiring done, let’s find the icons we want to use. Back on the Font Awesome website, navigate to the Icons page. Here, you can see all the available icons. Clicking on one will display further information about it, and it is from here that we can get the key piece of information we need in order to display it, and that is the unicode character. I’ll select the following icons for our menu, but feel free to choose whichever icons you want:

Now, let’s replace the Button components on our MasterView with a Text component for each of our icons:

Column {
    Text {
        font {
            family: Style.fontAwesome
            pixelSize: 42
        }
        color: "#ffffff"
        text: "uf0c9"
    }
    Text {
        font {
            family: Style.fontAwesome
            pixelSize: 42
        }
        color: "#ffffff"
        text: "uf015"
    }
    Text {
        font {
            family: Style.fontAwesome
            pixelSize: 42
        }
        color: "#ffffff"
        text: "uf234"
    }
    Text {
        font {
            family: Style.fontAwesome
            pixelSize: 42
        }
        color: "#ffffff"
        text: "uf002"
    }
}

You will also need to add the assets 1.0 import if you haven’t already:

Next, we’ll add the descriptive text for the client commands. Wrap each of the Text components in a Row and add a further Text component for the description, as follows:

Row {
    Text {
        font {
            family: Style.fontAwesome
            pixelSize: 42
        }
        color: "#ffffff"
        text: "uf234"
    }
    Text {
        color: "#ffffff"
        text: "New Client"
    }
}

The Row component will lay out its children horizontally—first the icon and then the descriptive text. Repeat this for the other commands. Add the descriptions Dashboard and Find Client for the other buttons and simply an empty string for the toggle command:

Before we get too carried away making further changes, we’ll take a breath, do some refactoring, and look at introducing components.