Qt in Education. The Qt object model and the signal slot concept



Similar documents
Surface and Volumetric Data Rendering and Visualisation

[PRAKTISCHE ASPEKTE DER INFORMATIK SS 2014]

Qt Signals and Slots. Olivier Goffart. October 2013

A Deeper Look at Signals and Slots

Variable Base Interface

The C Programming Language course syllabus associate level

First Java Programs. V. Paúl Pauca. CSC 111D Fall, Department of Computer Science Wake Forest University. Introduction to Computer Science

Qt Tips and Tricks. Integrated Computer Solutions Incorporated. Justin Noel and the ICS Team Oct 2010

INTRODUCTION TO OBJECTIVE-C CSCI 4448/5448: OBJECT-ORIENTED ANALYSIS & DESIGN LECTURE 12 09/29/2011

CORBA Programming with TAOX11. The C++11 CORBA Implementation

Best Practices in Qt Quick/QML. Langston Ball Senior Qt Developer ICS, Inc.

Network Programming in Qt. TCP/IP Protocol Stack

Computing Concepts with Java Essentials

Object-Oriented Design Lecture 4 CSU 370 Fall 2007 (Pucella) Tuesday, Sep 18, 2007

Java Interview Questions and Answers

Cross-platform C++ development using Qt

Java (12 Weeks) Introduction to Java Programming Language

Beginning Nokia Apps. Development. Qt and HTIVIL5 for Symbian and MeeGo. Ray Rischpater. Apress. Daniel Zucker

Mobile App Design Project #1 Java Boot Camp: Design Model for Chutes and Ladders Board Game

Building a Python Plugin

AP Computer Science Java Subset

C++FA 5.1 PRACTICE MID-TERM EXAM

Getting Started with the Internet Communications Engine

Visual Basic Programming. An Introduction

16 Collection Classes

Software documentation systems

New Qt APIs for Mobile Development. Mobility I Alex Blasche

A generic framework for game development

Andreas Burghart 6 October 2014 v1.0


KITES TECHNOLOGY COURSE MODULE (C, C++, DS)

Crash Course in Java

Storage Classes CS 110B - Rule Storage Classes Page 18-1 \handouts\storclas

Handout 1. Introduction to Java programming language. Java primitive types and operations. Reading keyboard Input using class Scanner.

Object Oriented Software Design II

Creating Carbon Menus. (Legacy)

: provid.ir

How To Port A Program To Dynamic C (C) (C-Based) (Program) (For A Non Portable Program) (Un Portable) (Permanent) (Non Portable) C-Based (Programs) (Powerpoint)

Qt/Embedded Whitepaper. Trolltech

PROBLEM SOLVING SEVENTH EDITION WALTER SAVITCH UNIVERSITY OF CALIFORNIA, SAN DIEGO CONTRIBUTOR KENRICK MOCK UNIVERSITY OF ALASKA, ANCHORAGE PEARSON

Textbook: T. Issariyakul and E. Hossain, Introduction to Network Simulator NS2, Springer

Event Log. Chapter 7 Event Log Event Log Management Excel Editing Create a New Event Log... 9

Practical Data Visualization and Virtual Reality. Virtual Reality VR Software and Programming. Karljohan Lundin Palmerius

core. Volume I - Fundamentals Seventh Edition Sun Microsystems Press A Prentice Hall Title ULB Darmstadt

CS 111 Classes I 1. Software Organization View to this point:

Object Oriented Software Design II

Glossary of Object Oriented Terms

Performance Improvement In Java Application

Boolean Expressions, Conditions, Loops, and Enumerations. Precedence Rules (from highest to lowest priority)

Java Application Developer Certificate Program Competencies

Application Note C++ Debugging

MPLAB Harmony System Service Libraries Help

An Overview of Java. overview-1

Android Application Development Course Program

Software Engineering Techniques

Extending Desktop Applications to the Web

