CSCI 104 Qt Intro Mark Redekopp David Kempe
- Slides: 88
CSCI 104 Qt Intro Mark Redekopp David Kempe
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 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 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 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() 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 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? – 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 '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 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 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 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. 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. 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 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 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 – – – 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 – (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[]) { 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 – 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 – 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 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 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[]) { 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 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 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
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 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 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 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, 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 (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). © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 34
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
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, 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 39
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 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, 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 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 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 Ø 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 – 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 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 Ø 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 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 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 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 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. 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 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 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 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 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 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. 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 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
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; – 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
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 Ø 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. 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 Rights Reserved 68
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. 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, 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 ) { 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 (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 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 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 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 Reserved 77
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 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 ‘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 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 ) { //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, 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 Nash & Mark Redekopp, All Rights Reserved 84
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 ( 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 ‘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 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
- Csci 104
- Csci 104
- Xkcd tommy tables
- Mark redekopp
- Mark redekopp
- Mark redekopp
- Mark redekopp
- Mark redekopp
- Mark redekopp
- Mark redekopp
- Mark redekopp
- The ghost of thomas kempe comprehension answers
- Benjamin kempe
- The ghost of thomas kempe comprehension answers
- Kempe
- Lori kempe
- Game development lifecycle
- Cmsc 104 umbc
- Programa 104
- Lativ 104
- Mth104
- Odette
- Who is this
- Opw 687
- Gg-104
- Cct 104
- Aphorism 83 to 104
- Cao 104
- Cao 104 voorbeelden
- Kyrie eleison hakuna
- How to solve conversion problems
- I 102 104
- Daily104
- Cs 104
- 104-r planned academic worksheet
- Tel 104
- Penny 4x102 b1
- Psalm 23 nbv
- Quien invento el primer teclado
- 101 102 103 104 105 106 107 108 109 110
- 240-104
- Sum 104 kg
- Give two examples from lines 26-31 that juliet
- Lcm of 7 8 11 12
- 50000/104
- Grupo gerdau
- Legge 104
- Ps 104
- Art 104 tuf
- Rue amelot paris
- Psalm 22 nbv
- P 104
- Psak 104
- Jumlah kelereng doni dan fajar 48
- Mark david chapman catcher in the rye
- Csci 4211
- Csci 530
- Csci 530 security systems
- Csci 530 security systems
- Csci430
- Contoh knapsack problem
- Major minor patch build
- Scott warfield ucf
- Csci 1951a
- Csci 2670
- Csci 2670
- Maria hybinette
- Csci 5551
- Csci 513 usc
- Fun2data
- Csci 201
- Csci 2720
- Reva freedman
- Csci3160
- Csci 3160
- Csci 2670
- Csci 2141
- Csci 572
- Csci e-20
- Csci 530 usc
- Csci 5922
- Csci 5922
- Csci 3160
- Cyk algorithm
- Formal language
- Csci3130
- Csci 3130
- Csci-b 551 elements of artificial intelligence
- Usc csci 201