入门: 跳转
1.注册qml对象
main.cpp中注册上下文全局对象
一般你是qml程序 基本可以找到qml引擎---->engine
缺点:全局对象嘛,每个qml文件都能使用
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("id",&对象);
c++函数想要被qml使用需要在方法声明前面Q_INVOKABLE
c++属性想要被qml访问需要使用Q_PROPERTY定义
c++枚举想要被qml使用需要使用Q_ENUM
c++信号想要被qml使用,可以直接使用,只需要使用qml的connections连接信号与槽
// 方法
class MyObject : public QObject{
Q_OBJECT
// 将属性暴露给qml---需要封装好 读取与赋值方法,与变化信号(变化信号用来通知ui绑定项变动)
Q_PROPERTY(type name READ name WRITE setname NOTIFY nameChanged FINAL)
public:
Q_INVOKABLE bool load(QString fileName); //将方法暴露给qml
enum MyEnum {
Option1,
Option2,
Option3
};
Q_ENUM(MyEnum) //将枚举暴露给qml
}
2.注册qml类型
main.cpp中注册为qml使用的类型
使用直接跟qml组件一样就可以了,如果想要被qml使用属性,方法,枚举跟上面一样既可
qmlRegisterType<CppObject>("MyCppObject", 1, 0, "CppObject");
3. c++封装qml组件
①派生QQuickPaintedItem
重写方法virtual void paint(QPainter *painter) = 0
②派生QQuickImageProvider
MyImageProvider.h
#ifndef MYIMAGEPROVIDER_H
#define MYIMAGEPROVIDER_H
#include <QImage>
#include <QQuickImageProvider>
class MyImageProvider : public QQuickImageProvider
{
public:
explicit MyImageProvider();
QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize) override;
private:
QImage m_image;
signals:
};
#endif // MYIMAGEPROVIDER_H
MyImageProvider.cpp
#include "MyImageProvider.h"
#include <QDebug>
MyImageProvider::MyImageProvider()
: QQuickImageProvider{QQuickImageProvider::Image}
{
m_image.load("1.bmp");
}
QImage MyImageProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize)
{
qDebug()<<size->width();
qDebug()<<size->height();
qDebug()<<requestedSize;
return m_image;
}
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QApplication>
#include <QDebug>
#include <MyImageProvider.h>
int main(int argc, char *argv[])
{
//qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard"));
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
//QGuiApplication app(argc, argv);
QApplication app(argc,argv);
MyImageProvider myImageProvider;
QQmlApplicationEngine engine;
engine.addImageProvider(QLatin1String("myImageProvider"),&myImageProvider);
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(
&engine,
&QQmlApplicationEngine::objectCreated,
&app,
[url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
},
Qt::QueuedConnection);
engine.load(url);
return app.exec();
}
main.qml
requestImage(const QString &id, QSize *size, const QSize &requestedSize) 有三个参数
id-------source: "image://myImageProvider/1.bmp"中的1.bmp
requestedSize -------Image::sourceSize
import QtQuick 2.15
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import QtQuick.Window 2.15
Window {
id: window
width: 640
height: 480
visible: true
title: qsTr("Hello World")
ScrollView{
width: 300
height: 300
Image{
source: "image://myImageProvider/1.bmp"
}
}
}
4.qquickwidget启动qml
这样做的意义是什么呢? 由于qml绘画吃显卡,qwidget吃cpu,
通过混用
我们可以在一些静态页面那里使用qml 工作,
比如设计一个绘图编辑器的时候需要更加高效,我们就可以使用qwidget
将原来的
QQmlApplicationEngine engine;
engine.addImageProvider(QLatin1String("myImageProvider"),&myImageProvider);
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(
&engine,
&QQmlApplicationEngine::objectCreated,
&app,
[url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
},
Qt::QueuedConnection);
engine.load(url);
改为
#include <QQuickWidget>
QQuickWidget mainWidget;
const QUrl url(QStringLiteral("qrc:/main.qml"));
mainWidget.engine()->addImageProvider(QLatin1String("myImageProvider"),&myImageProvider);
mainWidget.setSource(url);
mainWidget.show();
并且将main.qml中Window改为Rectangle
import QtQuick 2.15
//import QtQuick.Controls 2.12
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
//import com.ui.custom 1.0
Rectangle {
id: window
width: 640
height: 480
visible: true
//title: qsTr("Hello World")
ScrollView{
width: 300
height: 300
Image{
source: "image://myImageProvider"
}
}
}
当然最快捷的方法就是创建一个qwidget项目
然后新增一个qrc资源文件,里面主要放我们的qml文件,然后重复上面的操作就可以实现
qwidget与qml 混用了