CSCI 104 Qt Intro Mark Redekopp David Kempe

  • Slides: 88
Download presentation
CSCI 104 Qt Intro Mark Redekopp David Kempe

CSCI 104 Qt Intro Mark Redekopp David Kempe

Qt Ø What is QT? – Pronounced “cute” – An cross-platform application development framework

Qt Ø What is QT? – Pronounced “cute” – An cross-platform application development framework built by Nokia – A toolkit for building Graphical User Interfaces (GUIs) – GUI toolkits are composed of many classes including many widgets • "Widget" is GUI-lingo for a 'control' or graphical component that a user can interact with Ø QT has bindings available for many languages – C++, Python, Ruby, Java, etc. Ø We are using QT v 4. 8. 1 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 2

QApplication Ø Every major QT widget has its own header – See QPush. Button

QApplication Ø Every major QT widget has its own header – See QPush. Button in the example Ø QApplication #include <QApplication> #include <QPush. Button> int main(int argc, char *argv[]) { QApplication app(argc, argv); QPush. Button button("Hello world!"); – The main class that controls all the default button. show(); GUI behavior and manages application return app. exec(); } resources – Every QT GUI application must have a QApplication instance (and only one!) – QApplication parses the command line input and pulls out any display-related parameters – A QApplication must be created before any GUI-related features can be used © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 3

QPush. Button Ø QPush. Button – A button object that you can click on

QPush. Button Ø QPush. Button – A button object that you can click on Ø QPush. Button button("Hello World!"); – Creates a clickable button on the GUI – We can only do this now that we already created a QApplication to handle all the backend stuff – The button is clickable just by nature – The button will have the text “Hello World” on it – There all kinds of button function/display attributes we could set if we really wanted to #include <QApplication> #include <QPush. Button> int main(int argc, char *argv[]) { QApplication app(argc, argv); QPush. Button button("Hello world!"); button. show(); return app. exec(); } • Color, Size, Text/Image, Animation, Border, etc. © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 4

Display Widgets Ø button. show(); – Widgets are always invisible by default when they

Display Widgets Ø button. show(); – Widgets are always invisible by default when they are created, you must call show() to display them – Calling show() on a widget also calls show on all the widgets it contains (all of its children) #include <QApplication> #include <QPush. Button> int main(int argc, char *argv[]) { QApplication app(argc, argv); QPush. Button button("Hello world!"); button. show(); return app. exec(); } • Some widgets are merely containers for other widgets (i. e. a display grid that display other widgets in some tabular format) © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 5

Event-Driven Program Flow Ø return app. exec(); #include <QApplication> – At this point, main()

Event-Driven Program Flow Ø return app. exec(); #include <QApplication> – At this point, main() passes control #include <QPush. Button> to the QT framework int main(int argc, char – exec() will not return until the window { QApplication app(argc, is terminated *argv[]) Ø Question? argv); QPush. Button button("Hello world!"); button. show(); return app. exec(); – What happens to your code flow? } – How do you get any other code to run? – Welcome to the world of event-driven programs • You write code (member functions) that is 'automatically' called/executed when an event occurs (e. g. click(), resize(), mouse. Over(), …) – More on this later. . . © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 6

End Result Ø All of this results in… #include <QApplication> #include <QPush. Button> int

End Result Ø All of this results in… #include <QApplication> #include <QPush. Button> int main(int argc, char *argv[]) { QApplication app(argc, argv); QPush. Button button("Hello world!"); button. show(); return app. exec(); } © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 7

Compiling Qt Applications Ø We can't just type 'g++ -o qtex. cpp'. Why? –

Compiling Qt Applications Ø We can't just type 'g++ -o qtex. cpp'. Why? – We have external dependencies that aren't part of standard C++ – How will the compiler find the QT. h files? – How will the linker find the QT compiled code? – QT has to build Meta-Objects to handle communication between GUI pieces – The individual. cpp files need to compile and link separately in some cases Ø 'make' and 'qmake' to the rescue – We've seen 'make' which helps us specify dependencies, compile order, and compiler commands – 'qmake' will examine code in the current directory and help to automatically generate a 'Makefile' © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 8

3 -Step Qt Compiler Process Ø Step 1: Generate a Qt project file with

3 -Step Qt Compiler Process Ø Step 1: Generate a Qt project file with 'qmake' – $ qmake –project – The command will make Qt examine all the source code in the current directory and make a platform-independent project file (with a. pro extension) that specifies dependencies between your. h and. cpp files Ø Step 2: Generate the platform dependent Makefile – $ qmake – This command will make QT read the. pro file from the current directory and generate a Makefile that contains all the commands for compiling the code and linking it with the QT libraries Ø Step 3: Run 'make' – $ make – If you have any compiler or linker errors, this is the step in the process where you will see them – If you only need to recompile, you only need to use this particular step of the 3 step process © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 9

