《QDebug 2024年1月》

一、Qt Widgets 问题交流

1.

二、Qt Quick 问题交流

1.Repeator 的 delegate 在 remove 移除时的注意事项

Qt Bug Tracker:https://bugreports.qt.io/browse/QTBUG-47500

Repeator 在调用 remove 函数之后,对应的 Item 会立即释放,后续就无法访问上下文的属性了:

javascript 复制代码
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15

Window {
    id: root
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")

    ListModel {
        id: list_model
        ListElement { value: 1 }
        ListElement { value: 2 }
        ListElement { value: 3 }
    }

    Flow {
        anchors.fill: parent
        Repeater {
            id: repeator
            model: list_model
            delegate: Rectangle {
                id: item
                width: 100
                height: 50
                border.color: "black"
                Text {
                    anchors.centerIn: parent
                    text: model.index
                }
                MouseArea {
                    anchors.fill: parent
                    onClicked: {
                        console.log("before", item.width, repeator.count, model.value)
                        list_model.remove(model.index, 1)
                        console.log("after", item.width, repeator.count, model.value)
                    }
                }
                Component.onDestruction: {
                    console.log("free")
                }
            }
        }
    }
}

测试代码在调用 remove 后,Component.onDestruction 立即触发了,之后只能访问 item 属性,外部属性以及 model role 无法继续访问了。

但如果把 Repeator 换成 ListView,Component.onDestruction 在 onClicked 执行完后才会触发。

2.非动态创建的对象调用 destroy() 不触发 Component.onDestruction

如下代码调用 destory 后没有触发 Component.onDestruction:

javascript 复制代码
    Rectangle {
        id: item
        width: 300
        height: 300
        anchors.centerIn: parent
        color: "red"
        MouseArea {
            anchors.fill: parent
            onClicked: {
                item.destroy()
            }
        }
        Component.onDestruction: {
            console.log("item free")
        }
    }

如果替换成自定义的 C++ 类,在习惯加上打印,会发现析构是执行了的:

cpp 复制代码
#include <QQuickItem>
#include <QDebug>

class CppItem : public QQuickItem
{
    Q_OBJECT
public:
    explicit CppItem(QQuickItem *parent = nullptr)
        : QQuickItem(parent) {
        qDebug() << Q_FUNC_INFO;
    }
    ~CppItem(){
        qDebug() << Q_FUNC_INFO;
    }
};
javascript 复制代码
    CppItem {
        id: cpp_item
        Component.onCompleted: {
            console.log("init")
        }
        Component.onDestruction: {
            console.log("free")
        }
    }
    MouseArea {
        anchors.fill: parent
        onClicked: {
            cpp_item.destroy()
        }
    }
3.View 嵌套的问题

QML 自带的 ListView、GridView、TableView 等,在可视区域和 cacheBuffer 范围外的元素一般是没有在初始化时加载的,只有显示对应的元素时才动态加载。当组合 View 实现更复杂的效果时会有个问题,子级 View 一般需要加载全部内容才能得到这一级的宽高,或者二级嵌套的 Flow + Repeator 等默认就全部加载的组件。当子级 View 内容很多,或者加载了大量图片数据,内存占用就会很高。

这里还有个恶心的地方,无论是 QML 还是 Widgets,View 的相关源码都用到一些未导出的类,这就导致很难直接子类化 C++ View 类然后重写部分接口,要么把相关类都 Copy 一下,要么得改源码重新编译下 Qt 对应模块。

三、其他

1.
相关推荐
四维碎片7 小时前
【Qt】UDP跨平台调试工具
qt·学习·udp
踏过山河,踏过海8 小时前
【用ui文件做个简单工具的开发,为什么修改完ui后,程序重新编译运行后,GUI界面还是不变呢?】
qt·ui
向阳开的夏天9 小时前
麒麟V10源码编译QT5.6.3 (x86 & arm64)
开发语言·qt
打码的猿11 小时前
Qt对话框不锁死主程序的方法
开发语言·qt
小小码农Come on14 小时前
Qt Creator常用设置
qt
wkm95616 小时前
在arm64 ubuntu系统安装Qt后编译时找不到Qt3DExtras头文件
开发语言·arm开发·qt
小小码农Come on18 小时前
QT开发环境安装
开发语言·qt
小小码农Come on18 小时前
QT内存管理
开发语言·qt
有理想的打工人18 小时前
QT的安装
qt
SilentSlot20 小时前
【QT-QML】8. 输入元素
qt·qml