Brent A. Perdue. July 15, 2009

Implementação. Interfaces Pessoa Máquina 2010/ Salvador Abreu baseado em material Alan Dix. Thursday, June 2, 2011

Parallelization: Binary Tree Traversal

Bypassing Browser Memory Protections in Windows Vista

Java CPD (I) Frans Coenen Department of Computer Science

Performance Analysis and Visualization of SystemC Models. Adam Donlin and Thomas Lenart Xilinx Research

Event Log. Chapter 7 Event Log Event Log Management Excel Editing Create a New Event Log... 10

El Dorado Union High School District Educational Services

PART IV Performance oriented design, Performance testing, Performance tuning & Performance solutions. Outline. Performance oriented design

C# Cookbook. Stephen Teilhet andjay Hilyard. O'REILLY 8 Beijing Cambridge Farnham Köln Paris Sebastopol Taipei Tokyo '"J""'

Third AP Edition. Object-Oriented Programming and Data Structures. Maria Litvin. Gary Litvin. Phillips Academy, Andover, Massachusetts

#820 Computer Programming 1A

C Programming Review & Productivity Tools

C++ Programming Language

Netscape Internet Service Broker for C++ Programmer's Guide. Contents

CS 141: Introduction to (Java) Programming: Exam 1 Jenny Orr Willamette University Fall 2013

MULTIPLE CHOICE. Choose the one alternative that best completes the statement or answers the question.

Sources: On the Web: Slides will be available on:

Crash course to. Qt Quick Game Programming

iphone Objective-C Exercises

Virtuozzo Virtualization SDK

Introducing Apache Pivot. Greg Brown, Todd Volkert 6/10/2010

Pemrograman Dasar. Basic Elements Of Java

Java the UML Way: Integrating Object-Oriented Design and Programming

Fundamentals of Java Programming

Intel EP80579 Software for Security Applications on Intel QuickAssist Technology Cryptographic API Reference

InTouch Example Description

Praktikum im Bereich Praktische Informatik Entwicklung eines Ray-Tracing Systems. computer graphics & visualization

Lecture 5: Java Fundamentals III

Tail call elimination. Michel Schinz

Logging. Working with the POCO logging framework.

Informatica e Sistemi in Tempo Reale

Free Java textbook available online. Introduction to the Java programming language. Compilation. A simple java program

The GenomeTools Developer s Guide

MICROSOFT OFFICE ACCESS NEW FEATURES

Chapter 5 Names, Bindings, Type Checking, and Scopes

CS506 Web Design and Development Solved Online Quiz No. 01

Free Java textbook available online. Introduction to the Java programming language. Compilation. A simple java program

RTAP Database Lifecycle Management

Lecture 1 Introduction to Android

language 1 (source) compiler language 2 (target) Figure 1: Compiling a program

Advanced Web Development SCOPE OF WEB DEVELOPMENT INDUSTRY

25 Writing a Graphical User Interface

Comp 411 Principles of Programming Languages Lecture 34 Semantics of OO Languages. Corky Cartwright Swarat Chaudhuri November 30, 20111

Transcription:

Qt in Education The Qt object model and the signal slot concept.

2010 Nokia Corporation and its Subsidiary(-ies). The enclosed Qt Educational Training Materials are provided under the Creative Commons Attribution-Non-Commercial-Share Alike 2.5 License Agreement. The full license text is available here: http://creativecommons.org/licenses/by-nc-sa/2.5/legalcode. Nokia, Qt and the Nokia and Qt logos are the registered trademarks of Nokia Corporation in Finland and other countries worldwide.

The QObject QObject is the base class of almost all Qt classes and all widgets It contains many of the mechanisms that make up Qt events signals and slots properties memory management

The QObject QObject is the base class to most Qt classes. Examples of exceptions are: Classes that need to be lightweight such as graphical primitives Data containers (QString, QList, QChar, etc) Classes that needs to be copyable, as QObjects cannot be copied

