c++ - QAbstractListModel 崩溃

标签 c++ qt list model qml

我正在使用 QAbstractListModel 将数据公开给 QML ListView。除此之外还使用了 QML SectionScroller,它使用 get 和 data 函数。

滚动一段时间后,出现崩溃。回溯是:

Program received signal SIGILL, Illegal instruction.
0x0000cdcc in QBasicAtomicInt::ref (
    this=0x35)
    at /usr/include/QtCore/qatomic_armv6.h:119
119 /usr/include/QtCore/qatomic_armv6.h: No such file or directory.
    in /usr/include/QtCore/qatomic_armv6.h
(gdb) bt
#0  0x0000cdcc in QBasicAtomicInt::ref (
    this=0x35)
    at /usr/include/QtCore/qatomic_armv6.h:119
#1  0x0000f4e8 in QString (
    this=0xbebf1a5c, other=...)
    at /usr/include/QtCore/qstring.h:729
#2  [address] in IrregularVerb::getForm0
    (this=0x92e428) at IrregularVerb.h:16
#3  0x0000e29c in IrregularListWrapper::data (this=0x92dd20, index=..., role=33)
    at IrregularListWrapper.cpp:37
#4  0x4010e9c6 in ?? ()
   from /usr/lib/libQtDeclarative.so.4
#5  0x4010e9c6 in ?? ()
   from /usr/lib/libQtDeclarative.so.4
Backtrace stopped: previous frame identical to this frame (corrupt stack?)

在其他设备上(第一个是 N900,第二个是 N950),回溯是相似的。它是 SIGSEGV 而不是 SIGILL,但除此之外的回溯是相同的。我注意到曾经有一种情况,在崩溃的那一刻,一些字段变成了空白。 (使用 getForm0 和 getForm1 的)

当我向返回值添加额外的赋值时,崩溃发生在赋值处。

一些重要的代码:

元素:

class IrregularVerb : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString form0 READ getForm0 CONSTANT)
    Q_PROPERTY(QString form1 READ getForm1 CONSTANT)
    Q_PROPERTY(QString form2 READ getForm2 CONSTANT)
public:
    QString forms[3];
    QString getForm0() const { return forms[0]; }
    QString getForm1() const { return forms[1]; }
    QString getForm2() const { return forms[2]; }
    IrregularVerb(QString a, QString b, QString c) { forms[0] = a; forms[1] = b; forms[2] = c; }
};

模型:

class IrregularListWrapper : public QAbstractListModel
{
    Q_OBJECT
    Q_PROPERTY(QString langName READ getLangName NOTIFY langChanged)
    Q_PROPERTY(int count READ rowCount NOTIFY langChanged)
    Q_ENUMS(Language)
public:

    Q_INVOKABLE int rowCount(const QModelIndex& = QModelIndex()) const { return db->count(); }
    Q_INVOKABLE QObject* get(int index) const {return db->at(index);}
    QVariant data(const QModelIndex &index, int role) const;

    enum Language
    {
        English = 0,
        German = 1
    };

    enum IrregularVerbRoles
    {
        Form0Role = Qt::UserRole + 1,
        Form1Role,
        Form2Role
    };

    IrregularListWrapper();

    QString getLangName() const { return langName; }
    Q_INVOKABLE void changeLang(Language l) { beginResetModel(); db = 0; setLang(l); endResetModel(); }

    static QMap<Language, QString> plugins;

signals:
    void langChanged();
protected:
    void setLang(Language);
    QString langName;
    AbstractIrregularList * db;

};


QVariant IrregularListWrapper::data(const QModelIndex &index, int role) const
{
    if (!index.isValid()) return QVariant();

    int rowno = index.row();

    qDebug() << "Row is " << index.row() << flush;

    const IrregularVerb* verb = db->at(index.row());

    switch (role)
    {
    case Form0Role:
        return verb->getForm0();
        break;
    case Form1Role:
        return verb->getForm1();
        break;
    case Form2Role:
        return verb->getForm2();
        break;
    }
    return QVariant();
}

抽象不规则列表:

class AbstractIrregularList : public QObject, public QList<IrregularVerb*>
{
    Q_OBJECT
public:
    void IV(const char* a, const char* b, const char* c) { append (new IrregularVerb(a, b, c)); }
    void IV(const char *a, const char *b) { IV(a, b, b); }
    void IV(const char *a) { IV(a,a,a); }
};

Q_DECLARE_INTERFACE(AbstractIrregularList, "com.marmistrz.Plugin.AbstractIrregularList/1.0");

你知道为什么会这样吗?谢谢!

/edit1:感谢您的回复。这样可以吗?

Q_INVOKABLE QObject* get(int index)
{
    QObject* item = db->at(index);
    QDeclarativeEngine::setObjectOwnership(item, QDeclarativeEngine::CppOwnership);
    item->setParent(this); // do I need to do this? An QList<QObject*>-child would clean it, right? 
    return item;
}

谢谢

最佳答案

看起来您在 QML 端使用 QAbstractListModel 遇到了“经典”问题。您的 IrregularListWrapper 具有 get 方法,该方法返回具有 JS 所有权的对象(这种所有权是 Q_INVOKABLE 方法的默认值),它们将被垃圾收集QML 端的 JS 引擎。为了防止这种情况,您应该在使用 QDeclarativeEngine::setObjectOwnership 将对象返回给 QML 之前更改对象的所有权。 .请参阅我的回答中的示例 here .

关于c++ - QAbstractListModel 崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16002315/

相关文章:

java - 如何检测二值图像中的圆圈

c++ - 初始化 QString 的最佳方法

python:[[1,2],[3,4],[5,6],[7,8]] 转化为 [[1],[2,3],[4,5],[6,7 ],[8]] 反之亦然

python - 如何从数据框中创建项目字典?

c++ - 我可以使用什么 Mac/iOS/Portable 库来格式化信息以打印到标签纸上?

c++ - 无法在我自己的 dll 中使用 GetProcAddress 调用函数

qt - 更改 QCalendarWidget 的水平标题背景颜色

qt - Qt 快速编译器究竟做了什么?

c# - 使封装 List<> 的对象可通过 [] 运算符访问?

c++ using-declarations 用于从基类调用函数