TableView with different cell widgets.



  • Hello,

    I am trying to create a table view like the following mock-up. My idea is to load a list of devices from an xml/json file and programmatically populate the cell item with some widgets like combobox, buttons and label.

    I have seen the spinbox delegate example but it is only for a single widget. May I know what should I use to create something like this?

    Table View


  • Moderators

    I have seen the spinbox delegate example but it is only for a single widget.

    The delegate returns a single widget, true, but nothing stops it from being a plain QWidget with a layout and a couple more widgets inside it.



  • You can create multiple custom delegates for different columns and use setItemDelegateForColumn(); this should be sufficient to achieve the tableView in the attached image.

    You can also create a holder class which specifies a componentType (e.g pushButton ,combobox etc) and set this holder to each index of the tableView usinge setData(Qt::UserRole). In the delegate you can check the holder instance for that particular index and based on the componentType render the required widget / editor (this implementation is complicated but powerful - as for any cell you can specify any type of widget )

    PS:

    You can create a single delegate and handle/render/create different widget based on the column index eg in

    createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
        if (index.column() == 1)
       {
           //create and return combobox;
       } else if (index.column() == 2)
      {
       // create and return custom widget
      }
    }
    


  • Thanks Chris and Sam, I think I'll go with setItemDelegateForColum() method as it is easier.



  • I managed to cobble up together a combobox delegate for the tableview. When I run, there is no visual indication that the widget inside the cell is a combobox until I double-clicked it. Is there a way to force the widget to always show up as a combobox instead of a normal cell when it is not selected?

    Table View



  • Nevermind, I did that by applying qabstractitemview.html#openPersistentEditor on the respective cell:

    ui->tableView->openPersistentEditor(index);
    

    Note: someone advised against doing this if you're having a large table.



  • In the paint() method of the delegate you can render a combobox , also change the tableView editTriggers to QAbstractItemView::AllEditTriggers

    void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
    {
      QStyleOptionComboBox box;
     
      box.rect = option.rect;
      box.currentText = "test";
     
      QApplication::style()->drawComplexControl(QStyle::CC_ComboBox, &box, painter, 0);
      QApplication::style()->drawControl(QStyle::CE_ComboBoxLabel, &box, painter, 0);
    }
    

    Note: code is not tested



  • Thanks Sam, I managed to make it work using other method that is opening the persistent editor for the cell widget.

    Now I have a QTableWidget with 2 custom delegates: QComboBox and QPushButton. I originally used a QTableView but changed to QTableWidget instead because I do not have any proper model.

    TableWidget with custom delegates

    Is there a way get the current row index from the delegates? Or pass the row index from the delegate to its parent (MainWindow). I need link the index action to the socket that is managed in the MainWindow. I have tried accessing the sender property as posted in some threads in this forum but I couldn't make it work because the way they do it is to set the cell widget directly using the button whereas I used the delegate method.

    Any idea?

    TableWidgetDelegate Example Project


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.