It took some trial and error to create an appropriate paint method for inactive items in an item delegate for QT’s list view. Here are some pointers.
- Start by creating a subclass of QItemDelegate:
class MyItemDelegate : public QItemDelegate
- Implement your versions of createEdtior, setModelData, and updateEditorGeometry.
- Create custom paint routine.
void MyItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { if (!index.isValid()) return; QVariant value = index.data(Qt::EditRole); QString display = index.data(Qt::DisplayRole).toString(); if(---your logic to determine if it is a dropdown---) { QStyleOptionComboBox comboBoxOption; comboBoxOption.init((QWidget*)parent()); comboBoxOption.state |= QStyle::State_Enabled; comboBoxOption.state &= !QStyle::State_HasFocus; comboBoxOption.direction = QApplication::layoutDirection(); comboBoxOption.rect = option.rect; comboBoxOption.fontMetrics = QApplication::fontMetrics(); comboBoxOption.currentText = display; comboBoxOption.editable = false; QApplication::style()->drawComplexControl(QStyle::CC_ComboBox, &comboBoxOption, painter, (QWidget*)parent()); QApplication::style()->drawControl(QStyle::CE_ComboBoxLabel, &comboBoxOption, painter); } else if (value.canCast(QVariant::Bool)) // or your specific logic { Qt::CheckState checkState; if (value.toBool()) checkState = Qt::Checked; else checkState = Qt::Unchecked; QRect checkRect = check(option, option.rect, checkState); // draw the background color if (option.showDecorationSelected && (option.state & QStyle::State_Selected)) { QPalette::ColorGroup cg = option.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled; if (cg == QPalette::Normal && !(option.state & QStyle::State_Active)) cg = QPalette::Inactive; painter->fillRect(option.rect, option.palette.brush(cg, QPalette::Highlight)); } else { value = index.data(Qt::BackgroundColorRole); if (value.isValid() && qvariant_cast<QColor>(value).isValid()) painter->fillRect(option.rect, qvariant_cast<QColor>(value)); } // draw the item drawCheck(painter, option, checkRect, checkState); } else if(--- your logic for editable item---) { QStyleOptionFrameV2 frameOption; QStyleOptionViewItem option2 = option; frameOption.init((QWidget*)parent()); frameOption.state |= QStyle::State_Enabled; frameOption.state &= !QStyle::State_HasFocus; frameOption.rect = option.rect; frameOption.rect.adjust(1, 1, -3, -1); frameOption.lineWidth = 1; QApplication::style()->drawPrimitive(QStyle::PE_PanelLineEdit, &frameOption, painter); drawDisplay(painter, option2, option.rect, display); } else { QItemDelegate::paint(painter, option, index); } }
Edit the above and add any additional styles based on your inputs. This will make your application more user friendly than listing a bunch of options without any hints that they can be edited.