QT – Introduction C++ GUI Programming with Qt 4 Blanchette and Summerfield, Ch. 1 Miller, 2004.
-
Upload
zechariah-currier -
Category
Documents
-
view
245 -
download
0
Transcript of QT – Introduction C++ GUI Programming with Qt 4 Blanchette and Summerfield, Ch. 1 Miller, 2004.
QT – Introduction
C++ GUI Programming with Qt 4Blanchette and Summerfield, Ch. 1
Miller, 2004
Overview
• About UI programming systems, or toolkits– View hierarchy, stroke drawing, pixel model, input handling, widgets– They are all alike and all different
• A software layer
• Qt, as software layer “above” Windows api, provides a different view– Makes most day to day things easier
• “Slots” and “signals” for event handling and inter-dialog communication
• Widget styles– Window system native, or common across platforms
• Qt ide and resources
About UI Programming Systems
• UI programming systems, or “toolkits”, consist of these elements– E.g., MS windows (below), Swing (AWT for Java), Motif (X-windows), Qt (cross-
platform
• Components (view hierarchy)– Windows and child windows
• Stroke drawing package– GDI
• Pixel model– Bitmaps
• Input handling– Messages sent to a window procedure
• Widgets– Buttons, menus, text boxes
Examples
MS Windows Swing HTML Qt
Components Windows JComponents Elements Windows
Strokes GDI Graphics (none) Graphics
Pixels Bitmaps Image Inline images Images
Input Messages -> window proc
Listeners Javascript event handlers
Connections and slots
Widgets Button, menu, textbox, …
Jbutton, Jmenu, …
Form controls, links
Button, …
• All programming systems have these basic elements
Widgets
• Widget: again, “window gadget” (Qt), etc.– Controls, interactors, gizmos, gadgets
• At core of Qt programming paradigm
• Reusable user interface components
• Examples– Buttons, checkboxes, radio buttons– List boxes, combo boxes, drop-downs– Menus, toolbars– Scrollbars, splitters, zoomers– One-line text, multiline text, rich text– Trees, tables– Simple dialogs
Widgets
• Success (or unsuccess) story for user interface programming
• Advantages– Reuse of development effort
• Coding, testing, debugging, maintenance• Design, iteration and evaluation
– External consistency
• Disadvantages– Constrain designer’s thinking– Encourage menu & forms style, rather than richer direct manipulation style– May be used inappropriately
• E.g., instructions in title bar
– Is WIMP all there is?– Long record of mediocre (but not really bad) interfaces
Widget Data
• Data used in widgets
• Embedded model– Application data must be copied into the widget– Changes must be copied out’
• Linked model– Or, data binding– Application provides model satisfying an interface– Enables “data-bound” widgets, e.g. a table showing thousands of database rows,
or a combo box with thousands of choices
UI Toolkits
Athena Motif GTK+ Qt
XLib
• Often built on top of other toolkits
• Can provide cross-platform portability
• May add more powerful features• E.g., X Windows• XLib provides view hierarchy, stroke drawing, input handling• Xlib not provide widgets• Toolkits do
UI Toolkits - Qt
Qt
MS Windows XLib Mac
• Cross-platform portability• Re-implements native system look and feel• Or, can have (program) internal consistency
• Extends widget set, e.g., spin boxes
• Qt provides C++, Java, and Python language bindings
• Also, allows direct access to other sw api’s/layers, e.g., OpenGL
• As well as, allows direct access to MS Windows API• But, is much more efficient to program in
• Remember this?
Qt is easy …in many ways
Hello World 1: ~60 lines –WinMain HELLOWIN.C – Petzold --- (main just sets things up – quite a few things – very low level)
#include <windows.h>LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{ static TCHAR szAppName[] = TEXT ("HelloWin") ; HWND hwnd ; MSG msg ; WNDCLASS wndclass ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance = hInstance ; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ; wndclass.lpszClassName = szAppName ;
if (!RegisterClass (&wndclass)) {
MessageBox (NULL, TEXT ("This program requires Windows NT!"), szAppName, MB_ICONERROR) ; return 0 ;
} (cont’d)
Microsoft Windows
program
start
me
ssages
WinMain()- initialization- define windows- create windows- message loop
WindowProc()- process messages
Windows API
Windows Application
API Calls
Old Familiar WinMain (cont’d)
hwnd = CreateWindow (szAppName, // window class name TEXT ("The Hello Program"), // window caption WS_OVERLAPPEDWINDOW, // window style CW_USEDEFAULT, // initial x position CW_USEDEFAULT, // initial y position CW_USEDEFAULT, // initial x size CW_USEDEFAULT, // initial y size NULL, // parent win handle
NULL, // window menu handle hInstance, // prog inst handle NULL) ; // creation parameters
ShowWindow (hwnd, iCmdShow) ; UpdateWindow (hwnd) ;
while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ;
} return msg.wParam ;
}
Microsoft Windows
program start
messages
WinMain()- initialization- define windows- create windows- message loop
WindowProc()- process messages
Windows API
Windows Application
API Calls
Hello World: WinProc, the Message Handler
Note similarity to paradigm message handler of any event driven architecture:
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, L… lParam){
HDC hdc ; PAINTSTRUCT ps ; RECT rect ;
switch (message) { case WM_CREATE:
PlaySound (TEXT("hellowin.wav"), NULL, SND_FILENAME | SND_ASYNC) ;
return 0 ;
case WM_PAINT: // “window redraws itself!” hdc = BeginPaint (hwnd, &ps) ; GetClientRect (hwnd, &rect) ; DrawText (hdc, TEXT ("Hello, Windows 98!"), -1, &rect,
DT_SINGLELINE | DT_CENTER | DT_VCENTER) ; EndPaint (hwnd, &ps) ;
return 0 ;
case WM_DESTROY: PostQuitMessage (0) ;
return 0 ; }
return DefWindowProc (hwnd, message, wParam, lParam) ; // DefWindProc handles all message not handled in WndProc}
Microsoft Windows
program
start
me
ssages
WinMain()- initialization- define windows- create windows- message loop
WindowProc()- process messages
Windows API
Windows Application
API Calls
LOTS of “Windows functions” Calls Windows Function Calls
HELLOWIN - 18 Windows functions: LoadIcon Loads an icon for use by a program.
• LoadCursor Loads a mouse cursor for use by a program.
• GetStockObject Obtains a graphic object, in this case a brush used for painting the window's background.
• RegisterClass Registers a window class for the program's window.
• MessageBox Displays a message box.
• CreateWindow Creates a window based on a window class.
• ShowWindow Shows the window on the screen.
• UpdateWindow Directs the window to paint itself.
• GetMessage Obtains a message from the message queue.
• TranslateMessage Translates some keyboard messages.
• DispatchMessage Sends a message to a window procedure.
• PlaySound Plays a sound file.
• BeginPaint Initiates the beginning of window painting.
• GetClientRect Obtains the dimensions of the window's client area.
• DrawText Displays a text string.
• EndPaint Ends window painting.
• PostQuitMessage Inserts a "quit" message into the message queue.
• DefWindowProc Performs default processing of messages.
Hello, Qt!
Hello, Qt!9 lines!
#include <QApplication>
#include <QLabel>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QLabel *label = new QLabel("Hello Qt!");
label->show();
return app.exec();
}
• A bit for dramatic effect, but there will be advantages• Just a label in a field with no real “main window”
• Will look at some basics tonight• Slots and signals (vs. event queues), and layouts (this is a GUI builder),
Hello, Qt!the details
#include <QApplication> // Definitions of QApplication and
#include <QLabel> // QLabel classes
// Qt is truly object-oriented
int main(int argc, char *argv[])
{
QApplication app(argc, argv); // Creates a QApplication object to
// manage app-wide resources
QLabel *label = new QLabel("Hello Qt!"); // Creates a QApplication widget (used as
// a window) that displays string
label->show(); // Make label (window) visible
return app.exec(); // Passes control to Qt
} // (would also delete QLabel)
Handling Events: Signals and Slots
• Qt not handle events (or event queue) directly
• Qt widgets emit signals when user action or change of state occurs
• Signal can be connected to a function, or slot– When signal emitted the slot, or function, is executed
• In example, will connect button’s clicked signal to slot, the function quit()– quit() is “built-in” QApplication function (object)
A Signal and A Slot
#include <QApplication> // Include class definitions
#include <QPushButton>
int main(int argc, char *argv[])
{
QApplication app(argc, argv); // Create QApplication object
QPushButton *button = new QPushButton("Quit"); // Create labeled button
// Associate (connect) a particular signal of this application with a slot
QObject::connect ( button, SIGNAL(clicked()), &app, SLOT(quit()) );
button->show();
return app.exec(); // Pass control to QT
}
Synchronization & Layout of 2 WidgetsBook example – can be complex
• Example code creates three widgets:– QSpinbox, QSlider, QWidget (application’s main window, will be parent of others)
• Using signals and slots of the QSpinbox and QSlider, set value of one depending on value set in the other
– E.g., change spinbox value to 70, slider will move to appropriate position– Change slider to some position, spinbox value will be changed based on position
• “Layout manager” object will set size and position of widgets
“Setting up”, 1/3
#include <QApplication> // Include class definitions for
#include <QHBoxLayout> // layout,
#include <QSlider> // slider,
#include <QSpinBox> // and spinbox
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QWidget *window = new QWidget; // Again, window will be widget
window->setWindowTitle("Enter Your Age"); // Not good interface design!
Create & Synchronize Widgets, 2/3A little “tricky” …
QSpinBox *spinBox = new QSpinBox; // Create spinbox and slider
QSlider *slider = new QSlider(Qt::Horizontal);
spinBox->setRange(0, 130); // Set/define range of each
slider->setRange(0, 130);
// As before, a particular widget signal causes a function (slot) to be called
// here, when the value in the spinbox is changed, the function to set the value in the
// slider is called, and passed the new value of the spinbox to be the new value of the slider
QObject::connect(spinBox, SIGNAL(valueChanged(int)), slider, SLOT(setValue(int)));
// … and vice versa
QObject::connect(slider, SIGNAL(valueChanged(int)), spinBox, SLOT(setValue(int)));
spinBox->setValue(35); // Set initial value for spinbox, slider will then get set
Layout of Widgets by Qt, 3/3
// Qt manages the relative positioning of the child windows, here, as BoxLayout
QHBoxLayout *layout = new QHBoxLayout;
layout->addWidget(spinBox); // Place widgets in set to be
layout->addWidget(slider); // poistioned
window->setLayout(layout); // Installs layout manager on win
window->show();
return app.exec();
}
Widget Styles
• Recall, Qt is cross-platform
• Can have Qt applications in windowing system style where executed (external consistency) or in same style across windowing systems (internal consistency)
Qt IDE
• Works fine
Qt IDE
• Open project
• Open file
Help
• Works fine
Help
• Works fine
End
• .