Friday, 25 May 2018

Add checkbox in QTableView header using icons

There is no API to insert a checkbox into the header of a QTableView. The recommended way of achieving this is to subclass the QHeaderView and draw the checkbox in the paintSection() method which is in my opinion overkill for such a simple feature.

In this post, I show how to achieve a similar effect by simply adding icons in the header. The desired effect is shown below:



Code description

First, a table model is created by subclassing the QAbstractTableModel. The data for the table is initialised in self._array (which is a numpy array in this example) and self.test holds the check states for each row in the data. if it was not obvious self.header_icon will hold the current icon in the header. The current icon is determined by the setHeaderIcon() method.

The QAbstractTableModel.headerData() method is overloaded and the checkbox icon is drawn into the horizontal header of the table.

In the setHeaderIcon() method, the header icon is set depending on the states of the checkboxes in the columns. After changing the icon, a headerDataChanged signal is emitted to notify the table view that the header has been changed without this line the header icon will not be updated.

The icons used are checked.png (left), intermediate.png (middle) and unchecked.png (right).

The toggleCheckState() method toggles the check state of the data. The dataChanged signal is emitted to notify the table that the data has changed and the header is updated by calling setHeaderIcon() method.

In the main script, a table view is created with a NumpyModel object set as its model. Finally, the sectionPressed signal of the table view header is connected to the toggleState() method of the model, this ensures that clicking on the header changed the data's check state.

The complete python code is available below:

4 comments:

  1. This comment has been removed by a blog administrator.

    ReplyDelete
  2. This comment has been removed by a blog administrator.

    ReplyDelete
  3. Good night my friend. I managed to convert your code to PyQt6, but the checkbox in rows didn't accept being selected, just deselected.

    ReplyDelete
    Replies
    1. This worked for me
      https://gist.github.com/StephenNneji/dd94418ecef749525e6251e37c38f25a

      Delete