Presentation is loading. Please wait.

Presentation is loading. Please wait.

CSCI 104 Qt Intro Mark Redekopp David Kempe. 2 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved Qt  What is QT? –Pronounced “cute” –An.

Similar presentations


Presentation on theme: "CSCI 104 Qt Intro Mark Redekopp David Kempe. 2 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved Qt  What is QT? –Pronounced “cute” –An."— Presentation transcript:

1 CSCI 104 Qt Intro Mark Redekopp David Kempe

2 2 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 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 v4.8.1

3 3 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved QApplication  Every major QT widget has its own header –See QPushButton in the example  QApplication –The main class that controls all the default GUI behavior and manages application 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 #include int main(int argc, char *argv[]) { QApplication app(argc, argv); QPushButton button("Hello world!"); button.show(); return app.exec(); }

4 4 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved QPushButton  QPushButton –A button object that you can click on  QPushButton 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 are all kinds of button function/display attributes we could set if we really wanted to Color, Size, Text/Image, Animation, Border, etc. #include int main(int argc, char *argv[]) { QApplication app(argc, argv); QPushButton button("Hello world!"); button.show(); return app.exec(); }

5 5 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 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) Some widgets are merely containers for other widgets (i.e. a display grid that display other widgets in some tabular format) #include int main(int argc, char *argv[]) { QApplication app(argc, argv); QPushButton button("Hello world!"); button.show(); return app.exec(); }

6 6 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved Event-Driven Program Flow  return app.exec(); –At this point, main() passes control to the QT framework –exec() will not return until the window is terminated  Question? –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(), mouseOver(), …) –More on this later... #include int main(int argc, char *argv[]) { QApplication app(argc, argv); QPushButton button("Hello world!"); button.show(); return app.exec(); }

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

8 8 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved Compiling Qt Applications  We can't just type 'g++ -o qtex 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'

9 9 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 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

10 10 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 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 Makefile files 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.

11 11 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 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

12 12 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 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.

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

14 14 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved Container Examples Group BoxesTabbed Displays Scrolled DisplaysFrames Images from http://doc.trolltech.com/4.3/gallery-macintosh.html

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

16 16 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 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

17 17 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 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

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

19 19 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved Layout Example Code #include int main(int argc, char *argv[]) { QApplication app(argc, argv); QWidget *window = new Qwidget; QPushButton *button1 = new QPushButton("One"); QPushButton *button2 = new QPushButton("Two"); QPushButton *button3 = new QpushButton("Three"); QHBoxLayout *layout = new QHBoxLayout; layout->addWidget(button1); layout->addWidget(button2); layout->addWidget(button3); window->setLayout(layout); window->show(); return app.exec(); } Code from http://qt.nokia.com/doc/4.5/layout.html

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

21 21 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 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

22 22 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 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 never need to know about each other! –Widgets emit signals whether or not any other widgets are listening e.g. QPushButton has a clicked() signal –Widgets slots listen for signals whether or not there are any being emitted A slot is just a normal class member function! e.g. Create a widget with a handleClick() slot

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

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

25 25 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 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 QPushButton)  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

26 26 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved Qt Tutorial  A set of 14 example QT tutorials can all be found online here: http://doc.qt.digia.com/4.3/tutorial.htmlhttp://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://doc.qt.digia.com/stable/ –http://qt-project.org/doc/qt-4.8/http://qt-project.org/doc/qt-4.8/  Other resources –http://www.zetcode.com/gui/qt4/http://www.zetcode.com/gui/qt4/

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

28 28 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved Download the Code  $ mkdir lec_ttt  $ cd lec_ttt  $ wget http://ee.usc.edu/~redekopp/cs102/ttt_qt.tarhttp://ee.usc.edu/~redekopp/cs102/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

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

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

31 31 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 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)

32 32 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 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 GridLayout component which controls the display of the tic-tac- toe grid  finished() signal (no definition) –Signals have no definitions in a.cpp file –Notice the emit statement in  Connecting the clicks on buttons via buttonClicked –Notice the many-to-one relationship of TTT_Button::clicked() to TTT_Board::buttonClicked() –Look at buttonClicked() how do we determine which button was actually clicked?  updateButtons –Notice setEnabled() call…What does that do?

33 33 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 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)  QVBoxLayout –Each widgeth is added via addWidget and gets slotted vertically  QLabel: On screen text  QComboBox –Items have an ID and a display string usually –Selected value from the user can be obtained with currentIndex()  QPushButton –Notice we connect the signals and slots (some from TTT_Board, others from ourselves (i.e. TTT) )  newState() controls the string printed on the status label

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

