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;
        }

}
时间: 2024-10-05 02:59:00

Qt和Qml交互,及多线程的相关文章

4.7版本的qt中qml的背景透明设置和最小化

qml中的背景透明设置: view.setStyleSheet("background:transparent;"); view.setAttribute(Qt::WA_TranslucentBackground); qml中设置背景透明后showMinimized()(最小化)不好用解决方案是: 对qml的焦点事件重载 头文件: #ifndef QML_WIDGET_SET_H #define QML_WIDGET_SET_H #include <QDeclarativeVie

[Qt学习篇]Qthread实现多线程操作

一.QThread类概述 QThread类为用户管理多线程提供了一种平台无关的途径. #include <QThread> 继承自QObject类 二.QThread类详述 QThread对象在程序内部进行控制线程的管理,QThread起始于run()函数额执行.默认情况下,run()通过调用exec()启动事件循环(event loop),并在线程内部执行Qt 的事件循环. 以下示例通过QObject::moveToThread()调用把worker对象添加到线程中运行: class Wor

Modle/View/Delegate框架+QSqlQuery类实现QT和MYSQL交互

2020的春节,武汉的疫情让我安心在家学QT,很喜欢https://www.devbean.net/category/qt-study-road-2/文章,深入浅出,很接地气.虽然也存在一些问题,但觉得值得初学者一读. QT库一个很庞大的系统,由于时间和精力有限,不能系统的分门别类的总结相关知识点,概念及常规应用,这里先留下一些粗浅认识,做一个结点吧,后续结合具体案例来完善补充. 前前后后,看了不少例子,由几个应用主题为切入点,简单罗列下,具体操作可以查书. 1.模型视图框架( Modle/Vi

Go语言的GUI方案,与Qt和QML都能绑定,也有从头写的gxui

半官方:https://godoc.org/golang.org/x/exp/shiny 作者:王益链接:https://www.zhihu.com/question/22483719/answer/21753337来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 我从2014年底开始使用 andlabs/ui · GitHub 开发GUI 程序.这个库支持多个操作系统,包括 Linux 和 MacOSX.而且 API 和程序结构充分使用了 Go 的特色语法:lam

[文档和源码分享] 基于QT和websocket协议的多线程文件传输

做两个程序,实现文件收发 发送端放两个按钮,点击后打开电脑目录选择所要传输的文件,选好以后,把文件名和路径显示在界面上,点击第二个按钮,把文件传到远程机器(或者虚拟机)上由接收端接收 编写一接收端,把文件接收下来,存进指定的某个目录里 要能测试通过三个发送端同时发100M的文件,接收端能分别接收 使用多线程实现 Qt开发环境 websocket传输协议库 Win10_x64 参考博文和源码下载地址: https://www.write-bug.com/article/1275.html 原文地址

实现js与Qt程序的交互(使用QtWebkit)

在QtWebkit的javascript里访问QObject的最关键的关键就是下面这个方法: void QWebFrame::addToJavaScriptWindowObject ( const QString &name,QObject *object ) 我们要在js调用该QObject之前调用这个函数. 这个时机不好掌握, 不过我们可以按文档的建议, 把这个函数放在一个signal的槽里调用. 代码如下: /// in constructor ///connect(ui.webView-

QT环境下,&lt;POSIX多线程&gt;全局变量共享问题

开始的技术路线是: 首先有两个主线程: 1,gui线程 2,等待客户端socket连接用的,listen线程 (当有客户端连接时,即creat一个新的线程2用来跟客户端通信,再来新的客户端,继续creat新的work线程3用于通信,以此类推,目前最多可以creat5个线程,即可以同时跟5台客户端通信,设置了监听的socket服务器最多监听5个队列.线程2继续listen) 出现的问题是: 用来通信的work线程3,收到一个来自客户端的xml文件,然后解析文件,并将其数据放在一个全局的静态stru

Win32下 Qt与Lua交互使用(二):在Lua脚本中使用Qt类

话接上篇.成功配置好Qt+Lua+toLua后,我们可以实现在Lua脚本中使用各个Qt的类.直接看代码吧. #include "include/lua.hpp" #include <QWidget> #include <QApplication> #include <QFile> #include <QDebug> static int tolua_new_QWidget(lua_State* pState) { QWidget* wid

Win32下 Qt与Lua交互使用(三):在Lua脚本中connect Qt 对象

话接上文.笔者为了方便使用Lua,自己编写了一个Lua的类.主要代码如下: QLua.h 1 #ifndef QLUA_H 2 #define QLUA_H 3 4 // own 5 #include "include/lua.hpp" 6 7 // qt 8 #include <QObject> 9 #include <QFile> 10 #include <QDebug> 11 12 #include <QWidget> 13 #in