The QObject QObject instances are individuals! They can have a name (QObject::objectName) They are placed in a hierarchy of QObject instances They can have connections to other QObject instances Example: does it make sense to copy a widget at run-time?

Meta data Qt implements introspection in C++ Every QObject has a meta object The meta object knows about class name (QObject::className) inheritance (QObject::inherits) properties signals and slots general information (QObject::classInfo)

Meta data The meta data is gathered at compile time by the meta object compiler, moc. Ordinary C++ Build Process sources *.cpp compiles object files *.o links executables includes headers *.h

Meta data The meta data is gathered at compile time by the meta object compiler, moc. Qt C++ Build Process sources *.cpp compiles object files *.o links executables includes compiles headers *.h mocs generated moc_*.cpp The moc harvests data from your headers.

Meta data What does moc look for? Make sure that you inherit QObject first (could be indirect) The Q_OBJECT macro, usually first class MyClass : public QObject Q_OBJECT Q_CLASSINFO("author", "John Doe") public: MyClass(const Foo &foo, QObject *parent=0); Foo foo() const; General info about the class public slots: void setfoo( const Foo &foo ); Qt keywords signals: void foochanged( Foo ); private: Foo m_foo; };

Introspection The classes know about themselves at run-time if (object->inherits("qabstractitemview")) QAbstractItemView *view = static_cast<qabstractitemview*>(widget); view->... Enables dynamic casting without RTTI enum CapitalsEnum Oslo, Helsinki, Stockholm, Copenhagen }; int index = object->metaobject()->indexofenumerator("capitalsenum"); object->metaobject()->enumerator(index)->key(object->capital()); The meta object knows about the details Great for implementing scripting and dynamic language bindings Example:It is possible to convert enumeration values to strings for easier reading and storing

Properties QObject have properties with getter and setter methods Setter, returns void, takes value as only argument class QLabel : public QFrame Q_OBJECT Q_PROPERTY(QString text READ text WRITE settext) public: QString text() const; public slots: void settext(const QString &); }; Getter, const, returns value, takes no arguments Naming policy: color, setcolor For booleans: isenabled, setenabled

Properties Why setter methods? Possible to validate settings void setmin( int newmin ) if( newmin > m_max ) qwarning("ignoring setmin(%d) as min > max.", newmin); return; }... Possible to react to changes void setmin( int newmin )... } m_min = newmin; updateminimum();

Properties Why getter method? Indirect properties QSize size() const return m_size; } int width() const return m_size.width(); }

Properties Q_PROPERTY(type name READ getfunction [WRITE setfunction] [RESET resetfunction] [NOTIFY notifysignal] [DESIGNABLE bool] [SCRIPTABLE bool] [STORED bool] [USER bool] [CONSTANT] [FINAL])

Using properties Direct access QString text = label->text(); label->settext("hello World!"); Through the meta info and property system QString text = object->property("text").tostring(); object->setproperty("text", "Hello World"); Discover properties at run-time int QMetaObject::propertyCount(); QMetaProperty QMetaObject::property(i); QMetaProperty::name/isConstant/isDesignable/read/write/...

Dynamic properties Lets you add properties to objects at run-time bool ret = object->setproperty(name, value); true if the property has been defined using Q_PROPERTY false if it is dynamically added QObject::dynamicPropertyNames() const returns a list of the dynamic properties Can be used to tag objects, etc

Creating custom properties Macro describing the property class AngleObject : public QObject Q_OBJECT Q_PROPERTY(qreal angle READ angle WRITE setangle) public: AngleObject(qreal angle, QObject *parent = 0); qreal angle() const; void setangle(qreal); private: qreal m_angle; }; Private state Setter Getter Initial value

Creating custom properties AngleObject::AngleObject(qreal angle, QObject *parent) : QObject(parent), m_angle(angle) } qreal AngleObject::angle() const return m_angle; } void AngleObject::setAngle(qreal angle) } m_angle = angle; dosomething(); Getter simply returns the value. Here you can calculate complex values. Update internal state, then react to the change. Initial value

