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. How to implement setHeaderData in a subclass of QAbstractTableModel?
Forum Updated to NodeBB v4.3 + New Features

How to implement setHeaderData in a subclass of QAbstractTableModel?

Scheduled Pinned Locked Moved Solved General and Desktop
qtablemodeltable view
34 Posts 4 Posters 5.4k 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.
  • Christian EhrlicherC Christian Ehrlicher

    @jdent said in How to implement setHeaderData in a subclass of QAbstractTableModel?:

    I just want "Num 0" for column 0 and "Num 1" for column 1. What should I return for each value of role?

    You already return this.

    what do I need to call in QTableView to display the header of the model?

    Nothing - except you've hidden the header by yourself.

    J Offline
    J Offline
    jdent
    wrote on last edited by
    #9

    @Christian-Ehrlicher "You already return this." No, I don't see any header!!

    "what do I need to call in QTableView to display the header of the model?

    Nothing - except you've hidden the header by yourself." What do you mean, I have hidden the header??

    JonBJ 1 Reply Last reply
    0
    • J jdent

      @Christian-Ehrlicher "You already return this." No, I don't see any header!!

      "what do I need to call in QTableView to display the header of the model?

      Nothing - except you've hidden the header by yourself." What do you mean, I have hidden the header??

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

      @jdent
      Your code uses setHeaderData() to explicitly set some header.
      From that method you need to save/store that value. Somewhere in your subclass.
      Then your header() method needs to retrieve that and return it.
      This is what a model like, say, QStandardItemModel will do for you.
      When you use your own QAbstractTableModel you have to implement this. In your own member variable structure. For all roles you wish to allow the caller to store data in header.
      If you do not need to allow callers to set the header data, e.g. you can calculate what you want, then you don't need a setHeaderData() or storage, you can just write header() to compute and return values.
      It's the same principle as what you do with setData() and data() in your subclassed QAbstractTableModel, only done separately for the header data.

      1 Reply Last reply
      1
      • J Offline
        J Offline
        jdent
        wrote on last edited by
        #11

        QAbstractTableModel has no header() method nor its superclass!!

        Christian EhrlicherC 1 Reply Last reply
        0
        • J jdent

          QAbstractTableModel has no header() method nor its superclass!!

          Christian EhrlicherC Online
          Christian EhrlicherC Online
          Christian Ehrlicher
          Lifetime Qt Champion
          wrote on last edited by
          #12

          @jdent said in How to implement setHeaderData in a subclass of QAbstractTableModel?:

          QAbstractTableModel has no header() method nor its superclass!!

          It's a typo - it's headerData() as you already found out...

          Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
          Visit the Qt Academy at https://academy.qt.io/catalog

          1 Reply Last reply
          0
          • J jdent

            @Christian-Ehrlicher but what should I return when role is Qt::DisplayRole and when role is otherwise?
            Just imagine for now - to simplify the example - that I have no setHeaderData() overload and that I just want "Num 0" for column 0 and "Num 1" for column 1. What should I return for each value of role?

            J Offline
            J Offline
            jdent
            wrote on last edited by jdent
            #13

            @jdent I am needing to repeat myself because my question goes unanswered. please help!
            What is wrong with my headerData()? The problem is I cannot see the header of my QTableView! What am I doing wrong?

            JonBJ 1 Reply Last reply
            0
            • J jdent

              @jdent I am needing to repeat myself because my question goes unanswered. please help!
              What is wrong with my headerData()? The problem is I cannot see the header of my QTableView! What am I doing wrong?

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

              @jdent
              Start by correcting your code, your last 2 return statements are not acceptable for any role.

              	if (orientation == Qt::Horizontal)
              	{
              		if (role == Qt::DisplayRole)
              			return QVariant{ tr("Num %1").arg(section) };
              		return QVariant();
              	}
              	return QVariant();
              

              Then confirm with a breakpoint/debug statement that your headerData() is getting called, and report back.

              I assume you have a QHeaderView in your QTableView to see the headers?

              1 Reply Last reply
              0
              • J Offline
                J Offline
                jdent
                wrote on last edited by
                #15

                ok thanks
                I get Qt::Vertical with role 13, 6, 0, 1
                then I get Qt::Horizontal with roles 13, 6, 0, 1
                I did not have a QHeaderView!! Now I have:

                    ui.tableView->setHorizontalHeader(new QHeaderView{ Qt::Horizontal });
                

                and I see a header now!

                1 Reply Last reply
                0
                • J Offline
                  J Offline
                  jdent
                  wrote on last edited by
                  #16

                  But now I cannot sort by column!!
                  and I have

                      VectorModel* model = new VectorModel{ std::unique_ptr<AbstractCollection>(new PersistentCollection{ storage(), select(columns(&Claim::id, &Claim::amount))})};
                      QSortFilterProxyModel* proxy = new QSortFilterProxyModel{ this };
                      proxy->setSourceModel(model);
                      ui.tableView->setModel(proxy);
                      ui.tableView->setHorizontalHeader(new QHeaderView{ Qt::Horizontal });
                      ui.tableView->setSortingEnabled(true);
                      ui.tableView->setSelectionMode(QAbstractItemView::SingleSelection);
                  
                  1 Reply Last reply
                  0
                  • J Offline
                    J Offline
                    jdent
                    wrote on last edited by
                    #17

                    Anyway I needed to modify sorting: how do I take control of it? For instance if the column has text then alphanumerical sorting must be done and if it is numeric, then the text in the cell must be converted to numeric and the order set numerically! How is this done?

                    JonBJ 1 Reply Last reply
                    0
                    • J Offline
                      J Offline
                      jdent
                      wrote on last edited by
                      #18

                      How does one cell's value compare with another? I want to implement intelligent sorting!

                      1 Reply Last reply
                      0
                      • J jdent

                        Anyway I needed to modify sorting: how do I take control of it? For instance if the column has text then alphanumerical sorting must be done and if it is numeric, then the text in the cell must be converted to numeric and the order set numerically! How is this done?

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

                        @jdent
                        You should use a QSortFilterProxyModel for displaying your model sorted.

                        treeView = new QTreeView;
                        model = new YourModel;
                        proxyModel = new QSortFilterProxyModel(this);
                        proxyModel->setSourceModel(model);
                        treeview->setModel(proxyModel);
                        

                        Then you do sorting (and optionally filtering too) in the proxy model code.

                        1 Reply Last reply
                        0
                        • J Offline
                          J Offline
                          jdent
                          wrote on last edited by
                          #20

                          I have this but when I click the header nothing happens!

                          JonBJ 1 Reply Last reply
                          0
                          • J jdent

                            I have this but when I click the header nothing happens!

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

                            @jdent
                            If you go to the doc page I referenced and read through you will find it describes exactly what you need to do and how it relates to QSortFilterProxyModel or sorting your model.

                            The idea is to read through the documentation, search for examples and ask questions here when you have researched and have a problem.

                            1 Reply Last reply
                            0
                            • J Offline
                              J Offline
                              jdent
                              wrote on last edited by jdent
                              #22

                              Ok, I implemented a subclass of QSortFilterProxyModel in the following :

                              class SortFilterProxyModel : public QSortFilterProxyModel
                              {
                              	Q_OBJECT
                              public:
                              	SortFilterProxyModel(QObject* parent = nullptr) : QSortFilterProxyModel(parent) {}
                              
                              	bool lessThan(const QModelIndex& source_left, const QModelIndex& source_right) const override
                              	{
                              		QVariant left_data = sourceModel()->data(source_left);
                              		QVariant right_data = sourceModel()->data(source_right);
                              
                              		switch (left_data.userType())
                              		{
                              		case QMetaType::QDateTime:
                              			return left_data.toDateTime() < right_data.toDateTime();
                              		case QMetaType::Int:
                              			return left_data.toInt() < right_data.toInt();
                              		case QMetaType::QString:
                              			return left_data.toString() < right_data.toString();
                              		default:
                              			return QSortFilterProxyModel::lessThan(source_left, source_right);
                              		}
                              	}
                              };
                              

                              HOWEVER, I click on the header view and nothing happens!! Why?
                              This is with the subclass and without it!! I would expect resorting to occur in the reverse order when clicking the header but nothing changes!

                              1 Reply Last reply
                              0
                              • J Offline
                                J Offline
                                jdent
                                wrote on last edited by jdent
                                #23

                                Sorting is working fine.... its the header view that does not respond to the mouse! What can be going on with the header?

                                JonBJ 1 Reply Last reply
                                0
                                • J jdent

                                  Sorting is working fine.... its the header view that does not respond to the mouse! What can be going on with the header?

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

                                  @jdent
                                  Did you look at the docs page? Did you follow the Sorting section code?

                                  Although it does no harm, with what is in your lessThan() at present I don't think you needed to override it. QSortFilterProxyModel::lessThan() already handles the types you have coded for. But if you were to change the behaviour that's where you would do it.

                                  1 Reply Last reply
                                  0
                                  • J Offline
                                    J Offline
                                    jdent
                                    wrote on last edited by jdent
                                    #25

                                    Again, sorting is ok - and you are right not needed to subclass it... The problem I am having is that the QHeaderView does not respond to clicking the mouse!! So, I cannot change the column used to sort at runtime!!

                                    Yet I have:

                                        ui.tableView->setHorizontalHeader(new QHeaderView{ Qt::Horizontal });
                                        ui.tableView->setSortingEnabled(true);
                                    

                                    And yes I read the Sorting section code!

                                    JonBJ 1 Reply Last reply
                                    0
                                    • J jdent

                                      Again, sorting is ok - and you are right not needed to subclass it... The problem I am having is that the QHeaderView does not respond to clicking the mouse!! So, I cannot change the column used to sort at runtime!!

                                      Yet I have:

                                          ui.tableView->setHorizontalHeader(new QHeaderView{ Qt::Horizontal });
                                          ui.tableView->setSortingEnabled(true);
                                      

                                      And yes I read the Sorting section code!

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

                                      @jdent
                                      Then the docs say it should be calling sort() in your QSortFilterProxyModel. See if it does, and whether your lessThan() gets called. Is the column's sort indicator responding to your clicks even if sorting is not happening?

                                      1 Reply Last reply
                                      0
                                      • J Offline
                                        J Offline
                                        jdent
                                        wrote on last edited by jdent
                                        #27

                                        At runtime, sort() and lessThan() get called at the beginning (when below code executes) but not when I click the header... also the column's sort indicator is not responding to my clicks and sorting is not happening when I click the header only after the following code executes

                                        When this code executes, sort() is called once and lessThan() is called many times (proportional to number of rows):

                                        ui.tableView->setSortingEnabled(true);
                                        

                                        but not anymore afterwards !

                                        Christian EhrlicherC JonBJ 2 Replies Last reply
                                        0
                                        • J jdent

                                          At runtime, sort() and lessThan() get called at the beginning (when below code executes) but not when I click the header... also the column's sort indicator is not responding to my clicks and sorting is not happening when I click the header only after the following code executes

                                          When this code executes, sort() is called once and lessThan() is called many times (proportional to number of rows):

                                          ui.tableView->setSortingEnabled(true);
                                          

                                          but not anymore afterwards !

                                          Christian EhrlicherC Online
                                          Christian EhrlicherC Online
                                          Christian Ehrlicher
                                          Lifetime Qt Champion
                                          wrote on last edited by
                                          #28

                                          @jdent said in How to implement setHeaderData in a subclass of QAbstractTableModel?:

                                          but not anymore afterwards !

                                          Why should it - once it's sorted why would it need to sort it again?

                                          Please provide a minimal, compilable example of your problem.

                                          Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                                          Visit the Qt Academy at https://academy.qt.io/catalog

                                          1 Reply Last reply
                                          0

                                          • Login

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