本文介绍了当C ++尝试访问向量的元素(在范围内)时,Qt Quick Windows应用程序崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Windows上的Qt Quick应用程序遇到非常奇怪的崩溃。

My Qt Quick application on Windows is experiencing a very weird crash.

我有一个 QObject 派生的c ++类,称为 QObjectVector 允许QML端访问容器中的QObject指针。
在QML方面,我有一堆按钮显示该容器中对象的名称。当我滚动鼠标滚轮时,我会手动更新每个按钮的 currentItem 属性。

I have a QObject derived c++ class called QObjectVector that allows QML side to access QObject pointers in a container.On the QML side, I have a bunch of buttons displaying names of objects in that container. when I scroll the mouse wheel, I manually update each button's currentItem property.

奇怪的是,只有有时,在不可预测的次数快速滚动之后,程序崩溃了(停止工作)。调试后,我发现崩溃发生在 at 函数访问 m_data [i] 时。我已确保 i 在有效范围[0, m_data.size())内,因此它是不是索引超出范围的错误。我的猜测是,尝试管理内存时,QML引擎会以某种方式删除我的对象。

Strangely, and only sometimes, after an unpredictable number of fast scrolling, the program crashes (stopped working). After debugging, I found that the crashing happens when the at function access m_data[i]. I have made sure that i is within the valid range [0, m_data.size()), so it is not an index-out-of-range error. My guess is that, somehow, the QML engine deletes my objects on the heap when trying to manage memory.

QObjectVector.h

QObjectVector.h

#pragma once

#include <QObject>
#include <QVector>

#include "Types.h"

namespace LPP
{
    class QObjectVector : public QObject
    {
        Q_OBJECT

        Q_PROPERTY(Int size READ size NOTIFY sizeChanged)

    public:
        explicit QObjectVector();
        virtual ~QObjectVector();

        Int size();
        Q_INVOKABLE QObject* at(Int);
        void push(QObject*);
        void remove(Int);
        void remove(QObject*);

        QVector<QObject*> &getData();

        bool deleteChildrenOnDestroy;

    private:
        QVector<QObject*> m_data;

    signals:
        void sizeChanged();

    public slots:
    };
}

QObjectVector.cpp

QObjectVector.cpp

...
    QObject* QObjectVector::at(Int i)
    {
        qDebug() << "size: " << this->m_data.size();
        for (int i = 0; i < this->m_data.size(); i++){
            qDebug() << "i: " << i << " item: ";
            //when I scroll rapidly, crash happens here when I trace objects in vector
            qDebug() << this->m_data[i];
        }
        qDebug() << "returning.";
        return (i >= 0 && i < this->m_data.size()) ? this->m_data[i] : nullptr;
    }
....

ButtonContainer.qml

ButtonContainer.qml

....
    //this function is called when I scroll mouse wheel.
    //itemList contains list of Buttons

    function refreshDisplay() {
        var i, j = 0;

        for (i = 0; i < itemList.length; i++){
            itemList[i].visible = itemList[i].enabled = false;
        }

        var start = Utils.clamp(Math.floor(scrollView.flickableItem.contentY / (itemHeight + itemVSpacing)), 0, currentFolder.size);
        var end = Utils.clamp(Math.ceil((scrollView.flickableItem.contentY + scrollView.flickableItem.height) / (itemHeight + itemVSpacing)), 0, currentFolder.size);

        var item;

        for (i = start; i < end; i++){
            if (j >= itemList.length){
                itemList.push(tableItem_comp.createObject(tableArea));
            }

            itemList[j].visible = itemList[j].enabled = true;

            item = currentFolder.at(i);
            itemList[j].currentItem = item;
            j++;
        }
    }
....

Button.qml

Button.qml

....
    property var currentItem: null;

    anchors.left: parent.left
    anchors.right: parent.right

    SimpleButton {
        id: button
        width: 100
        height: 50
        text: currentItem.name;
        onClicked: {
            viewer.select(currentItem);
        }
    }
....

此问题是非常奇怪和不可预测,解决它对我的应用程序的开发非常关键,所以请拜托,我们将不胜感激。

This problem is very weird and unpredictable, and solving it is very crucial to the development of my app, so please please please, any help will be appreciated.

谢谢!

汤米

推荐答案

这是因为您要返回的对象归所有者所有

This is because the objects you're returning are owned by the QML engine, and can therefore be garbage collected at any time.

尝试调用

QQmlEngine::setObjectOwnership(object, QQmlEngine::CppOwnership)

在将每个对象返回到QML之前(例如,构造时)。

on each object before it is returned to QML (e.g. when it's constructed).

请参见:

此外,QML引擎尊重Qt C ++对象的常规QObject父所有权语义,并且将永远不会拥有已经存在的QObject实例的所有权有一个父母。

Additionally, the QML engine respects the normal QObject parent ownership semantics of Qt C++ objects, and will not ever take ownership of a QObject instance which already has a parent.

这篇关于当C ++尝试访问向量的元素(在范围内)时,Qt Quick Windows应用程序崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-29 15:56