Custom properties - enumerations class AngleObject : public QObject Q_OBJECT Q_ENUMS(AngleMode) Q_PROPERTY(AngleMode anglemode READ...) Macro informing Qt that AngleMode is an enum type. Ordinary enum declaration. public: enum AngleMode Radians, Degrees}; };... Property using enum as type.

Memory Management QObject can have parent and children When a parent object is deleted, it deletes its children QObject *parent = new QObject(); QObject *child1 = new QObject(parent); QObject *child2 = new QObject(parent); QObject *child1_1 = new QObject(child1); QObject *child1_2 = new QObject(child1); delete parent; parent parent deletes child1 and child2 child1 deletes child1_1 and child1_2 child1 child1_1 child2 child1_2

Memory Management This is used when implementing visual hierarchies. QDialog *parent = new QDialog(); QGroupBox *box = new QGroupBox(parent); QPushButton *button = new QPushButton(parent); QRadioButton *option1 = new QRadioButton(box); QRadioButton *option2 = new QRadioButton(box); delete parent; parent deletes box and button box deletes option1 and option2

Usage Patterns Use the this-pointer as top level parent Dialog::Dialog(QWidget *parent) : QDialog(parent) QGroupBox *box = QGroupBox(this); QPushButton *button = QPushButton(this); QRadioButton *option1 = QRadioButton(box); QRadioButton *option2 = QRadioButton(box);... Allocate parent on the stack void Widget::showDialog() Dialog dialog; } if (dialog.exec() == QDialog::Accepted)... } dialog is deleted when the scope ends

Heap When using new and delete, memory is allocated on the heap. Heap memory must be explicitly freed using delete to avoid memory leaks. Objects allocated on the heap can live for as long as they are needed. new Construction Destruction delete

Stack Local variables are allocated on the stack. Stack variables are automatically destructed when they go out of scope. Objects allocated on the stack are always destructed when they go out of scope. int a Construction Destruction }

Stack and Heap To get automatic memory management, only the parent needs to be allocated on the stack. MyMainWindow QApplication int main(int argc, char **argv) QApplication a(argc, argv); MyMainWindow w; w.show(); return a.exec(); } MyMainWindow::MyMainWindow(... new QLabel(this); new... }

Changing Ownership QObjects can be moved between parents obj->setparent(newparent); The parents know when children are deleted delete listwidget->item(0); // Removes the first item (unsafe) Methods that return pointers and take releases data from its owner and leaves it in the takers care QLayoutItem *QLayout::takeAt(int); QListWidgetItem *QListWidget::takeItem(int); // Safe alternative QListWidgetItem *item = listwidget->takeitem(0); if (item) delete item; } List items are not children per se, but owned. The example demonstrates the nomenclature.

Constructor Etiquette Almost all QObjects take a parent object with a default value of 0 (null) QObject(QObject *parent=0); The parent of QWidgets are other QWidgets Classes have a tendency to provide many constructors for convenience (including one taking only parent) QPushButton(QWidget *parent=0); QPushButton(const QString &text, QWidget *parent=0); QPushButton(const QIcon &icon, const QString &text, QWidget *parent=0); The parent is usually the first argument with a default value QLabel(const QString &text, QWidget *parent=0, Qt::WindowFlags f=0);

Constructor Etiquette When creating your own QObjects, consider Always allowing parent be 0 (null) Having one constructor only accepting parent parent is the first argument with a default value Provide several constructors to avoid having to pass 0 (null) and invalid (e.g. QString()) values as arguments

Break

Signals and Slots Dynamically and loosely tie together events and state changes with reactions What makes Qt tick

Signals and Slots in Action emit clicked();

