qtexercises

Upload: kafu46

Post on 10-Apr-2018

216 views

Category:

Documents


0 download

TRANSCRIPT

  • 8/8/2019 QtExercises

    1/22

    Qt for MobileDevelopers

    (Forum Nokia Training days, Copenhagen19-20 Nov 2009)

    Exercise Book

    F O R U M N O K I A

    Version 1.1; November, 2009

    Qt

  • 8/8/2019 QtExercises

    2/22

    Qt for Mobile developers, Exercise Book 2

    Copyright 2009 Nokia Corporation. All rights reserved.

    Nokia and Forum Nokia are trademarks or registered trademarks of Nokia Corporation. Javaand all Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc.Other product and company names mentioned herein may be trademarks or trade names of

    their respective owners.

    Disclaimer

    The information in this document is provided as is, with no warranties whatsoever, includingany warranty of merchantability, fitness for any particular purpose, or any warranty otherwisearising out of any proposal, specification, or sample. This document is provided forinformational purposes only.

    Nokia Corporation disclaims all liability, including liability for infringement of any proprietaryrights, relating to implementation of information presented in this document. Nokia Corporationdoes not warrant or represent that such use will not infringe such rights.

    Nokia Corporation retains the right to make changes to this document at any time, withoutnotice.

    Licence

    A licence is hereby granted to download and print a copy of this document for personal useonly. No other license to any other intellectual property rights is granted herein.

  • 8/8/2019 QtExercises

    3/22

    Qt for Mobile developers, Exercise Book 3

    Contents

    Objectives.............................................................................................. 5Overview................................................................................................ 5Practical Outline...................................................................................... 5QtCreator intro ....................................................................................... 6

    Exercise 1b (optional): UI Design BMI Calculator...................................................................................... 7Objectives.............................................................................................. 7Overview................................................................................................ 7Practical Outline...................................................................................... 7Optional................................................................................................. 8

    Exercise 1c (optional): Signals and Slots BMI Calculator ........................................................................ 9Objectives.............................................................................................. 9Overview................................................................................................ 9Practical Outline...................................................................................... 9

    Exercise 2 (optional): UI Design Jackpot Game in QtCreator ..............................................................10Objectives............................................................................................ 10Overview.............................................................................................. 10Practical Outline.................................................................................... 10Optional............................................................................................... 12

    Exercise 3: Event Handling ...............................................................................................................................13Objectives............................................................................................ 13Overview.............................................................................................. 13Practical Outline.................................................................................... 13Optional............................................................................................... 14

    Exercise 4: Graphics View Symbol Reels....................................................................................................15Objectives............................................................................................ 15Overview.............................................................................................. 15Practical Outline.................................................................................... 15

    Exercise 5: Animations and Transformations.............................................................................................18Objectives............................................................................................ 18Overview.............................................................................................. 18Practical Outline.................................................................................... 18Optional............................................................................................... 19

    Exercise 6: Finishing the Application Engine Integration ...................................................................20Objectives............................................................................................ 20Overview.............................................................................................. 20Practical Outline.................................................................................... 20

  • 8/8/2019 QtExercises

    4/22

    Qt for Mobile developers, Exercise Book 4

    Exercise 7: QtWebKit ..........................................................................................................................................21Objectives............................................................................................ 21References ........................................................................................... 21Overview.............................................................................................. 21Practical Outline.................................................................................... 21

  • 8/8/2019 QtExercises

    5/22

    Qt for Mobile developers, Exercise Book 5

    Exercise 1: First Qt Application in Maemo

    Objectives

    - Write a very simple HelloWorld application.- Familiarize yourself with the Qt and Maemo build chain and various project files.- Check QtCreator and Scratchbox.

    Overview

    You will start off by writing a simple HelloWorld application from scratch, without the help of any IDE wizardsor similar. You will also create all the needed project files, compile the application and run it. All this is donefrom the command line in Scratchbox.

    In the second phase of the exercise we will be introduced with the desktop Qt IDE, QtCreator.

    Upon completion of this exercise you should be able to create, build and run simple Qt applications from thecommand line and to understand what happens during each step in the build process.

    Practical Outline

    1. Open a terminal Applications > Accessories > TerminalApplications > Accessories > TerminalApplications > Accessories > TerminalApplications > Accessories > Terminal. Create a base directory for yourHelloWorld project, for example, /scratchbox/users/maemo/home/maemo/workspace//scratchbox/users/maemo/home/maemo/workspace//scratchbox/users/maemo/home/maemo/workspace//scratchbox/users/maemo/home/maemo/workspace/HelloWorldHelloWorldHelloWorldHelloWorld.

    This directory will contain all the source, header and project files for your project.

    Start Scratchbox (give the command scratchboxscratchboxscratchboxscratchbox). Check that your current target is FREMANTLE_X86FREMANTLE_X86FREMANTLE_X86FREMANTLE_X86.If not, change it with the command sbsbsbsb----conf select FREMANTLE_X86conf select FREMANTLE_X86conf select FREMANTLE_X86conf select FREMANTLE_X86. Switch toworkspace/workspace/workspace/workspace/helloworldhelloworldhelloworldhelloworld directory, which should be located in your home folder inside Scratchbox.

    2. Write a main.cppmain.cppmain.cppmain.cpp source file containing the code needed for a simple HelloWorld application. All theapplication needs to do is to display a QLabel with the text Hello World! at this point we are notinterested in how the application actually looks like.

    You can use for instance nano or vi editors to write the code. Open the code from command linewith command nano main.cpp. You may edit the source code file using your favorite editor byopening the editor outside Scratchbox and accessing the file using the path/scratchbox/users/maemo/home/maemo/workspace/HelloWorld.

    3. Create a HelloWorldHelloWorldHelloWorldHelloWorld.pro.pro.pro.pro file for your project by running the commandqmake project

    Optionally you could create the file manually in a text editor, if you wish.

    Open the generated HelloWorld.HelloWorld.HelloWorld.HelloWorld.propropropro file using a text editor and take a look at the contents. Noticeespecially that the main.cppmain.cppmain.cppmain.cpp is already listed in the sources section this happens because qmake project automatically includes any existing file (or more precisely: file type) it recognizes in the projectdirectory. By default, qmake will also make a recursive search into sub-directories.

    Once the initial .pro.pro.pro.pro file has been created, it can easily be edited manually. However, beware: if youlater run qmake project again, your manual modifications might be lost!

    Which other keywords could be added to the .pro.pro.pro.profile? For example, how would you add a library your

    application needs to use? How about header files?

    The next step is to create the platform specific make files. To do this, run the command

    qmake

    Take a note of the files generated by this command. What sort of files do you get and what sort ofbuilds can you do with them?

    As you saw in the previous step, the .pro.pro.pro.pro file does not need to contain very much information for a

    simple project such as this.

  • 8/8/2019 QtExercises

    6/22

    Qt for Mobile developers, Exercise Book 6

    This command also performs various operations related to the Qt meta-object system, as we will seein later modules.

    4.4.4.4. Now you are ready to build the application for the first time:make

    This one generates the debug build (why?). You can build the release version with:

    make release

    5. Launch the application from command prompt (./myApp(./myApp(./myApp(./myApp). Note that you may need to give the path ././././prefix, if your current path is not in the PATH environment variable. Does your application look like aMaemo application? Why?

    6. Close the application. Open another terminal and launch Xephyr X server outside Scratchbox.Xephyr :2 -host-cursor -screen 800x480x16 -dpi 96 -ac &

    7. Inside Scratchbox,a. Define an environment variable DISPLAY and set it to :2

    EXPORT DISPLAY=:2

    b. Launch Maemo application frameworkaf-sb-init.sh start

    c. Launch the application with Maemo stylerun-standalone.sh ./myApp

    8. Finally, a brief summary of the commands used during the build process:qmake project // Creates the .pro fileqmake // Creates platform specific makefiles

    // AND

    make // Same as make debug

    // OR

    make release

    QtCreator intro

    9. Launch QtCreator from the start menu.10.Select Open and locate your helloworld project file. QtCreator wants to import the project

    settingsallow it.

    11.Check your program code from QtCreator, do some modifications for it (like changing thetext).

    12.Build and execute.13.Try debugging: Set a breakpoint to the application, launch debugger and try it out!

  • 8/8/2019 QtExercises

    7/22

    Qt for Mobile developers, Exercise Book 7

    Exercise 1b (optional): UI Design BMI Calculator

    Objectives

    - Learn how to create a new Qt project in QtCreator.- Use the Qt Designer embedded in QtCreator to create the initial UI of a BMI Calculator application

    Overview

    Exercise starting point:

    Start a new project from scratch. You can unload the previous project form QtCreator.

    In this exercise you will create a small Gui application using a custom dialog. The application will calculate theBMI value for the user from the given weight and height. The initial UI will be done in this exercise and laterwe will add custom slot functionality to the exercise.

    Practical Outline

    1. Launch QtCreator and use its new project wizard to create a new Qt project:File -> New -> Project -> Qt -> Qt Project

    In this case we want create a Gui application, so select

    Qt4 Gui Application

    Name your project BMICalc and select a suitable folder for the project (/Workspace/). When the wizard asks for the Qt Modules to be included, Core and Gui aresufficient.

    Next the wizard asks for the class name and base class. Lets keep it simple, and do a plain dialog.Select QDialog for the base class and name your dialog for instance BMICalculator.

    2. Take a look at the project structure. All the files you need to run the application are already there(main.cppmain.cppmain.cppmain.cpp, bmicalculatorbmicalculatorbmicalculatorbmicalculator.cpp/.h.cpp/.h.cpp/.h.cpp/.h etc.) and the project compiles without errors. You have notcreated the UI design yet, so at this stage the screen would be blank.

    Double click on the bmicalculatorbmicalculatorbmicalculatorbmicalculator.ui.ui.ui.ui file to open it for editing in the embedded Qt Designer tool.Now you should have the Qt Designer edit buttons and tabs visible in your perspective.

    3. Try to create a layout for your BMI Calculator application. Feel free to use your imagination!Hint: Placing the UI widgets inside the vertical and horizontal layout items might prove to be a littletricky if you try to do it by dragging and dropping. Instead, you could try the following for each

    horizontal layout:

    o Drag and drop the buttons, labels and other widgets onto the designer canvas and orderthem roughly in the correct position

    o Select the widgets you intend to layout horizontally, right-click and set the needed layoutusing the context menu

    o Once the horizontal layouts and their contents have been created, place them inside thevertical layout in the same way

  • 8/8/2019 QtExercises

    8/22

    Qt for Mobile developers, Exercise Book 8

    CChheecckkppooiinntt:: ccoommpp iillee aanndd rruunn yyoouurr aapppp lliiccaattiioonn ..

    4. Modify the properties of the widgets (like text labels and default values) to match the correct ones.Recompile to see the changes.

    5. When the application is compiled, Qt UI compiler (uic) generates a header file containing source codecorresponding to the UI design. Take a look at the file (Open it, with Open) ui_ui_ui_ui_bmicalculatorbmicalculatorbmicalculatorbmicalculator.h.h.h.h.

    What does the function setupUi() do?

    Open bmicalculatorbmicalculatorbmicalculatorbmicalculator.h.h.h.h. Does your project use single or multiple inheritance? How can you tell?Notice

    also the Q_OBJECT macro being used in the class, and the format used with the system includestatements: .

    6. By default, Qt Designer gives objects quite non-descriptive names such as label, label_2, etc. Sinceyoull be using these objects in your code later, these default names would eventually causeunnecessary confusion.

    Using the designers Qt C++ Property Editor, change the object names of at least the buttons andlabels to something more suitable.

    7. As you know by now, signals and slots between UI components can sometimes be connected in the QtDesigner without writing a single line of code by hand. You can try this with two alternatives:

    a. Add a slider to your project (for instance for weight input) and connect a suitable signal of it tothe lcdnumber to see them bound together.

    b. Add an exit button to your application and connect that to the accept signal of the dialog itself.8. Compile, run and test!

    Optional

    9. If you have time at the end of the exercise, you can try fine tuning your UI design. Try if you can findout how you could e.g. remove the frame around the LCDNumber object and change its segment styleto flat.

  • 8/8/2019 QtExercises

    9/22

    Qt for Mobile developers, Exercise Book 9

    Exercise 1c (optional): Signals and Slots BMI Calculator

    Objectives

    - Create custom slot functions for your custom dialog- Connect signals to your custom slots, manually and automatically (by name)- Try input validator and palette change

    Overview

    Exercise starting point:

    Your own solution to exercise 1b.

    Since the initial UI design is now finished, it is time add some actual functionality for the BMI Calculator: howto calculate the BMI value! We will also add some input validating and check for logically correct values.

    Practical Outline

    1. Lets start by adding a slot for our BMICalculator dialog class for calculating the value. Add thefollowingprivate slot function:

    void calculateBMI();

    In this function, calculate the BMI value from the weight and height given for the suitable UI

    components. If weight is entered using a line edit, you will need to change it to integer from QString.See QtCreators help (QtAssistant) for doing this.

    The formula for BMI value is

    BMI = weight / heightInMeters^2

    Remember to show the result in the dialog after calculating it.

    2. Connect your slot function to suitable slots, so that it gets called whenever the values of weight orheight are modified. Where to connect?

    3. Compile, run and test your application!4. Lets add a check for the program that it will change the weight line edit to red text color if the given

    weight is too less or too much (lets say under 30 or over 200). For this, we will try an automaticallyconnected slot function. The connection is made based on its name. So, what name should you givefor the function to have it executed every time the weight is edited.

    Implement the function to have logic for checking the weight value and modifying the whole QPaletteof the line edit. see QtAssistant for syntax.

    5. Build, compile and enjoy! Good job!

  • 8/8/2019 QtExercises

    10/22

    Qt for Mobile developers, Exercise Book 10

    Exercise 2 (optional): UI Design Jackpot Game in QtCreator

    Objectives

    - Learn how to create a new Qt project in QtCreator- Use the Qt Designer embedded in Qt Creator to create the initial UI of the Jackpot game.- Build and run your application using QtCreator

    Overview

    Exercise starting point:

    Start a new project from scratch.

    Exercise example solution:

    Exercises/Exercises/Exercises/Exercises/ex2_solex2_solex2_solex2_sol

    In this exercise you will create the initial project and UI design for a Jackpot game application. In theforthcoming exercises you will gradually write code to add functionality in your game, such as event handlingand graphics. The example solutions and certain templates for this and later exercises are available in theExercisesExercisesExercisesExercises.zip.zip.zip.zip. Unzip the file to Scratchbox e.g. /scratchbox/maemo/users/home/maemo/workspace/scratchbox/maemo/users/home/maemo/workspace/scratchbox/maemo/users/home/maemo/workspace/scratchbox/maemo/users/home/maemo/workspace or

    similar.

    The instructions to this exercise are intentionally slightly less detailed than the ones in the previous exercise.If you are unsure of how to proceed at any stage, feel free to ask the instructor for guidance!

    After this exercise you should know how to use QtCreator IDE and the embedded Qt tools to design a simpleQt UI application.

    Practical Outline

    1. Launch QtCreator and use its new project wizard to create a new Qt project:File -> New -> Qt4 Gui Application

    Name your project JackpotUI. When the wizard asks for the Qt Modules to be included, you can letCore and Gui to be the only ones.

    In this case we want to create a QMainWindow-based UI (for simplicity), so make sure your base classis QMainWindow. You can give your own main class a more describing name, for instance JackpotUI.

    2. Take a look at the project structure. All the files you need to run the application are already there(main.cppmain.cppmain.cppmain.cpp, JackpotUI.cpp/.hJackpotUI.cpp/.hJackpotUI.cpp/.hJackpotUI.cpp/.h etc.) and the project compiles without errors. You have not created the

    UI design yet, so at this stage the screen would be blank.

    Double click on the JackpotUI.uiJackpotUI.uiJackpotUI.uiJackpotUI.ui file to open it for editing in the embedded Qt Designer tool. Nowyou should have the Qt Designer edit buttons and tabs visible.

    3. Try to create a layout that matches the example below. Your design does not need to be an exact copybut all the shown buttons, labels etc. should be present these will be needed in the later exercises.

    The picture on the left is a Qt Designer screen shot and the picture on the right explains which

    designer components (widgets) have been used to create it. Notice that the latter is not in the correctscale for presentation purposes.

  • 8/8/2019 QtExercises

    11/22

    Qt for Mobile developers, Exercise Book 11

    Hint: Placing the UI widgets inside the vertical and horizontal layout items might prove to be a littletricky if you try to do it by dragging and dropping. Instead, you could try the following for eachhorizontal layout (see the image below for illustration):

    o Drag and drop the buttons, labels and other widgets onto the designer canvas and orderthem roughly in the correct position

    o Select the widgets you intend to layout horizontally, right-click and set the needed layoutusing the context menu

    o Once the horizontal layouts and their contents have been created, place them inside thevertical layout in the same way

    Hint 2: the top-left label (QLabel) does not have any displayable text at this point eventually it willcontain the text You win! whenever the player wins. That is why it is barely visible next to thehorizontal spacer in the Qt Designer.

    CChheecckkppooiinntt:: ccoommpp iillee aanndd rruunn yyoouurr aapppp lliiccaattiioonn ..

    4. Depending on your designer default values, you may notice that the UI does not look very attractiveyet. First of all, you might need change the font size on the labels and buttons. Secondly, take a lookat main.cppmain.cppmain.cppmain.cpp instead of calling show() on your main window, which other functions could you use and

    whats the difference?

    Hint: see course slides or QWidget documentation in the Qt Assistant (public slots).

  • 8/8/2019 QtExercises

    12/22

    Qt for Mobile developers, Exercise Book 12

    What is the difference between these three options?Try them yourself! Later on when resize eventhandling is implemented, the difference between them is even more visible.

    5. When the application is compiled, Qt UI compiler (uic) generates a header file containing source codecorresponding to the UI design. Take a look at the file ui_JackpotUI.hui_JackpotUI.hui_JackpotUI.hui_JackpotUI.h. What does the function

    setupUi() do?

    Open JackpotUI.hJackpotUI.hJackpotUI.hJackpotUI.h. Notice also the Q_OBJECT macro being used in the class, and the format usedwith the system include statements: .

    6. By default, Qt Designer gives objects quite non-descriptive names such as label, label_2, etc. Sinceyoull be using these objects in your code later, these default names would eventually causeunnecessary confusion.

    Using the designers Qt C++ Property Editor, change the object names of at least the buttons andlabels to something more suitable.

    Note: from now on in this exercise book we will refer to the UI objects by the following names (asthey are in the solution of this exercise), starting from the top-left label:

    statusLabel, horizontalSpacer, creditsLabel, creditsLcd, betLabel, betSlider,betDisplayLabel, runButton, cashOutButton, newGameButton, exitButton

    7. As you know by now, signals and slots between UI components can sometimes be connected in the QtDesigner without writing a single line of code by hand. Connect a signal from the betSlider to a

    suitable slot in the betDisplayLabel, so that when the slider is moved the bet changes. Also, changethe betSliders range to 1 20.

    Note: there are multiple signals in QSlider you can use here pick the one that is emitted both whenthe slider is moved by dragging it or by clicking on it.

    CChheecckkppooiinntt:: ccoommpp iillee aanndd rruunn yyoouurr aapppp lliiccaattiioonn aanndd cchheecckk tthhaatt tthhee ss lliiddeerrwwoorrkkss pprrooppeerrllyy..

    Optional

    8. If you have time at the end of the exercise, you can try fine tuning your UI design. Try if you can findout how you could e.g. remove the frame around the creditsLcd object and change its segment style toflat (so that it looks roughly the same as in the example screen shot).

  • 8/8/2019 QtExercises

    13/22

    Qt for Mobile developers, Exercise Book 13

    Exercise 3: Event Handling

    Objectives

    - Connect button presses to suitable slot functions.- Enable playing the game also by using hardware keys, i.e. handle key events properly.- Time permitting: add an Options menu to the application.

    Overview

    Exercise starting point:

    Your own solution to exercise 2 or the example solution in ExercisesExercisesExercisesExercises////ex2_solex2_solex2_solex2_sol.

    Exercise example solution:

    Exercises/Exercises/Exercises/Exercises/ex3_solex3_solex3_solex3_sol

    Since the initial UI design is now finished, it is time add event handling to the Jackpot game. In this exerciseyou will add the needed signal-to-slot connections and key event handling function that will be used later toplay the game. Your task is to write an initial (dummy) implementation of various functions, which you willlater modify to perform meaningful operations.

    In the optional section you will implement a handler function for resize events to react to layout changes (e.g.

    in case of screen orientation change or similar). The optional section will also demonstrate how Options menuand menu items can be added to the application.

    Practical Outline

    1. Lets start by adding a few slot functions to which the buttons signals can be connected. ModifyJackpotUI.cppJackpotUI.cppJackpotUI.cppJackpotUI.cpp and JackpotUI.hJackpotUI.hJackpotUI.hJackpotUI.h to add the followingprivate slot functions:

    void newGame();void runSymbolReels();void on_cashOutButton_clicked();

    The slot functions are private; does it mean that only signals emitted from this object itself can beconnected to them? How would you justify/explain your answer?Ask the instructor if unsure. For nowthe slot functions can remain empty, implementation will be added later (except for the cash outbutton this will be left as an extra assignment for you to implement any way you like!).

    2. Declare and implement a private function called :void initButtons();

    In this function, connect the correct buttons signals to the slots created in step 1. For examples sakehere, some of the connections are made manually and some can be made automatically. Which one(s)do you need to connect?How does the automatic connection work exactly?

    Call initButtons() from the JackpotUIs constructor.

    3. In the class QApplication (or more precisely, QCoreApplication) there is a slot that exitButton can beconnected to use Qt Assistant or lecture notes to find out which one it is and add the connection toinitButtons(). How do you get access to the QApplication instance in your application?

    To test that connections from each of the five buttons work properly at this stage, you can create atemporary implementation for each of the slot functions, for example, to change the text in thestatusLabel. Again, use Qt Assistant to find a suitable function for this in the QLabel class.

    4. All devices do not necessarily have a touch screen so it would be nice to be able to play the gameusing a keypad as well. For this you will need to enable key event handling.

    QWidget base class defines a virtual function that can be overwritten by a subclass:

    virtual void QWidget::keyPressEvent(QKeyEvent* event);

  • 8/8/2019 QtExercises

    14/22

    Qt for Mobile developers, Exercise Book 14

    Implement this function in your JackpotUI class (notice that you might need to add a suitable includestatement in your header file for successful compilation). A typical implementation of this functioncontains a switch-case block where the key code is checked and a corresponding helper function is

    called to perform the wanted operation. For example, when the key 1 is pressed, newGame() is calledand so on.

    Note: if you do not want to handle a certain key yourself, forward the key event to the base classimplementation of keyPressEvent() instead!

    Hint: the key code given in the event argument is the ASCII code for each numeric key in the keypad(e.g. key 1 has the hexadecimal value 0x31; key 2 has the value 0x32 etc). It is recommended,however, that you use the platform-independent enumeration values defined in Qt::Key.

    Hint 2: some widgets, when focused, will consume certain key presses (depending on the widget, e.g.the selection key Qt::Key_Select). To have full control over key presses in your dialog class, you willneed to set the widgets in the dialog not to accept focus. See QWidget class documentation for help ondisabling focus on widgets; you can do this in the initButtons() function.

    CChheecckkppooiinntt:: ccoommpp iillee aanndd rruunn yyoouurr aapppp lliiccaattiioonn aanndd cchheecckk tthhaatt eevveenntt

    hhaannddlliinngg wwoorrkkss pprrooppeerrllyy..

    Optional

    5. Adding an Options menu on a QMainWindow based application is simple. To do this,1. Create the menu in the Qt Designer and add a few items such as New game and Cash out

    to it.

    2. Your menu now contains QActions you will need to connect signals from these actions toslots in your JackpotUI class (if you do not already have suitable slots, create them). Use QtAssistant to find out which signal is emitted when a menu item is selected.

  • 8/8/2019 QtExercises

    15/22

    Qt for Mobile developers, Exercise Book 15

    Exercise 4: Graphics View Symbol Reels

    Objectives

    - Learn how to use Qts graphics view to display graphical items.- Study how images can be loaded from a resource file and displayed in widgets inside the graphics

    view.

    - Implement simple event handling on items within the graphics view.Overview

    Exercise starting point:

    Your own solution to exercise 3 or the example solution in Exercises/Exercises/Exercises/Exercises/exexexex3333_sol_sol_sol_sol.

    Templates used in the exercise:

    Exercises/templatExercises/templatExercises/templatExercises/templates/es/es/es/exexexex4444

    Exercise example solution:

    Exercises/Exercises/Exercises/Exercises/ex4_solex4_solex4_solex4_sol

    In this exercise you will start adding elements to the graphics view widget created in the design phase ofexercise 2. Graphics view is a widget that contains a graphics scene to render multiple graphical items on the

    screen, as well as perform transformations on and forward events to them.

    Here the graphical items are simple widgets on top of which .png.png.png.png format images are drawn. Note that SVGimages could be used as well through the QSvg* classes this is rather simple to do and thus omitted in thisexercise.

    The exercise also shows how a layout can be applied to a container widget inside the graphics view.

    For more information on the graphics view system in Qt, an excellent piece of documentation can be found inthe Qt Assistant by searching for the graphics view framework. Especially the section on coordinate systemsis worth reading before doing this exercise.

    Upon finishing the exercise your application should look something like this in the emulator (status pane andsoftkeys omitted for simplicity):

    Practical Outline

    1. The graphics view will contain three symbol reel items, each of which will display various iconsimitating a rolling reel. Copy the Exercises/templates/ex4/Exercises/templates/ex4/Exercises/templates/ex4/Exercises/templates/ex4/imagesimagesimagesimages folder to the root of yourJackpotUI project the following instructions assume that the imagesimagesimagesimages folder containing the images isfound in your project.

    2. The folder Exercises/templates/Exercises/templates/Exercises/templates/Exercises/templates/ex4ex4ex4ex4 also contains header and source stubs for the class SymbolReel.Copy these files into your project and make sure they are added to the .pro.pro.pro.pro file.

    Note: notice especially the first argument in SymbolReels constructor the reelId. It will be used toidentify the given SymbolReel instance once the application engine is taken into use in exercise 6.

  • 8/8/2019 QtExercises

    16/22

    Qt for Mobile developers, Exercise Book 16

    Note 2: take a look at how the class derivation of the SymbolReel class goes (SymbolReel ->QGraphicsWidget -> QGraphicsLayoutItem). This is important because ultimately SymbolReels will be

    placed inside a layout object.

    You will add more implementation to SymbolReel.hSymbolReel.hSymbolReel.hSymbolReel.h and .cpp.cpp.cpp.cpp later.

    3. The icons in the imagesimagesimagesimages folder are used through a resource file, similarly to the Symbian way ofhandling images. The resource file is compiled by Qt resource compiler (rcc) automatically during a

    normal build process.At which stage of the build process does this happen exactly?Create the resource file and call it jackpotuijackpotuijackpotuijackpotui.qrc.qrc.qrc.qrc (where qrc stands for Qt Resource Collection):

    File -> New : Qt -> Resource File

    By creating the file this way it is automatically added to the .pro.pro.pro.pro file open the file in a text editor tosee which keyword is used and how.

    Double-clicking on the resource file opens it in the resource editor. This is actually an XML file, so it

    could also be edited in a text editor. Select Add prefix. The prefix can be used to logically groupimages even though they are in the same folder in this case, set the prefix to simply be a slash:/ instead of the default value /new/prefix1.

    Add all the images from the imagesimagesimagesimages folder to the resource file by using the Add button. Once you aredone, save the file and compile your project. Resource compilation produces the file

    qrc_jackpotui.cppqrc_jackpotui.cppqrc_jackpotui.cppqrc_jackpotui.cpp. Take a look what the file looks like it is a source file containing all the imagesand some code for accessing them.

    4. As briefly mentioned earlier, the graphics view needs a graphics scene to be able to render graphicsitems on the screen. In JackpotUI.hJackpotUI.hJackpotUI.hJackpotUI.h, declare two private functions and a few member variables:

    // Functions:void loadPixmaps();void initGraphicsView();

    // Member variables:QList m_pixmaps;SymbolReel* m_leftReel;SymbolReel* m_centerReel;SymbolReel* m_rightReel;

    Call initGraphicsView() from your JackpotUIs constructor. The others will be handled later in this

    exercise.

    In initGraphicsView():

    1. Create a QGraphicsScene of size 150x40 pixels at position (0,0) and pass this (your JackpotUIobject) as the parent argument (the scene will later hold three 40x40 items with 15 pixelsdefault spacing between each of them). Notice that this way you do not need to store thescene in a member variable in your class! Can you explain why?After creating the scene, set itto be the views scene.

    Hint: QSize and QRectF can be used to determine the size and position of the scene.

    Note: By default, a scene smaller than the view port of the graphics view will be centered inthe view port (this is the case here as well).

    2. The background image can be rendered either on the graphics view or the graphics scene. Inthis case, draw it on the view. To do this, create a QPixmap object as shown below and set itas the background brush to the view:

    QPixmap background(:/images/blue_angle_swirl.jpg);

    CChheecckkppooiinntt:: ccoommpp iillee aanndd rruunn yyoouurr aapppp lliiccaattiioonn ttoo cchheecckk tthhaatt tthhee bbaacckkggrroouunndd iiss ddrraawwnn ccoorrrreeccttllyy..

  • 8/8/2019 QtExercises

    17/22

    Qt for Mobile developers, Exercise Book 17

    5. Next you will add a layout widget and draw the actual symbol reels on the graphics scene. Before thiscan be done, you need to load the rest of the icons (*.png*.png*.png*.png) from the resource file into the m_pixmapslist declared in the previous step.

    Implement loadPixmaps() to initialize this list by loading each image from the resource file into aQPixmap (as shown before) and then appending it to the list. Call loadPixmaps() frominitGraphicsView().

    6.

    You are now ready to start laying out graphics items on the graphics scene/view. If you have troublein implementing the following steps, feel free to take a look at the solution for tips and tricks!

    In initGraphicsView():

    a. Create an instance of QGraphicsWidget (call it containerWidget). The container widget doesnot necessarily need a parent, since it will later be added to the scene and the scene will takeownership of the widget.

    b. Initialize the symbol reel members defined in step 4. A good size for each symbol reel is 40x40in our case. These do not necessarily need a parent either; in the next step the reels will beadded to a linear layout object which takes ownership.

    c. The containerWidget also needs the actual layout. Open QGraphicsLinearLayout documentationin Qt Assistant and study how

    I. An instance of QGraphicsLinearLayout is created (call it horizontalLayout, parent shouldbe the containerWidget),

    II. The content margins inside horizontalLayout are set to 0 all around,III. The symbol reels are added to the horizontalLayout, andIV. How the containerWidget is finally set to the graphics scene created earlier.

    7. You can compile your project and even run it, but the reels will not be drawn. Open SymbolReel.hSymbolReel.hSymbolReel.hSymbolReel.h and.cpp.cpp.cpp.cpp in the editor and study their contents for a while. Note especially how an instance of this class isconstructed and what kind of member variables the class has.

    Follow and implement the TODOs 1-4 in the function paint(...). This function comes from a base classand is called automatically by the graphics view framework whenever it needs to draw this particulargraphics item.

    CChheecckkppooiinntt:: ccoommpp iillee aanndd rruunn yyoouurr aapppp lliiccaattiioonn ttoo cchheecckk tthhaatt tthhee ggrraapphh iiccss

    vviieeww ccoonnttaaiinn iinngg tthhee ssyymmbbooll rreeeellss iiss ddrraawwnn ccoorrrreeccttllyy ((rroouugghh llyy aass sshhoowwnn iinn tthhee oovveerrvviieeww)) ..

    8. Typically in a game like jackpot a player has the possibility to lock one or two reels in order tomaximize his/her chances of winning. The game engine that will be taken into use later will handle the

    logic behind locking and unlocking a reel, but we can already prepare for this by adding support forlocking in the UI.

    In SymbolReel.hSymbolReel.hSymbolReel.hSymbolReel.h and .cpp.cpp.cpp.cpp:

    a. Add a public function called lock() that will toggle the value of a member variable boolm_locked and each time request a repaint by calling a base class function update().

    b. Modify the paint() function to set a different color brush depending on the value of m_locked(for example, red if locked and green otherwise).

    c. Overwrite the base class function QGraphicsItem::mousePressEvent(...) so that it calls lock()when a mouse press event is received. The mousePressEvent(...) function is calledautomatically by the graphics view framework when the user clicks on the symbol reel on thetouch screen.

    You can also modify the JackpotUI::keyPressEvent(...) implementation to call lock() on m_leftReel,m_centerReel and m_rightReel when a suitable key is pressed (e.g. 1, 2 or 3, respectively).

    CChheecckkppooiinntt:: ccoommpp iillee aanndd rruunn yyoouurr aapppp lliiccaattiioonn ttoo cchheecckk tthhaatt lloocckkiinngg aanndduunnlloocckkiinngg aa rreeee ll wwoorrkkss aass eexxppeecctteedd..

  • 8/8/2019 QtExercises

    18/22

    Qt for Mobile developers, Exercise Book 18

    Exercise 5: Animations and Transformations

    Objectives

    - Learn how to add simple timer-based animations and transformations to items within a graphics view.

    OverviewExercise starting point:

    Your own solution to exercise 4 or the example solution in Exercises/Exercises/Exercises/Exercises/exexexex4444_sol_sol_sol_sol.

    Exercise example solution:

    Exercises/Exercises/Exercises/Exercises/ex5_solex5_solex5_solex5_sol

    The game engine will be added to the jackpot game in the next exercise the engine will contain the logic todetermine whether a player wins or not. When the player wins, the UI should display an animation to properlyillustrate this. Furthermore, animations are needed when the symbol reels are rolled.

    In this exercise you will prepare the UI animations, so that they can easily be taken into use in the nextexercise. Some functions implemented during this exercise might be fairly tedious since they contain a fairamount of logic and index manipulations. In such cases, feel free to check the example solution for hints!

    Basically there are a couple of options regarding animation timers in Qt: either use QTimeLine or QTimer. Inthis exercise you will be using QTimer through certain convenience functions in QObject, for simplicitys sake.

    For more information on QTimeLine and direct usage of QTimer, refer to Qt Assistant documentation.

    Practical Outline

    1. The easiest way to use a periodic timer is to use the timer handling functions from QObject base class:startTimer(), timerEvent() and killTimer().

    In your JackpotUI class:

    a. Write a function runWinAnimation() which starts a timer and stores the returned timer ID intoa member variable (m_timerId). You will need this ID to kill the timer later. Once the timer isstarted, it will periodically call timerEvent() until it is explicitly killed.

    b. Implement timerEvent() so that it calls QGraphicsView::rotate() to rotate your graphics viewe.g. 20 degrees at a time, as many times as needed to rotate full 360 degrees. When this hasbeen reached, kill the timer.

    c. You can also implement a temporary way of triggering the animation, e.g. by pressing key 5on the keypad. Once the game engine has been added to the project, the temporary triggercan be removed.

    d. Try to set your timer interval and amount of rotation per timer event so that the animationruns smoothly.

    CChheecckkppooiinntt:: ccoommpp iillee aanndd rruunn yyoouurr aapppp lliiccaattiioonn ttoo sseeee wwhhaatt tthhee aanniimmaattiioonn llooookkss lliikkee..

    2. You might see a scrollbar flashing on the side of the graphics view if at some point during theanimation the reels exceed the dimensions of the graphics view. By default graphics view displaysscrollbars whenever the graphics scene and its contents do not fit inside the view.

    Try to find out how you can change this default behavior on the graphics view and change it in thebeginning of initGraphicsView().

    3. Play around with the other transformation functions defined in QGraphicsView: scale(), matrix(),setMatrix() and so on. You can try, for example, to make the view appear to be moving away from theviewer as it rotates (scale). Once it has rotated for a while, restore the original state of the view (levelthe reels just as they were before the animation started; in other words, restore the original

    transformation matrix).

    4. As you might have noticed earlier, SymbolReel objects are given a list of five symbols to use when thegame is played. The game engine will eventually be used to determine which symbol is randomlyshown by each reel.

  • 8/8/2019 QtExercises

    19/22

    Qt for Mobile developers, Exercise Book 19

    At this point you can already implement the animations in the SymbolReel class. To do this, you willneed to:

    a. Add the following kind of a public function which can be used to roll the reel (the given numberof times through all icons, stopping at the given index in the icon list, timer interval is

    forwarded to startTimer() call).

    void rollReel(int numOfFullRounds, int untilIndex,

    int timerInterval);

    Note that you should only roll the reel if it is not locked this check can be made in therollReel() function.

    b. Use startTimer(), timerEvent() and killTimer() roughly as you did in the JackpotUI classearlier; when timerEvent() is called, draw the next icon in the icon list until the given indexhas been reached, then kill the timer.

    Building all this logic might be fairly tedious, check the solution to assist you in thetimerEvent() implementation if necessary.

    Note that you will also need to modify the paint() function to draw the correct icon! Whichfunction do you need to call to cause a repaint?

    c. Add a few member variables to keep track of e.g. number of full rounds rolled, current iconindex, timer id, and so on.

    d. Change the implementation of JackpotUI::runSymbolReels() so that it rolls each reel usingsome dummy arguments.

    CChheecckkppooiinntt:: ccoommpp iillee aanndd rruunn yyoouurr aapppp lliiccaattiioonn ttoo cchheecckk tthhaatt rroo lllliinngg tthhee

    rreeee llss wwoorrkkss aass eexxppeecctteedd..

    Optional

    5. If you have time at the end of the exercise, you can already implement a piece of functionality neededin the next exercise.

    Make your SymbolReel emit a signal reelRollFinished() once it is has stopped rolling the reel. This wayyour JackpotUI class can observe when the reels have finished and react to it.

    For example; if the player wins, the win animation is shown only after the reels have all stopped.

    Furthermore, buttons on the UI could now be disabled whilst the reels are rolling and enabled once therolling has finished.

    Note: if each reel emits the same signal that leads to the same slot in your JackpotUI, you will getthree consecutive slot function calls. How would you be able to tell when your slot function has beencalled three times?

    An example solution to this, although not a very scalable one, can be found in the solution of the nextexercise: Exercises/Exercises/Exercises/Exercises/ex6_solex6_solex6_solex6_sol.

  • 8/8/2019 QtExercises

    20/22

    Qt for Mobile developers, Exercise Book 20

    Exercise 6: Finishing the Application Engine Integration

    Objectives

    - To integrate the engine to the UI partOverview

    Exercise starting point:

    Your own solution to exercise 5 or the example solution in Exercises/Exercises/Exercises/Exercises/exexexex5555_sol_sol_sol_sol.

    Templates used in the exercise:

    Exercises/templates/Exercises/templates/Exercises/templates/Exercises/templates/exexexex6666

    Exercise example solution:

    Exercises/ex6_solExercises/ex6_solExercises/ex6_solExercises/ex6_sol

    Your Jackpot UI written in Qt is now fully implemented. Next you will combine the UI with a ready-madeengine class.

    Practical Outline

    1. From the folder Exercises/templates/ex6Exercises/templates/ex6Exercises/templates/ex6Exercises/templates/ex6 you will find a class JackpotEngine. Add thesefiles to your project.

    2. You will need to modify your JackpotUI and SymbolReel classes to utilize the wrapper class:a. In JackpotUI, declare and implement a private function and a member variable:

    void initEngine();JackpotEngine* m_engine;

    Call initEngine() from initGraphicsView(), right after the loadPixmaps() function call.InitEngine() should:

    I. Initialize m_engine, giving the correct values for the constructorII. Call JackpotEngineWrapper::setBet(..) with suitable arguments,

    III. Set the correct value to ui.creditsLcd.In initGraphicsView(), pass m_engine also to the SymbolReels constructor (you will need to

    modify the constructor accordingly).Remember to delete m_engine in JackpotUIs destructor!

    b. Using the functionality provided by JackpotEngine, you should now be able to finalize yourJackpotUI class.

    Note: if you did not implement the optional part in exercise 5, do it now. In case the playerwins, you will need to implement a callback mechanism so that the SymbolReel class caninform JackpotUI once the reel roll animations have all finished and the win animation can thusbe run.

    c. SymbolReel class only needs to use JackpotEngine in one place: when the lock() function iscalled on the reel.

    d. The betSliders signal was earlier connected to the betDisplayLabels slot during the UI designphase. To actually enable changing the bet, implement a new slot in your JackpotUI class andconnect the betSliders signal to this slot as well.

    CChheecckkppooiinntt:: ccoommpp iillee aanndd rruunn yyoouurr ffuunnccttiioonnaall JJaacckkppoott ggaammee!!

  • 8/8/2019 QtExercises

    21/22

    Qt for Mobile developers, Exercise Book 21

    Exercise 7: QtWebKit

    Objectives

    Learn the use of the most important classes of QtWebKit module.

    ReferencesExercise starting point:

    Exercises/Templates/ex7Exercises/Templates/ex7Exercises/Templates/ex7Exercises/Templates/ex7

    Exercise example solution:

    Exercises/ex7_solExercises/ex7_solExercises/ex7_solExercises/ex7_sol

    Overview

    Your task is to create an application that shows thumbnail images of a few web pages so that those pages canbe launched in a bigger web view for browsing.

    Practical Outline

    1. Open the exercise starting point in Qt Creator, build and run. You will see a main window with twogroup boxes the left one will contain web page thumbnails and right one will contain the bigger webview used for browsing.

    2. Open WebPageThumbnail.hWebPageThumbnail.hWebPageThumbnail.hWebPageThumbnail.h and notice that it is actually just a QLabel that will eventually display aQPixmap thumbnail of the given web page. Take a look at this classs constructor implementation tosee that for now it simply displays the given URL the thumbnail functionality will be added later.

    3. Lets start by adding a few more UI elements and thumbnail stubs to the application manually. InBrowserMainWindows constructor, implement TODOs 1-4.

    CChheecckkppooiinntt:: BBuu iilldd aanndd rruunn ttoo tteesstt tthhaatt tthhee ppaaggee aaccttiioonnss aanndd tthhee UURRLL lliinneeeeddiitt wwiiddggeett aarree vviiss iibb llee iinn tthhee ttooooll bbaarr,, aanndd tthhaatt tthhee tthhuummbbnnaaiill lliisstt sshhoowwss

    tthhee tthhuummbbnnaaiillss yyoouu ccrreeaatteedd ((aatt tthh iiss ss ttaaggee jjuuss tt tthhee UURRLL)) ..

    4. Next you will modify WebPageThumbnail implementation so that it actually contains a thumbnailimage. To do this,

    a. Take a proper look at the WebPageThumbnail.h header file to see what kind of functionalitythe class contains especially signals, slots, and member variable m_page.

    b. Implement TODOs in WebPageThumbnail::render() function. This function is the one thatcreates and displays the thumbnail.

    Hint: You can find a similar example in QWebPages documentation in Qt Assistant. Thatexample uses a QImage to create a thumbnail into a .png image; here you will just use a

    QPixmap and the label itself (WebPageThumbnail) to show the thumbnail image!

    c. Implement TODOs 1-3 in WebPageThumbnails constructor. Notice how the slotWebPageThumbnail::pageLoadProgress() is implemented to show the load progressinformation.

    CChheecckkppooiinntt:: RRuunn ttoo tteesstt tthhaatt wweebb ppaaggee tthhuummbbnnaaiillss aanndd llooaadd pprrooggrreessss aarree sshhoowwnn ccoorrrreeccttllyy..

    5. When a thumbnail is double-clicked on the left group box, the web page in question should be shownin the right hand sides QWebView widget.

  • 8/8/2019 QtExercises

    22/22

    Qt for Mobile developers, Exercise Book 22

    a. Notice that WebPageThumbnail reimplements QLabels mouseDoubleClickEvent() eventhandler function, because by default QLabel ignores double-click events. Take a look at theimplementation it simply emits a signal with the URL shown by the thumbnail.

    b. Implement TODO 5 in BrowserMainWindows constructor, as well as the related slotBrowserMainWindow::showWebPage().

    Note: Function showWebPage() is also called at the end of the constructor, meaning that nowthat it is implemented, the default page will become visible even without double-clicking anythumbnail.

    CChheecckkppooiinntt:: RRuunn ttoo tteesstt tthhaatt ddoouubb llee--cclliicckkiinngg aa tthhuummbbnnaaiill wwiillll ddiisspp llaayy tthhee ccoorrrreecctt wweebb ppaaggee iinn tthhee mmaaiinn wweebb vviieeww oonn tthhee rriigghhtt..

    6. To let the user manually enter a URL in the line edit widget in the toolbar, implement TODO 6 inBrowserMainWindows constructor, as well as the related slot BrowserMainWindow::urlEdited().

    Note: Notice that the URL the user enters must contain the prefix http:// as well, QUrl does not addit to a URL string automatically.

    7. The toolbar in UI contains a reload action button added in step 3. When this action is selected by theuser, the main view automatically reloads its web page. To make the thumbnails refresh as well at thesame time, implement TODO 7 in BrowserMainWindows constructor and the related slotWebPageThumbnail::refresh().

    8. For monitoring main web views load progress and finishing, implement TODO 8 inBrowserMainWindows constructor, as well as the related slotBrowserMainWindow::webViewLoadFinished().

    BrowserMainWindow::webViewLoadProgress() has already been implemented, take a look how.

    CChheecckkppooiinntt:: RRuunn aanndd tteess tt yyoouurr ffiinn iisshheedd aapppplliiccaattiioonn!! NNoottiiccee eessppeecciiaa llllyy hhoowwtthhee BBaacckk aanndd FFoorrwwaarrdd aaccttiioonnss wwoorrkk aanndd hhooww pprrooggrreessss iinn ffoorrmmaattiioonn iiss ddiisspp llaayyeedd..