近年来,QMl被Qt官方夸得天花乱坠,作为一枚传统的Qter,习惯了用QWidget,毋容置疑的是qml做出来的页面确实炫酷,那么如何在传统的qwidget中嵌入qml呢?倒腾了一上午,终于摸清了他的套路
qt版本:5.12
1.首先创建一个传统的QApplication 应用程序
2.添加新文件选择QMLFILE
3.编写qml
import QtQuick 2.0
Item {
signal signal2Widget
signal signal2qml
Rectangle{
id:root
color:"green"
width: 200
height: 200
Text {
id: mytext
anchors.bottom: parent
text:CppData.getCurrentDateTime()
}
Connections{
target: CppData
onRefshTime:{
mytext.text = CppData.getCurrentDateTime()
}
}
Rectangle{
id:sub
color: "red"
width: 100
height: 100
anchors.centerIn: root
Text {
id: subtext
font.pointSize: 11
anchors.centerIn: parent
text: qsTr(str)
}
MouseArea{
anchors.fill:parent
onClicked: signal2qml()
}
}
}
}
两个独立的矩形框,一个id为root,它的Text CppData.getCurrentDateTime()是有cpp传过来的,还有Connections连接了一个refshTime()的信号,信号触发时执行oNRefshTime函数,也就是他的text会更新。
一个id为sub,点击时会触发signal2qml()信号,等会我们在widget里面接收这个信号;
4.编写cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtQuick/QQuickView>
#include <QtQml/QQmlContext>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
m_pButton = new QPushButton("click",this);
QQuickView *view = new QQuickView;
view->rootContext()->setContextProperty("CppData",&d);
QString str = "mainwindow str";
view->rootContext()->setContextProperty("str",str);
QWidget *widget = QWidget::createWindowContainer(view,this);
view->setResizeMode(QQuickView::SizeRootObjectToView);
view->setSource(QUrl("/root/2020/qtProject/yumo/QmlFile.qml"));
//view->show();
widget->resize(200,200);
widget->move(70,60);
//widget and qml communication
QObject *pRoot = static_cast<QObject*>(view->rootObject());
if(pRoot != nullptr)
{
connect(pRoot,SIGNAL(signal2qml()),this,SLOT(resiveFromQml()));
//connect(m_pButton,SIGNAL(clicked(bool)),pRoot,SIGNAL(signal2qml()));
}
m_timer = new QTimer(this);
connect(m_timer,&QTimer::timeout,this,&MainWindow::updateTime);
m_timer->start(500);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::resiveFromQml()
{
m_pButton->setText("change form qml");
qDebug()<<"signal from qml";
}
void MainWindow::updateTime()
{
emit d.refshTime();
}
QDateTime MainWindow::getCurrentDateTime() const
{
return QDateTime::currentDateTime();
}
可以使用 QQuickView加载 QML 文档。QQmlComponent 将 QML 文档加载为一个 C++ 对象,然后可以从 C++ 代码中修改该对象。QQuickView 也做到了这一点,但由于 QQuickView 是一个基于 QWindow 的派生类,加载的对象也将被渲染至可视化显示,QQuickView 通常用于将一个可视化的 QML 对象集成到应用程序的用户界面中。QQuickView可以通过QWidget::createWindowContainer(QQuickView *,parent);的方式转换城QWidget;
QQuickView 可以通过rootContext()->setContextProperty("CppData",&d);函数将对象和名称绑定,然后在qml里面可以通过名称访问该对象;
QObject *pRoot = static_cast<QObject*>(view->rootObject()); //将qml文件转为QObject对象
if(pRoot != nullptr) //转换成功后可以将qml里面的信号和cpp里面的槽函数链接起来
{
connect(pRoot,SIGNAL(signal2qml()),this,SLOT(resiveFromQml()));
//connect(m_pButton,SIGNAL(clicked(bool)),pRoot,SIGNAL(signal2qml()));
}
运行后,qml嵌入了qWidget里面了,qml里面的矩形的text被timeout信号一直改变,点击sub时的信号会触发widget的resiveFromQml的槽函数。
一个简单的qml嵌入widget的Demo;