您的位置:首页 > 编程语言 > Qt开发

Qt和Qml交互,及多线程

2016-05-08 17:56 393 查看
注册一个对象给qml,实现代码:

Gamesub.h

#pragma once
#include <QObject>
#include<QVariant>
#include<QQmlApplicationEngine>
#include <QquickItem>
class Gamesub :public QObject
{
Q_OBJECT
public:
Gamesub(QObject* parent=NULL);
~Gamesub();
QQmlApplicationEngine*  m_mainroot;
QQuickItem*  m_page;
Q_INVOKABLE void   setpage(QQuickItem* page);
void   setroot(QQmlApplicationEngine* mainroot);
Q_INVOKABLE void   init();
Q_INVOKABLE void msg(QVariant  var);
Q_INVOKABLE QVariant getobj();

};


Gamesub.cpp

#include "Gamesub.h"

Gamesub::Gamesub(QObject* parent):QObject(parent)
{
}

Gamesub::~Gamesub()
{
}

Q_INVOKABLE void   Gamesub::setpage(QQuickItem* page)
{
m_page = page;
OutputDebugStringA(m_page->objectName().toStdString().c_str());

}
int cout = 0;
DWORD  thtest(LPVOID lp)
{
QQuickItem*  m_page = (QQuickItem*)lp;

QVariant   item;
//BlockingQueuedConnection 多线程 中使用,否则会出错
bool ret2 = QMetaObject::invokeMethod(m_page, "getitem", Qt::ConnectionType::BlockingQueuedConnection, Q_RETURN_ARG(QVariant, item), Q_ARG(QVariant, cout));
if (ret2 == false)
{
AfxMessageBox("eRROR");
}
QObject*  obj;
obj = item.value<QObject*>();

//  可用item.typeName()获取返回值类型,然后,使用item.value<类型>() 进行转换
int  var =0;
while (true)
{
var=var+1;
if (obj!=NULL  && IsBadWritePtr(obj,4)==false)
{
QMetaObject::invokeMethod(obj, "test", Qt::ConnectionType::QueuedConnection, Q_ARG(QVariant, QString::number(var)));
//此处也可修改为 Qt::ConnectionType::BlockingQueuedConnection
}

Sleep(1000);
}
return  0;
}
Q_INVOKABLE void   Gamesub::init()
{

for (int i=0;i<5;i++)
{
QVariant  s;
s = i;
QMetaObject::invokeMethod(m_page, "addmodel", Q_ARG(QVariant, s.toString()));

}
QVariant ret;
QMetaObject::invokeMethod(m_page, "getlen", Q_RETURN_ARG(QVariant, ret));
//AfxMessageBox(ret.typeName());
AfxMessageBox(ret.toString().toStdString().c_str());

QVariant   item;
bool ret2 = QMetaObject::invokeMethod(m_page, "getitem", Q_RETURN_ARG(QVariant, item), Q_ARG(QVariant, 0));
if (ret2 == false)
{
AfxMessageBox("eRROR");
}
QObject*  obj;
obj = item.value<QObject*>();
AfxMessageBox(obj->objectName().toStdString().c_str());

for (int i = 0; i < ret.toInt(); i++)
{
AfxBeginThread(AFX_THREADPROC(thtest), m_page);
Sleep(100);
cout++;

}

}
void Gamesub::setroot(QQmlApplicationEngine * mainroot)
{
m_mainroot = mainroot;
}

Q_INVOKABLE void Gamesub::msg(QVariant var)
{
AfxMessageBox(var.toString().toStdString().c_str());

}

Q_INVOKABLE QVariant Gamesub::getobj()
{
if (m_mainroot !=NULL)
{

QObject *tmp = m_mainroot->findChild<QObject *>("mmodel");
if (tmp!=NULL)
{
OutputDebugStringA("OK  object");
}
else
{
OutputDebugStringA("Null  object");
}

}
return 0;
}


main.cpp:

// 首先注册一下类
qmlRegisterType<Gamesub>(
"game",
1,
0,
"game");
QApplication* app = (QApplication *)QApplication::instance();

OutputDebugStringA("local file");

QQmlApplicationEngine engine(app);

Gamesub*  tmp = new Gamesub();
tmp->m_mainroot = &engine;
engine.rootContext()->setContextProperty("game", (QObject*)tmp);
engine.load(QUrl::fromLocalFile(QStringLiteral("main.qml")));


点击运行,C++代码动态添加model,并且在多线程中,刷新UI

Qml文件:

main.qml

import QtQuick 2.6
import QtQuick.Window 2.2
import Material 0.1  as  Material
import Material.ListItems 0.1 as ListItems
import Material.Extras 0.1     as Ex

Material.ApplicationWindow{
property Item tmp: null
visible:  true
title: "主窗口"
property var mytabs:  ["主要"]
theme{
primaryColor: Material.Palette.colors["blue"]["500"]
primaryDarkColor: Material.Palette.colors["blue"]["700"]
accentColor: Material.Palette.colors["teal"]["500"]
tabHighlightColor: "white"
}

initialPage: Material.Page{
id:mainpage
title: "主窗口"
tabs: mytabs

onSelectedTabChanged: {
if(selectedTab==1)
{
mainrun.visible=false
loader.source=Qt.resolvedUrl("run2.qml")
loader.visible=true
}else{
mainrun.visible=true
loader.visible=false
}
}
Loader{
anchors.fill: parent
visible: false
id:loader
// source: Qt.resolvedUrl("run2.qml")
}

Material.Button{
id:mainrun
visible: true
text: "运行"
elevation: 1
onClicked: {

mytabs[1]="进行中"
mainpage.tabs  =mytabs
mainpage.selectedTab=1
text="runing"
}

}
}

DropArea{
anchors.fill: parent
onDropped: {
for(var i=0;i<drop.urls.length;i++)
{
title=title+drop.text +","
}

}
}
}


run2.qml:

import QtQuick 2.6
import QtQuick.Window 2.2
import Material 0.1  as  Material
import Material.ListItems 0.1 as ListItems
import Material.Extras 0.1     as Ex

Material.View{

id:page
objectName: "mmodel"
Component.onDestruction: {
console.log("onDestruction")
}

Flow{
spacing: 5
anchors.fill: parent
Repeater{
id:rey
model:mmodel
delegate: componet

}
Component.onCompleted: {

game.setpage(page);
game.init();
}
}

ListModel{
id:mmodel
ListElement{txt:"test"}
ListElement{txt:"test2"}
ListElement{txt:"test3"}
}

Component{
id:componet
Material.View{
id:m_view
objectName: "index"
elevation: 3
width: 120
height: 300
anchors.margins: 5
Column{
width: parent.width
Material.Button{
id:btn
elevation: 1
width: parent.width
text:txt;
}
Repeater{
model: mmodel2
delegate: ListItems.Standard{
valueText: index
itemLabel.font.pixelSize: 14
elevation: 1
id:labels
text: shows

}

}
}
ListModel{
id:mmodel2
ListElement{shows:"test"}
}
function  test(txt)
{
if(mmodel2.count>5)
{
mmodel2.clear()
mmodel2.sync()
}
mmodel2.append({shows:txt})
}
}
}

function  getitem(index)
{

var i= rey.itemAt(index)
console.log("index:"+index+":"+i)
return i;
}

function  addmodel(argtxt)
{
mmodel.append({txt:argtxt})
}
function getlen()
{
return mmodel.count;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: