QTableView 的 QItemDelegate 编辑器上的自定义小部件

Custom widget on QItemDelegate editor for QTableView

我有一个 QTableView 显示来自自定义模型的数据。每个单元格上的版本都有一个 QItemDelegate。视图的一列有一个自定义小部件,由 QLineEditQCheckBox 组成。当我单击此列的单元格时,会显示编辑器并且它可以工作,但它不适合 table 单元格。而且,当我放大一行并单击单元格时,我可以看到小部件后面的单元格的数据。

有没有一种方法可以让我的小部件在视图上像 QItemDelegate 的普通编辑小部件一样工作?即创建时它使用单元格的所有垂直 space?

这是我的小部件(简体):

class MyWidget(QtGui.QWidget):
    def __init__(self, parent = None):
        super(MyWidget, self).__init__(parent)
        self.lineEdit = QtGui.QLineEdit(parent)
        self.checkBox = QtGui.QCheckBox(parent)
        self.checkBox.setChecked(False)
        self.gridLayout = QtGui.QGridLayout(self)
        self.gridLayout.setSpacing(3)
        self.gridLayout.addWidget(self.lineEdit, 0, 0)
        self.gridLayout.addWidget(self.checkBox, 0, 1)

我的代表(简体):

class MyDelegate(QtGui.QItemDelegate):
    def __init__(self, parent = None):
        super(MyDelegate, self).__init__(parent)

    def createEditor(self, parent, option, index):
        return MyWidget(parent)

    def setModelData(self, editor, model, index):
        pass

    def setEditorData(self, editor, model, index):
        pass

有许多不同的问题:

  1. 默认情况下 QLineEdit 的垂直尺寸策略是固定的,因此它不会展开以填充可用空间 space。

  2. 布局有一个默认的内容边距(即填充),这可能会限制所包含的小部件的大小。

  3. 默认情况下,QWidget 不会自动绘制自己的背景,因此单元格的数据可能在下方可见。

  4. 如果小部件在单元格中占据全部 space,将无法再显示单元格被选中。

所有这些问题都可以通过以下方式解决:

class MyWidget(QtGui.QWidget):
    def __init__(self, parent = None):
        super(MyWidget, self).__init__(parent)
        # create an inner widget
        widget = QtGui.QWidget(self)
        # disable widget transparency
        widget.setAutoFillBackground(True)
        # allow the line-edit to fully expand
        self.lineEdit = QtGui.QLineEdit(widget)
        self.lineEdit.setSizePolicy(QtGui.QSizePolicy(
            QtGui.QSizePolicy.MinimumExpanding,
            QtGui.QSizePolicy.MinimumExpanding))
        self.checkBox = QtGui.QCheckBox(widget)
        self.checkBox.setChecked(False)
        # trim space on right side of checkbox
        self.checkBox.setText('')
        hbox = QtGui.QHBoxLayout(widget)
        # remove the inner margin
        hbox.setContentsMargins(0, 0, 0, 0)
        hbox.setSpacing(3)
        hbox.addWidget(self.lineEdit)
        hbox.addWidget(self.checkBox)
        layout = QtGui.QVBoxLayout(self)
        # set the selection rectangle width
        layout.setContentsMargins(2, 2, 2, 2)
        layout.addWidget(widget)

看起来像这样: