user20679
user20679

Reputation: 442

Custom widget on QItemDelegate editor for QTableView

I have a QTableView showing a data from a custom model. I have a QItemDelegate for the edition on each of the cells. One column of the view has a custom widget comprised by a QLineEdit and a QCheckBox. When I click on the cells of this column the editor is shown and it works, but it doesn't fit the table cell. Moreover, when I enlarge a row and click on the cell, I can see the data of the cell behind the widget.

Is there a way that my widget behaves like a normal editing widget for a QItemDelegate on the view? i.e when created it uses all the vertical space of the cell?

This is my widget (simplified):

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)

My delegate (simplified):

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

Upvotes: 3

Views: 2362

Answers (1)

ekhumoro
ekhumoro

Reputation: 120578

There are a number of different problems:

  1. The vertical size-policy of a QLineEdit is fixed by default, so it will not expand to fill the availabe space.

  2. The layout has a default contents margin (i.e. padding) which may constrain the size of the contained widgets.

  3. By default, a QWidget does not draw its own background automatically, so the cell's data may be visible underneath.

  4. If the widget takes up all the space in the cell, it will no longer be possible to show that the cell is selected.

All these problems can be fixed as follows:

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)

And will look like this:

enter image description here

Upvotes: 4

Related Questions