Skip to content

Commit 4f14748

Browse files
rm5248murraycu
authored andcommitted
Added example of using libsigc++ with Qt
Pull Request #35.
1 parent 2131f6b commit 4f14748

File tree

6 files changed

+190
-0
lines changed

6 files changed

+190
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,4 @@ Makefile.in
2626
/stamp-h?
2727
untracked/build_scripts/
2828
untracked/docs/
29+
*.pro.user

examples/qt_with_qmake/README.md

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# libsigc++ with Qt
2+
3+
It is possible to use libsigc++ with Qt. However, because of the signals/slots
4+
mechanism of Qt, there is some setup that must be done in order for this to
5+
happen correctly.
6+
7+
The official Qt documentation may be found here: https://doc.qt.io/qt-5/signalsandslots.html#using-qt-with-3rd-party-signals-and-slots
8+
9+
Steps to use libsigc++ with Qt:
10+
1. In your .pro file, add `CONFIG += no_keywords`. This configures Qt to not
11+
define the macros `emit`, `signals`, and `slot`. These are keywords for moc,
12+
which preprocesses the source files in order to use Qt signals/slots.
13+
2. In your header files, change the `signals:` section of your class to instead
14+
be `Q_SIGNALS`
15+
3. In your header files, change the `public slots:` section of your class to
16+
instead be `public Q_SLOTS:`
17+
4. In any class that you emit a signal, change `emit` to be `Q_EMIT`.
18+
19+
In general, using the Q\_ macros is a good idea if your code is a library
20+
intended to be used by people other than yourself, as they may be using
21+
code(e.g. libsigc++/boost signals) that will conflict with Qt(moc) keywords.
22+
23+
Here's an example of a class before and after this conversion(note: irrelevant
24+
code has been removed):
25+
26+
```
27+
class ExampleClass : public QObject {
28+
signals:
29+
void exampleSignal();
30+
public slots:
31+
void example_slot(){
32+
emit exampleSignal();
33+
}
34+
};
35+
```
36+
37+
After conversion:
38+
```
39+
class ExampleClass : public QObject {
40+
Q_SIGNALS:
41+
void exampleSignal();
42+
public Q_SLOTS:
43+
void example_slot(){
44+
Q_EMIT exampleSignal();
45+
}
46+
};
47+
```
48+
49+
## Qt Slots Notes
50+
Since libsigc++ simply requires a slot to be a function, you can call Qt
51+
slots easily using libsigc++. Similarly, a function that is a libsigc++ slot
52+
can also be used as a Qt slot.
53+
54+
# Other Build Systems
55+
If you are not using qmake to build your Qt project, you must tell your
56+
buildsystem to define `QT_NO_KEYWORDS`. If you're using CMake, this may
57+
be done like the following:
58+
59+
```
60+
add_definitions(-DQT_NO_KEYWORDS)
61+
```
62+
63+
or in a more modern CMake way:
64+
65+
```
66+
target_compile_definitions(some_target PRIVATE QT_NO_KEYWORDS)
67+
```
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#include <QCoreApplication>
2+
3+
#include "exampleclass.h"
4+
5+
ExampleClass::ExampleClass(QObject *parent) :
6+
QObject(parent)
7+
{
8+
/* Create a slot from our example_slot method. */
9+
m_sigc_slot = sigc::mem_fun( *this, &ExampleClass::example_slot );
10+
11+
/* Connect our sigc++ signal to our sigc++ slot */
12+
m_sigc_signal.connect( m_sigc_slot );
13+
14+
/* Emit a sigc++ signal */
15+
m_sigc_signal.emit();
16+
17+
/* Connect the Qt signal to our Qt slot */
18+
connect( &m_timer, &QTimer::timeout,
19+
this, &ExampleClass::timer_slot );
20+
m_timer.start( 200 );
21+
22+
/* Emit a Qt signal */
23+
Q_EMIT example_signal();
24+
}
25+
26+
void ExampleClass::timer_slot(){
27+
qDebug() << "Timer slot called";
28+
29+
QCoreApplication::exit( 0 );
30+
}
31+
32+
void ExampleClass::example_slot(){
33+
qDebug() << "Example slot called";
34+
}

examples/qt_with_qmake/exampleclass.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#ifndef EXAMPLECLASS_H
2+
#define EXAMPLECLASS_H
3+
4+
#include <QObject>
5+
#include <QTimer>
6+
#include <QDebug>
7+
8+
#include <sigc++/sigc++.h>
9+
10+
class ExampleClass : public QObject
11+
{
12+
Q_OBJECT
13+
public:
14+
explicit ExampleClass(QObject *parent = nullptr);
15+
16+
/* Instead of using the keyword 'signals', use the 'Q_SIGNALS' macro */
17+
Q_SIGNALS:
18+
void example_signal();
19+
20+
/* Instead of using the keyword 'slots', use the 'Q_SLOTS' macro */
21+
public Q_SLOTS:
22+
void timer_slot();
23+
24+
/**
25+
* This slot is called using libsigc++, however since it is defined under Q_SLOTS
26+
* it could also be used with the Qt signals/slots
27+
*/
28+
void example_slot();
29+
30+
private:
31+
sigc::slot<void()> m_sigc_slot;
32+
sigc::signal<void()> m_sigc_signal;
33+
QTimer m_timer;
34+
};
35+
36+
#endif // EXAMPLECLASS_H

examples/qt_with_qmake/main.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#include <QCoreApplication>
2+
#include <QTimer>
3+
4+
#include "exampleclass.h"
5+
6+
int main(int argc, char *argv[])
7+
{
8+
QCoreApplication a(argc, argv);
9+
10+
ExampleClass ex;
11+
12+
return a.exec();
13+
}

examples/qt_with_qmake/qt-sigcpp.pro

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
QT -= gui
2+
3+
CONFIG += console
4+
CONFIG -= app_bundle
5+
6+
# Qt 5.12 introduces the 'c++17' config option; this sets it manually
7+
QMAKE_CXXFLAGS += -std=c++17
8+
9+
# Since Qt #defines emit, signal, and slot, we need to disable those keywords
10+
CONFIG += no_keywords
11+
12+
# We must link with sigc++-3.0
13+
unix{
14+
CONFIG += link_pkgconfig
15+
PKGCONFIG += sigc++-3.0
16+
}
17+
18+
# The following define makes your compiler emit warnings if you use
19+
# any Qt feature that has been marked deprecated (the exact warnings
20+
# depend on your compiler). Please consult the documentation of the
21+
# deprecated API in order to know how to port your code away from it.
22+
DEFINES += QT_DEPRECATED_WARNINGS
23+
24+
# You can also make your code fail to compile if it uses deprecated APIs.
25+
# In order to do so, uncomment the following line.
26+
# You can also select to disable deprecated APIs only up to a certain version of Qt.
27+
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
28+
29+
SOURCES += \
30+
main.cpp \
31+
exampleclass.cpp
32+
33+
# Default rules for deployment.
34+
qnx: target.path = /tmp/$${TARGET}/bin
35+
else: unix:!android: target.path = /opt/$${TARGET}/bin
36+
!isEmpty(target.path): INSTALLS += target
37+
38+
HEADERS += \
39+
exampleclass.h

0 commit comments

Comments
 (0)