我有一个类MainWindow
作为不同视图的容器。 MainWindow
继承Qml元素Window
。 MainWindow.qml
是主要的qml文件。目前它看起来像这样:
MainWindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QQmlApplicationEngine>
#include <string>
#include "CustomMenu.h"
class MainWindow : public QObject
{
Q_OBJECT
private:
QQmlApplicationEngine engine_;
QObject* content_;
public:
MainWindow(QObject* parent = 0);
Q_INVOKABLE void changeContent(std::string contentID);
};
#endif // MAINWINDOW_H
MainWindow.cpp:
#include "MainWindow.h"
#include <QQmlComponent>
#include <QObject>
#include <QtQml>
#include <iostream>
// Legt ein neues MainWindow-Objekt an und registriert die eigenen Typen für QML
MainWindow::MainWindow(QObject* parent)
: QObject(parent), engine_(new QQmlApplicationEngine())
{
std::cout << "in mainwindow ctor" << std::endl;
// Registriere Typen für QML
qmlRegisterType<MainWindow>("com.Gui", 1, 0, "MainWindow");
qmlRegisterType<CustomMenu>("com.Gui", 1, 0, "StartMenu");
qmlRegisterType<CustomMenu>("com.Gui", 1, 0, "HelpMenu");
// Lade MainWindow
engine_.load(QUrl(QStringLiteral("qrc:/Gui/MainWindow.qml")));
}
void MainWindow::changeContent(std::string contentID)
{
// not implemented yet
}
MainWindow.qml:
import QtQuick 2.3
import QtQuick.Window 2.2
import com.Gui 1.0
Window {
visible: true
id: main
width: 1024
height: 768
property string contentID: "startMenu"
property CustomMenu content: null
MouseArea {
anchors.fill: parent
onClicked: {
main.changeContent("StartMenu")
}
}
}
Main.cpp的
#include <QGuiApplication>
#include "Gui/MainWindow.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
MainWindow* mainwindow = new MainWindow();
return app.exec();
}
当我尝试拨打changeContent()
时,它会说:TypeError: Property 'changeContent' of object MainWindow_QMLTYPE_1(0x1e8b5c0) is not a function
。
如何在不在qml文件中实例化MainWindow
的情况下调用它?
或者:我如何让qml根元素知道它是MainWindow
中Main.cpp
的实例?
编辑:所做的更改:
MainWindow.cpp(分别更改了标题)
...
MainWindow::MainWindow(QWindow* parent)
: QQuickView(parent), engine_(new QQmlApplicationEngine())
{
std::cout << "in mainwindow ctor" << std::endl;
}
void MainWindow::show()
{
// Registriere Typen für QML
qmlRegisterType<MainWindow>("com.Gui", 1, 0, "MainWindow");
qmlRegisterType<CustomMenu>("com.Gui", 1, 0, "StartMenu");
qmlRegisterType<CustomMenu>("com.Gui", 1, 0, "HelpMenu");
// Setze diese Instanz als Rootobjekt in QML
this->rootContext()->setContextProperty("mainWindowInstance", this);
// Lade MainWindow
engine_.load(QUrl(QStringLiteral("qrc:/Gui/MainWindow.qml")));
}
...
MainWindow.qml
import QtQuick 2.3
import QtQuick.Window 2.2
import com.Gui 1.0
Window {
visible: true
id: main
width: 1024
height: 768
property string contentID: "startMenu"
property CustomMenu content: null
property MainWindow mainWindowInstance
MouseArea {
anchors.fill: parent
onClicked: {
mainWindowInstance.changeContent("StartMenu")
}
}
}
Main.cpp的
#include <QGuiApplication>
#include "Gui/MainWindow.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
MainWindow* mainwindow = new MainWindow();
mainwindow->show();
return app.exec();
}
答案 0 :(得分:1)
您可以使用QQmlContext::setContextProperty()
导出已注册类型的实例。
在我的应用中,我打电话,例如:
qmlRegisterType<MyClass>("MyModule", 1, 0, "MyClass");
MyClass* mClassInstance = new MyClass;
mMainView->rootContext()->setContextProperty("classInstance", mClassInstance);
现在,我可以在导入classInstance
后访问QML世界中的MyModule
。
我的mMainView
此处继承自QQuickView
。
我想你会明白这个想法。