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 [qt-project.org] 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:
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 [qt-project.org] 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.)
↧