QML TableView与动态列中的动态条目ComboBox

时间:2016-10-17 20:40:18

标签: qt combobox delegates qml qtquick2

我是QML的新手,我正在评估在我当前的项目中使用它。我有2年前的WPF经验,但我觉得他们的安静不同。

  1. 我尝试做的是一个TableView,根据模型,它的列是动态生成的。这部分对我来说没关系,它有效。

  2. 第二件事是根据其中的数据类型使用不同的组件作为不同列的委托。我打算使用Checkbox list和ComboBox,为它提供文本字段。一般来说,它按预期工作。

  3. 这是3天以来的问题,我发现无法让它工作:我希望动态定义ComoboBox的条目,如果它是ComboBox,我无法绑定该函数模式:(

  4. 以下是代码:

    TableEditing.qml

    import QtQuick 2.4
    import QtQuick.Controls 1.4
    import QtQuick.Layouts 1.1
    
    TableView {
    
        Layout.fillWidth: true
    
        id: view
        model: myModel
    
        Component {
            id: columnComponent
            TableViewColumn
            {
                width: 100
            }
        }
    
        // <---you can ignore this editableDelegate, it's not relevant to this question
        Component {
            id: editableDelegate
            Item {
    
                Text {
                    width: parent.width
                    anchors.margins: 4
                    anchors.left: parent.left
                    anchors.verticalCenter: parent.verticalCenter
                    elide: styleData.elideMode
                    text: styleData.value !== undefined ? styleData.value : ""
                    color: styleData.textColor
                    visible: !styleData.selected
                }
                Loader {
                    id: loaderEditor
                    anchors.fill: parent
                    anchors.margins: 4
                    Connections {
                        target: loaderEditor.item
                        onAccepted: {
                            if (typeof styleData.value === 'number')
                                largeModel.setProperty(styleData.row, styleData.role, Number(parseFloat(loaderEditor.item.text).toFixed(0)))
                            else
                                largeModel.setProperty(styleData.row, styleData.role, loaderEditor.item.text)
                        }
                    }
                    sourceComponent: styleData.selected ? editor : null
                    Component {
                        id: editor
                        TextInput {
                            id: textinput
                            color: styleData.textColor
                            text: styleData.value
                            MouseArea {
                                id: mouseArea
                                anchors.fill: parent
                                hoverEnabled: true
                                onClicked: textinput.forceActiveFocus()
                            }
                        }
                    }
                }
            }
        }
    
        // Read from here will be better
        Component {
            id: editableCombo
            Item {
                property var modelData : ["aa", "bb"] // <- This works
                ComboBox {
                    id : combox
                    anchors.verticalCenter: parent.verticalCenter
                }
    
                Binding {
                    target: combox
                    property: "model"
                    value: modelData
                }
    
            }
        }
    
        function getEditor(type, options) {
            switch(type) {
            case 3: return editableCombo
            default: return editableDelegate;
            }
        }
    
        function addCol(role, index) {
            var colType = myModel.columnType(index);
            var colOptions = myModel.optionList(index);
            var editor = getEditor(colType, colOptions);
            var cellEditor = {
                role: role,
                title: role,
                delegate: editor \\ <--------- I think here need some work, I think I need to bind colOptions to the modelData of editor, but I have tried many forms, the loader and bindings, it doesn't work
    
            };
            view.addColumn(columnComponent.createObject(view, cellEditor))
        }
    
        Connections {
            target: myModel
            onHeaderDataChanged: myModel.columnNames.forEach(addCol)
        }
    
    }
    

    这是模型的标题,columnType()给出了列中的数据类型,optionList()给出了可能的条目。

    #pragma once
    
    #include "ItemControllerBase.h"
    #include "ItemPropertyDescriptor.h"
    #include "Macro.h"
    #include "Const.h"
    
    namespace PROJECTNAME { namespace Controller {
    
    class TableEditingModel : public QAbstractItemModel {
        Q_OBJECT
        Q_PROPERTY(QStringList columnNames READ columnNames CONSTANT)
    
    public:
        TableEditingModel() = default;
    
        //! \brief  Déstructeur.
        ~TableEditingModel();
    
        Q_INVOKABLE int columnType(int columnIndex) const;
        Q_INVOKABLE QStringList optionList(int columnIndex) const;
    
        QStringList columnNames() const;
    
        QHash<int, QByteArray> roleNames() const override;
    
        //! \brief  L'index dans QListView.
        //! \param  row     La ligne.
        //! \param  column  Le column.
        //! \return Un QModelIndex.
        QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
    
    
        //! \brief  Obtiens le parent.
        //! \param  child   Le fils.
        //! \return L'index de parent.
        QModelIndex parent(const QModelIndex &) const override
        {
            return QModelIndex();
        }
        //! \brief  Le numbre totale des lignes.
        //! \param  parent  Le parent.
        //! \return Le nombre totale des lignes.
        int rowCount(const QModelIndex & = QModelIndex()) const override
        {
            //! \todo
            return m_controllers.size();
        }
    
        //! \brief  Le nombre totales des column.
        //! \param  parent  (Optional) Le parent.
        //! \return Le nombre totales des column.
        int columnCount(const QModelIndex & = QModelIndex()) const override
        {
            return m_controllers.size() > 0 ? m_controllers[0]->descriptor()->size() : 0;
        }
    
        //! \brief  Données d'un celule.
        //! \param  index   L'objet index.
        //! \param  role    Le rôle.
        //! \return La données.
        QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
    
        //! \brief  Mise à jour de données.
        //! \param  index   L'index.
        //! \param  value   La valeur.
        //! \return Vrai si la modification est réussit
        bool setData(const QModelIndex & index, const QVariant & value, int role = Qt::EditRole) override;
    
        //! \brief  Renvoie le numéro de ligne d'un élément.
        //! \param  element Elément recherché
        //! \return Numéro de ligne de l'élément recherché
        int indexOf(QSharedPointer<Controller::ItemControllerBase> element) { return m_controllers.indexOf(element); }
    
        //! \brief  Lors l'ajoute d'une élément.
        //! \param [in,out] descriptor  Le déscripteur d'élément.
        void addElement(QSharedPointer<Controller::ItemControllerBase> element);
    
        //! \brief  Lors la suppression d'une élément.
        //! \param [in,out] descriptor  Le déscripteur d'élément
        void removeElement(QSharedPointer<Controller::ItemControllerBase> element);
    
        void refreshElement(QSharedPointer<Controller::ItemControllerBase> element);
    
    private:
        QueryableVector<QSharedPointer<Controller::ItemControllerBase>> m_controllers;  //!< Liste des controlleurs
        QueryableVector<std::tuple<QString, Model::PropertyValueType, QStringList>> m_horizontalHeaders;    //!< Liste des titres de colonne };
    
    } // Controller } // PROJECTNAME
    

0 个答案:

没有答案