Qt Memory Management & Signal and Slots

Post on 03-Sep-2014

8.694 views 4 download

Tags:

description

 

Transcript of Qt Memory Management & Signal and Slots

Qt Memory Management &Signals and Slots

Jussi PohjolainenTampere University of Applied Sciences

About Memory Management

• In Java: Garbage Collector• In C++: stack, heap, static– Stack: release is done automatically when out of

scope– Heap: release is done by the programmer

• Qt is C++, but it has it's "own way" of releasing heap-objects.

Qt Object Trees

• QObjects organize themselves in object trees• When you create a QObject with another

object as parent, it's added to the parent's children() list, and is deleted when the parent is.

Simple Example

int main() { QWidget window; QPushButton* quit = new QPushButton("Quit", &window);

//QPushButton is released, when //QWidget is out of scope }

QObject

• Automatic Memory Handling works only when class is inherited from QObject

• Every GUI-classes (widgets) are inherited from QObject.

SIGNAL & SLOTS

Qt's Meta-Object System

• Meta-object system: extension to C++ by Qt– signals-slots (event-handling)– Introspection without RTTI• className()

– Internationalization • tr()

– Setting properties dynamically• setProperty()

Meta Object Compiler (moc)

• Enabling meta-object features:class Counter : public QObject{ Q_OBJECT ...

• moc generates another .cpp file• counter.cpp -> moc_counter.cpp

Signal & Slots

• Qt's event handling mechanism• Signals are emitted by widgets when

something happens• Slots are used to handle signals• Most of the work is done by Qt's meta classes

and macros. Code can look strange, but in the end, it's standard C++.

Signal & Slots

• Communication between objects• In Java: Event listener– Requires additional work (interfaces etc)

• Connecting:QObject::connect(exitButton, SIGNAL( clicked() ), &app, SLOT( quit() ));

Signal & SlotsQObject::connect(exitButton, // Sender SIGNAL( clicked() ), // Sender's signal &app, // Receiving object SLOT( quit() )); // Receiver's slot

QPushButton QApplication

Signalsclicked()

Slots

Signals

Slotsquit()

Defining Signals and Slots

• The signals and slots are available to any QObject's subclass.

• Slots are normal methods• Signals are just declarations used by the moc

compiler

Exampleclass Counter : public QObject { Q_OBJECT

public: Counter() { m_value = 0; }

int value() const { return m_value; }

public slots: void setValue(int value);

signals: void valueChanged(int newValue);

private: int m_value; };

Example#include "counter.h"

void Counter::setValue(int value) { if (value != m_value) { m_value = value; emit valueChanged(value); } }

Example#include <QtCore/QCoreApplication>#include "counter.h"

int main(int argc, char *argv[]){ QCoreApplication app(argc, argv); Counter a, b; QObject::connect(&a, SIGNAL(valueChanged(int)), &b, SLOT(setValue(int))); a.setValue(12); // a.value() == 12, b.value() == 12 b.setValue(48); // a.value() == 12, b.value() == 48 return app.exec();}

About Signals and Slots

• Only available if class inherites QObject• Truly independent components, objects don't

know of each other• Multiple signals to one slot• One signal to multiple slots

SignalMapper

• Multiple signals to one slot– Multiple buttons -> something happens– We want different logic depending on the button

#include <QtGui>#include "listener.h"

int main(int argc, char *argv[]){ QApplication a(argc, argv);

QFrame parent;

QVBoxLayout* layout = new QVBoxLayout(&parent);

QPushButton* push1 = new QPushButton("Hello"); QPushButton* push2 = new

QPushButton("World"); layout->addWidget(push1); layout->addWidget(push2);

QSignalMapper* signalMapper = new

QSignalMapper(&parent); signalMapper->setMapping(push1,

QString("Hello")); signalMapper->setMapping(push2,

QString("World"));

QObject::connect(push1, SIGNAL(clicked()), signalMapper, SLOT(map()));

QObject::connect(push2, SIGNAL(clicked()), signalMapper, SLOT(map())); Listener* listener = new Listener(&parent);

QObject::connect(signalMapper, SIGNAL(mapped(const QString &)), listener, SLOT(buttonWasClicked(const QString

&)));

parent.show();

return a.exec();}

Listener

#include "listener.h"

Listener::Listener(QObject* parent) : QObject(parent) { }

void Listener::buttonWasClicked(const QString& whichButton) {

if(whichButton == "Hello") qDebug() << "Hello was pressed!"; else if(whichButton == "World") qDebug() << "World was pressed";}

SignalMapper

push1 => "Hello"push2 => "World"clicked()

clicked()

slots: map()

signals: mapped(QString)

buttonWasClicked("Hello")

push1

push2buttonWasClicked("World")