《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 会立即释放,后续就无法访问上下文的属性了:

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:

    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++ 类,在习惯加上打印,会发现析构是执行了的:


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

相关推荐

  1. 202411日答案

    2024-02-01 14:46:03       32 阅读
  2. 2024115日

    2024-02-01 14:46:03       22 阅读
  3. 2024116日

    2024-02-01 14:46:03       27 阅读
  4. 2024122日

    2024-02-01 14:46:03       36 阅读
  5. 2024127日

    2024-02-01 14:46:03       33 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-02-01 14:46:03       14 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-02-01 14:46:03       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-02-01 14:46:03       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-02-01 14:46:03       18 阅读

热门阅读

  1. 代码随想录算法训练营|day22

    2024-02-01 14:46:03       33 阅读
  2. Android studio布局详解

    2024-02-01 14:46:03       34 阅读
  3. 达梦数据库存储过程

    2024-02-01 14:46:03       26 阅读
  4. vue3:中warch监听的几种写法

    2024-02-01 14:46:03       33 阅读
  5. ModuleNotFoundError: No module named ‘flask._compat‘

    2024-02-01 14:46:03       28 阅读
  6. rsync将远程文件同步到本地

    2024-02-01 14:46:03       30 阅读
  7. Docker加固策略,防止攻击

    2024-02-01 14:46:03       28 阅读