Signals and Slots in Action 2x connect(addbutton,signal(clicked()),this,slot(...)) ; clear(); connect(clearbutton,signal(clicked()),listwidget,slot(clear())); private slots: void on_addbutton_clicked(); void on_deletebutton_clicked();

} Signals and Slots in Action... emit clicked();... QString newtext = QInputDialog::getText(this, "Enter text", "Text:"); } if(!newtext.isempty() ) ui->listwidget->additem(newtext); }... emit clicked();... } foreach (QListWidgetItem *item, ui->listwidget->selecteditems()) delete item; } }... emit clicked();... clear();

Signals and Slots vs Callbacks A callback is a pointer to a function that is called when an event occurs, any function can be assigned to a callback No type-safety Always works as a direct call Signals and Slots are more dynamic A more generic mechanism Easier to interconnect two existing classes Less knowledge shared between involved classes

What is a slot? A slot is defined in one of the slots sections public slots: void apublicslot(); protected slots: void aprotectedslot(); private slots: void aprivateslot(); A slot can return values, but not through connections Any number of signals can be connected to a slot connect(src, SIGNAL(sig()), dest, SLOT(slt())); It is implemented as an ordinary method It can be called as an ordinary method

What is a signal? A signal is defined in the signals section signals: void asignal(); A signal always returns void A signal must not be implemented The moc provides an implementation A signal can be connected to any number of slots Usually results in a direct call, but can be passed as events between threads, or even over sockets (using 3 rd party classes) The slots are activated in arbitrary order A signal is emitted using the emit keyword emit asignal();

Making the connection QObject* QObject::connect( src, SIGNAL( signature ), dest, SLOT( signature ) ); settitle(qstring text) setvalue(42) <function name> ( <arg type>... ) A signature consists of the function name and argument types. No variable names, nor values are allowed. setitem(itemclass) Custom types reduces reusability. clicked() toggled(bool) settext(qstring) textchanged(qstring) rangechanged(int,int)

Making the connection Qt can ignore arguments, but not create values from nothing Signals rangechanged(int,int) rangechanged(int,int) rangechanged(int,int) Slots setrange(int,int) setvalue(int) updatedialog() valuechanged(int) valuechanged(int) valuechanged(int) setrange(int,int) setvalue(int) updatedialog() textchanged(qstring) setvalue(int) clicked() clicked() setvalue(int) updatedialog()

Automatic Connections When using Designer it is convenient to have automatic connections between the interface and your code on_ object name _ signal name ( signal parameters ) on_addbutton_clicked(); on_deletebutton_clicked(); on_listwidget_currentitemchanged(qlistwidgetitem*,qlistwidgetitem*) Triggered by calling QMetaObject::connectSlotsByName Think about reuse when naming Compare on_widget_signal to updatepagemargins updatepagemargins can be connected to a number of signals or called directly.

Synchronizing Values Connect both ways connect(dial1, SIGNAL(valueChanged(int)), dial2, SLOT(setValue(int))); connect(dial2, SIGNAL(valueChanged(int)), dial1, SLOT(setValue(int))); An infinite loop must be stopped no signal is emitted unless an actual change takes place void QDial::setValue(int v) if(v==m_value) return;... This is the responsibility of all code that can emit signals do not forget it in your own classes

Custom signals and slots class AngleObject : public QObject Q_OBJECT Q_PROPERTY(qreal angle READ angle WRITE setangle NOTIFY anglechanged) public: AngleObject(qreal angle, QObject *parent = 0); qreal angle() const; Add a notify signal here. public slots: void setangle(qreal); signals: void anglechanged(qreal); private: qreal m_angle; }; Setters make natural slots. Signals match the setters

Setter implementation details void AngleObject::setAngle(qreal angle) if(m_angle == angle) return; } m_angle = angle; emit anglechanged(m_angle); Protection against infinite loops. Do not forget this! Update the internal state, then emit the signal. Signals are protected so you can emit them from derived classes.

