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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy