Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Highlighting selected row to be Bold in QTreeView
Forum Updated to NodeBB v4.3 + New Features

Highlighting selected row to be Bold in QTreeView

Scheduled Pinned Locked Moved Solved General and Desktop
21 Posts 5 Posters 4.0k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • sierdzioS sierdzio

    You can probably simply use Qt::ItemDataRole::FontRole and return a bold font (in model::data() method) for the row you want to be bold..

    qwasder85Q Offline
    qwasder85Q Offline
    qwasder85
    wrote on last edited by
    #9

    @sierdzio This. Do this.

    sierdzioS 1 Reply Last reply
    0
    • qwasder85Q qwasder85

      @sierdzio This. Do this.

      sierdzioS Offline
      sierdzioS Offline
      sierdzio
      Moderators
      wrote on last edited by
      #10

      @qwasder85 said in Highlighting selected row to be Bold in QTreeView:

      @sierdzio This. Do this.

      Hm?

      (Z(:^

      1 Reply Last reply
      1
      • S Offline
        S Offline
        sogo
        wrote on last edited by
        #11

        Hi @sierdzio Oh this is new for me, please give me sometime to check and play with it a little and see how can I implement bold row on double click on any row and if I have any question, I'll ping here. Here is the updated code, were some issues in there:

        QVariant FileSystem::data(const QModelIndex &index, int role) const
        {
          int row = index.row();
          int col = index.column();
          const bool shouldBeBold = (row == 0 && col == 0);
          if (role == Qt::FontRole && shouldBeBold) {
            QFont boldFont;
            boldFont.setBold(true);
            return boldFont;
          } else {
            return QFileSystemModel::data(index, role); // This will call the original QFileSystem::data method
          }
        }
        

        @JonB thanks for your update too

        I have one question though, I was reading the QFileSystemModel source code and I didn't see any case of QT::FontRole in qfilesystemmodel.cpp "::data" method. What confuses me is that in this code this statement "if (role == QT::FontRole && shouldBeBold)", how is it checking this.

        sierdzioS JonBJ 2 Replies Last reply
        0
        • S sogo

          Hi @sierdzio Oh this is new for me, please give me sometime to check and play with it a little and see how can I implement bold row on double click on any row and if I have any question, I'll ping here. Here is the updated code, were some issues in there:

          QVariant FileSystem::data(const QModelIndex &index, int role) const
          {
            int row = index.row();
            int col = index.column();
            const bool shouldBeBold = (row == 0 && col == 0);
            if (role == Qt::FontRole && shouldBeBold) {
              QFont boldFont;
              boldFont.setBold(true);
              return boldFont;
            } else {
              return QFileSystemModel::data(index, role); // This will call the original QFileSystem::data method
            }
          }
          

          @JonB thanks for your update too

          I have one question though, I was reading the QFileSystemModel source code and I didn't see any case of QT::FontRole in qfilesystemmodel.cpp "::data" method. What confuses me is that in this code this statement "if (role == QT::FontRole && shouldBeBold)", how is it checking this.

          sierdzioS Offline
          sierdzioS Offline
          sierdzio
          Moderators
          wrote on last edited by
          #12

          @sogo said in Highlighting selected row to be Bold in QTreeView:

          I have one question though, I was reading the QFileSystemModel source code and I didn't see any case of QT::FontRole in qfilesystemmodel.cpp "::data" method.

          In general, this flag is rarely used. I think most of the time, delegates just take default font from QPalette / QSS.

          What confuses me is that in this code this statement "if (role == QT::FontRole && shouldBeBold)", how is it checking this.

          I don't understand your question, sorry. How is what checking this?

          (Z(:^

          1 Reply Last reply
          0
          • S sogo

            Hi @sierdzio Oh this is new for me, please give me sometime to check and play with it a little and see how can I implement bold row on double click on any row and if I have any question, I'll ping here. Here is the updated code, were some issues in there:

            QVariant FileSystem::data(const QModelIndex &index, int role) const
            {
              int row = index.row();
              int col = index.column();
              const bool shouldBeBold = (row == 0 && col == 0);
              if (role == Qt::FontRole && shouldBeBold) {
                QFont boldFont;
                boldFont.setBold(true);
                return boldFont;
              } else {
                return QFileSystemModel::data(index, role); // This will call the original QFileSystem::data method
              }
            }
            

            @JonB thanks for your update too

            I have one question though, I was reading the QFileSystemModel source code and I didn't see any case of QT::FontRole in qfilesystemmodel.cpp "::data" method. What confuses me is that in this code this statement "if (role == QT::FontRole && shouldBeBold)", how is it checking this.

            JonBJ Offline
            JonBJ Offline
            JonB
            wrote on last edited by JonB
            #13

            @sogo
            Every model inherits https://doc.qt.io/qt-5/qabstractitemmodel.html#data. The Qt infrastructure (e.g. QTreeView) calls the model's data() method multiple times (behind the scenes), passing in the various roles listed in https://doc.qt.io/qt-5/qt.html#ItemDataRole-enum, to get all the information it wants from the model to display each item as desired. One of the roles it passes in is FontRole. Your override of data() returns a bold font if and only if you want it to be bold. In the code proposed, that is when row == 0 && col == 0, so that item (only) comes out in bold.

            1 Reply Last reply
            2
            • S Offline
              S Offline
              sogo
              wrote on last edited by
              #14

              What I mean't is we are not giving "role" as argument to call the function "QFileSystemModel::data", how does the program knows if role is equal to Qt::FontRole. Does the QFileSystemModel:data function goes to check through all the Qt::ItemDataRole?

              JonBJ sierdzioS 2 Replies Last reply
              0
              • S sogo

                What I mean't is we are not giving "role" as argument to call the function "QFileSystemModel::data", how does the program knows if role is equal to Qt::FontRole. Does the QFileSystemModel:data function goes to check through all the Qt::ItemDataRole?

                JonBJ Offline
                JonBJ Offline
                JonB
                wrote on last edited by JonB
                #15

                @sogo
                Your post has crossed with my latest. Read that and see if you follow now? Yes, behind the scenes it calls your data() many times, with different values for role. You can put in a qDebug() statement, to see how many times it is called, with which row/column and with various values for role.

                1 Reply Last reply
                0
                • S Offline
                  S Offline
                  sogo
                  wrote on last edited by
                  #16

                  Hi @JonB
                  Yea, now I get it. Thanks a lot for clarification

                  1 Reply Last reply
                  0
                  • S sogo

                    What I mean't is we are not giving "role" as argument to call the function "QFileSystemModel::data", how does the program knows if role is equal to Qt::FontRole. Does the QFileSystemModel:data function goes to check through all the Qt::ItemDataRole?

                    sierdzioS Offline
                    sierdzioS Offline
                    sierdzio
                    Moderators
                    wrote on last edited by
                    #17

                    @sogo said in Highlighting selected row to be Bold in QTreeView:

                    What I mean't is we are not giving "role" as argument to call the function "QFileSystemModel::data", how does the program knows if role is equal to Qt::FontRole. Does the QFileSystemModel:data function goes to check through all the Qt::ItemDataRole?

                    const QModelIndex &index, int role role is there, it's the second argument.

                    If you call data() manually and skip the role, it defaults to Qt::DisplayRole. But the view (QTreeView and others) will call data() with other roles, too, don't worry. If you want to force it (as you should in case of your double click thingy), emit dataChanged() for the row which should be bold.

                    (Z(:^

                    S 1 Reply Last reply
                    0
                    • sierdzioS sierdzio

                      @sogo said in Highlighting selected row to be Bold in QTreeView:

                      What I mean't is we are not giving "role" as argument to call the function "QFileSystemModel::data", how does the program knows if role is equal to Qt::FontRole. Does the QFileSystemModel:data function goes to check through all the Qt::ItemDataRole?

                      const QModelIndex &index, int role role is there, it's the second argument.

                      If you call data() manually and skip the role, it defaults to Qt::DisplayRole. But the view (QTreeView and others) will call data() with other roles, too, don't worry. If you want to force it (as you should in case of your double click thingy), emit dataChanged() for the row which should be bold.

                      S Offline
                      S Offline
                      sogo
                      wrote on last edited by
                      #18

                      @sierdzio said in Highlighting selected row to be Bold in QTreeView:

                      If you call data() manually and skip the role, it defaults to Qt::DisplayRole.

                      I'm not sure but whenever I have to call it manually, I have to give Qt::ItemDataRole as arg.. For now this is what I tried in my TreeView.cpp code:

                      #include "TreeView.h"
                      #include "ui_TreeView.h"
                      
                      TreeView::TreeView(QWidget *parent) :
                          QWidget(parent),
                          ui(new Ui::TreeView)
                      {
                          ui->setupUi(this);
                          myModel = new FileSystem;
                          connect( ui->treeView, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT( onClick(const QModelIndex&) ) );
                      }
                      
                      TreeView::~TreeView()
                      {
                          delete ui;
                      }
                      
                      void TreeView::openFile(const QString& folderPath)
                      
                      {
                      myModel->setRootPath(folderPath);
                      QModelIndex index = myModel->index(folderPath);
                      myModel->setFilter(QDir::NoDotAndDotDot | QDir::AllDirs);
                      ui->treeView->setModel(myModel);
                      ui->treeView->setRootIndex(index);
                      ui->treeView -> expand(index);
                      }
                      
                      void TreeView::onClick(const QModelIndex &index)
                      {
                          myModel->data(index,Qt::DisplayRole);
                      
                      }
                      

                      @sierdzio said in Highlighting selected row to be Bold in QTreeView:

                      will call data() with other roles, too, don't worry. If you want to force it (as you should in case of your double click thingy), emit dataChanged() for the row which should be bold

                      I also tried tried creating new signal which will emit dataChanged(const QModelIndex&) and emit when double clicked signal:

                      void TreeView::onClick(const QModelIndex &index)
                      {
                         emit dataChanged(index);
                      }
                      

                      I'm not sure how to catch this signal in my FileSystem class so that I can connect it with data function. Another issue is if I change hard code row and columns in FileSystem::data function, it calls it everytime to populate tree view which causes rows and columns to be bold out when directory is loaded. This part.

                      int row = index.row();
                        int col = index.column();
                        const bool shouldBeBold = (row && col);
                        if (role == Qt::FontRole && shouldBeBold) {
                      
                      1 Reply Last reply
                      0
                      • sierdzioS Offline
                        sierdzioS Offline
                        sierdzio
                        Moderators
                        wrote on last edited by
                        #19

                        You need to change the way you think about the view and the model a bit, I think.

                        In Qt model-view framework, there is a clear separation: the model is "the boss". The view is just a dumb "output" for data provided by the model.

                        So for example, do not do this:

                        void TreeView::onClick(const QModelIndex &index)
                        {
                            myModel->data(index,Qt::DisplayRole);
                        }
                        

                        The data has not changed, so calling data() here is pointless! Instead, tell the model which row was clicked and update the data inside of the model. I mean something like:

                        // view
                        void TreeView::onClick(const QModelIndex &index)
                        {
                            myModel->rowClicked(index);
                        }
                        
                        // model
                        
                        void FileModel::rowClicked(const QModelIndex &index)
                        {
                          // m_boldRow is some private member variable you add to your model class
                          // Probably better to use QPersistentIndex here!
                          m_boldRow = index; 
                          emit dataChanged(index, index, Qt::FontRole);
                        }
                        
                        QVariant FileSystem::data(const QModelIndex &index, int role) const
                        {
                          const bool shouldBeBold = (index == m_boldRow);
                          if (role == Qt::FontRole && shouldBeBold) {
                            QFont boldFont;
                            boldFont.setBold(true);
                            return boldFont;
                          } else {
                            return QFileSystemModel::data(index, role); // This will call the original QFileSystem::data method
                          }
                        }
                        

                        (Z(:^

                        1 Reply Last reply
                        3
                        • S Offline
                          S Offline
                          sogo
                          wrote on last edited by
                          #20

                          I see, I was trying something similar next i.e. catching the QModelIndex in FileSystem class in separate function and changing the condition inside the data function but I wasn't sure how to update the model. If I'm not wrong, the emit dataChanged() signal is doing that. Thanks for this, this is working. Closing this thread

                          1 Reply Last reply
                          0
                          • S sogo

                            Hi,
                            I'm working on highlighting a selected row in QTreeView bold when double clicked or to be specific through using index of that row selected. As this is an old issue and there are multiple solutions online that I found, I started using QStyledItemDelegate by sub-classing it and using it's paint function.
                            In my main window, I have separate class "TreeView" which holds QTreeView widget and in that I'm calling another class "FileSystem" that has sub-classed QStyleItemDelegate.
                            Here is the code of TreeView:
                            TreeView.h

                            #include <QFileSystemModel>
                            #include <QModelIndex>
                            #include <QDebug>
                            #include <QStyledItemDelegate>
                            
                            #include "filesystem.h"
                            namespace Ui {
                            class TreeView;
                            }
                            
                            class TreeView : public QWidget
                            {
                                Q_OBJECT
                            
                            public:
                                explicit TreeView(QWidget *parent = nullptr);
                                ~TreeView();
                                void openFile(const QString& folderPath);
                                QFileSystemModel *myModel;
                                FileSystem *ite;
                            
                            public slots:
                                void onClick(const QModelIndex&);
                            
                            private:
                                Ui::TreeView *ui;
                            };
                            
                            #endif // TREEVIEW_H
                            

                            TreeView.cpp

                            #include "TreeView.h"
                            #include "ui_TreeView.h"
                            
                            TreeView::TreeView(QWidget *parent) :
                                QWidget(parent),
                                ui(new Ui::TreeView)
                            {
                                ui->setupUi(this);
                                myModel = new QFileSystemModel;
                                ite = new FileSystem;
                                connect( ui->treeView, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT( onClick(const QModelIndex&) ) );
                            }
                            
                            TreeView::~TreeView()
                            {
                                delete ui;
                                delete ite;
                                delete myModel;
                            }
                            
                            void TreeView::openFile(const QString& folderPath)
                            
                            {
                            myModel->setRootPath(folderPath);
                            QModelIndex index = myModel->index(folderPath);
                            myModel->setFilter(QDir::NoDotAndDotDot | QDir::AllDirs);
                            ui->treeView->setModel(myModel);
                            ui->treeView->setRootIndex(index);
                            ui->treeView -> expand(index);
                            
                            }
                            
                            void TreeView::onClick(const QModelIndex &index)
                            {
                                ui->treeView->setItemDelegateForRow(index.row(),ite);
                            }
                            

                            FileSystem.h

                            #ifndef FILESYSTEM_H
                            #define FILESYSTEM_H
                            #include <QFileSystemModel>
                            #include <QStyledItemDelegate>
                            class FileSystem: public QStyledItemDelegate
                            {
                            public:
                                FileSystem();
                                QStyledItemDelegate *item;
                                void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
                            };
                            
                            #endif // FILESYSTEM_H
                            
                            

                            FileSystem.cpp

                            #include "filesystem.h"
                            #include <QFont>
                            #include <QDebug>
                            #include <QBrush>
                            FileSystem::FileSystem()
                            {
                              item = new QStyledItemDelegate;
                            }
                            
                            void FileSystem::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
                            {
                                QStyleOptionViewItem opt = option;
                                initStyleOption(&opt, index);
                                opt.font.setBold(true);
                            
                                QStyledItemDelegate::paint(painter, opt, index);
                            }
                            

                            So I'm using QAbstractItemView's function "setItemDelegateForRow(index.row(), ite)" to set custom style item delegate for that specific row. Now their are two problems I'm facing:
                            1- As I'm using index.row(), it returns integer number of row which is same for the treeView child rows and all those child rows also get highlighted. Is there any option that can segregate parent from their child rows, please see image below
                            1.PNG

                            2- When I select another row, the previous one selected needs to get un-bold or back to default view. Is their a way to unset my custom item delegate on previously selected row

                            I'm not sure if this is the best way to do it so I'm open to suggestions also. Thanks

                            eyllanescE Offline
                            eyllanescE Offline
                            eyllanesc
                            wrote on last edited by eyllanesc
                            #21

                            @sogo A simple solution is to override the initStyleOption method of QStyledItemDelegate:

                            class StyledItemDelegate: public QStyledItemDelegate{
                            public:
                                using QStyledItemDelegate::QStyledItemDelegate;
                            protected:
                                void initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const {
                                    QStyledItemDelegate::initStyleOption(option, index);
                                    if(option->state & QStyle::State_Selected){
                                        option->font.setBold(true);
                                    }     
                                }
                            };
                            

                            If you want me to help you develop some work then you can write to my email: e.yllanescucho@gmal.com.

                            1 Reply Last reply
                            1

                            • Login

                            • Login or register to search.
                            • First post
                              Last post
                            0
                            • Categories
                            • Recent
                            • Tags
                            • Popular
                            • Users
                            • Groups
                            • Search
                            • Get Qt Extensions
                            • Unsolved