Temperature Converter Uses the TempConverter class to convert between Celsius and Fahrenheit Emits signals when temperature changes

Temperature Converter The dialog window contains the following objects A TempConverter instance Two QGroupBox widgets, each containing A QDial widget A QLCDNumber widget

Temperature Converter class TempConverter : public QObject QObject as parent Q_OBJECT Q_OBJECT macro first parent pointer public: TempConverter(int tempcelsius, QObject *parent = 0); int tempcelsius() const; int tempfahrenheit() const; public slots: void settempcelsius(int); void settempfahrenheit(int); signals: void tempcelsiuschanged(int); void tempfahrenheitchanged(int); private: int m_tempcelsius; }; Read and write methods Emitted on changes of the temperature Internal representation in integer Celsius.

Temperature Converter The settempcelsius slot: void TempConverter::setTempCelsius(int tempcelsius) if(m_tempcelsius == tempcelsius) return; Test for change to break recursion m_tempcelsius = tempcelsius; Update object state } emit tempcelsiuschanged(m_tempcelsius); emit tempfahrenheitchanged(tempfahrenheit()); The settempfahrenheit slot: Emit signal(s) reflecting changes void TempConverter::setTempFahrenheit(int tempfahrenheit) int tempcelsius = (5.0/9.0)*(tempFahrenheit-32); Convert and pass on settempcelsius(tempcelsius); as Celsius is the internal } representation

tempfahrenheitchanged setvalue Temperature Converter The dials are interconnected through the TempConverter The LCD displays are driven directly from the dials TempConverter valuechanged settempcelsius tempcelsiuschanged setvalue settempcelsius settempfahrenheit tempcelsiuschanged tempfahrenheitchanged valuechanged settempfahrenheit valuechanged display connect(celsiusdial, SIGNAL(valueChanged(int)), tempconverter, SLOT(setTempCelsius(int))); connect(celsiusdial, SIGNAL(valueChanged(int)), celsiuslcd, SLOT(display(int))); connect(tempconverter, SIGNAL(tempCelsiusChanged(int)), celsiusdial, SLOT(setValue(int))); connect(fahrenheitdial, SIGNAL(valueChanged(int)), tempconverter, SLOT(setTempFahrenheit(int))); connect(fahrenheitdial, SIGNAL(valueChanged(int)), fahrenheitlcd, SLOT(display(int))); connect(tempconverter, SIGNAL(tempFahrenheitChanged(int)), fahrenheitdial, SLOT(setValue(int)));

tempfahrenheitchanged setvalue Temperature Converter The user moves the celsiusdial TempConverter valuechanged settempcelsius tempcelsiuschanged setvalue settempcelsius settempfahrenheit tempcelsiuschanged tempfahrenheitchanged valuechanged settempfahrenheit valuechanged display connect(celsiusdial, SIGNAL(valueChanged(int)), tempconverter, SLOT(setTempCelsius(int))); connect(celsiusdial, SIGNAL(valueChanged(int)), celsiuslcd, SLOT(display(int))); connect(tempconverter, SIGNAL(tempCelsiusChanged(int)), celsiusdial, SLOT(setValue(int))); connect(fahrenheitdial, SIGNAL(valueChanged(int)), tempconverter, SLOT(setTempFahrenheit(int))); connect(fahrenheitdial, SIGNAL(valueChanged(int)), fahrenheitlcd, SLOT(display(int))); connect(tempconverter, SIGNAL(tempFahrenheitChanged(int)), fahrenheitdial, SLOT(setValue(int)));

