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?
-
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 } }
-
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?
-
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.
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?