QTable Widgets and List Views
How often have you wanted to place additional widgets in the header row of a list view or a table view? Take, for example, a checkmark in the header in order to turn on and off an entire column. Qt 5 does not natively support this feature.
A quick search will turn up some solutions, but they all have limitations. For example, the solution outlined in this stack overflow question only supports a checkbox and, even then, only one per table. Another proposed solution also only supports a checkbox, but at least it’s a good place to start.
Taking our cue from the second source, we build on it with these goals in mind:
- Support for any type of widget.
- Support for multiple columns, each having its own widget.
- Ease of use.
How It Works
The trick is to have a custom header view (QHeaderView
) that can be set on a table (QTableWidget
) or list (QListWidget
). The custom header view tracks the widgets used as headers for each column. The view also handles placing and resizing the widgets to fit within the header.
Since the widgets are drawn on top of the header, you should not set any title for that column, but instead use a widget that has a label. Since any widget is supported, you can create a container to place an additional label if the widget you want to use does not have one.
Placing the widget on top works because Qt paints parent-widgets before children. Since the additional widgets are children of the header view, they get painted after the header and thus appear on top of it.
The API to use the custom header is very simple. You just create an instance of QHeaderViewWithWidgets
, add the widgets to the column (called “section” in Qt), and set the header view on your table. In short, it looks like this:
// Create a combo-box for the header.
auto col1_check = new QCheckBox("My checkbox");
// Create the header view with the combo-box for column 1.
auto header = new QHeaderViewWithWidgets(Qt::Orientation::Horizontal);
header->addSectionWidget(1, col1_check);
// Create the table and set the custom header.
auto list = new QTableWidget;
list->setHorizontalHeader(header);
The Code
The C++ code you need to put widgets in the header of a table is available in this public repository on GitHub.
An example of an application using the custom header view with sub-widgets is available in the same repository, in the examples\ExampleListHeaderWidget
folder.