35 35 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved Graphics Example  Go to your Qt examples directory  $ mkdir ex11  $ cd ex11  $ wget http://ee.usc.edu/~redekopp/cs102/ex11.tarhttp://ee.usc.edu/~redekopp/cs102/ex11.tar  $ tar xvf ex11.tar  $ qmake –project  $ qmake  $ make  $./ex11  Examine the code and walkthrough at the URL below –http://doc.qt.digia.com/4.3/tutorial-t11.htmlhttp://doc.qt.digia.com/4.3/tutorial-t11.html

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

37 37 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 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.

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

39 39 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved QMainWindow Layout

40 40 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved MenuBar in QMainWindow  A QMenuBar already exists in QMainWindow. You don’t make one.  To get a reference to it (from a class that inherits QMainWindow, just call the menuBar() method. –QMenuBar *mb = menuBar();  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.

41 41 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved Setting Up Menus  The code below gets the QMenuBar object from a class that inherits from QMainWindow  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 exitFunction(). We must implement this function.  For each action in a menu, you repeat the last 3 lines. QMenuBar *mb = menuBar(); fileMenu = new QMenu("File“, this); mb->addMenu(fileMenu); QAction *exitAction = new QAction( "Exit", this ); fileMenu->addAction( exitAction ); connect(exitAction, SIGNAL(triggered()), this, SLOT(exitFunction()));

42 42 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved Toolbars with QMainWindow  Unlike the menu bar section of a QMainWindow, Qt does not automatically make a QToolBar 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.

43 43 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 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.

44 44 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 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.

45 45 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved Proper Toolbar with Qt  Create a new class that inherits from QToolBar  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 PA4, 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.

46 46 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved QToolBar with QMainWindow  In the class that inherits from QToolBar –Create one QAction object for each “button” –Add each QAction to this class with addAction –Have one connect statement for each QAction QAction *startGameAction = new QAction( "Start Game", this ); addAction( startGameAction ); connect( startGameAction, SIGNAL( triggered() ), this, SLOT( startGame() )));

47 47 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved Getting Started on PA4  If you haven’t started. Start with the code we gave you for lab 9. –Change MainWindow class to another class name. Have it inherit from QGraphicsView, not QWidget  Create a new MainWindow class that inherits from QMainWindow  Create an instance of your QGraphicsView class in the MainWindow constructor and put it into the Central Widget with the setCentralWidget 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.

48 48 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved PA4 Step 3  Create a new class that inherits from QToolBar  Create the 3 actions that you need and connect each of them to a method to handle the action

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

50 50 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved QDockWidgets  In the QMainWindow layout scheme, there are 4 areas that immediately surround the Central Widget area. These are QDockWidgets.  QDockWidgets must be assigned to one of the four locations –Qt::TopDockWidgetArea, Qt::BottomDockWidgetArea, Qt::LeftDockWidgetArea, Qt::RightDockWidgetArea  QDockWidgets have their own layout, that you cannot change. You must create a separate class that inherits from QWidget that you add to a QDockWidget object to be able to lay out your UI components in the way you want.

51 51 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved PA4 Example - QLineEdits  In PA4, you must have three text fields to replace the three command line arguments from PA3. The QLineEdit class is handy for single-line user input.  QLineEdit 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 QLineEdit objects - QFormLayout

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

53 53 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved Show me the Code! layout = new QFormLayout(); setLayout( layout ); sizeEdit = new QLineEdit(); startMovesEdit = new QLineEdit(); randomSeedEdit = new QLineEdit(); layout->addRow( “Board Size:", sizeEdit ); layout->addRow( “Starting Moves:"), startMovesEdit ); layout->addRow( “Random Seed Value:"), randomSeedEdit );

54 54 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved Adding my QWidget to the Dock  The last step is to create an instance of our new class and add it to the QDockWidget that we want.  In the example below, this variable is uiWindow.  We do this in our class that inherits from QMainWindow  The setFeatures method turns off the user’s ability to close our dock widget, or make it a separate window. QDockWidget *qdw = new QDockWidget(); qdw->setWidget( uiWindow ); addDockWidget(Qt::LeftDockWidgetArea, qdw ); qdw->setFeatures(QDockWidget::NoDockWidgetFeatures);

55 55 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved PA4 Step 1 – From Lab 9  Rename MainWindow from Lab 9 to a new class that inherits from QGraphicsView – instead of QWidget. Do not create a QGraphicsView in this class – since it is one.  Create an instance of this class in your new MainWindow class that inherits from QMainWindow  Add this graphic window object to the Central Widget area in your new MainWindow class with the setCentralWidget method

56 56 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved PA4 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 PA3. 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 mousePressEvent method to your GUITile class so that the user can play the game using the mouse

57 57 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved PA4 Step 2 Continued  The mousePressEvent 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

58 58 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved PA4 Step 2 Continued  For the mousePressEvent 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

59 59 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved Show me the Code!  Let’s say my graphic window class is called GraphicWindow. My variable in GUITile is called gWindow  In this class, I have a method moveTile that knows how/when to move a tile. This must be called from the mousePressEvent method in GUITile to get a tile moved, or not. void GUITile::mousePressEvent ( QGraphicsSceneMouseEvent* event ) { gWindow->moveTile( this ); }

60 60 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved PA4 – 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 QLineEdit objects – use QFormLayout –One class for the QToolBar – the 3 “buttons” you need –One class for the 2 QRadioButton objects – use QHBoxLayout, or QVBoxLayout, depending on which dock widget you use –One class for the QListWidget (holds A* results)

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

62 62 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved Layouts  We've seen different layouts –QVBoxLayout –QHBoxLayout –QFormLayout  Each widget (or derived class) can have only one Layout –Set by calling: widget->setLayout(pointer to the layout) method  But a layout may contain either widgets or OTHER LAYOUTS in each of its entries –Set by calling: layout->addLayout(pointer to child layout) –Set by calling: layout->addWidget(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

63 63 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved More Notes  Widgets have a virtual function sizeHint() –Qsize sizeHint() 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::sizeHint() 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 pre- connected to certain actions/signals) –Just override them and usually call the BaseClass version

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

