Qt和Qml交互,及多线程

注册一个对象给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;
        }

}
  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
QtQML是两种不同的编程语言,用于开发跨平台的应用程序。Qt是一个完整的框架,用于开发桌面、移动和嵌入式应用程序。QML是一种声明性的语言,用于设计用户界面。 QtQML之间的数据交互可以通过connections和信号槽机制实现。connections是Qt中用于连接信号和槽函数的宏,可以让两个对象之间建立通信通道。在QML中,可以使用QtQuick里的Connections元素来建立与Qt对象的连接。 在Qt中,通过使用QObject派生类中的信号和槽机制来实现对象之间的通信。信号是一种特殊的成员函数,用于通知其他对象发生了特定的事件。槽是接收信号的函数,它可以响应接收到的信号并执行相应的操作。 QML中的信号和槽可以通过在QML元素上定义信号和槽属性来实现。QML元素可以作为Qt的对象被使用,在Qt代码中可以通过QObject派生类和Q_PROPERTY宏来访问这些元素。通过使用connections来建立Qt对象和QML元素之间的链接,使得它们能够相互发送信号和响应槽函数。 QtQML之间的数据交互主要有以下几种方式: 1. 在Qt中定义一个QObject派生类,将其作为QML元素的属性,通过connections建立信号和槽的关联,从而实现数据的传递和交互。 2. 在Qt中定义一个Q_PROPERTY,并在QML中使用property绑定来实现数据的双向绑定。 3. 使用信号和槽来处理用户界面上的事件,比如点击按钮、滑动滑块等。 总的来说,QtQML之间的数据交互可以通过connections和信号槽机制来实现。这使得QtQML两种语言能够方便地在应用程序中进行通信和数据传递,提高了应用程序的灵活性和效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值