WebEngineContext used before QtWebEngine::initialize() or OpenGL context creation failed
–
出现情况:vs2015+Qt5.9.4 使用QWebEngineView类,选择32bit编译时正常, 选择64bit编译出现上述错误,并崩溃
解决方法:在new QWebEngineView前 加上QCoreApplication::setAttribute(Qt::AA_UseOpenGLES);
QML与C++交互:
在C++里创建一个继承于QObject的类MyClass
使用Q_PROPERTY定义属性
Q_PROPERTY(QString mystring READ getString WRITE setString NOTIFY mystringChanged)
读,写,信号量
public槽函数,以及Q_INVOKABLE宏标记的public函数,还通过Q_PROPERTY注册了的属性,这些方法和属性之后都可以在QML中进行访问。
QT使用qmlRegisterType方法将类注册到QML中,例:
qmlRegisterType<MyClass>("RegisterMyType",1,0,"MyClassType");
其中,第一个参数是作为QML中引用的url;第二个参数是主版本号;第三个参数是次版本号;第四个参数是QML中使用的元素名称。
经过上面的步骤之后,我们就可以直接在QML中创建MyClassType对象了。例:
MyClassType {
id: myobj
}
对象创建成功后,我们可以为QML绑定感兴趣的信号了。
Connections {
target: myobj;
onMystringChanged: {
// 这里的value是signal信号函数里面的参数
console.log("value: " + value)
}
}
第二种方式直接在cpp中创建对象,然后将对象暴露给qml这样就不需要register和在qml中注册了
在上面的例子中,我们可以下面的方式,我们首先在C++代码中做如下声明:
QQmlApplicationEngine *qmlEngine = new QQmlApplicationEngine;
QQmlComponent component(qmlEngine, QUrl("qrc:/MyClass.qml"));
MyClass *myClass = qobject_cast<MyClass *>(component.create());
qmlEngine->rootContext()->setContextProperty("myQmlClass", myClass);
其中,QQmlComponent用来封装QML组件。需要注意的是,MyClass.qml中,需要使用上面讲到的MyClassType作为顶层元素。 setContextProperty函数定义暴露给QML的对象。第一个参数是QML中使用的对象名称,相当于重命名,可在QML中直接使用;第二个参数暴露给QML的对象。而信号的绑定,只需要将上面讲到的Connections中的target修改为myQmlClass即可。即:
Connections {
target: myQmlClass;
onMystringChanged: {
// 这里的value是signal信号函数里面的参数
console.log("value: " + value)
}
}
QML与HTML交互
QML与HTML交互采用WebEngine和WebChannel的方式
WebChannel进行qml和html的连接,在qml中定义一个对象
QtObject定义如下:
QtObject {
id: myObject
WebChannel.id: "myWebObject"
property string name: "QtObjectName"
signal onMystringChanged(var myStr)
}
WebChannel定义如下:
WebChannel {
id: myChannel
registeredObjects: [myObject]
}
在WebEngine中挂载html和webchannel
WebEngineView {
id: webView
url: "file:///C:/test.html"
webChannel: myChannel
}
至此,QML端的工作就已经完成了
在html中绑定qwebchannel库
<script type="text/javascript" src="qwebchannel.js"></script>
new QWebChannel(qt.webChannelTransport, function(channel) {
var myClass = channel.objects.myClass;
var myObject = channel.objects.myWebObject;
myObject.onMystringChanged.connect(function(myStr) {
console.log(myStr);
});
});
Qt与Json文档的交互
写入 删除 修改都是一套流程
如果使用object那么写入和读取都是无序的,使用array则有序
先以只读方式打开
QFile file(QStringLiteral("url"));
file.open(QIODevice::ReadOnly);
QByterArray allData = file.readAll();
file.close();
创建JsDoc进行编辑
QJsonDocument jsonDoc(QJsonDocument::fromJson(allData));
QJsonObject obj = jsonDoc.object();
//编辑内容
jsonDoc.setObject(obj);
以重写的方式将文档写入
file.open(QIODevice::WriteOnly|QIODevice::Truncate);
file.write(jsonDoc.toJson());
file.close();
MVC
在TreeView中如果想使用设置当前值的方法需要设置selection:ItemSelectionModel和selection.setCurrentIndex()
CMake工程设置qrc的时候使用qt5_add_resources添加qrc,否则中文无法使用
CMake在set QML_IMPORT_PATH属性时还需要设置CACHE,否则语法依然不高亮