Qt Memory Management & Signal and Slots
-
Upload
jussi-pohjolainen -
Category
Technology
-
view
8.694 -
download
4
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")