为什么在QML代码中会出现这个错误:ReferenceError: m_jsonDocStr is not defined
,即使在C++代码中指定了m_jsonDocStr
:
Q_PROPERTY(QString m_jsonDocStr READ jsonDocToStr WRITE setJsonDocStr NOTIFY jsonDocStrChanged)
为什么不能从QML打开www.example.com()C函数?QmlLink.open() C function is not opened from QML? (neither as a normal member function nor as a slot)
TypeError: Property 'open' of object [object Object] is not a function
接下来,用“<--”注解,我指向代码的关键行,以及我得到的错误消息。
这是QML文件:
/** Main.qml */
import QtCore
import QtQuick
import QtQuick.Window
import QtQuick.Controls
import QtQuick.Dialogs
import QtQuick.Layouts
import main
ApplicationWindow {
id: window
width: 640
height: 480
visible: true
title: qsTr("Data input widget")
property string dataFilename: ""
property string dataFile: ""
menuBar: MenuBar {
Menu {
title: qsTr("&File")
Action {
text: qsTr("&Open...")
onTriggered: fileDialog.open()
}
}
}
ScrollView {
id: fileContents
anchors.fill: parent
property string dataFile: m_jsonDocStr // <-- ReferenceError: m_jsonDocStr is not defined
TextArea {
text: "File: " + dataFilename + "\n" + dataFile + "\nLength: " + dataFile.length
}
}
FileDialog {
id: fileDialog
title: "Open data file"
nameFilters: ["JSON files (*.json)"]
onAccepted: {
dataFilename = selectedFile
console.log("Open file: " + dataFilename)
QmlLink.open(dataFilename) // <-- TypeError: Property 'open' of object [object Object] is not a function
console.log("File contents: " + m_jsonDocStr)
}
onRejected: {
console.log("No file selected.")
}
}
}
下面是头文件:
/** QmlLink.hpp */
#ifndef QMLLINK_HPP
#define QMLLINK_HPP
#include <QObject>
#include <QJsonDocument>
#include <QtQml/qqmlregistration.h>
class QmlLink : public QObject
{
Q_OBJECT
Q_PROPERTY(QJsonDocument m_jsonDoc READ jsonDoc WRITE setJsonDoc NOTIFY jsonDocChanged)
Q_PROPERTY(QString m_jsonDocStr READ jsonDocToStr WRITE setJsonDocStr NOTIFY jsonDocStrChanged)
QML_ELEMENT
public:
explicit QmlLink(QObject *parent = nullptr);
public slots:
QJsonDocument jsonDoc() const { return m_jsonDoc; }
void setJsonDoc(const QJsonDocument &jsonDoc) { m_jsonDoc = jsonDoc; }
QString jsonDocToStr() const { return m_jsonDoc.toJson(); }
void setJsonDocStr(const QString &jsonDoc) { m_jsonDoc = QJsonDocument::fromJson(jsonDoc.toUtf8()); }
signals:
void jsonDocChanged();
void jsonDocStrChanged();
public slots:
void menuOpen();
int open(QString filePath);
private:
QJsonDocument m_jsonDoc;
QString m_jsonDocStr;
QString m_jsonFileName = "default.json";
};
#endif // QMLLINK_HPP
这是实现文件:
/** QmlLink.cpp */
#include "QmlLink.hpp"
#include <iostream>
#include <QDebug>
#include <QFile>
#include <QQmlContext>
#include <QQmlEngine>
#include <QQuickView>
QmlLink::QmlLink(QObject *parent) : QObject{parent} {}
void QmlLink::menuOpen() {
open(m_jsonFileName);
}
int QmlLink::open(QString filePath)
{
m_jsonFileName = filePath;
QUrl url(filePath);
QFile jsonFile;
jsonFile.setFileName(url.toLocalFile());
if(jsonFile.open(QIODevice::ReadOnly) == false) {
return -1;
}
const QByteArray data = jsonFile.readAll();
m_jsonDoc = QJsonDocument::fromJson(data);
const QString strDoc(m_jsonDoc.toJson(QJsonDocument::Compact));
std::cout << "Data file contents: " << strDoc.toStdString() << std::endl;
return 0;
}
这是一个经典的main()函数:
/** main.cpp */
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "QmlLink.hpp"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QmlLink qmlLink;
QQmlApplicationEngine engine;
const QUrl url(u"qrc:/main/Main.qml"_qs);
QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed,
&app, []() { QCoreApplication::exit(-1); },
Qt::QueuedConnection);
engine.load(url);
QQmlContext *rootContext = engine.rootContext();
rootContext->setContextProperty("QmlLink", &qmlLink);
return app.exec();
}
这是一个简单的JSON文件:
{
"Array": [
true,
999,
"string"
],
"Key": "Value",
"null": null
}
工具版本:
- Qt 6.5
- 操作系统:Linux
- gcc 13.1
- clang 15
2条答案
按热度按时间c2e8gylq1#
在加载url之前,您应该设置context属性:
并修复
Main.qml
:要在
ScrollView
中显示文件的内容,QmlLink.cpp
中还需要做一些改动:QmlLink.hpp
:f87krz0w2#
我认为你不能把
QJsonDocument
从C++传递给QML。正如你提到的,你会得到一个“无法将[undefined]赋值给QString”错误。但是我的想法是通过QByteArray。下面是我的例子:
在main.cpp中:
在Main.qml中
这是我的结果: