3

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

1 Answer 1

4

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

0

Not the answer you're looking for? Browse other questions tagged or ask your own question.