3

Good day all

Background:

I am at the point of building and test-deploying my application on debian systems, however I have run into some trouble

My application uses QOverload for the QNetworkReply, as suggested by the documentation page.

An example usage is (from doc page):

connect(networkReply, QOverload<QNetworkReply::NetworkError>::of(&QNetworkReply::error),
    [=](QNetworkReply::NetworkError code){ /* ... */ });

or another usage found in my application:

# header
QButtonGroup *grpProtocol;
QMetaObject::Connection conProtocol

# implementation
conProtocol = QObject::connect(ui->grpProtocol, QOverload<QAbstractButton *, bool>::of(&QButtonGroup::buttonToggled), [this](){
    //do some action when a radio button in a QButtonGroup is toggled
});

Problem:

When calling make on my application, make complains with an error:

mainwindow.cpp: In member function ‘void MainWindow::initConnectors()’:
mainwindow.cpp:462:53: error: ‘QOverload’ was not declared in this scope
     conProtocol = QObject::connect(ui->grpProtocol, QOverload<QAbstractButton *, bool>::of(&QButtonGroup::buttonToggled), [this](){
                                                     ^
mainwindow.cpp:462:79: error: expected primary-expression before ‘*’ token
     conProtocol = QObject::connect(ui->grpProtocol, QOverload<QAbstractButton *, bool>::of(&QButtonGroup::buttonToggled), [this](){
                                                                               ^
mainwindow.cpp:462:80: error: expected primary-expression before ‘,’ token
     conProtocol = QObject::connect(ui->grpProtocol, QOverload<QAbstractButton *, bool>::of(&QButtonGroup::buttonToggled), [this](){
                                                                                ^
mainwindow.cpp:462:82: error: expected primary-expression before ‘bool’
     conProtocol = QObject::connect(ui->grpProtocol, QOverload<QAbstractButton *, bool>::of(&QButtonGroup::buttonToggled), [this](){
                                                                                  ^
Makefile:476: recipe for target 'mainwindow.o' failed

Now, this leads me to check when QOverload is found and include the header.

QOverload can be found in qglobal.h but was only introduced in QT 5.7

  • Qoverload requires the use of C++11

  • Or qOverload, using C++14

The problem is that Ubuntu 16.04 uses Qt version 5.5:

qtchooser -print-env
QT_SELECT="default"
QTTOOLDIR="/usr/lib/x86_64-linux-gnu/qt5/bin"
QTLIBDIR="/usr/lib/x86_64-linux-gnu"

/usr/lib/x86_64-linux-gnu/qt5/bin/qmake -v
QMake version 3.0
Using Qt version 5.5.1 in /usr/lib/x86_64-linux-gnu

What I tried:

I resolved to using preprocessor directives to do the version checking for me.

#if QT_VERSION <= QT_VERSION_CHECK(5, 7, 0)
    qDebug(mainclient) << "Adding connector for settings prefered connection protocol";
    conProtocol = QObject::connect(ui->grpProtocol, QOverload<QAbstractButton *, bool>::of(&QButtonGroup::buttonToggled), [this](){
        // my code here which which handles events
    });
#endif

However, the above error of make resulted with the preprocessor directive included. i.e. Including the Qt version check still threw the QOverload out of scope.

Question:

Put simply, what did I do wrong? Why, with a specific QT version check set, does make ignore this and build everything still?

Update with possible alternative solutions

  1. Eliminate the QOverload entirely and replace with pre QT 5.7 code which will make my code slightly bulkier and some redundant code (possible)
  2. Add the header file to my application files and include it only if the system has a Qt version < Qt5.7 (considered very bad practise)
CybeX
  • 2,060
  • 3
  • 48
  • 115
  • Probably forgot to include some headers? – vahancho Dec 18 '17 at 08:41
  • @vahancho in `Qt5.7+` there is a `qglobal.h` header where the `QOverload` function is found. Pre `Qt5.7`, there simply is no `QOverload` function as it didn't exist before then, thus there is no header to include – CybeX Dec 18 '17 at 08:42
  • as suggested by an answer (now delete): `#if (QT_VERSION <= QT_VERSION_CHECK(5, 7, 0))` doesn't work (adding the parenthesis) – CybeX Dec 18 '17 at 09:09
  • I deleted the answer 'cause I'm not sure, just checking (and it could be creator, btw). – p-a-o-l-o Dec 18 '17 at 09:12
  • @p-a-o-l-o no. I uploaded the source to my github account, and pulled onto a fresh Ubuntu 16.04 LTS VM install and built from there. So no, it is not QT-Creator causing the issue. I will mention, that on my dev machine, the application compiles without a problem. My dev machine uses `QMake 3.1` with `QT version 5.9.3` – CybeX Dec 18 '17 at 09:17

2 Answers2

10

You can use static_cast to replace QOverload:

connect(networkReply, static_cast<void (QNetworkReply::*)(QNetworkReply::NetworkError)>(&QNetworkReply::error),
    [=](QNetworkReply::NetworkError code){ /* ... */ });

from here: Connecting overloaded signals and slots in Qt 5

fouronnes
  • 3,838
  • 23
  • 41
0

You have an error in logical expression here:

#if QT_VERSION <= QT_VERSION_CHECK(5, 7, 0)

Which basically says "enable following block if the version is less or equal than 5.7". And Qt 5.5 meets this criteria.

Teivaz
  • 5,462
  • 4
  • 37
  • 75