340 likes | 358 Views
Department of Computer and Information Science, School of Science, IUPUI. Introduction to Visual Programming. Dale Roberts, Lecturer Computer Science, IUPUI E-mail: droberts@cs.iupui.edu. Event Driven Processing. Application Level Programmer
E N D
Department of Computer and Information Science,School of Science, IUPUI Introduction to Visual Programming Dale Roberts, Lecturer Computer Science, IUPUI E-mail: droberts@cs.iupui.edu
Event Driven Processing Application Level Programmer Uses widget sets and style guidelines to create application GUIs. Examples: Motif, MFC, Qt, GTK, etc. Graphical Systems Programmer Person who implements the widget sets and windowing systems above User You! Qt
Programming Paradigms By now, you have been exposed to two programming paradigms: • Functional Programming • Object-oriented Programming Can you explain their differences in terms of: • How to decompose a problem? • How to express control?
Functional Decomposition • How do to decompose a problem? • Top-down functional decomposition approach. • Step-wise refinement • Successive versions of algorithms written in pseudo-code • Problem is divided into smaller subproblems • Each “decomposition” is a function call. • Keep decomposing until functions are close enough to target language to code. • How do you express control? • Each step is a function call. • Flow of control statements are used within functions
Object-Oriented Design • How do to decompose a problem? • Bottom-up building block approach. • Identify objects needed to solve the problem. • Create an Abstract Data Type implemented with objects • Identify how values are represented in private data members. • Define operations that act upon values as public member functions. • Encapsulate implementation details within the class. • How do you express control? • Use UML to define relationships between classes. • Flow-of-control between classes is relatively unstructured. • Must still define a client that uses classes to solve a problem. • Client is usually responsible for user-interaction, not classes. • Stratifies application into presentation, processing, and data layers.
Event-driven Programming • Event-driven programming is the standard approach to creating graphical user interfaces (GUIs) • An event-driven program is object-oriented • Object-oriented programming was originally development to implement graphical objects within GUI operating systems • Although object-oriented, flow-of-control is sufficiently different that we are going to classify it as a different paradigm that extends OOP. • However, top-level control is expressed differently • The user is the top-level loop • Think of Word, or a game program • Every action in your program is a reaction to the user • Decompose program in terms of “what will I do if the user does…” • User inaction may trigger background actions (e.g. games)
Detecting Asynchronous Events • Polling • Repeatedly read input devices in an infinite loop • Interrupt-driven • Hardware-triggered context-switching in response to user-events • Event-driven • Explicit event waiting • Call-back functions (i.e. signals) in response to user events Qt uses event-driven processing.
Method #1 Polling Interaction is governed by a simple loop: Loop forever: { read input respond to input } What limitations does this have? Does it have any advantages?
Method #2 Interrupt-driven Processing • Enable device, then • proceed with “background” processing until an interrupt is received, at which point • Save state (context-switch) • Respond to input • Restore state and go to step #2. What advantages/disadvantages does this have?
Method #3: Event-driven Processing Interaction is once again governed by a loop: Loop forever: { if (event) then respond else do (one unit of) background processing or go to sleep (for one unit) }
Event-driven Processing (cont) • All major GUI packages (Motif, MGC, Qt, GTK, Java AWT, …) are event driven. • Why? • More portable than interrupt-driven.At the expense of what? • More efficient than polling • most do have polling commands • Can rely on operating system to do time-slicing • context-switching is very hardware/operating system specific.
Events / Signals • Any event-driven graphics package has devices that can signal events • In old standards, this was limited to hardware devices • In newer packages (e.g. Qt), any widget can signal events; the (hardware) mouse is the same as a (software) slider or button. • Generally, the event tells you • Which device/widget signaled the event • Some “measure” giving the new state • E.g., whether a mouse button was depressed or released Warning: old systems tend to use the term “events” while newer systems may call them signals (e.g. Qt)
Callback Function • One of the most feared and hackish aspects of GUI programming has always been the dreaded callback-function. • A register table for widget (e.g. Motif) - no type checking - example: • quit = XtVaCreateManagedWidget(……); • tAddCallback( quit, XmNactivateCallback, QuitCallback, NULL); • void QuitCallback( Widget w, XtPointer, clientData, XtPointer callData);
Callback Function • Virtual function (e.g. wxWindows) - too many classes need to inherit for all widgets - high dependence between GUI and kernel of application - would be slower in a inefficient vtable • Macro (e.g. MFC、OWL) - message map was complicated and difficult to coding - need additional preprocessor, IDE or application builder
Event Handling • QT's new approach: signals and slots • A widget sends out various signals • Object methods can be declared as slots • Compatible signals and slots can be connected or plugged together like a telephone switchboard (parameter types must match) • Strict separation • This strict separation between UI components and program elements lends itself to component-based programming • Goal: separate UI from program logic
Signals and Slots clicked_method()
Signals and Slots (cont) • advantage: - independent interface - type-safe - process transparence • disadvantage: - not as fast as a direct function pointer call. ( A signal triggering a slot has been measured to approximately 50 microseconds on a SPARC2. )
Signals and Slots(cont) 1 class PixmapRotator : public QWidget { 2 Q_OBJECT 3 public: 4 PixmapRotator(QWidget *parent=0, const char *name=0); 5 public slots: 6 void setAngle(int degrees); 7 signals: 8 void angleChanged(int); 9 private: 10 int ang; 11 }; 12 void PixmapRotator::setAngle( int degrees ) { 13 degrees = degrees % 360; // keep in range <-360, 360> 14 if(ang == degrees) 15 return; // actual state change? 16 ang = degrees; // a new angle 17 emit angleChanged(ang); // tell world ... 18 } 19 QObject::connect(scrollBar, SIGNAL(valueChanged(int)), rotator, SLOT(setAngle(int)));
Signals and Slots(cont) • Qt meta object compiler (moc) - It parses C++ header files and generates C++ code necessary for Qt to handle signals and slots. The signals, slots and emit keywords are macros, so the compiler preprocessor changes or removes them. • How to do? 1. moc –o moc_file.moc moc_file.cpp moc_file.h 2. #include “moc_file.moc” Fortunately, the Qt utility qmake takes care of all this.
qmake • The qmake utility is typically invoked with the following three commands] qmake –project qmake make (or nmake under Windows) • Rules: • Be sure to place code in its own directory. • qmake scans all subdirectories for dependencies. Do not place archive version under a “save” subdirectory. • If you reorganize your files, like adding a new .h, delete all the .pro and other working files, then start over.
Defining Signals and Slots • New C++ syntax for defining signals and slots, added to public, private, etc. class myClass : public Qobject { Q_OBJECT //required macro, no semicolon … signals: void somethingHappened(); … public slots: void slotDoSomething(); … private slots: void slotDoSomethingInternal(); … };
Events • Signals: emit events • declare as signals, otherwise normal member functions • You don't implement them. Rather, you send them with the (new) keyword emit • E.g. emit(sliderChanged(5)) • Slots: receive and handle events • Normal member functions declared as slots • Connect: must connect signals to slots • QObject::connect( mymenu, SIGNAL(activated(int)), myobject, SLOT(slotDoMenuFunction(int)) ); • moc: meta object compiler (preprocessor) converts these new keywords to real C++
Widgets • Base class for all UI widgets • Properties • width, height, backgroundColor, font, mouseTracking, backgroundPixmap, etc. • Slots • repaint, show, hide, move, setGeometry, setMainWidget, etc. • Signals: • mouseMoveEvent, keyPressEvent, resizeEvent, paintEvent, enterEvent, leaveEvent, etc.
Qt, a GUI toolkit • Events processed with signals and slots • signal generates an event, e.g., button push • slot processes the event, e.g., pop up a file dialog box QPushButton * quitB = new QPushButton(“Quit”,...,...); • connect (quitB, SIGNAL(clicked()), qApp, SLOT(quit()); • qApp is a global variable, of type QApplication • one QApplication per program defined first in main() • main returns qApp.exec() • SIGNAL and SLOT are macros, expanded by a meta-object • compiler (moc) • moc generates .cpp files from user-defined Qt subclasses
Other Features of Qt • The Qt Paint Engine • QPainter is highly optimized and contains several caching mechanisms to speed up drawing. Under X11, it caches GCs (graphics contexts), which often make it faster than native X11 programs. • QPainter contains all the functionality one would expect from a professional 2D graphics library. The coordinate system of a QPainter can be transformed using the standard 2D transformations (translate, scale, rotate and shear). • Qt supports Open GL for 3D graphics. • Qt also contains a set of general purpose classes and a number of collection-classes to ease the development of multi-platform applications. • Qt has platform independent support for the operating system dependent functions, such as time/date, files/directories and TCP/IP sockets.
Call-back Functions / Slots • A call-back function is an application-specific function called in response to an event • In Qt, these are called “slots”, but this term is unique to Qt • Generally, the “measure” of the event is passed as an argument • The main loop of a GUI program is: • Wait for an event • Call the associated call-back function • Return to the top of the loop
GUI API Event Loops Loop forever: { if (input) then { find out which application receives the event; invoke the callback function; } else select one application with a background callback function; invoke background callback; }
Pick Correlation • The process of selecting which window (or application) an event belongs to is called pick correlation • Pick correlation is usually object-oriented: • Every window knows where its children are • children send parents a message when they move, etc. • The top-level window assigns events to children • Child processes may • handle the event through a call-back; or • ask their children “is this yours”?
Hiding the Main Loop • Modern widget packages (like Qt) hide the main loop from the programmer. • Programmers declare signals • i.e. what events to respond to • Programmers define slots • i.e. how to respond to events • Programmers connect signals to slots • The main loop (wait for signal / call slot / loop) is part of the widget package • Programmers call the main loop, but can’t alter it, other than through signals and slots
Example: A Main Loop in Qt int main (int argc, char* argv[]) { QApplication app( argc, argv); GUI main( &app, &state) app.setMainWidget( &main); main.Show(); return app.exec(); } Where’s the program? GUI is a widget. The GUI class defines signals and slots, and the GUI’s constructor connection them…
What (really) are widgets? • The objects in an object-oriented GUI are called widgets. • Every widget: • Knows its location (for pick correlation) • Knows whether of not its visible • Knows how to resize itself • Knows how to redraw itself • Knows its “children” widgets (if it’s a container) • Has call-back functions (slots) for handling events (signals) • Every window is a widget • Not all widgets are windows
Examples of widgets • Text editing windows (canvases) • Push buttons • Menus • Sliders • Radio buttons • LED displays • Borders
Building a GUI • Every application has a top-level widget • In Qt, the top-level widget is called QApplication • QApplication implements the main signal/slot loop • QApplication is a widget but not a window • QApplication in turn has a single top-level window • Inside is a hierarchy of lesser widgets: • frames, etc., for grouping and position widgets • low-level widgets:buttons, pop-up menus, etc. • Call-back functions (signals) are attached to implement responded to user actions • Events are passed by the OS to the application’s top-level widget.
Acknowledgements • Some of the slides were originally written by J. Ross Beveridge, updated by Dale Roberts.