C++要做的事情:
1.QML中注册C++类型(qmlRegisterType)
2.获取元对象树,从中提取注册的指针【这样就和普通的对象一样了】
qml要做的事情:
1.import注册的C++类型
2.使用onXXX进行qml与C++的交互
通过Q_PROPERTY进行交互
-----------------------------------------------------------
因为qml启动开销大,第一次是创造界面,然后在第二次,第三次等仅仅是隐藏,并没有销毁窗口;
程序运行截图如下:
源码如下:
test.h
#ifndef TEST_H
#define TEST_H
#include <QObject>
class Test : public QObject
{
Q_OBJECT
public:
explicit Test(QObject *parent = 0);
Q_PROPERTY(QString msg READ msg WRITE setMeg NOTIFY msgChanged)
Q_PROPERTY(QString close READ close WRITE setClose NOTIFY closeChanged)
QString msg();
QString close();
void setClose(QString close);
void setMeg(QString msg);
signals:
void msgChanged();
void aquireData(QString msg);
void closeChanged();
void hideQMLWindow();
private:
QString m_msg;
};
#endif // TEST_H
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
class QQmlApplicationEngine;
class Test;
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
public slots:
void btnClicked();
void getMes(QString msg);
void closeQML();
private:
Ui::Widget *ui;
QQmlApplicationEngine *m_engine;
Test *m_test;
bool m_windowShow;
bool m_realLoad;
};
#endif // WIDGET_H
main.cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
test.cpp
#include "test.h"
#include <QDebug>
Test::Test(QObject *parent) : QObject(parent)
{
}
QString Test::msg()
{
return "";
}
QString Test::close()
{
}
void Test::setClose(QString close)
{
Q_UNUSED(close)
emit closeChanged();
emit hideQMLWindow();
}
void Test::setMeg(QString msg)
{
emit aquireData(msg);
}
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include "test.h"
#include <QDebug>
#include <QQmlApplicationEngine>
#include <QQuickView>
#include <QList>
#include <typeinfo>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
m_realLoad=false;
m_windowShow=false;
m_engine=new QQmlApplicationEngine;
connect(ui->pushButton,SIGNAL(clicked(bool)),this,SLOT(btnClicked()));
}
Widget::~Widget()
{
delete ui;
}
void Widget::btnClicked()
{
if(m_windowShow){
return;
}
if(m_realLoad){
qDebug()<<"开启";
m_test->setClose("开启");
return;
}
qmlRegisterType<Test>("Test",1,0,"Test");
m_engine->load(QUrl(QLatin1String("qrc:/example.qml")));
QList<QObject*> qmlList=m_engine->rootObjects();
QObjectList list=qmlList[0]->children()[0]->children();
for(int i=0;i<list.size();i++){
if(QString(typeid(*list[i]).name()).contains("Test")){
m_test=qobject_cast<Test*>(list[i]);
connect(m_test,SIGNAL(aquireData(QString)),this,SLOT(getMes(QString)));
connect(m_test,SIGNAL(deleteQMLWindow()),this,SLOT(closeQML()));
m_windowShow=true;
m_realLoad=true;
break;
}
}
}
void Widget::getMes(QString msg)
{
QStringList list=msg.split(";");
for(int i=0;i<list.size();i++){
ui->plainTextEdit->insertPlainText(list[i]+"\n");
}
ui->plainTextEdit->insertPlainText("---------------------\n");
m_windowShow=false;
}
void Widget::closeQML()
{
m_windowShow=false;
}
example.qml
import QtQuick 2.5
import QtQuick.Window 2.2
import Test 1.0
import QtQuick.Controls 1.4
Window {
id:window
visible: true
width: 240
height: 100
title: qsTr("QML数据发出窗口")
onClosing: {
test.close="close"
window.hide()
}
Column{
spacing:2
Row{
spacing:2
Label{
text:"姓名:"
font.pixelSize: 22
font.italic: true
}
TextEdit{
id:name
width:240
font.pixelSize: 20
}
}
Row{
spacing:2
Label{
text:"性别:"
font.pixelSize: 22
font.italic: true
}
TextEdit{
id:sex
width:240
font.pixelSize: 20
}
}
Row{
spacing:2
Label{
text:"年龄:"
font.pixelSize: 22
font.italic: true
}
TextEdit{
id:age
width:240
font.pixelSize: 20
}
}
Button{
id:submit
width:240
text: qsTr("提交")
onClicked:{
test.msg="姓名:"+name.text+";"+"性别:"+sex.text+";"+"年龄:"+age.text
window.hide();
}
}
Test{
id:test
onCloseChanged:{
window.show()
}
}
}
}