Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Properly define a delegate to be used in a QtQuick object?



  • I am writing a custom QtQuick object. I want to define delegate components the way other qml objects do. So I have a property of the qtquick object that is a QQmlComponent*
    Object in qml:

                                 FileSystemTreeView {
                                    id: treeview
    
                                    anchors.left: parent.left
                                    anchors.right: parent.right
                                    height: 100
    
                                    Rectangle {
                                        anchors.fill: parent
                                        color: "steelblue"
                                    }
    
                                    delegate: Rectangle {
                                        width: 100
                                        height: 25
                                        color: "yellow"
                                    }
                                }
    

    Object in c++:

    class FileSystemModel : public QFileSystemModel
    {
        Q_OBJECT
    public:
        FileSystemModel(QObject* parent=nullptr)
            : QFileSystemModel(parent)
        {
        }
    
    public slots:
        QString getRoot(){
            return rootPath();
        }
    
    };
    
    class FilesDialogUI : public QObject
    {
        Q_OBJECT
        Q_PROPERTY(QList<QObject*> drives READ getDrives NOTIFY drivesChanged)
    public:
        explicit FilesDialogUI(QObject *parent = nullptr);
    
        QList<QObject*> getDrives() const
        {
            QList<QObject*> list;
            for(const auto item: qAsConst(m_drives)){
                list.push_back(item);
            }
            return list;
        }
    
    signals:
        void drivesChanged();
    
    public slots:
        void refreshFileSystems();
    
    protected:
        // file system objects
        QList<FileSystemModel*> m_drives;
    };
    

    cpp:

    FileSystemTreeView::FileSystemTreeView()
        : m_delegate(nullptr)
    {
    }
    

    However, it is segfaulting here:

    1   QQmlObjectCreator::setPropertyBinding  qqmlobjectcreator.cpp 876  0x7ffff6b3259b 
    2   QQmlObjectCreator::setupBindings       qqmlobjectcreator.cpp 777  0x7ffff6b345be 
    3   QQmlObjectCreator::populateInstance    qqmlobjectcreator.cpp 1469 0x7ffff6b31036 
    4   QQmlObjectCreator::createInstance      qqmlobjectcreator.cpp 1306 0x7ffff6b31a7d 
    5   QQmlObjectCreator::setPropertyBinding  qqmlobjectcreator.cpp 825  0x7ffff6b33d10 
    6   QQmlObjectCreator::setupBindings       qqmlobjectcreator.cpp 777  0x7ffff6b345be 
    7   QQmlObjectCreator::populateInstance    qqmlobjectcreator.cpp 1469 0x7ffff6b31036 
    8   QQmlObjectCreator::createInstance      qqmlobjectcreator.cpp 1306 0x7ffff6b31a7d 
    9   QQmlObjectCreator::setPropertyBinding  qqmlobjectcreator.cpp 825  0x7ffff6b33d10 
    10  QQmlObjectCreator::setupBindings       qqmlobjectcreator.cpp 777  0x7ffff6b345be 
    11  QQmlObjectCreator::populateInstance    qqmlobjectcreator.cpp 1469 0x7ffff6b31036 
    12  QQmlObjectCreator::createInstance      qqmlobjectcreator.cpp 1306 0x7ffff6b31a7d 
    13  QQmlObjectCreator::create              qqmlobjectcreator.cpp 203  0x7ffff6b34fce 
    14  QQmlIncubatorPrivate::incubate         qqmlincubator.cpp     299  0x7ffff6abb7a0 
    15  QQmlEnginePrivate::incubate            qqmlincubator.cpp     89   0x7ffff6abbec5 
    16  QQmlDelegateModelPrivate::object       qqmldelegatemodel.cpp 1078 0x7ffff6b926e2 
    17  QQmlDelegateModel::object              qqmldelegatemodel.cpp 1114 0x7ffff6b92902 
    18  QQuickItemViewPrivate::createItem      qquickitemview.cpp    2285 0x7ffff7a14e1f 
    19  QQuickListViewPrivate::addVisibleItems qquicklistview.cpp    696  0x7ffff7a24718 
    20  QQuickItemViewPrivate::refill          qquickitemview.cpp    1744 0x7ffff7a14602 
    ... <More>                                                                           
    

    I assume the pointer is not correct or something. Do I need to use some other object besides QQmlComponent*? Like QObject* and cast? I don't get why it is creating the object in the first place. I would have thought it would create a template in QML.

    I cannot find how to do this in the docs:
    https://doc.qt.io/qt-5/qtqml-cppintegration-interactqmlfromcpp.html



  • I am looking in qquicklistview_p.h and .cpp. My code for the property is almost exactly the same. Why is it crashing? Is there an object in between?



  • What? I just cleaned, qmaked, built again and now it works? Is this gonna be one of those days?


  • Lifetime Qt Champion

    @fcarney
    Yes its one of these days.



  • Also note, if you are instancing an object from a QQmlComponent you need to specify the context or it won't see any of the variables from the parent:

            QQuickItem* child = dynamic_cast<QQuickItem*>(m_delegate->create(m_delegate->creationContext()));
            //m_children.push_back(child); // not needed, implementation specific
            child->setParentItem(this);
    

    I also think this is the appropriate location to create a custom context for injecting node specific properties into the context. Anyway, now I am having fun!


Log in to reply