65 65 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 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.

66 66 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved Images in Qt  A convenient class for images is QGraphicsPixmapItem  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  QGraphicsPixmapItem objects can be created and passed a QPixmap object. This is what you will display. QPixmap: Reads an image…Do this once QGraphicsPixmapItem: Create as many as you want passing a pointer to the QPixMap to each

67 67 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved QGraphicsPixmapItem  You add these to your scene just like QGraphicsRectItem and QGraphicsSimpleTextItem – addItem method  You move them just like QGraphicsSimpleTextItem – setPos 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 QGraphicsPixmapItem object through the setPixmap method

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

69 69 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 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!!!!

70 70 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 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!

71 71 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved Create an Abstract Superclass class Thing: public QGraphicsPixmapItem { 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 vX; int vY; QPixmap *pixMap; //Good idea. Explain later. }; //Every ‘thing’ needs this. You may want even more inherited here

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

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

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

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

76 76 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 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.

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

78 78 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved QMouseEvents  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 repaintEvent for TTTButtons)  You used the mousePressEvent method in PA4. You can use this for your game in PA5  What if you want to “follow” the mouse cursor?  Use the mouseMoveEvent  Your mouse event methods belong to your GraphicWindow class or some other QGraphicsItem or QWidget derived object

79 79 © 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 –keyPressEvent() or keyReleaseEvent()  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.

80 80 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 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 QMainWindow) –You can set the focus on this main window so that it will receive the keyPressEvents() –This object is the entire GUI window. This means it has focus all the time, except when the cursor is in a QLineEdit, or QTextEdit field, or equivalent type of GUI component.

81 81 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved Show me the code! class MainWindow: public QMainWindow { Q_OBJECT //Any class that uses events, signals/slots must have this protected: void keyPressEvent( QKeyEvent *e ); //You’ll certainly have other stuff here!

82 82 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved More code void MainWindow::keyPressEvent( QKeyEvent *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

83 83 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 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. QMainWindow inheriting class) you MUST add one more statement to your constructor: setFocus()  This will ensure the non-alphanumeric keys will work as soon as your program starts.

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

85 85 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 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: collidesWithItem() 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

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

87 87 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved 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.

88 88 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved PA4 versus PA 5  If you created a GraphicWindow class and put it in your central widget window in PA4, you are in good shape for PA5.  All you need to do is change your GraphicWindow 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 GraphicWindow class


Download ppt "CSCI 104 Qt Intro Mark Redekopp David Kempe. 2 © Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved Qt  What is QT? –Pronounced “cute” –An."

Similar presentations


Ads by Google