Couldn't connect() to QTcpSocket::error with the new signal/slot syntax in Qt5
-
Environment:
Gentoo ~amd64, x11-libs/qt-core-5.0.1 (c++11 glib icu -debug -test) from qt overlay, and qt-network-5.0.1 (c++11 ssl -connman -debug -networkmanager -test). I have Qt 5.0.1 and Qt 4.8.4 installed side by side.
The problem:
I just started programming with Qt and C++ and wishes to write a network application. I spotted "the new signal/slot syntax":http://qt-project.org/wiki/New_Signal_Slot_Syntax introduced in Qt 5 and found it interesting. I tried using the new syntax to connect() to other signals of QTcpSocket and it works beautifully:
@
QTcpSocket socket;// ...
connect(&socket, &QTcpSocket::connected, this, &MarketInfoWorkerDzh::onConnected);
connect(&socket, &QTcpSocket::readyRead, this, &MarketInfoWorkerDzh::onReadyRead);
@However, I simply couldn't connect() to QTcpSocket::error:
@
connect(&socket, static_cast<void (QTcpSocket::*) (QAbstractSocket::SocketError)>(&QAbstractSocket::error), this, &MarketInfoWorkerDzh::onError);
@It works during compilation -- not even a warning with clang++ -Weverything -- but at runtime I spot this:
bq. QObject::connect: signal not found in QTcpSocket
The old syntax works correctly:
@
connect(&socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(onError(QAbstractSocket::SocketError)))
@Things I've tried:
-
Switching between clang-3.1 and gcc-4.7.2. No luck.
-
Try compiling from qt-creator-2.6.4 and manually with qmake/make. No changes.
-
Make a skeleton project with Qt Creator, and copy the example code from "New Signal Slot Syntax Coming in Qt 5":http://qt-project.org/wiki/New_Signal_Slot_Syntax directly.
@
QByteArray page;
QTcpSocket *socket = new QTcpSocket;
socket->connectToHost("qt.nokia.com", 80);
QObject::connect(socket, &QTcpSocket::connected, [socket, page] () {
socket->write(QByteArray("GET " + page + "\r\n"));
});
QObject::connect(socket, &QTcpSocket::readyRead, [socket] () {
qDebug()<< "GOT DATA "<< socket->readAll();
});
QObject::connect(socket, &QTcpSocket::disconnected, [socket] () {
qDebug()<< "DISCONNECTED ";
socket->deleteLater();
});QObject::connect(socket, static_cast<void (QTcpSocket::*)(QAbstractSocket::SocketError)>(&QAbstractSocket::error), [socket] (QAbstractSocket::SocketError) { qDebug()<< "ERROR " << socket->errorString(); socket->deleteLater(); });
@
I get the same error.
- Grab the fortuneclient example from qtbase-opensource-src-5.0.1.tar.xz, modify two lines to use the new signal/slot syntax:
@
connect(tcpSocket, static_cast<void (QTcpSocket::*)(QAbstractSocket::SocketError)>(&QAbstractSocket::error),
//! [3]
this, &Client::displayError);
@Then it exhibits the very issue.
-
"LD_PRELOAD=/usr/lib64/libQt5Network.so.5.0.1". Doesn't help.
-
Build qt-core with debugging symbols. I traced down to QObject::connectImpl(), ./src/corelib/kernel/qobject.cpp, line 4202:
@
QMetaObject::Connection QObject::connectImpl(const QObject *sender, void **signal,
const QObject *receiver, void **slot,
QtPrivate::QSlotObjectBase *slotObj, Qt::ConnectionType type,
const int *types, const QMetaObject *senderMetaObject)
{
if (!sender || !signal || !slotObj || !senderMetaObject) {
qWarning("QObject::connect: invalid null parametter");
if (slotObj)
slotObj->destroyIfLastRef();
return QMetaObject::Connection();
}
int signal_index = -1;
void *args[] = { &signal_index, signal };
senderMetaObject->static_metacall(QMetaObject::IndexOfMethod, 0, args);
if (signal_index < 0 || signal_index >= QMetaObjectPrivate::get(senderMetaObject)->signalCount) {
qWarning("QObject::connect: signal not found in %s", senderMetaObject->className());
slotObj->destroyIfLastRef();
return QMetaObject::Connection(0);
}
// ...
@I believe the parameter "signal" is passed to it correctly:
@
$1 = (void *) 0x7ffff7f48ed0 QAbstractSocket::error(QAbstractSocket::SocketError)
@But the static_metacall(QMetaObject::IndexOfMethod, ...) call later doesn't modify signal_index at all:
@
(gdb) p signal_index
$2 = -1
(gdb) p senderMetaObject->static_metacall(QMetaObject::IndexOfMethod, 0, args)
$3 = -1
(gdb) p signal_index
$4 = -1
(gdb) p signal_index = -2
$5 = -2
(gdb) p senderMetaObject->static_metacall(QMetaObject::IndexOfMethod, 0, args)
$6 = -1
(gdb) p signal_index
$7 = -2
@(The forum says "The maximum number of allowed characters is 6000"..., so I have to break my post down here.)
-
-
(My thread continues here...)
It feels like there's something wrong in static_metacall(QMetaObject::IndexOfMethod, ...), but I do not know where static_metacall() actually goes to:
@
(gdb) n
4213 int signal_index = -1;
(gdb) n
4214 void *args[] = { &signal_index, signal };
(gdb) n
4215 senderMetaObject->static_metacall(QMetaObject::IndexOfMethod, 0, args);
(gdb) s
QMetaObject::static_metacall (this=0x7ffff7fc64e0 QTcpSocket::staticMetaObject,
cl=QMetaObject::IndexOfMethod, idx=0, argv=0x7fffffffdfa0)
at /var/tmp/portage/x11-libs/qt-core-5.0.1/work/qtbase-opensource-src-5.0.1/src/corelib/kernel/q
metaobject.cpp:291
291 {
(gdb) s
293 if (!d.static_metacall)
(gdb) s
291 {
(gdb) s
293 if (!d.static_metacall)
(gdb) s
295 d.static_metacall(0, cl, idx, argv);
(gdb) s
296 return -1;
(gdb) s
297 }
(gdb) s
QObject::connectImpl (sender=0x55555575ccc0, signal=<optimized out>, receiver=0x55555575ccc0,
slot=0x0, slotObj=0x55555575e1a0, type=Qt::DirectConnection, types=0x0,
senderMetaObject=0x7ffff7fc64e0 QTcpSocket::staticMetaObject)
at /var/tmp/portage/x11-libs/qt-core-5.0.1/work/qtbase-opensource-src-5.0.1/src/corelib/kernel/qobject.cpp:4216
4216 if (signal_index < 0 || signal_index >= QMetaObjectPrivate::get(senderMetaObject)->signalCount) {
(gdb) s
4217 qWarning("QObject::connect: signal not found in %s", senderMetaObject->className())
@So, any ideas what's wrong? Thanks in advance.
-
Thanks for the hint. :-) I'm using qmake, the default configuration:
@
QMAKE_CXXFLAGS += -std=c++11QT += core gui network sql
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
INCLUDEPATH += $$[QT_INSTALL_PREFIX]/src/3rdparty/zlib
TARGET = ssa
TEMPLATE = appSOURCES += \
...
@
"As far as I know qmake in Qt 5 is already forcing -fPIE":http://qt.gitorious.org/qt/qtbase/commit/482d96a0c5d523ace63f56bda6851926b4469dd0/diffs , and I could confirm the generated Makefile has -fPIE in C(XX)FLAGS indeed.
I updated to Qt 5.1.0-beta1 and seemingly nothing changed.
-
The bad news is that it's a Qt bug I found some weeks ago.
The good news is that it's fixed in the upcoming 5.1 by this commit https://codereview.qt-project.org/#change,55606 :)
-
[quote author="peppe" date="1370793539"]The bad news is that it's a Qt bug I found some weeks ago.
The good news is that it's fixed in the upcoming 5.1 by this commit https://codereview.qt-project.org/#change,55606 :)[/quote]
I see. Thanks! :-)
-
-Did the change make it in Qt5.1.1?-
-I just installed the latest version and still have this issue.-Forget it, my bad. QtCreator seduced me with a slot instead of a signal...