Qt和Qml交互,及多线程

注册一个对象给qml,实现代码:
Gamesub.h

#pragma once
#include 
#include
#include
#include 
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();

    // 可用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();
    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("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
                {
                    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;
        }

}

你可能感兴趣的:(Qt,Quick)