tempfahrenheitchanged setvalue Temperature Converter The user moves the celsiusdial TempConverter valuechanged settempcelsius tempcelsiuschanged setvalue settempcelsius settempfahrenheit tempcelsiuschanged tempfahrenheitchanged valuechanged settempfahrenheit valuechanged display connect(celsiusdial, SIGNAL(valueChanged(int)), tempconverter, SLOT(setTempCelsius(int))); connect(celsiusdial, SIGNAL(valueChanged(int)), celsiuslcd, SLOT(display(int))); connect(tempconverter, SIGNAL(tempCelsiusChanged(int)), celsiusdial, SLOT(setValue(int))); connect(fahrenheitdial, SIGNAL(valueChanged(int)), tempconverter, SLOT(setTempFahrenheit(int))); connect(fahrenheitdial, SIGNAL(valueChanged(int)), fahrenheitlcd, SLOT(display(int))); connect(tempconverter, SIGNAL(tempFahrenheitChanged(int)), fahrenheitdial, SLOT(setValue(int)));

tempcelsiuschanged setvalue tempfahrenheitchanged setvalue Temperature Converter The user moves the celsiusdial TempConverter valuechanged settempcelsius settempcelsius settempfahrenheit tempcelsiuschanged tempfahrenheitchanged valuechanged settempfahrenheit valuechanged display connect(celsiusdial, SIGNAL(valueChanged(int)), tempconverter, SLOT(setTempCelsius(int))); connect(celsiusdial, SIGNAL(valueChanged(int)), celsiuslcd, SLOT(display(int))); connect(tempconverter, SIGNAL(tempCelsiusChanged(int)), celsiusdial, SLOT(setValue(int))); connect(fahrenheitdial, SIGNAL(valueChanged(int)), tempconverter, SLOT(setTempFahrenheit(int))); connect(fahrenheitdial, SIGNAL(valueChanged(int)), fahrenheitlcd, SLOT(display(int))); connect(tempconverter, SIGNAL(tempFahrenheitChanged(int)), fahrenheitdial, SLOT(setValue(int)));

tempcelsiuschanged setvalue tempfahrenheitchanged setvalue Temperature Converter The user moves the celsiusdial TempConverter valuechanged settempcelsius settempcelsius settempfahrenheit tempcelsiuschanged tempfahrenheitchanged valuechanged settempfahrenheit valuechanged display connect(celsiusdial, SIGNAL(valueChanged(int)), tempconverter, SLOT(setTempCelsius(int))); connect(celsiusdial, SIGNAL(valueChanged(int)), celsiuslcd, SLOT(display(int))); connect(tempconverter, SIGNAL(tempCelsiusChanged(int)), celsiusdial, SLOT(setValue(int))); connect(fahrenheitdial, SIGNAL(valueChanged(int)), tempconverter, SLOT(setTempFahrenheit(int))); connect(fahrenheitdial, SIGNAL(valueChanged(int)), fahrenheitlcd, SLOT(display(int))); connect(tempconverter, SIGNAL(tempFahrenheitChanged(int)), fahrenheitdial, SLOT(setValue(int)));

tempcelsiuschanged setvalue tempfahrenheitchanged setvalue Temperature Converter The user moves the celsiusdial TempConverter valuechanged settempcelsius settempcelsius settempfahrenheit tempcelsiuschanged tempfahrenheitchanged valuechanged settempfahrenheit valuechanged display connect(celsiusdial, SIGNAL(valueChanged(int)), tempconverter, SLOT(setTempCelsius(int))); connect(celsiusdial, SIGNAL(valueChanged(int)), celsiuslcd, SLOT(display(int))); connect(tempconverter, SIGNAL(tempCelsiusChanged(int)), celsiusdial, SLOT(setValue(int))); connect(fahrenheitdial, SIGNAL(valueChanged(int)), tempconverter, SLOT(setTempFahrenheit(int))); connect(fahrenheitdial, SIGNAL(valueChanged(int)), fahrenheitlcd, SLOT(display(int))); connect(tempconverter, SIGNAL(tempFahrenheitChanged(int)), fahrenheitdial, SLOT(setValue(int)));

