尝试在 QML 中获取子子属性时的 PyQt 段错误 [英] PyQt segfault when trying to get a sub-sub-property in QML

查看:66
本文介绍了尝试在 QML 中获取子子属性时的 PyQt 段错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在 Python 中返回一个角色中的对象并在 QML 中获取另一个对象的引用.最后,我发现我可以使用 Property 来做到这一点.

I was trying to Return an object in a role in Python and get a reference of another object in QML. Finally, I found I can use Property to do it.

但是,我想获得 QML 中另一个对象的另一个引用的引用,PyQt 只是段错误.我切换到 PySide,但运行它时它仍然崩溃.

But, I want to get a reference of another reference of another object in QML, PyQt just segfault. I switched to PySide but it was still crashing when I run it.

我做错了吗?

GDB 说

Cannot access memory at address 0xb
Cannot access memory at address 0x3

main.py

import sys
from PySide import QtCore, QtGui, QtDeclarative
from PySide.QtCore import Property, Signal, QObject


class TweetModel(QtCore.QAbstractListModel):
    def __init__(self, prototype, parent=None):
        QtCore.QAbstractListModel.__init__(self, parent)
        self.setRoleNames(prototype.roles)
        self.tweets = []

    def appendRow(self, item):
        self.tweets.append(item)

    def rowCount(self, parent=QtCore.QModelIndex()):
        return len(self.tweets)

    def data(self, index, role):
        return self.tweets[index.row()].data(role)


class UserItem(QtCore.QObject):
    def __init__(self, item, parent=None):
        super(UserItem, self).__init__()
        self._data = item

    @QtCore.Property(str)
    def name(self):
        return self._data.get('name')


class TweetItem(QObject):
    roles = {
        QtCore.Qt.UserRole + 1: 'id',
        QtCore.Qt.UserRole + 6: 'original',
    }

    id_changed = Signal()

    def __init__(self, id=None, original=None, author=None, parent=None):
        QObject.__init__(self, parent=parent)

        self._data = {'original': original,
                'id': id, 'author': author}

    def data(self, key):
        return self._data[self.roles[key]]

    @Property(str, constant=True)
    def id(self):
        return self._data['id']

    @Property(QtCore.QObject, constant=True)
    def original(self):
        return self._data['original']

    @Property(QtCore.QObject, constant=True)
    def author(self):
        return UserItem(self._data['author'])

if __name__ == "__main__":
    model = TweetModel(TweetItem)
    item = TweetItem("0001", None, {'name': 'test'}, model)
    item_2 = TweetItem("0002", item, None, model)
    item_3 = TweetItem("0003", item_2, None, model)
    model.appendRow(item_3)

    App = QtGui.QApplication(sys.argv)
    view = QtDeclarative.QDeclarativeView()
    view.rootContext().setContextProperty("mymodel", model)
    view.setSource(QtCore.QUrl.fromLocalFile("main.qml"))
    view.show()
    App.exec_()

main.qml

import QtQuick 1.0

Rectangle {
    width: 360
    height: 360

    ListView {
        anchors.fill: parent
        model: mymodel
        delegate: Item { 
            Text { 
                text: id + " " + original.id + " " + original.original.author.name
            } 
        }
    } 
} 

推荐答案

我认为这是 垃圾收集 问题.

您在 author 方法中创建的 UserItem 不会在 Python 代码中的任何地方被引用并被垃圾收集.

Your UserItem that you make in author method isn't referenced anywhere afterwards in python code and gets garbage collected.

为避免这种情况,您可以在 main 中创建 UserItem:

To avoid this, you can make UserItem in your main:

item = TweetItem("0001", None, UserItem({'name': 'test'}), model)

或在创建时将其存储在 TweetItem 中:

or store it in TweetItem upon creation:

if not self._author:
    self._author = UserItem(self._data['author'])
return self._author

我可能会采用第一种方式,或者将 dict 传递给 TweetItem 并将其转换为 __init__ 中的 UserItem:

I'd probably do the first way or maybe pass dict to the TweetItem and convert it to UserItem in __init__:

self._data = {'original': original,
        'id': id, 'author': UserItem(author)}

这篇关于尝试在 QML 中获取子子属性时的 PyQt 段错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