我试图打包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:Property' press'对象QmlTest_QMLTYPE_0(0x1b4c780)不是函数
显然,它试图调用属性pressed
而不是信号pressed
。这有解决方法吗?请记住,界面必须模仿MouseArea
,因此需要同时具有pressed
属性和信号。
这确实让我觉得它是一个错误,显然MouseArea
管理它,但它是从C ++声明的。我知道任何稍微复杂的QML问题的通常答案是"在C ++"中做,但因为绝大多数QtQuick类是私有的,所以它通常不实用。
答案 0 :(得分:1)
听起来你自己已经回答了这个问题。我怀疑QML中是否有针对此问题的解决方法,答案可能是#34;在C ++中做到这一点" - 但我无法肯定地说。
以下是如何在C ++中执行此操作,定义使用QQuickItem
在内部创建MouseArea
的{{1}}:
QQmlComponent
#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
}
并想知道为什么我有一个空MouseArea
,然后发现它是documented not to have a context at that stage:
请注意,当在QObject子类的构造函数内部调用时,这些函数将返回null,因为该实例还没有上下文或引擎。
唯一的问题是QQmlEngine
的{{3}};其MouseArea
参数为pressed signal。您可能能够以某种方式封装该类,并为用户提供包含其所有属性的JavaScript对象,但此时似乎更容易使用私有API。