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. TableView with different delegates for its columns (QtQuick 2.15)
Forum Updated to NodeBB v4.3 + New Features

TableView with different delegates for its columns (QtQuick 2.15)

Scheduled Pinned Locked Moved Solved QML and Qt Quick
4 Posts 2 Posters 893 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.
  • SeDiS Offline
    SeDiS Offline
    SeDi
    wrote on last edited by SeDi
    #1

    Hi,
    I want to show a TableView that shows a few of its roles with CheckBoxes or Buttons, other roles as normal text delegates, other roles not at all.
    I am using a c++ model derived from QAbstractTableModel (togethter with a QSortFilterProxyModel). Currently Qt 15.0.

    I am aware of the DelegateChooser , but the fact that it is in qt-labs lets me hesitate to use it.

    I'd hate to lose TableView's goodies (e.g. resizing columns) by using a ListView and I should avoid QtQuick 1 for performance reasons (and being deprecated in the first place).

    I have also contemplated just using a bunch of delegates inside an Item of which only one is visible at a time, depending on the role. But that'd be ugly and very memory-consuming.

    What is a proper way to go? Is it safe to go for a "labs" feature?

    BR
    Sebastian

    B 1 Reply Last reply
    0
    • SeDiS SeDi

      Hi,
      I want to show a TableView that shows a few of its roles with CheckBoxes or Buttons, other roles as normal text delegates, other roles not at all.
      I am using a c++ model derived from QAbstractTableModel (togethter with a QSortFilterProxyModel). Currently Qt 15.0.

      I am aware of the DelegateChooser , but the fact that it is in qt-labs lets me hesitate to use it.

      I'd hate to lose TableView's goodies (e.g. resizing columns) by using a ListView and I should avoid QtQuick 1 for performance reasons (and being deprecated in the first place).

      I have also contemplated just using a bunch of delegates inside an Item of which only one is visible at a time, depending on the role. But that'd be ugly and very memory-consuming.

      What is a proper way to go? Is it safe to go for a "labs" feature?

      BR
      Sebastian

      B Offline
      B Offline
      Bob64
      wrote on last edited by
      #2

      @SeDi the 'classic' way to do this is to use a Loader in your delegate and use a switch or if-else if-... construct to instantiate the appropriate component. This is what I do in a similar situation involving a ListView - but I am stuck on 5.9.6 at the moment. I would use DelegateChooser if I had the option, even if it is a labs component, as I could always switch back to my current approach if it stopped being supported or whatever.

      SeDiS 1 Reply Last reply
      2
      • B Bob64

        @SeDi the 'classic' way to do this is to use a Loader in your delegate and use a switch or if-else if-... construct to instantiate the appropriate component. This is what I do in a similar situation involving a ListView - but I am stuck on 5.9.6 at the moment. I would use DelegateChooser if I had the option, even if it is a labs component, as I could always switch back to my current approach if it stopped being supported or whatever.

        SeDiS Offline
        SeDiS Offline
        SeDi
        wrote on last edited by
        #3

        @Bob64 That sounds convincing - thank you!

        SeDiS 1 Reply Last reply
        0
        • SeDiS SeDi

          @Bob64 That sounds convincing - thank you!

          SeDiS Offline
          SeDiS Offline
          SeDi
          wrote on last edited by
          #4

          @SeDi For posterity, here's my working solution:

          delegate: Rectangle {
                                          width: childrenRect.width
                                          height: childrenRect.height
                                          Loader {
                                              sourceComponent: {
                                                  switch(columnNo) {
                                                  case 0: return firstDelegate;
                                                  case 1: return secondDelegate;
                                                  // ...
                                                  default: return etcDelegate;
                                                  }
                                              }
                                          }
                                          Component {
                                              id: firstDelegate
                                              Rectangle {
                                                  width: childrenRect.width
                                                  height: childrenRect.height
                                                  color: "lightgray"
                                                   Text {
                                                       width: contentWidth + contentHeight
                                                       height: contentHeight * 1.1
                                                       text: "first"
                                                       verticalAlignment: Text.AlignVCenter
                                                       horizontalAlignment: Text.AlignHCenter
                                                   }
                                              }
                                          }
                                          Component {
                                              id: secondDelegate
                                              Rectangle {
                                                  width: childrenRect.width
                                                  height: childrenRect.height
                                                  color: "yellow"
                                                   Text {
                                                       width: contentWidth + contentHeight
                                                       height: contentHeight * 1.1
                                                       text: "second"
                                                       verticalAlignment: Text.AlignVCenter
                                                       horizontalAlignment: Text.AlignHCenter
                                                   }
                                              }
                                          }
                                          Component {
                                              id: etcDelegate
                                              Rectangle {
                                                  width: childrenRect.width
                                                  height: childrenRect.height
                                                  color: "lightgreen"
                                                   Text {
                                                       width: contentWidth + contentHeight
                                                       height: contentHeight * 1.1
                                                       text: foodName
                                                       verticalAlignment: Text.AlignVCenter
                                                       horizontalAlignment: Text.AlignHCenter
                                                   }
                                              }
                                          }
                                      }
          

          To provide the columnNo role I had to do some work in my QAbstractTableModel.
          The roles enum in the header:

          class LogTableModel : public QAbstractTableModel
          {
              enum Role {
                  DisplayRole         = Qt::DisplayRole,
                  DecorationRole      = Qt::DecorationRole,
                  StatusTipRole       = Qt::StatusTipRole,
                  //whatever...
                  ColumnNoRole        = Qt::UserRole+5 // or wherever it suits
          ...
          
          

          In data(...) I have implemented:

          QVariant LogTableModel::data(const QModelIndex &index, int role) const
          {
              if (index.isValid()) {
                  switch(role)
                  {
                  case DisplayRole: return  QVariant::fromValue(m_columns.at(index.column())->at(index.row()));
                  case ColumnNoRole: return QVariant::fromValue(index.column());
          ...
          

          roleNames() must also know it:

          QHash<int, QByteArray> LogTableModel::roleNames() const
          {
              QHash<int, QByteArray> roles;
              roles[DisplayRole] = "display";
              roles[ColumnNoRole] = "columnNo";
          ...
          
          1 Reply Last reply
          1

          • Login

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