Qt Compilation Notes Ø Keep each project in a separate directory (this is why

Qt Compilation Notes Ø Keep each project in a separate directory (this is why we can run qmake with no arguments) Ø If you add new. h or. cpp files, you need to re-run the entire compilation process (i. e. Make new. pro and Makefiles again) Ø If your object needs slots or signals, then you MUST put it into separate. h and. cpp files Ø If you're getting weird linker errors, try make clean or try rebuilding the. pro file and the Makefile Ø You may notice that when you compile some projects with QT, it actually generate extra. cpp files – These extra files are generated by QT's moc (Meta Object Compiler) – QT makes extensive use of the preprocessor to generate code that makes things like its signals and slots mechanisms work – Don't bother changing these files. They'll just get overwritten next time you compile. © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 10

Qt Organization Ø For your programming purposes, the QT windowing framework consists of three

Qt Organization Ø For your programming purposes, the QT windowing framework consists of three major parts (in reality, it's MUCH more complicated than this): – Widgets – Layouts – Signals & Slots © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 11

Qt Widgets Ø What is a widget? – A user interface object that can

Qt Widgets Ø What is a widget? – A user interface object that can process input, emit signals and draw graphics – A widget can be styled to have a vastly different appearance than its default – Most widgets generate signals that can be received by pieces of your code called slots Ø QT comes pre-packaged with a ton of pre-made widgets to suit most of your GUI-building needs – Buttons, Containers, Menus, etc. © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 12

Qt Button Examples Push Buttons Tool Buttons Checkboxes Radio Buttons Images from http: //doc.

Qt Button Examples Push Buttons Tool Buttons Checkboxes Radio Buttons Images from http: //doc. trolltech. com/4. 3/gallery-macintosh. html © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 13

Container Examples Group Boxes Tabbed Displays Frames Scrolled Displays Images from http: //doc. trolltech.

Container Examples Group Boxes Tabbed Displays Frames Scrolled Displays Images from http: //doc. trolltech. com/4. 3/gallery-macintosh. html © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 14

User Input Widget Examples Text Entry Combo Boxes Sliders Spin Boxes Calendars Images from

User Input Widget Examples Text Entry Combo Boxes Sliders Spin Boxes Calendars Images from http: //doc. trolltech. com/4. 3/gallery-macintosh. html © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 15

Qt Layouts Ø What is a layout? – A layout describe how widgets are

Qt Layouts Ø What is a layout? – A layout describe how widgets are organized and positioned in a user interface Ø The jobs of a QT layout – – Positioning of widgets in GUI Choosing sensible default and minimum sizes Handling window resize events Automatic updates when content changes • Font size, text or other widget changes • Add or removal of new widgets • Showing and hiding of existing widgets © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 16

More About Layouts Ø QT layouts and widgets share numerous parent/child relationships – –

More About Layouts Ø QT layouts and widgets share numerous parent/child relationships – – – Widgets can contain other widgets Widgets can have layouts Layouts can contain widgets Layouts can contain other layouts There can be a gigantic graph of parent and child relationships in a GUI Ø The best way to make a complex layout is usually to combine many simpler layouts Ø FYI: Getting a layout right is HARD © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 17

Sample Layouts Ø QVBox. Layout – Layout all children in a vertical column –

Sample Layouts Ø QVBox. Layout – Layout all children in a vertical column – (top to bottom or bottom to top) Ø QHBox. Layout – Layout all children in a horizontal row – (left to right or right to left) © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 18 Images from http: //qt. nokia. com/doc/4. 5/layout. html

Layout Example Code #include <QApplication> #include <QPush. Button> int main(int argc, char *argv[]) {

Layout Example Code #include <QApplication> #include <QPush. Button> int main(int argc, char *argv[]) { QApplication app(argc, argv); QWidget *window = new Qwidget; QPush. Button *button 1 = new QPush. Button("One"); QPush. Button *button 2 = new QPush. Button("Two"); QPush. Button *button 3 = new Qpush. Button("Three"); QHBox. Layout *layout = new QHBox. Layout; layout->add. Widget(button 1); layout->add. Widget(button 2); layout->add. Widget(button 3); window->set. Layout(layout); window->show(); return app. exec(); } © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 19 Code from http: //qt. nokia. com/doc/4. 5/layout. html

More Layouts Ø QGrid. Layout – Layout widgets in a 2 D grid –

More Layouts Ø QGrid. Layout – Layout widgets in a 2 D grid – Widgets can span multiple rows/columns Ø QForm. Layout – Layout children in a 2 -column descriptive label-field style. © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 20 Images from http: //qt. nokia. com/doc/4. 5/layout. html

Event-Based Programming Ø GUI-based programs follow a different paradigm than basic command line programs

Event-Based Programming Ø GUI-based programs follow a different paradigm than basic command line programs – The window will sit there indefinitely until the user does something – Your code no longer functions on line-by-line flow, it is triggered by events Ø In QT, all widgets are capable of firing events and receiving events – – Signals are used to notify (emit) widgets of an event Slots are used to receive (listen for) widget events connect is used to tie together a signal & a slot Signals & slots can have M-to-N connections © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 21

Qt Signals and Slots Ø Signals and Slots provide communication between various object in

Qt Signals and Slots Ø Signals and Slots provide communication between various object in your application – Often when one widget changes, you need another widget to know about it Ø A signal emitter and a slot receiver need to know about each other! – Widgets emit signals whether or not any other widgets are listening • e. g. QPush. Button has a clicked() signal – Widgets slots listen for signals whether or not there any being emitted • A slot is just a normal class member function! • e. g. Create a widget with a handle. Click() slot © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 22

QT Signals & Slots Image © Copyright 2013 Brent Nash & Mark Redekopp, All

QT Signals & Slots Image © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 23 from http: //doc. trolltech. com/4. 6/signalsandslots. html

Qt Signal/Slot Example #include <QApplication> #include <QPush. Button> int main(int argc, char *argv[]) {

Qt Signal/Slot Example #include <QApplication> #include <QPush. Button> int main(int argc, char *argv[]) { QApplication app(argc, argv); QPush. Button button("QUIT"); //connect(object 1 pointer, object 1 signal, // object 2 pointer, object 2 slot) QObject: : connect(&button, SIGNAL(clicked()), &app, SLOT(quit())); button. show(); return app. exec(); } © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 24 Code from http: //qt. nokia. com/doc/4. 5/layout. html

QT Signals & Slots Summary Ø Using event-driven programming in QT involves three major

QT Signals & Slots Summary Ø Using event-driven programming in QT involves three major parts: Ø 1. A widget with a SIGNAL to emit events when they occur (e. g. clicked() on QPush. Button) Ø 2. A widget with a SLOT to receive events that have been emitted (e. g. quit() on QApplication) Ø 3. A connect statement to wire the signal and slot together so that when the signal is emitted, the slot receives it © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 25

Qt Tutorial Ø A set of 14 example QT tutorials can all be found

Qt Tutorial Ø A set of 14 example QT tutorials can all be found online here: http: //doc. qt. digia. com/4. 3/tutorial. html or http: //web. njit. edu/all_topics/Prog_Lang_Docs/html/qt/tutorial. html Ø Official? Qt Page – http: //doc. qt. digia. com/stable/ – http: //qt-project. org/doc/qt-4. 8/ Ø Other resources – http: //www. zetcode. com/gui/qt 4/ © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 26

NEXT PART © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 27

NEXT PART © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 27

Download the Code Ø Ø Ø $ mkdir lec_ttt $ cd lec_ttt $ wget

Download the Code Ø Ø Ø $ mkdir lec_ttt $ cd lec_ttt $ wget http: //ee. usc. edu/~redekopp/cs 102/ttt_qt. tar $ tar xvf ttt_qt. tar Look up instructions on the 3 steps from our previous Qt lecture to setup and build/compile the project © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 28

Overall structure Ø TTTButton models a single square in the grid and contains its

Overall structure Ø TTTButton models a single square in the grid and contains its type: Blank, Circle, Cross Ø TTTBoard models the Nx. N tic-tac-toe grid Ø TTT models the other controls of the game and UI © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 29

TTTButton Ø Is a derived Push. Button Ø TTTButton models a single square in

TTTButton Ø Is a derived Push. Button Ø TTTButton models a single square in the grid and contains its type: Blank, Circle, Cross – set. Type() calls repaint() – Repaint() triggers paint. Event() which TTTButton overrides Ø Examine TTTButton: : paint. Event() – What if we don't call the base class version or change the ordering? © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 30

Q_OBJECT macro Ø Helps Qt preprocessor define the. moc files (meta-objects) – If your

Q_OBJECT macro Ø Helps Qt preprocessor define the. moc files (meta-objects) – If your class derives from a Qt widget/other GUI control or uses signals and slots you should place it in the definition Ø Declare on a line (w/o a semicolon to follow) © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 31

TTTBoard Ø Is derived from QWidget (because it contains other widgets, receives user input,

TTTBoard Ø Is derived from QWidget (because it contains other widgets, receives user input, and needs to be drawn/painted) Ø Stores the TTT buttons and implements the move AI and win/lose/draw logic Ø Examine Grid. Layout component which controls the display of the tic-tactoe grid Ø finished() signal (no definition) – Signals have no definitions in a. cpp file – Notice the emit statement in Ø Connecting the clicks on buttons via button. Clicked – Notice the many-to-one relationship of TTT_Button: : clicked() to TTT_Board: : button. Clicked() – Look at button. Clicked() how do we determine which button was actually clicked? Ø update. Buttons – Notice set. Enabled() call…What does that do? © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 32

TTT Ø Models the overall UI and main window Ø Is derived from QWidget

TTT Ø Models the overall UI and main window Ø Is derived from QWidget (because it contains other widgets, receives user input, and needs to be drawn/painted) Ø QVBox. Layout – Each widgeth is added via add. Widget and gets slotted vertically Ø QLabel: On screen text Ø QCombo. Box – Items have an ID and a display string usually – Selected value from the user can be obtained with current. Index() Ø QPush. Button – Notice we connect the signals and slots (some from TTT_Board, others from ourselves (i. e. TTT) ) Ø new. State() controls the string printed on the status label © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 33

main Ø Instantiates a TTT widget and shows it (then enters the execution loop).

main Ø Instantiates a TTT widget and shows it (then enters the execution loop). © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 34

Graphics Example Ø Ø Ø Ø Ø Go to your Qt examples directory $

Graphics Example Ø Ø Ø Ø Ø Go to your Qt examples directory $ mkdir ex 11 $ cd ex 11 $ wget http: //ee. usc. edu/~redekopp/cs 102/ex 11. tar $ tar xvf ex 11. tar $ qmake –project $ qmake $. /ex 11 Examine the code and walkthrough at the URL below – http: //doc. qt. digia. com/4. 3/tutorial-t 11. html © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 35

© Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 36

© Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 36

GUI Applications Ø Are quite different from command-line applications – Users have far more

GUI Applications Ø Are quite different from command-line applications – Users have far more control over what happens next – Our code must be “ready” to handle what the user wants to do next • • Execute a menu Button gets clicked Text typed into a text field And so on Ø This makes GUI applications Event Based – An event is started by something with the hardware: keyboard, mouse, etc. Ø And complex in how things are “laid out”. We have menus, buttons, text fields, lists, combo boxes, etc. © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 37

GUI and Qt Ø To ease the pain of laying out a nice looking

GUI and Qt Ø To ease the pain of laying out a nice looking GUI, Qt has a very handy class called QMain. Window. It contains: – – A place for menus A tool bar A status bar 5 locations for more complex widgets © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 38

QMain. Window Layout © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved

QMain. Window Layout © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 39

Menu. Bar in QMain. Window Ø A QMenu. Bar already exists in QMain. Window.

Menu. Bar in QMain. Window Ø A QMenu. Bar already exists in QMain. Window. You don’t make one. Ø To get a reference to it (from a class that inherits QMain. Window, just call the menu. Bar() method. – QMenu. Bar *mb = menu. Bar(); Ø You add QMenu objects to the menu bar. They are laid out from left to right. Ø You add QAction objects to menus. They are laid out from top to bottom. Ø You use the connect() method to connect a QAction to a method to handle the action for when the menu item is clicked on with the mouse. © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 40

Setting Up Menus Ø The code below gets the QMenu. Bar object from a

Setting Up Menus Ø The code below gets the QMenu. Bar object from a class that inherits from QMain. Window Ø It creates one menu – a ‘file’ menu Ø It adds one action to that menu – an ‘exit’ action Ø It connect the exit action to the slot function exit. Function(). We must implement this function. Ø For each action in a menu, you repeat the last 3 lines. QMenu. Bar *mb = menu. Bar(); file. Menu = new QMenu("File“, this); mb->add. Menu(file. Menu); QAction *exit. Action = new QAction( "Exit", this ); file. Menu->add. Action( exit. Action ); connect(exit. Action, SIGNAL(triggered()), this, SLOT(exit. Function())); © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 41

Toolbars with QMain. Window Ø Unlike the menu bar section of a QMain. Window,

Toolbars with QMain. Window Ø Unlike the menu bar section of a QMain. Window, Qt does not automatically make a QTool. Bar object. Ø Tool bars are essentially a place for a set of buttons Ø They are laid out horizontally. Ø Because tool bars are meant to be a place for buttons, you don’t have to create button objects. You create QAction objects directly and add them to the toolbar. Ø It’s like the menu bar, but you don’t have to make QMenu objects. © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 42

Good GUI Program Organization Ø Up to 80% of code in a GUI program

Good GUI Program Organization Ø Up to 80% of code in a GUI program is just for creation of GUI objects, laying them out, and getting them displayed so they look nice. Ø For each UI component, you must create it, add it to a layout, possibly add an action, and connect the action to a method. Ø That’s up to 4 lines of code for a single UI component – like a button. Ø In addition, different parts of our application screen need to be laid out differently – some horizontally, some vertically, etc. © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 43

Good GUI Program Organization Ø The best way to build any GUI application, is

Good GUI Program Organization Ø The best way to build any GUI application, is to have each different part of the UI window be a separate class. Ø Each class has its own layout, it also handles any signals/slots that it contains. Ø It has a pointer to the class that created it so it can pass responsibility for some tasks to the “boss” class. © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 44

Proper Toolbar with Qt Ø Create a new class that inherits from QTool. Bar

Proper Toolbar with Qt Ø Create a new class that inherits from QTool. Bar Ø Put your actions in this class Ø Put the connect statements for each action in this class Ø Put the methods for each connect statement in this class Ø For PA 4, you need 3 buttons – start game, quit game, run A*. That can be 3 QAction objects with 3 connect statements, and 3 methods for handling the actions. © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 45

QTool. Bar with QMain. Window Ø In the class that inherits from QTool. Bar

QTool. Bar with QMain. Window Ø In the class that inherits from QTool. Bar – Create one QAction object for each “button” – Add each QAction to this class with add. Action – Have one connect statement for each QAction *start. Game. Action = new QAction( "Start Game", this ); add. Action( start. Game. Action ); connect( start. Game. Action, SIGNAL( triggered() ), this, SLOT( start. Game() ))); © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 46

Getting Started on PA 4 Ø If you haven’t started. Start with the code

Getting Started on PA 4 Ø If you haven’t started. Start with the code we gave you for lab 9. – Change Main. Window class to another class name. Have it inherit from QGraphics. View, not QWidget Ø Create a new Main. Window class that inherits from QMain. Window Ø Create an instance of your QGraphics. View class in the Main. Window constructor and put it into the Central Widget with the set. Central. Widget method Ø Compile and run your code. You should see the bouncing rectangle in the middle of the window. You may have to resize the window to see it. © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 47

PA 4 Step 3 Ø Create a new class that inherits from QTool. Bar

PA 4 Step 3 Ø Create a new class that inherits from QTool. Bar Ø Create the 3 actions that you need and connect each of them to a method to handle the action © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 48

QMain. Window Central Widget Ø This is to be the main screen in a

QMain. Window Central Widget Ø This is to be the main screen in a Qt GUI application Ø For PA 4, this is going to be your ‘graphics’ window, where your puzzle game will be displayed and users will ‘play’ it. © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 49

QDock. Widgets Ø In the QMain. Window layout scheme, there are 4 areas that

QDock. Widgets Ø In the QMain. Window layout scheme, there are 4 areas that immediately surround the Central Widget area. These are QDock. Widgets. Ø QDock. Widgets must be assigned to one of the four locations – Qt: : Top. Dock. Widget. Area, Qt: : Bottom. Dock. Widget. Area, Qt: : Left. Dock. Widget. Area, Qt: : Right. Dock. Widget. Area Ø QDock. Widgets have their own layout, that you cannot change. You must create a separate class that inherits from QWidget that you add to a QDock. Widget object to be able to lay out your UI components in the way you want. © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 50

PA 4 Example - QLine. Edits Ø In PA 4, you must have three

PA 4 Example - QLine. Edits Ø In PA 4, you must have three text fields to replace three command line arguments from PA 3. The QLine. Edit class is handy for single-line user input. Ø QLine. Edit text fields need a prompt to tell the user what the text field is for. You cannot assume the user knows what a given text field is for Ø Qt provides a very nice layout for QLine. Edit objects - QForm. Layout © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 51

Using QForm. Layout Ø Like any other “screen” you will want to create a

Using QForm. Layout Ø Like any other “screen” you will want to create a new class that inherits from QWidget Ø In the constructor, create a QForm. Layout object (it needs to be an instance variable of the class) Ø Create each of the QLine. Edit objects Ø For each “row” you use the add. Row method of the layout © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 52

Show me the Code! layout = new QForm. Layout(); set. Layout( layout ); size.

Show me the Code! layout = new QForm. Layout(); set. Layout( layout ); size. Edit = new QLine. Edit(); start. Moves. Edit = new QLine. Edit(); random. Seed. Edit = new QLine. Edit(); layout->add. Row( “Board Size: ", size. Edit ); layout->add. Row( “Starting Moves: "), start. Moves. Edit ); layout->add. Row( “Random Seed Value: "), random. Seed. Edit ); © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 53

Adding my QWidget to the Dock Ø The last step is to create an

Adding my QWidget to the Dock Ø The last step is to create an instance of our new class and add it to the QDock. Widget that we want. Ø In the example below, this variable is ui. Window. Ø We do this in our class that inherits from QMain. Window Ø The set. Features method turns off the user’s ability to close our dock widget, or make it a separate window. QDock. Widget *qdw = new QDock. Widget(); qdw->set. Widget( ui. Window ); add. Dock. Widget(Qt: : Left. Dock. Widget. Area, qdw ); qdw->set. Features(QDock. Widget: : No. Dock. Widget. Features); © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 54

PA 4 Step 1 – From Lab 9 Ø Rename Main. Window from Lab

PA 4 Step 1 – From Lab 9 Ø Rename Main. Window from Lab 9 to a new class that inherits from QGraphics. View – instead of QWidget. Do not create a QGraphics. View in this class – since it is one. Ø Create an instance of this class in your new Main. Window class that inherits from QMain. Window Ø Add this graphic window object to the Central Widget area in your new Main. Window class with the set. Central. Widget method © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 55

PA 4 Step 2 Ø Replace the bouncing rectangle code in your graphic window

PA 4 Step 2 Ø Replace the bouncing rectangle code in your graphic window class with code to create a solved puzzle – Don’t worry about a 9 -tile, or a 16 -tile puzzle, yet. Just ensure you can create a puzzle and have it displayed in the central widget Ø Integrate the code to scramble the puzzle from PA 3. This requires moving the tiles to the proper locations – Compile and run the code. Make sure you graphically moved the tiles correctly. Ø Now you are ready to add the mouse. Press. Event method to your GUITile class so that the user can play the game using the mouse © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 56

PA 4 Step 2 Continued Ø The mouse. Press. Event method is in your

PA 4 Step 2 Continued Ø The mouse. Press. Event method is in your GUITile class. Ø The GUITile class knows only about a single GUITile Ø It doesn’t know if a tile can be moved, or not Ø The responsibility for “knowing” if a move is valid is in your graphic window class Ø This means the GUITile class must pass the responsibility for handling a mouse click, on a GUITile, to the graphic window class © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 57

PA 4 Step 2 Continued Ø For the mouse. Press. Event method in the

PA 4 Step 2 Continued Ø For the mouse. Press. Event method in the GUITile class to call a method of the graphic window class, it must have a reference to that class Ø Pass the reference to graphic window to the constructor of GUITile Ø Create an instance variable pointer in GUITile to the graphic window object. Set the variable in the GUITile constructor © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 58

Show me the Code! Ø Let’s say my graphic window class is called Graphic.

Show me the Code! Ø Let’s say my graphic window class is called Graphic. Window. My variable in GUITile is called g. Window Ø In this class, I have a method move. Tile that knows how/when to move a tile. This must be called from the mouse. Press. Event method in GUITile to get a tile moved, or not. void GUITile: : mouse. Press. Event ( QGraphics. Scene. Mouse. Event* event ) { g. Window->move. Tile( this ); } © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 59

PA 4 – And Beyond Ø Create one class at a time for some

PA 4 – And Beyond Ø Create one class at a time for some of the UI components. Compile and test each class as you create them. Ø Consider the following class organization: – One class for the 3 QLine. Edit objects – use QForm. Layout – One class for the QTool. Bar – the 3 “buttons” you need – One class for the 2 QRadio. Button objects – use QHBox. Layout, or QVBox. Layout, depending on which dock widget you use – One class for the QList. Widget (holds A* results) © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 60

OTHER NOTES © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 61

OTHER NOTES © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 61

Layouts Ø We've seen different layouts – QVBox. Layout – QHBox. Layout – QForm.

Layouts Ø We've seen different layouts – QVBox. Layout – QHBox. Layout – QForm. Layout Ø Each widget (or derived class) can have only one Layout – Set by calling: widget->set. Layout(pointer to the layout) method Ø But a layout may contain either widgets or OTHER LAYOUTS in each of its entries – Set by calling: layout->add. Layout(pointer to child layout) – Set by calling: layout->add. Widget(pointer to the child widget) Ø So for each widget think about whether you want to add items vertically or horizontally and pick a Vbox or Hbox Layout and then add child layouts within that context © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 62

More Notes Ø Widgets have a virtual function size. Hint() – Qsize. Hint() const;

More Notes Ø Widgets have a virtual function size. Hint() – Qsize. Hint() const; – If you want your widget to start at a particular size, add this to your class and simply have it return a Qsize object which is just pixel rows x columns – Qsize MYCLASS: : size. Hint() const { return QSize(400, 400); } Ø Defining your own signals – – Signals go in the "signals: " section of your class They are just prototypes (you don't write an implementation) Use the 'emit' keyword followed by a "call" to this signal function Whatever slot has been connected to this signal will in turn be called Ø Events are not slots (think of them as "slots" that are preconnected to certain actions/signals) – Just override them and usually call the Base. Class version © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 63

© Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 64

© Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 64

PA 5 Ø PA 5 is the first of two assignments for creating a

PA 5 Ø PA 5 is the first of two assignments for creating a game in Qt Ø You are to have 5 types of ‘things’ in your game. – One does not have to move (walls, buildings, etc. ) – The movement behaviors MUST be different. Just moving faster/slower is not ‘different’. Ø To play your game, you can use the mouse, or the keyboard, or both. It is your choice. It is your game! Ø Each of your 5 things are to be displayed with images. No rectangles, ellipses, etc. Ø You are to have menus for starting a game, pausing a game, stopping a game, and quitting the program. Ø You are to have a ‘score’ for the player, and health/lives. © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 65

Images in Qt Ø A convenient class for images is QGraphics. Pixmap. Item Ø

Images in Qt Ø A convenient class for images is QGraphics. Pixmap. Item Ø Key: Loading an image, initially, from a file is SSSSLLLLOOOOWWW!!!! Ø You only want to read an image file once! Ø Displaying an image in a scene is separate from reading the image file. You can display the same image file in multiple locations. QPixmap is the class for reading an image file Ø QGraphics. Pixmap. Item objects can be created and passed a QPixmap object. This is what you will display. © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved QPixmap: Reads an image…Do this once QGraphics. Pixmap. Item: Create as many as you want passing a pointer to the QPix. Map to each 66

QGraphics. Pixmap. Item Ø You add these to your scene just like QGraphics. Rect.

QGraphics. Pixmap. Item Ø You add these to your scene just like QGraphics. Rect. Item and QGraphics. Simple. Text. Item – add. Item method Ø You move them just like QGraphics. Simple. Text. Item – set. Pos method – providing the x and y coordinates of the upper left corner Ø They contain a QPixmap object inside of them Ø You can assign a QPixmap object to a QGraphics. Pixmap. Item object through the set. Pixmap method © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 67

Tracking Items POLYMORPHISM & INHERITANCE © Copyright 2013 Brent Nash & Mark Redekopp, All

Tracking Items POLYMORPHISM & INHERITANCE © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 68

Here’s a possible game Ø There are 3 different ‘things’ shown Ø Some overlap

Here’s a possible game Ø There are 3 different ‘things’ shown Ø Some overlap – they have ‘collided’ Ø Do some ‘die’, or is it a good thing? How do we know they have collided? Ø We have to keep track of EVERY thing!!!! © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 69

Keeping Track of Things Ø You are to have 5 different types of things.

Keeping Track of Things Ø You are to have 5 different types of things. You will want 5 different classes for your things. Ø To keep track of them, you would need 5 different lists Ø Finding collisions means comparing the items in one list to each of the items in the other 4 lists. That’s multiple for loops. Ø Unless we use inheritance, virtual functions, and the benefit of polymorphism (many forms). Then we can do it with a single list! © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 70

Create an Abstract Superclass Thing: public QGraphics. Pixmap. Item { public: Thing (QPixmap *pm,

Create an Abstract Superclass Thing: public QGraphics. Pixmap. Item { public: Thing (QPixmap *pm, int nx, int ny); virtual void move() = 0; //virtual function. Class Thing is abstract. For a reason. private: //Every thing has a origin and a velocity – maybe 0 int x; int y; int v. X; int v. Y; QPixmap *pix. Map; //Good idea. Explain later. }; //Every ‘thing’ needs this. You may want even more inherited here © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 71

Thing Superclass Constructor Thing: : Thing( QPixmap* p, int nx, int ny ) {

Thing Superclass Constructor Thing: : Thing( QPixmap* p, int nx, int ny ) { pix. Map = p; //Handy to store separate to get image width/height, etc. set. Pixmap( *p ); //First Qt method that doesn’t take a pointer : -> x = nx; y = ny; set. Pos( x, y ); //how you set the position } © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 72

Create a Subclass from Thing class Big. Thing: public Thing { public: Big. Thing

Create a Subclass from Thing class Big. Thing: public Thing { public: Big. Thing (QPixmap *pm, int nx, int ny); void move(); // Implement the move method }; Big. Thing: : Big. Thing( QPixmap *pm, int nx, int ny ) : Thing( pm, nx, ny ) { //Any specific initialization code for Big. Thing goes here. } void Big. Thing: : move() { //Implement the movement behavior of Big. Thing here. This is required. } //You may need other methods © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 73

Create Another Subclass Small. Thing: public Thing { public: Small. Thing (QPixmap *pm, int

Create Another Subclass Small. Thing: public Thing { public: Small. Thing (QPixmap *pm, int nx, int ny); void move(); // Implement the move method }; Small. Thing: : Amall. Thing( QPixmap *pm, int nx, int ny ) : Thing( pm, nx, ny ) { //Any specific initialization code for Small. Thing goes here. } void Small. Thing: : move() { //Implement the movement behavior of Small. Thing here. This is required. } //You may need other methods © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 74

So what? Ø Big. Thing and Small. Thing are both Things. Yes? Ø That

So what? Ø Big. Thing and Small. Thing are both Things. Yes? Ø That means that we can have a single list that contains both Big. Things and Small. Things. Or can we? Ø How about his code? Vector<Thing*> my. Things; Big. Thing* b = new Big. Thing(); // Let’s pretend a default constructor my. Thing. push_back( b ); Small. Thing* s = new Small. Thing(); my. Thing. push_back( s); for ( int i=0; i<things. size(); i++ ) { things[i]. move(); //What move method gets called? } © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 75

Inheritance and Polymorphism Ø Without each Thing subclass inheriting from a single class, you

Inheritance and Polymorphism Ø Without each Thing subclass inheriting from a single class, you would have to have a different list for each of your types of things Ø With the virtual move function in the Thing superclass, when you iterate though your single list, the move method of the original subclass object will be called. Ø This saves a LOT of coding. © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 76

MOUSE & KEYBOARD EVENTS © Copyright 2013 Brent Nash & Mark Redekopp, All Rights

MOUSE & KEYBOARD EVENTS © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 77

QMouse. Events Ø Events are signals and slots that are already known to Qt

QMouse. Events Ø Events are signals and slots that are already known to Qt – Qt has connected the signal to a slot already – the event method – Event methods are not ‘public slot’ methods, they are usually 'protected' (or sometime 'public' methods) that your derived class can override – You must define them exactly. Qt will call them automatically. – Often want to call base class event method after your event processing (remember Tic-Tac-Toe repaint. Event for TTTButtons) Ø You used the mouse. Press. Event method in PA 4. You can use this for your game in PA 5 Ø What if you want to “follow” the mouse cursor? Ø Use the mouse. Move. Event Ø Your mouse event methods belong to your Graphic. Window class or some other QGraphics. Item or QWidget derived object 78 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved

Keyboard Events Ø Keyboard events work like mouse events Ø They have a predefined

Keyboard Events Ø Keyboard events work like mouse events Ø They have a predefined method you must overload – key. Press. Event() or key. Release. Event() Ø However, keyboard events are not connected to a particular window, like a mouse event – you didn’t click on something! – Keyboard events only work on a ‘window’ that has ‘focus’ – Mouse events always work, since you are ‘clicking’ on a particular widget. Qt knows which widget you wanted to do something with. © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 79

Keyboard Control and Focus Ø Key events only happen in the window that has

Keyboard Control and Focus Ø Key events only happen in the window that has ‘focus’ Ø You will want to define n window” / "parent" class to inherit from QWidget (or any other class that inherits from QWidget like QMain. Window) – You can set the focus on this main window so that it will receive the key. Press. Events() – This object is the entire GUI window. This means it has focus all the time, except when the cursor is in a QLine. Edit, or QText. Edit field, or equivalent type of GUI component. © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 80

Show me the code! class Main. Window: public QMain. Window { Q_OBJECT //Any class

Show me the code! class Main. Window: public QMain. Window { Q_OBJECT //Any class that uses events, signals/slots must have this protected: void key. Press. Event( QKey. Event *e ); //You’ll certainly have other stuff here! © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 81

More code void Main. Window: : key. Press. Event( QKey. Event *e ) {

More code void Main. Window: : key. Press. Event( QKey. Event *e ) { //We need to find out which key was pressed //Let’s say we want to use the 4 arrow keys switch ( e->key() ) { case Qt: : Key_Left : //Left arrow pushed – do the work case Qt: : Key_Right : //Right arrow pushed case Qt: : Key_Up : //Up arrow pushed case Qt: : Key_Down //Down arrow pushed } //There are “codes” for all possible keys in Qt © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 82

Last Keyboard Focus Issue Ø When Qt starts up, nothing has focus. Ø Interesting,

Last Keyboard Focus Issue Ø When Qt starts up, nothing has focus. Ø Interesting, that alphanumeric keys work, but arrow keys do not, if you do not set an initial focus Ø In your main window class (e. g. QMain. Window inheriting class) you MUST add one more statement to your constructor: set. Focus() Ø This will ensure the non-alphanumeric keys will work as soon as your program starts. © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 83

How to detect collision of QGraphics. Items WHEN ITEMS COLLIDE © Copyright 2013 Brent

How to detect collision of QGraphics. Items WHEN ITEMS COLLIDE © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 84

Collisions Matter Ø You may have: – Good things hit bad things – Good

Collisions Matter Ø You may have: – Good things hit bad things – Good things hit good things – help life, etc. – Bad things hurt/help bad things Ø It all comes down to collisions Ø How to know when a thing collides with a thing? – Simple: collides. With. Item() method – What’s the algorithm? • It depends. Is it all the “bad things” against the player? Or can a bad thing take away a good thing, so that the player cannot get it? – Worst case. Any ‘thing’ can interact with any other ‘thing’ • That’s O(n 2) – Best case. It’s the player against the ‘bad guy’ world © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 85

Worst Case Collisions Ø Any thing can interact with any other thing for (

Worst Case Collisions Ø Any thing can interact with any other thing for ( int i=0; i< things. size(); i++ ) { Thing* item. A = my. Things[i]; for ( int j=0; j< things. size(); j++ ) { Thing* item. B = my. Things[j]; if ( i == j ) { continue; //I can always collide with myself } if ( item. A. collides. With. Item( item. B) ) { //There is a collision. Handle it. } } } © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 86

You Against the World Ø If your game is the player against all the

You Against the World Ø If your game is the player against all the ‘bad things’ – You don’t need a double for loop. – You will compare the player against the list of things – A single for loop is all you need. © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 87

PA 4 versus PA 5 Ø If you created a Graphic. Window class and

PA 4 versus PA 5 Ø If you created a Graphic. Window class and put it in your central widget window in PA 4, you are in good shape for PA 5. Ø All you need to do is change your Graphic. Window class to be your game Ø You will need to change your dock widgets (or other control widgets), but that is a separate task from changing your Graphic. Window class © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 88