Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. How to add QComboBox and TextField inside TreeView with delegate QML?

How to add QComboBox and TextField inside TreeView with delegate QML?

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
qmltreeviewdelegateqabstractitemmoqcombobox
4 Posts 2 Posters 3.4k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • T Offline
    T Offline
    tamlong0205
    wrote on last edited by tamlong0205
    #1

    Hi, I had implement TreeView following this tutorial, But I had implement with Qt Quick Control (does not has .ui file). tutorial here. With load text and show on TreeView, it work fine. But I had another problem:

    I know that a row is a TreeItem and the model is TreeModel extend from QAbstractItemModel.

    • My TreeView has four columns and I set data for TreeItem with its itemData, each itemData has 4 element.

    • On Value Column (column 2) I want to add dynamic component (QComboBox and TextField), it depend on value of TreeItem the TreeModel. [The figure below] 2.

    • I set data for TreeItem and TreeModel from .cpp file, and set model for TreeView in .qml file.

    • I have a objectA with 8 element (name, value, data to assign component for column 2, current index of Combobox if have Combobox, data1,...) with second element maybe QStringList or QString. My TreeItem get data from objectA with TreeItem (name,value,data1,data2).

    I have 3 problems need to be solve:

    • First problem, I had delegate the column 2 to all ComboBox or all TextField ok, But I cannot mix them together. When the value of TreeItem is a QStringList, I want delegate for Combobox, and when it is QString I want delegate for TextField. But I cannot access to the return data, I dont know that I need to define it on .cpp file or .qml file. I know that "styleData.value" is the value for a cell data, access from .qml file. But I cant to know data Type of "styleData.value" .
    • Second problem, Another problem that I dont know how to set current index for Combobox on load data. For example: the value(second element) of TreeItem is: [item1, item2, item3] and the current Index is at item 2.
    • Third problem, when data is loaded, I change data for ComboBox. How to get current Data of the TreeItem, current Index of Combobox.

    Sorry for long question, and a lot of problem.
    Please help me if you know any my problem. Thank in advance

    1 Reply Last reply
    0
    • T Offline
      T Offline
      tamlong0205
      wrote on last edited by tamlong0205
      #2

      My TreeModel.h

      class TreeModel : public QAbstractItemModel
      {
          Q_OBJECT
          enum DelegateEnum
              {
                  NameEnum = 0,
                  ValueEnum,
                  DeviceEnum,
                  UnitEnum
          };
      public:
          explicit TreeModel(QObject *parent = 0);
          TreeModel(const QStringList &headers,const QList<PlcView *> &plcViewList, const QString &topIO, QObject *parent = 0);
          ~TreeModel();
      
          int columnCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
          QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE;
          Qt::ItemFlags flags(const QModelIndex &index) const Q_DECL_OVERRIDE;
          QVariant headerData(int section, Qt::Orientation orientation,
                              int role = Qt::DisplayRole) const Q_DECL_OVERRIDE;
          QModelIndex index(int row, int column,
                            const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
          bool insertColumns(int position, int columns,
                             const QModelIndex &parent = QModelIndex()) Q_DECL_OVERRIDE;
          bool insertRows(int position, int rows,
                          const QModelIndex &parent = QModelIndex()) Q_DECL_OVERRIDE;
          QModelIndex parent(const QModelIndex &index) const Q_DECL_OVERRIDE;
          bool removeColumns(int position, int columns,
                             const QModelIndex &parent = QModelIndex()) Q_DECL_OVERRIDE;
          bool removeRows(int position, int rows,
                          const QModelIndex &parent = QModelIndex()) Q_DECL_OVERRIDE;
          int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
      
          bool setData(const QModelIndex &index, const QVariant &value,
                       int role = Qt::EditRole) Q_DECL_OVERRIDE;
          bool setHeaderData(int section, Qt::Orientation orientation,
                             const QVariant &value, int role = Qt::EditRole) Q_DECL_OVERRIDE;
          QHash<int, QByteArray> roleNames() const Q_DECL_OVERRIDE;
      private:
          void setupModelData(const QStringList &lines, TreeItem *parent);
          void setupModelData2(const QList<PlcView *> &plcViewList, TreeItem *parent, const QString &topIO);
          TreeItem *getItem(const QModelIndex &index) const;
      
          TreeItem *rootItem;
      };
      

      roleNames() function:

      QHash<int, QByteArray> TreeModel::roleNames() const
      {
          QHash<int, QByteArray> roles;
          roles[NameEnum] = "name";
          roles[ValueEnum] = "value";
          roles[DeviceEnum] = "device";
          roles[UnitEnum] = "unit";
          return roles;
      }
      
      1 Reply Last reply
      0
      • T Offline
        T Offline
        tamlong0205
        wrote on last edited by tamlong0205
        #3

        My mydevice.ui.qml file.

        Item {
            id: content
            width: 320
            height: 480
            property alias valueColumnDelegate: valueColumn.delegate
        TreeView {
                    id: treeView
                    Layout.fillHeight: true
                    Layout.fillWidth: true
                    opacity: 1
                    highlightOnFocus: true
                    Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
                    anchors.fill: parent
                    anchors.margins: 2
        
                    headerDelegate: Rectangle {
                        height: 60
                        Layout.fillHeight: true
                        border.width: 1
                        border.color: "#000000"
                        //color:   pallete.altBgColor
                        Text {
                            anchors.fill: parent
                            text: styleData.value
                            renderType: Text.NativeRendering
                            color: "#000000"
                            verticalAlignment:   Text.AlignVCenter
                            horizontalAlignment: Text.AlignHCenter
                        }
                    }
        
                    TableViewColumn {
                        role: "name"
                        title: "Name"
                        width: parent.width/4 + parent.width/16
                        delegate: TextDelegate{}
                    }
                    TableViewColumn {
                        id: valueColumn
                        role: "value"
                        title: "Value"
                        width: parent.width/4 - parent.width/12
                    }
                    TableViewColumn {
                        role: "device"
                        title: "Device"
                        width: parent.width/8 + parent.width/12
                        delegate: TextDelegate{}
                    }
                    TableViewColumn {
                        role: "unit"
                        title: "Unit"
                        width: parent.width/4 + parent.width/16
                        delegate: TextDelegate{}
                    }
                }
            }
        }
        
        1 Reply Last reply
        0
        • p3c0P Offline
          p3c0P Offline
          p3c0
          Moderators
          wrote on last edited by
          #4

          @tamlong0205 I think most of this can be done from C++ side.

          1. You can add a function in the model which can return what type is the data for current index. This function will be called from QML and depending upon its value use a Loader to load the specific delegate.

          2. Perhaps setting currentIndex in Component.onCompleted handler ?

          3. Create a C++ function which will store in info in the model itself i.e When you change the index in ComboBox call this function and update the value there and may be maintain a role to store this update.

          157

          1 Reply Last reply
          0

          • Login

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved