QT 在 QML中 嵌入显示qwidget界面显示的两种方式,已在项目中验证

这两种方式都可以 复用已有的widget界面,不必使用qml重新开发,大大减少了开发时间。

第一种方式: qwidget界面会一直 悬浮在QML界面的上方, 代码中可控制这个widget show或者hide。 然后这个widget界面可以直接处理事件,比如说点击,长按之类的, 就是在widget里面正常写交互逻辑, 缺点就是会悬浮在QML界面上方。 我使用的场景是显示3D模型,需要手指拖动来进行交互,使用的此种方式。

实现方式如下:

1、现在QML里面留出一个位置,确定大小和坐标,这里叫widgetitem

css 复制代码
    Rectangle{
        id: test_widget

        x: 400
        y: 44
        width: 880
        height: 597
        color: "transparent"
        border.color: "black"
        border.width: 5
        visible: false
        Item{
            objectName: "widgetItem"
            width: 880
            height: 597
        }
    }

2、再把widget实例化出来

cpp 复制代码
    navWidget = new TestWidget(":/images/robot.png",rootWidget);


    auto pWidgetItem = rootWidget->rootObject()->findChild<QQuickItem*>("widgetItem");
    QRectF rect = pWidgetItem->mapRectToItem(0, QRectF(pWidgetItem->x(),
                                                pWidgetItem->y(),
                                                pWidgetItem->width(),
                                                pWidgetItem->height()));
    navWidget->setGeometry(rect.toRect());

    navWidget->hide();

3、后面在合适的时机控制 show/hide就完成了

第二种方式:

qwidget界面就像一个QML组件一样, 可以使用anchor 来控制位置和大小,解决上面一直悬浮在QML界面上方的问题, 这个的交互需要转发事件,但我嫌麻烦没有继续深究 怎么转发事件, 因为我的使用场景 是 把widget当背景 在qml界面的最下方 显示摄像头的视频数据,不需要交互。就没写事件转发。

1、先继承QQuickPaintedItem 写一个中间类,帮助后面的widget嵌入进去

cpp 复制代码
#ifndef WIDGETSITEM_H
#define WIDGETSITEM_H


#include <QQuickPaintedItem>
#include <QWidget>
#include <QPainter>

class WidgetItem : public QQuickPaintedItem {
    Q_OBJECT
    Q_PROPERTY(QVariant thirdWidget WRITE setThirdWidget)
public:
    explicit WidgetItem(QQuickItem *parent = nullptr) : QQuickPaintedItem(parent), m_widget(nullptr) {
        setFlag(ItemHasContents, true);
    }

    void setThirdWidget(QVariant widget) {
    }

protected:

    void paint(QPainter *painter) override {

    }

    void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override {
        QQuickPaintedItem::geometryChanged(newGeometry, oldGeometry);
        if (m_widget) {
            m_widget->setGeometry(newGeometry.toRect());
        }
    }

    bool eventFilter(QObject *obj, QEvent *e) override {
        if (obj == m_widget && e->type() == QEvent::Paint) {
            update();
        }
        return QQuickPaintedItem::eventFilter(obj, e);
    }

private:
    QWidget *m_widget;
};

#endif // WIDGETSITEM_H

2、然后在main函数注册

cpp 复制代码
    qmlRegisterType<WidgetItem>("THWidgetItem", 1, 0, "ThirdWidgetItem");

3、示例要嵌入的widget

cpp 复制代码
    sceneWidget = new TestWidget(":/images/2.jpg",1020,596);
    bomWidget = new TestWidget(":/images/4.jpg",1280,596);

    rootWidget->engine()->rootContext()->setContextProperty("thScentWidget", sceneWidget);
    rootWidget->engine()->rootContext()->setContextProperty("thBomWidget", bomWidget);

4、在qml中使用

css 复制代码
ThirdWidgetItem{
    id:scencbg
    anchors.fill: parent
    thirdWidget: thScentWidget
}
相关推荐
常乐か8 小时前
拉取FreeCAD项目步骤
qt·freecad·occ
_OP_CHEN8 小时前
【从零开始的Qt开发指南】(十二)Qt 布局管理器终极指南:5 大布局 + 实战案例,搞定所有界面排版需求
开发语言·qt·前端开发·qt控件·布局管理器·gui开发
水煎包V:YEDIYYDS8881 天前
QT QML 实现的摇杆按钮,类似王者荣耀 左边方向导航键
qt·qml·摇杆按钮·导航键
winfield8211 天前
MCP 协议详解
开发语言·网络·qt
秦jh_1 天前
【Qt】常用控件(上)
服务器·数据库·qt
刃神太酷啦1 天前
C++ list 容器全解析:从构造到模拟实现的深度探索----《Hello C++ Wrold!》(16)--(C/C++)
java·c语言·c++·qt·算法·leetcode·list
水煎包V:YEDIYYDS8881 天前
QT modbus 通信教程,把modbus封装到线程单例中,在线程内完成数据收发,解析。把重要数据以信号方式通知到qml层展示,解决UI卡顿
qt·modbus·线程服务
东哥很忙XH1 天前
python使用PyQt5开发桌面端串口通信
开发语言·驱动开发·python·qt
汪宁宇1 天前
如何在QT5+MinGW环境中编译使用QGIS开发地图应用
c++·qt·qgis·mingw·地图库