Congratulations to our 2022 Qt Champions!

Changing headerData in QTreeView depending on selection

  • Hi,

    i have a QTreeView, that shows some model derived from QAbstractItemModel.
    now i want to show different headerData on the TreeView depending on which type of Item in the view is selected.
    How do i implement this?

    My problem is, that normally MyTreeModel does not know the TreeView and therefore I do not know where to get the selection information from.

    I have tried to get the inof directly from the view, which kind of works, however when using a QSortFilterProxyModel it will crash.

    QVariant MyTreeModel::headerData(int section, Qt::Orientation orientation, int role) const
        if(m_root_item != NULL){
            if (orientation == Qt::Horizontal && role == Qt::DisplayRole){
                // getting the current item from a pointer to the view stored in the model
                // this seems to be kind of a bad idea
                QModelIndex index = m_tree_view->currentIndex();
                    return QVariant();
                Item* item_selected = static_cast<Item*>(index.internalPointer());
                if(item_selected != NULL){
                    std::string value;
                    value = item_selected->getHeader(section);
                    return QVariant(value.c_str());
        return QVariant();
    what is the right way to implement this?

  • Lifetime Qt Champion

    Why not listening on QTreeView::selectionChanged somewhere and adjust the header data the way you need it?

  • @Christian-Ehrlicher Thanks for the hint.

    The easiest way to implement this i can imagine atm is something as follows:

    • A slot in MyTreeView that is called when selection changes.
    • From there i call the TreeModel::data() for the current index and add a new role to get the headerData from the items.
    • Then i call setHeaderData for all the columns and store the data in the TreeModel.
    • This data is returned when headerData() is called.

    I guess this will work, however it sound not like the straight forward approach for such a common application?

  • Lifetime Qt Champion

    This is also the way I would solve it. But I don't see this as a common situation. I've no application in mind which changes the header based on the current (selected) index ...

  • If you have a working implementation of setHeaderData and headerData in your model you can just:

    QObject::connect(treeView->selectionModel(),&QItemSelectionModel::selectionChanged,treeView->model(),[=](const QItemSelection &selected, const QItemSelection &deselected)->void{
    const auto selectedIndexes = selected.indexes();
    const auto deselectedIndexes = deselected.indexes();
    for(auto&& idx : selectedIndexes){
    treeView->model()->setHeaderData(idx.column(),Qt::Horizontal,QStringLiteral("%1 Selected").arg(idx.column()));
    for(auto&& idx : deselectedIndexes ){

Log in to reply