问题描述
我在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应用程序崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!