Question

I' m looking for an Event or Signal like "row height changed" that is called if the user changes the height of a row in my QTableView. I want to use this signal to resize all other rows in the QTableView to the new height. I didn' t find such an Event or Signal so I reckon there must be some kind of handy workaround.

Any suggestions will be appreciated.

Was it helpful?

Solution

Row resizing is performed by the vertical QHeaderView. The object emmiting it is QTableView::verticalHeader()

the signal you are interested in is

void QHeaderView::sectionResized ( int logicalIndex, int oldSize, int newSize )

This signal is emitted when a section is resized. The section's logical number is specified by logicalIndex, the old size by oldSize, and the new size by newSize.

OTHER TIPS

Use QHeaderView (You can get an instance by calling QTableView::horizontalHeader()/QTableView::verticalHeader() ) and connect to geometriesChanged() or sectionResized()

The solution with QHeaderView and sectionResized works very well for me. So for resizing all rows to the same height as the edited row I use this code now:

class MyWidget(QWidget):

    def __init__(self, parent=None):

        #Do some other init things

        self.myTable.verticalHeader().sectionResized.connect(
            self.row_resized)

    def row_resized(self, index, old_size, new_size):
        for i in range(self.myTable.verticalHeader().count()):
            self.myTable.setRowHeight(i, new_size)

I wanted to save data after a section was resized, but found sectionResized fired a signal continuously while adjusting, rather than once at the end. The simplest solution I could think of was to subclass the QHeaderView.

class CustomHeader(QtWidgets.QHeaderView):
    """
    Custom header class to return when a section has been resized
    Only after mouse released, opposed to continuously while resizing
    """
    on_section_resized = QtCore.Signal(int)

    def __init__(self, *args, **kwargs):
        super(CustomHeader, self).__init__(*args, **kwargs)
        self._has_resized = False
        self._index = 0

        self.sectionResized.connect(self.section_resized)

    def section_resized(self, index, old_size, new_size):
        self._has_resized = True
        self._index = index

        return

    def mouseReleaseEvent(self, event):
        super(CustomHeader, self).mouseReleaseEvent(event)

        if self._has_resized:
            self._has_resized = False
            self.on_section_resized.emit(self._index)

        return

In my main class I assigned the header to the table widget:

self.table_widget.setVerticalHeader(CustomHeader(QtCore.Qt.Vertical, self.table_widget))

Then connected the custom signal to my function within the original class:

self.table_widget.verticalHeader().on_section_resized.connect(self.save_section_height)

Part of the Save function:

def save_section_height(self, row):
    """
    Updates the edited row's section height

    :param row: int, row that has been changed

    :return: None
    """

    new_section_height = self.table_widget.verticalHeader().sectionSize(row)

I expect some things could be optimised better, but this at least fires one save signal opposed to ten plus, or something!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top