Qt 如果QML与属性具有相同的名称,则它无法发出信号

Qt 如果QML与属性具有相同的名称,则它无法发出信号,qt,qml,Qt,Qml,我试图包装一个MouseArea来定制它的行为,但遇到了一个奇怪的问题。下面的示例代码演示了该问题: import QtQuick 2.3 Item { id: base width: 100 height: 100 anchors.fill: parent property alias pressed: area.pressed signal pressed( var mouse ) MouseArea { id:

我试图包装一个
MouseArea
来定制它的行为,但遇到了一个奇怪的问题。下面的示例代码演示了该问题:

import QtQuick 2.3

Item {
    id: base
    width: 100
    height: 100
    anchors.fill: parent

    property alias pressed: area.pressed

    signal pressed( var mouse )

    MouseArea {
        id: area
        anchors.fill: parent

        onPressed: {
            base.pressed( mouse );
        }
    }
}
在矩形中单击会导致此错误:

TypeError:对象QmlTest_QMLTYPE_0(0x1b4c780)的属性“已按下”不是函数

显然,它试图调用属性
pressed
,而不是信号
pressed
。有解决办法吗?请记住,接口必须模拟
MouseArea
,因此需要同时具有
按下的属性和信号


这确实把我当作一个bug,正如《代码》> MouseArea <代码>管理它,但它是从C++声明的。我知道,对于任何稍微复杂的QML问题,通常的答案都是“用C++完成”,但因为绝大多数QtQuick类都是私有的,所以通常不实用。

听起来你自己已经回答了这个问题。我怀疑QML中是否有解决这一问题的方法,答案可能是“用C++实现”——尽管我不能肯定

这是如何在C++中定义一个<代码> qQuijys<代码> >在内部创建<代码> MouseArea <代码>使用<代码> QQMListabs>代码>:

main.cpp 内部mousearea.qml 起初,我使用构造函数创建了
MouseArea
,想知道为什么我有一个空的
QQmlEngine
,然后发现它是:

请注意,当在QObject子类的构造函数中调用这些函数时,它们将返回null,因为实例还没有上下文或引擎


唯一的问题是
MouseArea
;其
MouseEvent
参数为。您可能能够以某种方式封装该类,并为用户提供一个包含其所有属性的JavaScript对象,但此时使用私有API似乎更容易。

您的类型必须是注册的、可导入的QML类型吗,或者它可以是一个上下文属性吗?在一个普通的应用程序中,我会设想我的类型在许多地方用不同的参数实例化,所以我怀疑上下文属性是否实用。但是,如果这对其他人来说是一个有效的解决方法,请分享你的想法。啊,我刚刚意识到我忘记了带事件参数的pressed()信号。。。
#include <QGuiApplication>
#include <QtQml>
#include <QtQuick>

class CustomMouseArea : public QQuickItem
{
    Q_OBJECT

    Q_PROPERTY(bool pressed READ pressed NOTIFY pressedChanged)
public:
    CustomMouseArea() :
        mMouseArea(0)
    {
    }

    // Can't use constructor, as we don't have a QQmlContext by that stage.
    void componentComplete() {
        QQmlComponent component(qmlEngine(this), QUrl(QStringLiteral("qrc:///InternalMouseArea.qml")));
        if (component.status() != QQmlComponent::Ready) {
            qDebug() << component.errorString();
            return;
        }

        mMouseArea = qobject_cast<QQuickItem*>(component.create());
        Q_ASSERT(mMouseArea);
        mMouseArea->setParentItem(this);

        connect(mMouseArea, SIGNAL(pressedChanged()), this, SIGNAL(pressedChanged()));

        // Don't forget to call the base class' implementation, or no child items will show up! :)
        QQuickItem::componentComplete();
    }

    bool pressed() const {
        return mMouseArea->property("pressed").toBool();
    }
signals:
    void pressedChanged();
private:
    QQuickItem *mMouseArea;
};

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    qmlRegisterType<CustomMouseArea>("Test", 1, 0, "CustomMouseArea");

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:///main.qml")));

    return app.exec();
}

#include "main.moc"
import QtQuick 2.3
import QtQuick.Controls 1.2

import Test 1.0

ApplicationWindow {
    width: 400
    height: 400
    color: "green"
    visible: true

    CustomMouseArea {
        anchors.fill: parent

        onPressedChanged: print("pressed =", pressed)
    }
}
import QtQuick 2.0

MouseArea {
    anchors.fill: parent
}