tempcelsiuschanged setvalue tempfahrenheitchanged setvalue Temperature Converter The user moves the celsiusdial TempConverter valuechanged settempcelsius settempcelsius settempfahrenheit tempcelsiuschanged tempfahrenheitchanged valuechanged settempfahrenheit valuechanged display connect(celsiusdial, SIGNAL(valueChanged(int)), tempconverter, SLOT(setTempCelsius(int))); connect(celsiusdial, SIGNAL(valueChanged(int)), celsiuslcd, SLOT(display(int))); connect(tempconverter, SIGNAL(tempCelsiusChanged(int)), celsiusdial, SLOT(setValue(int))); connect(fahrenheitdial, SIGNAL(valueChanged(int)), tempconverter, SLOT(setTempFahrenheit(int))); connect(fahrenheitdial, SIGNAL(valueChanged(int)), fahrenheitlcd, SLOT(display(int))); connect(tempconverter, SIGNAL(tempFahrenheitChanged(int)), fahrenheitdial, SLOT(setValue(int)));

tempcelsiuschanged setvalue tempfahrenheitchanged setvalue Temperature Converter The user moves the celsiusdial TempConverter valuechanged settempcelsius settempcelsius settempfahrenheit tempcelsiuschanged tempfahrenheitchanged valuechanged settempfahrenheit valuechanged display connect(celsiusdial, SIGNAL(valueChanged(int)), tempconverter, SLOT(setTempCelsius(int))); connect(celsiusdial, SIGNAL(valueChanged(int)), celsiuslcd, SLOT(display(int))); connect(tempconverter, SIGNAL(tempCelsiusChanged(int)), celsiusdial, SLOT(setValue(int))); connect(fahrenheitdial, SIGNAL(valueChanged(int)), tempconverter, SLOT(setTempFahrenheit(int))); connect(fahrenheitdial, SIGNAL(valueChanged(int)), fahrenheitlcd, SLOT(display(int))); connect(tempconverter, SIGNAL(tempFahrenheitChanged(int)), fahrenheitdial, SLOT(setValue(int)));

Connect with a value? A common scenario is that you want to pass a value in the connect statement connect(key, SIGNAL(clicked()), this, SLOT(keyPressed(1))); For instance, the keyboard example This is not valid it will not connect

Connect with a value? Solution #1: multiple slots... connections public slots: void key1pressed(); void key2pressed(); void key3pressed(); void key4pressed(); void key5pressed(); void key6pressed(); void key7pressed(); void key8pressed(); void key9pressed(); void key0pressed(); }...

Connect with a value? Solution #2: sub-class emitter and add signal QPushButton QIntPushButton... signals: void clicked(int); QIntPushButton *b; b=new QIntPushButton(1); connect(b, SIGNAL(clicked(int)), this, SLOT(keyPressed(int))); b=new QIntPushButton(2); connect(b, SIGNAL(clicked(int)), this, SLOT(keyPressed(int))); b=new QIntPushButton(3); connect(b, SIGNAL(clicked(int)), this, SLOT(keyPressed(int))); }... }...

Solution evaluation #1: multiple slots Many slots containing almost the same code Hard to maintain (one small change affects all slots) Hard to extend (new slot each time) #2: sub-class emitter and add signal Extra class that is specialized (hard to reuse) Hard to extend (new sub-class for each special case)

The signal mapper The QSignalMapper class solves this problem Maps a value to each emitter Sits between reusable classes QSignalMapper *m = QSignalMapper(this); QPushButton *b; b=new QPushButton("1"); connect(b, SIGNAL(clicked()), m, SLOT(map())); m->setmapping(b, 1);... Create a signal mapper Connect the buttons to the mapper Associate an emitter with a value Connect the mapper to the slot } connect(m, SIGNAL(mapped(int)), this, SLOT(keyPressed(int)));

The signal mapper The signal mapper associates each button with a value. These values are mapped... connections QSignalMapper connection public slots: void keypressed(); }... When a value is mapped, the signal mapper emits the mapped(int) signal, carrying the associated value