Qt - 无法分配给不存在的属性(自定义C++类)

Qt - Cannot Assign to Non-existent property (custom C++ class)

本文关键字:属性 自定义 C++ 不存在 分配 Qt      更新时间:2023-10-16

我正在尝试为我的项目为QML制作一个自定义TCP小部件(WebSocket发送HTTP请求,它不允许我发送原始TCP数据包)。我创建了"TCPSocketConnection"(在 cpp 中命名为 TCPSocketConn)类,并使用占位符方法赋予它一些属性,并尝试将其插入到 QML 中。当我尝试使用该类时,出现以下错误

qrc:/qml/qmlwebsocketclient/main.qml:43:9: Cannot assign to non-existent property "onTextMessageReceived"

我有一个这样的 QML 文件

****************************************************************************/
import QtQuick 2.0
import QtWebSockets 1.0
import Qt.Comm 2.0
Rectangle {
    width: 360
    height: 360
    TCPSocketConnection{
        id: socket
        url: "ff"
        onTextMessageReceived: {
            console.log("On Recieve: " + messsage)
        }
    }
}

TCPSocketConnection 定义如下

qmlRegisterType<TCPSocketConn>("Qt.Comm", 2, 0, "TCPSocketConnection");

在 tcpsocketconn.h 中

#ifndef TCPSOCKETCONN_H
#define TCPSOCKETCONN_H
#include <QQuickItem>

class TCPSocketConn : public QQuickItem
{
    Q_PROPERTY(QString url READ url WRITE a_1 NOTIFY a_2)
    Q_PROPERTY(QString message READ message WRITE a_3 NOTIFY textMessageRecieved)
    Q_PROPERTY(int status READ status WRITE a_4 NOTIFY statusChanged)
public:
    explicit TCPSocketConn(QQuickItem *parent = 0);
    QString url();
    QString message();
    int status();
signals:
    void a_2();
    void textMessageReceived();
    void statusChanged();
public slots:
    void a_1(QString);
    void a_3(QString);
    void a_4(int);
};
#endif // TCPSOCKETCONN_H

使用占位符 CPP 文件

#include "tcpsocketconn.h"
TCPSocketConn::TCPSocketConn(QQuickItem *parent) : QQuickItem(parent)
{
}
QString TCPSocketConn::url(){
    return "";
}
QString TCPSocketConn::message(){
    return "";
}
int TCPSocketConn::status(){
    return 0;
}
void TCPSocketConn::a_1(QString d){
}
void TCPSocketConn::a_3(QString d){
}
void TCPSocketConn::a_4(int s){
}
void TCPSocketConn::textMessageReceived(){
}
void TCPSocketConn::statusChanged(){
}
void TCPSocketConn::a_2(){
}

你缺少Q_OBJECT宏;仅仅从QObject子类派生是不够的:

Q_OBJECT宏必须出现在类定义的私有部分,该定义声明自己的信号和插槽,或使用Qt元对象系统提供的其他服务。

还有这一段:

请注意,Q_OBJECT宏对于实现信号、槽或属性的任何对象都是必需的。您还需要在源文件上运行元对象编译器。我们强烈建议在 QObject 的所有子类中使用此宏,无论它们是否实际使用信号、插槽和属性,因为如果不这样做可能会导致某些函数表现出奇怪的行为。

此处对此进行了更详细的解释。