QObject::connect: 没有这样的信号运行时警告 - 找不到原因
Posted
技术标签:
【中文标题】QObject::connect: 没有这样的信号运行时警告 - 找不到原因【英文标题】:QObject::connect: No such signal runtime warning - cannot find the reasion for 【发布时间】:2016-08-15 10:08:38 【问题描述】:我正在开发基于this example 的异步多线程服务器。现在,我采用以下方法:
void UeClient::ueSlotReadyRead()
QList<QVariant> incomingData=QList<QVariant>();
QByteArray incomingMessage=this->ueSocket()->readAll();
UePosCommProtocolArch::UeCommand incomingCommand=UePOSCommProtocol::ueDecodeCommand(incomingMessage,
incomingData);
UeTask* ueTask=new UeTask("testDb",
"testUsername",
"testPassword",
"localhost",
"3306",
incomingCommand);
connect(ueTask,
SIGNAL(ueSignalTaskFinished(UePosCommProtocolArch::UeCommand,
QByteArray)),
this,
SLOT(ueSlotFetchData(UePosCommProtocolArch::UeCommand,
QByteArray)),
Qt::QueuedConnection);
QThreadPool::globalInstance()->start(ueTask);
// ueSlotReadyRead
我在QtCreator
中收到以下运行时警告/错误:
QObject::connect: No such signal UeTask::ueSignalTaskFinished(UePosCommProtocolArch::UeCommand, QByteArray) in ../../../net/ueclient.cpp:55
这里是UeTask类头文件,从中我们可以看到ueSignalTaskFinished(UePosCommProtocolArch::UeCommand& executedCommand, QByteArray& fetchedData);
IS声明:
#ifndef UETASK_H
#define UETASK_H
#include <QObject>
#include <QRunnable>
#include <QSqlDatabase>
#include <QSqlError>
#include <QUuid>
#include <QString>
#include <QSqlQuery>
#include <QSqlRecord>
#include <QVariant>
#include <QJsonDocument>
#include <QJsonValue>
#include <QJsonObject>
#include <QJsonArray>
#include <QByteArray>
#include "../../uePOSCommProtocol/uecommands.h"
#include "database/models/uefieldindexes.h"
#include "database/models/uequeries.h"
/*!
* \brief The UeTask class
*/
class UeTask : public QObject,
public QRunnable
Q_OBJECT
private:
/*!
* \brief m_ueDatabaseName
*/
QString m_ueDatabaseName;
/*!
* \brief m_ueUserName
*/
QString m_ueUserName;
/*!
* \brief m_uePassword
*/
QString m_uePassword;
/*!
* \brief m_ueHostName
*/
QString m_ueHostName;
/*!
* \brief m_uePort
*/
QString m_uePort;
/*!
* \brief m_ueCommand
*/
UePosCommProtocolArch::UeCommand m_ueCommand;
/*!
* @brief ueDatabaseName
* @return database name
*/
inline const QString& ueDatabaseName() const
return this->m_ueDatabaseName;
/*!
* @brief ueDatabaseUserName
* @return database user name
*/
inline const QString& ueDatabaseUserName() const
return this->m_ueUserName;
/*!
* @brief ueDatabasePassword
* @return database password
*/
inline const QString& ueDatabasePassword() const
return this->m_uePassword;
/*!
* @brief ueDatabasHost
* @return database host name
*/
inline const QString& ueDatabasHost() const
return this->m_ueHostName;
/*!
* @brief uePort
* @return database host port
*/
inline const QString& ueDatabaseHostPort() const
return this->m_uePort;
/*!
* \brief ueCommand
* \return task command
*/
inline UePosCommProtocolArch::UeCommand& ueCommand()
return this->m_ueCommand;
/*!
* @brief ueSetDatbaseName
* @param name
*/
inline void ueSetDatbaseName(const QString& name)
this->m_ueDatabaseName=name;
/*!
* @brief ueSetDatabaseUserName
* @param userName
*/
inline void ueSetDatabaseUserName(const QString& userName)
this->m_ueUserName=userName;
/*!
* @brief ueSetDatabasePassword
* @param password
*/
inline void ueSetDatabasePassword(const QString& password)
this->m_uePassword=password;
/*!
* @brief ueSetDatabaseHostName
* @param hostName
*/
inline void ueSetDatabaseHostName(const QString& hostName)
this->m_ueHostName=hostName;
/*!
* @brief ueSetDatabaseHostPort
* @param port
*/
inline void ueSetDatabaseHostPort(const QString& port)
this->m_uePort=port;
/*!
* \brief ueSetCommand
* \param command
*/
inline void ueSetCommand(const UePosCommProtocolArch::UeCommand& command)
this->m_ueCommand=command;
public:
/*!
* @brief UeTask
*/
explicit UeTask(const QString& databaseName,
const QString& userName,
const QString& password,
const QString& hostName,
const QString& port,
const UePosCommProtocolArch::UeCommand& command);
protected:
/*!
* @brief run
*/
void run();
signals:
/*!
* \brief ueSignalTaskFinished
* \param executedCommand
* \param fetchedData
*/
void ueSignalTaskFinished(UePosCommProtocolArch::UeCommand& executedCommand,
QByteArray& fetchedData);
/*!
* @brief ueSignalDatabaseConnectionOk
*/
void ueSignalDatabaseConnectionOk();
/*!
* @brief ueSignalDatabaseConnectionError
* @param error
*/
void ueSignalDatabaseConnectionError(const QSqlError& error);
;
#endif // UETASK_H
为什么我会收到这个运行时警告/错误,而signal
是不 连接到slot
?这可能是一个愚蠢的错误,但我已经为这个错误苦苦挣扎了几个小时......
【问题讨论】:
【参考方案1】:您的信号签名与您在SIGNAL
宏中编写的签名不匹配——这些是非常量引用:
SIGNAL(ueSignalTaskFinished(UePosCommProtocolArch::UeCommand&, // reference
QByteArray&)), //ditto
使用非常量引用作为信号参数已经足够可疑了,将它们与排队连接一起使用肯定是错误的。您想在这里实现什么目标?
【讨论】:
使用这两个参数,我想将数据从ueSignalTaskFinished
传输到slot
,这样我就可以处理获取的数据,这是错误的做法吗?!
那么为什么不通过引用传递给 const 呢?【参考方案2】:
信号签名是引用类型(UePosCommProtocolArch::UeCommand&, QByteArray&)。您正在尝试使用另一个签名将信号连接到插槽。
【讨论】:
请注意,如果它是 const 引用,它会匹配【参考方案3】:我已经设法通过@peppe 的回答解决了这个问题,并且我已将const
添加到SIGNAL
的声明中:
#ifndef UETASK_H
#define UETASK_H
#include <QObject>
#include <QRunnable>
#include <QSqlDatabase>
#include <QSqlError>
#include <QUuid>
#include <QString>
#include <QSqlQuery>
#include <QSqlRecord>
#include <QVariant>
#include <QJsonDocument>
#include <QJsonValue>
#include <QJsonObject>
#include <QJsonArray>
#include <QByteArray>
#include "../../uePOSCommProtocol/uecommands.h"
#include "database/models/uefieldindexes.h"
#include "database/models/uequeries.h"
/*!
* \brief The UeTask class
*/
class UeTask : public QObject,
public QRunnable
Q_OBJECT
private:
/*!
* \brief m_ueDatabaseName
*/
QString m_ueDatabaseName;
/*!
* \brief m_ueUserName
*/
QString m_ueUserName;
/*!
* \brief m_uePassword
*/
QString m_uePassword;
/*!
* \brief m_ueHostName
*/
QString m_ueHostName;
/*!
* \brief m_uePort
*/
QString m_uePort;
/*!
* \brief m_ueCommand
*/
UePosCommProtocolArch::UeCommand m_ueCommand;
/*!
* @brief ueDatabaseName
* @return database name
*/
inline const QString& ueDatabaseName() const
return this->m_ueDatabaseName;
/*!
* @brief ueDatabaseUserName
* @return database user name
*/
inline const QString& ueDatabaseUserName() const
return this->m_ueUserName;
/*!
* @brief ueDatabasePassword
* @return database password
*/
inline const QString& ueDatabasePassword() const
return this->m_uePassword;
/*!
* @brief ueDatabasHost
* @return database host name
*/
inline const QString& ueDatabasHost() const
return this->m_ueHostName;
/*!
* @brief uePort
* @return database host port
*/
inline const QString& ueDatabaseHostPort() const
return this->m_uePort;
/*!
* \brief ueCommand
* \return task command
*/
inline UePosCommProtocolArch::UeCommand& ueCommand()
return this->m_ueCommand;
/*!
* @brief ueSetDatbaseName
* @param name
*/
inline void ueSetDatbaseName(const QString& name)
this->m_ueDatabaseName=name;
/*!
* @brief ueSetDatabaseUserName
* @param userName
*/
inline void ueSetDatabaseUserName(const QString& userName)
this->m_ueUserName=userName;
/*!
* @brief ueSetDatabasePassword
* @param password
*/
inline void ueSetDatabasePassword(const QString& password)
this->m_uePassword=password;
/*!
* @brief ueSetDatabaseHostName
* @param hostName
*/
inline void ueSetDatabaseHostName(const QString& hostName)
this->m_ueHostName=hostName;
/*!
* @brief ueSetDatabaseHostPort
* @param port
*/
inline void ueSetDatabaseHostPort(const QString& port)
this->m_uePort=port;
/*!
* \brief ueSetCommand
* \param command
*/
inline void ueSetCommand(const UePosCommProtocolArch::UeCommand& command)
this->m_ueCommand=command;
public:
/*!
* @brief UeTask
*/
explicit UeTask(const QString& databaseName,
const QString& userName,
const QString& password,
const QString& hostName,
const QString& port,
const UePosCommProtocolArch::UeCommand& command);
protected:
/*!
* @brief run
*/
void run();
signals:
/*!
* \brief ueSignalTaskFinished
* \param executedCommand
* \param fetchedData
*/
void ueSignalTaskFinished(const UePosCommProtocolArch::UeCommand& executedCommand,
const QByteArray& fetchedData);
/*!
* @brief ueSignalDatabaseConnectionOk
*/
void ueSignalDatabaseConnectionOk();
/*!
* @brief ueSignalDatabaseConnectionError
* @param error
*/
void ueSignalDatabaseConnectionError(const QSqlError& error);
;
#endif // UETASK_H
然后我必须register meta type 与:
qRegisterMetaType<UePosCommProtocolArch::UeCommand>("UePosCommProtocolArch::UeCommand");
在上层类的构造函数中:
UeClient::UeClient(QObject *parent,
UeSettings* const settings)
: QObject(parent)
qRegisterMetaType<UePosCommProtocolArch::UeCommand>("UePosCommProtocolArch::UeCommand");
QThreadPool::globalInstance()->setMaxThreadCount(10);
this->ueSetSettings(settings);
// constructor
现在它可以工作了!
【讨论】:
以上是关于QObject::connect: 没有这样的信号运行时警告 - 找不到原因的主要内容,如果未能解决你的问题,请参考以下文章
QObject::connect: 没有这样的信号错误 C++
QObject::connect: 没有这样的信号progressbarV::keyReleaseEvent()
QObject::connect: 没有这样的信号运行时警告 - 找不到原因
如果在调用 QObject::connect() 之前发出信号,如何避免竞争?
QObject::connect: 需要括号,信号 QSerialPort::readyRead in ..\voltage_sensor\dialop.cpp:41