QtCreator 中针对 C++ 类型的自动补全

Auto completion in QtCreator for C++ types

我在 C++ 中定义了一些要在 QML 中使用的 classes。在编码时,我希望 QtCreator 自动列出 C++ 对象的所有可用属性和函数。

下面的例子说明了这个问题: 在 C++ 中,我定义了一个 Office class(地址 属性 和一个 sendEmail 方法)。我还定义了一个公司 class(有一个总部 属性 和一个办公室列表)。两个class的代码都加在最后。

main.cpp 中,我添加了以下几行,目的是让 QML/javascript 知道这些类型。

Company theCompany;
engine.rootContext()->setContextProperty("theCompany", &theCompany);
qmlRegisterType<Office>();

然而,这似乎还不够:在下面的 QML 代码中,我列出了哪些 properties/methods 是自动完成的,哪些不是

import QtQuick 2.9
import QtQuick.Window 2.2

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    property var company: theCompany         //auto-completion OK
    property var hq: theCompany.headquarters //auto-completion OK
    property var hqAddress: hq.address       //auto-completion NOT OK
    property var offices: theCompany.offices //auto-completion OK
    property var firstOffice: offices[0]
    property var firstAddress:  firstOffice.address  //auto-completion NOT OK
    function update() {
        hq.sendEMail()                       //auto-completion NOT OK
    }
}

因此问题是:我可以让 QML 知道 Office 类型吗?如果可以,怎么做?这也适用于 QList<Office*> 吗?

提前致谢,

马克

==================================

office.h

#ifndef OFFICE_H
#define OFFICE_H

#include <QObject>

class Office : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString address MEMBER m_address NOTIFY addressChanged)
public:
    explicit Office(QObject *parent = nullptr);
    Q_INVOKABLE void sendEMail(QString message){};

signals:
    void addressChanged();

public slots:

private:
    QString m_address;
};

#endif // OFFICE_H

office.cpp

#include "office.h"

Office::Office(QObject *parent) : QObject(parent)
{

}

company.h

#ifndef COMPANY_H
#define COMPANY_H

#include <QObject>

#include "office.h"

class Company : public QObject
{
    Q_OBJECT
    Q_PROPERTY(Office* headquarters MEMBER m_headquarters NOTIFY headquartersChanged)
    Q_PROPERTY(QList<Office *> offices MEMBER m_offices NOTIFY officesChanged)
public:
    explicit Company(QObject *parent = nullptr);

signals:
    void officesChanged();
    void headquartersChanged();

public slots:
private:
    QList<Office*> m_offices;
    Office* m_headquarters;
};

#endif // COMPANY_H

company.cpp

#include "company.h"

Company::Company(QObject *parent) : QObject(parent)
{

}

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>

#include "company.h"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);
    QQmlApplicationEngine engine;
    Company theCompany;
    engine.rootContext()->setContextProperty("theCompany", &theCompany);
    qmlRegisterType<Office*>();
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;
    return app.exec();
}

我明白了:

property var company: theCompany         //auto-completion OK
property var hq: theCompany.headquarters //auto-completion OK
property var hqAddress: hq.address       //auto-completion NOT OK
property var offices: theCompany.offices //auto-completion OK
property var firstOffice: offices[0]
property var firstAddress:  firstOffice.address  //auto-completion NOT OK
function update() {
    hq.sendEMail()                       //auto-completion NOT OK
}

那里我从来没见过

property Office firstOffice

明白了

property var firstOffice

类型var没有属性address,所以没有代码完成。
属性 仅在运行时存在。
至少对我来说,当 Office 被注册(有名字)并且类型是 Office 时,QtCreator 会给我正确的代码完成。

hq 也是如此 - 即使是 reader 的 QML 文件我也不知道它可能是什么类型。为什么 QtCreator 应该知道这个?


顺便说一句:与 QtCreator 类似,JIT 也不知道属性,因此在等式中使用类型 var,不会有任何 optimized bindings.