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. Make QHeaderView/QTableView-Header interactive but keep it stretched to the full available width.
Forum Updated to NodeBB v4.3 + New Features

Make QHeaderView/QTableView-Header interactive but keep it stretched to the full available width.

Scheduled Pinned Locked Moved Solved General and Desktop
20 Posts 3 Posters 4.3k 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 Offline
    Christian EhrlicherC Offline
    Christian Ehrlicher
    Lifetime Qt Champion
    wrote on last edited by Christian Ehrlicher
    #8

    And you still use rowCount() when trying to resize the horizontal header?

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

    V 1 Reply Last reply
    0
    • Christian EhrlicherC Christian Ehrlicher

      And you still use rowCount() when trying to resize the horizontal header?

      V Offline
      V Offline
      VogelPapaFinn
      wrote on last edited by VogelPapaFinn
      #9

      @Christian-Ehrlicher nope I dont. Why are you all so focused on the row Count?! Its a simple mistake I ONLY did in the post! The problem is NOT this for loop it is the function that is NOT working. If I remove the loop and hardcode it, it still DONT work.
      Again: the function resizeSection() has no effect no matter how I use it.

      1 Reply Last reply
      0
      • Christian EhrlicherC Offline
        Christian EhrlicherC Offline
        Christian Ehrlicher
        Lifetime Qt Champion
        wrote on last edited by
        #10

        You don't post useful code but blame us? Nice...
        Post what you're doing and where. resizeColumn() works as expected. resizeColumn() inside resizeEvent() may work but it must not.

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

        V 1 Reply Last reply
        0
        • Christian EhrlicherC Christian Ehrlicher

          You don't post useful code but blame us? Nice...
          Post what you're doing and where. resizeColumn() works as expected. resizeColumn() inside resizeEvent() may work but it must not.

          V Offline
          V Offline
          VogelPapaFinn
          wrote on last edited by VogelPapaFinn
          #11

          @Christian-Ehrlicher Im not blaming anyone Im just confused why you two are still asking about the row issue.
          What code do you want exactly? Every single thing I tried? Or my complete class?

          Im going to send you a complete rewritten problem description maybe we can then solve it together.

                  // TESTING
              
                  QSqlDatabase db = QSqlDatabase::addDatabase("QPSQL");
                  db.setHostName("127.0.0.1");
                  db.setDatabaseName("bugtracker");
                  db.setUserName("postgres");
                  db.setPassword("CENSORED");
                  db.open();
                  QSqlTableModel* model = new QSqlTableModel;
                  model->setTable("account");
                  model->setEditStrategy(QSqlTableModel::OnFieldChange);
                  model->select();
              
                  QFont font("Segoe UI", 8, -1, false);
                  font.setBold(true);
              
                  QHeaderView* header = new QHeaderView(Qt::Horizontal);
                  header->setSectionResizeMode(QHeaderView::Interactive);
                  for (int i = 0; i < model->columnCount(); i++) header->resizeSection(i, QHeaderView::Stretch);
                  header->setStretchLastSection(true);
                  header->setDefaultAlignment(Qt::AlignVCenter);
                  header->setStyleSheet("QHeaderView::section{background-color: #D9D9D9; border: none; border-top: 1px solid #999997; border-bottom: 1px solid #999997; border-right: 1px dashed #999997; padding-left: 3px;}");
                  header->setFont(font);
              
                  QTableView* view = findChild<QTableView*>("table_view");
                  view->setModel(model);
                  view->verticalHeader()->hide();
                  view->setHorizontalHeader(header);
                  view->horizontalHeader()->hideSection(0);
                  view->horizontalHeader()->hideSection(4);
                  view->horizontalHeader()->hideSection(5);
                  view->horizontalHeader()->hideSection(6);
                  view->horizontalHeader()->hideSection(9);
                  view->show();
              
                  // TESTING
          

          This is what the code for the QTableView + Header looks like rn. Its dirty I know. Im still testing it before I clean it up.
          549f43f8-4df4-4ebe-a28e-ac65368c9496-image.png
          This is how the Header/Table looks right now. But what I want is this:
          2cc69f0b-77bb-4b63-aca9-e482ee4cf530-image.png Unfortunately you cant see the cursor here. I want that the columns are still resizable with the mouse. The same thing you can do for example in Excel. But there is no QHeaderView::ResizeMode that supports stretch and interactive at once.

          Did this help?

          JonBJ 1 Reply Last reply
          0
          • V VogelPapaFinn

            @Christian-Ehrlicher Im not blaming anyone Im just confused why you two are still asking about the row issue.
            What code do you want exactly? Every single thing I tried? Or my complete class?

            Im going to send you a complete rewritten problem description maybe we can then solve it together.

                    // TESTING
                
                    QSqlDatabase db = QSqlDatabase::addDatabase("QPSQL");
                    db.setHostName("127.0.0.1");
                    db.setDatabaseName("bugtracker");
                    db.setUserName("postgres");
                    db.setPassword("CENSORED");
                    db.open();
                    QSqlTableModel* model = new QSqlTableModel;
                    model->setTable("account");
                    model->setEditStrategy(QSqlTableModel::OnFieldChange);
                    model->select();
                
                    QFont font("Segoe UI", 8, -1, false);
                    font.setBold(true);
                
                    QHeaderView* header = new QHeaderView(Qt::Horizontal);
                    header->setSectionResizeMode(QHeaderView::Interactive);
                    for (int i = 0; i < model->columnCount(); i++) header->resizeSection(i, QHeaderView::Stretch);
                    header->setStretchLastSection(true);
                    header->setDefaultAlignment(Qt::AlignVCenter);
                    header->setStyleSheet("QHeaderView::section{background-color: #D9D9D9; border: none; border-top: 1px solid #999997; border-bottom: 1px solid #999997; border-right: 1px dashed #999997; padding-left: 3px;}");
                    header->setFont(font);
                
                    QTableView* view = findChild<QTableView*>("table_view");
                    view->setModel(model);
                    view->verticalHeader()->hide();
                    view->setHorizontalHeader(header);
                    view->horizontalHeader()->hideSection(0);
                    view->horizontalHeader()->hideSection(4);
                    view->horizontalHeader()->hideSection(5);
                    view->horizontalHeader()->hideSection(6);
                    view->horizontalHeader()->hideSection(9);
                    view->show();
                
                    // TESTING
            

            This is what the code for the QTableView + Header looks like rn. Its dirty I know. Im still testing it before I clean it up.
            549f43f8-4df4-4ebe-a28e-ac65368c9496-image.png
            This is how the Header/Table looks right now. But what I want is this:
            2cc69f0b-77bb-4b63-aca9-e482ee4cf530-image.png Unfortunately you cant see the cursor here. I want that the columns are still resizable with the mouse. The same thing you can do for example in Excel. But there is no QHeaderView::ResizeMode that supports stretch and interactive at once.

            Did this help?

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

            @VogelPapaFinn said in Make QHeaderView interactive but keep it stretched to the full available width.:

            for (int i = 0; i < model->columnCount(); i++) header->resizeSection(i, QHeaderView::Stretch);

            I asked you before about the header->resizeSection(i, QHeaderView::Stretch); you use:

            I don't see any overload of QHeaderView::resizeSection() which should accept a QHeaderView::ResizeMode like QHeaderView::Stretch.

            Could you explain this to me? Thanks.

            V 1 Reply Last reply
            0
            • JonBJ JonB

              @VogelPapaFinn said in Make QHeaderView interactive but keep it stretched to the full available width.:

              for (int i = 0; i < model->columnCount(); i++) header->resizeSection(i, QHeaderView::Stretch);

              I asked you before about the header->resizeSection(i, QHeaderView::Stretch); you use:

              I don't see any overload of QHeaderView::resizeSection() which should accept a QHeaderView::ResizeMode like QHeaderView::Stretch.

              Could you explain this to me? Thanks.

              V Offline
              V Offline
              VogelPapaFinn
              wrote on last edited by VogelPapaFinn
              #13

              @JonB I cant find the source anymore but it was a qt-forum or stackoverflow post where somebody had the same issue. Somebody used it there so I tried it and neither my compiler nor my intellisense returned an error so I thought there is a function like this. Seems like there isnt.
              But like I said I tried resizeSection(i, 500) or resizeSection(0, 500) too without any changes.

              JonBJ 1 Reply Last reply
              0
              • V VogelPapaFinn

                @JonB I cant find the source anymore but it was a qt-forum or stackoverflow post where somebody had the same issue. Somebody used it there so I tried it and neither my compiler nor my intellisense returned an error so I thought there is a function like this. Seems like there isnt.
                But like I said I tried resizeSection(i, 500) or resizeSection(0, 500) too without any changes.

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

                @VogelPapaFinn
                Since QHeaderView::Stretch == 1 I think, using that as per your code would actually make them all minimum width which is exactly what you don't want, right? So it's important :)

                My next thought is you are setting those widths on a QHeaderView while it isn't attached to any model/has any columns. I simply don't know whether that is an issue.

                Try qDebug() << header->count() immediately after your loop: what does it return?

                Try moving the lines setting the section widths to just before the view->show();?

                Finally, since we are trying to understand what is going on comment out the hideSection()s, maybe they affect behaviour.

                Depending on answers, might have to move to showEvent() but we'll see.

                V 1 Reply Last reply
                1
                • JonBJ JonB

                  @VogelPapaFinn
                  Since QHeaderView::Stretch == 1 I think, using that as per your code would actually make them all minimum width which is exactly what you don't want, right? So it's important :)

                  My next thought is you are setting those widths on a QHeaderView while it isn't attached to any model/has any columns. I simply don't know whether that is an issue.

                  Try qDebug() << header->count() immediately after your loop: what does it return?

                  Try moving the lines setting the section widths to just before the view->show();?

                  Finally, since we are trying to understand what is going on comment out the hideSection()s, maybe they affect behaviour.

                  Depending on answers, might have to move to showEvent() but we'll see.

                  V Offline
                  V Offline
                  VogelPapaFinn
                  wrote on last edited by VogelPapaFinn
                  #15

                  @JonB Okay it seems like the unattached model was the problem. It now starts to work, yey. Now I just need to resize the columns correctly. I tried to calculate the size by doing this:

                      header->setSectionResizeMode(QHeaderView::Interactive);
                      for (int i = 0; i < model->columnCount(); i++) header->resizeSection(i, view->width() / model->columnCount());
                      header->setStretchLastSection(true);
                  

                  Result:
                  985693ee-4a38-45e6-b597-98f1951ff2b7-image.png
                  The problem here is that view->width() returns only 98 [pixels]. Removing header->setStretchLastSection(true); only decreases the width of the last section. So it does not affect the other sections. Its size policy is set to stretch and in the editor and when the app starts it fills the whole space (way more than 98 pixels). Any idea what is causing this?

                  1 Reply Last reply
                  0
                  • Christian EhrlicherC Offline
                    Christian EhrlicherC Offline
                    Christian Ehrlicher
                    Lifetime Qt Champion
                    wrote on last edited by Christian Ehrlicher
                    #16

                    Since the size of a widget is first known when the widget is shwon you have to do your resizing after the show event.

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

                    V 1 Reply Last reply
                    3
                    • Christian EhrlicherC Christian Ehrlicher

                      Since the size of a widget is first known when the widget is shwon you have to do your resizing after the show event.

                      V Offline
                      V Offline
                      VogelPapaFinn
                      wrote on last edited by
                      #17
                      This post is deleted!
                      1 Reply Last reply
                      0
                      • V Offline
                        V Offline
                        VogelPapaFinn
                        wrote on last edited by
                        #18

                        @Christian-Ehrlicher It now finaly works. Yeehaaw. I needed to reimplement the resizeFunction or otherwise they get resized before the window gets maximized > they are too small.
                        Im going to clean up the code rn and provide a complete description of the solution for people in the future with the same issue. Thanks to you two <3

                        1 Reply Last reply
                        0
                        • V Offline
                          V Offline
                          VogelPapaFinn
                          wrote on last edited by VogelPapaFinn
                          #19

                          Okay guys so this is my final code. If you here because of the same problem then this is for you.

                          • First we need to create all necessary objects:
                            • QSqlDatabase [only needed if you want to use it with a db],
                            • QSqlTableModel [you can use other models ofc],
                            • QTableView

                          Here is my code. This code snippet is in the constructor of my class UserSite. You can ignore my specific settings like the Font or the removeColumn calls.
                          ATTENTION: db_ = fbt::SqlConnection::getInstance();
                          This line of code uses a self-written class which handles the sql connections. You can replace this line of code with the usual db connection initialization.

                              // Establish SQL Connection
                              db_ = fbt::SqlConnection::getInstance();
                          
                              // Create Table Model
                              sql_model_ = new QSqlTableModel;
                              sql_model_->setTable("account");
                              sql_model_->setEditStrategy(QSqlTableModel::OnFieldChange);     // Edits the database when a cell is edited by the user
                              sql_model_->select();
                              sql_model_->removeColumn(0);    // Removes account_id
                              sql_model_->removeColumn(3);    // Removes password
                              sql_model_->removeColumn(3);    // Removes location
                              sql_model_->removeColumn(3);    // Removes birth
                              sql_model_->removeColumn(5);    // Removes created
                          
                              // Temporary saved font to use in the header
                              QFont font("Segoe UI", 8, -1, false);
                              font.setBold(true);
                          
                              // Create Table View
                              table_view_ = findChild<QTableView*>("table_view");
                              table_view_->setModel(sql_model_);
                              table_view_->verticalHeader()->hide();
                              table_view_->show();
                          
                              // Style header of the Table View
                              tv_header_ = table_view_->horizontalHeader();
                              tv_header_->setSectionResizeMode(QHeaderView::Interactive);     // Let the user resize the columns
                              tv_header_->setDefaultAlignment(Qt::AlignVCenter);              // Aligns the header text to the left
                              tv_header_->setStyleSheet("QHeaderView::section{background-color: #D9D9D9; border: none; border-top: 1px solid #999997; border-bottom: 1px solid #999997; border-right: 1px dashed #999997; padding-left: 3px;}");
                              tv_header_->setFont(font);
                          
                          • Now to the second and important part: the resizeEvent(QResizeEvent* event) function. We need to implement this so the columns get resized everytime the window itself gets resized. This is important because of two reasons:
                            1 - When we initialize the QTableView the QHeaderView etc. the window isnt open yet (at least this is the case in my code). This is bad because the QTableView doesnt know its size and we cant resize the columns properly.
                            2 - When the user resizes the whole window a scrollbar will appear at the bottom because every column keeps their size. I dont want this so its a win-win. If you dont want this then you need to find a way around that. Good luck then!

                          Enough text. Here is the code of the resizeEvent() function:

                          void UserSite::resizeEvent(QResizeEvent* event)
                          {
                              // Resize columns manually - this is to keep the columns stretched but resizable for the user
                              for (int i = 0; i < sql_model_->columnCount(); i++) tv_header_->resizeSection(i, table_view_->width() / sql_model_->columnCount());     // This resizes every column to the same size
                          
                              // Sets the ResizeMode of the last column to stretched so that the user can resize it. Otherwise the user can move it out of the max width and the scrollbar appears.
                              table_view_->horizontalHeader()->setSectionResizeMode(4, QHeaderView::Stretch);                                                         
                          
                              // Handle everything else
                              QWidget::resizeEvent(event);
                          }
                          

                          Now you should have a working QTableView header that is resizable by the user but stretched at the same time. If this didnt work or you have a problem feel free to reopen this thread or send me a private message. You can do this here in the forum or on Discord: VogelPapa | Finn#0442
                          Have a nice day <3

                          // Edit: Just realized, thanks to @Christian-Ehrlicher that you dont need a "new" QHeaderView because the QTableView already has one. I changed the code slightly so but it works the same way.

                          Christian EhrlicherC 1 Reply Last reply
                          0
                          • V VogelPapaFinn

                            Okay guys so this is my final code. If you here because of the same problem then this is for you.

                            • First we need to create all necessary objects:
                              • QSqlDatabase [only needed if you want to use it with a db],
                              • QSqlTableModel [you can use other models ofc],
                              • QTableView

                            Here is my code. This code snippet is in the constructor of my class UserSite. You can ignore my specific settings like the Font or the removeColumn calls.
                            ATTENTION: db_ = fbt::SqlConnection::getInstance();
                            This line of code uses a self-written class which handles the sql connections. You can replace this line of code with the usual db connection initialization.

                                // Establish SQL Connection
                                db_ = fbt::SqlConnection::getInstance();
                            
                                // Create Table Model
                                sql_model_ = new QSqlTableModel;
                                sql_model_->setTable("account");
                                sql_model_->setEditStrategy(QSqlTableModel::OnFieldChange);     // Edits the database when a cell is edited by the user
                                sql_model_->select();
                                sql_model_->removeColumn(0);    // Removes account_id
                                sql_model_->removeColumn(3);    // Removes password
                                sql_model_->removeColumn(3);    // Removes location
                                sql_model_->removeColumn(3);    // Removes birth
                                sql_model_->removeColumn(5);    // Removes created
                            
                                // Temporary saved font to use in the header
                                QFont font("Segoe UI", 8, -1, false);
                                font.setBold(true);
                            
                                // Create Table View
                                table_view_ = findChild<QTableView*>("table_view");
                                table_view_->setModel(sql_model_);
                                table_view_->verticalHeader()->hide();
                                table_view_->show();
                            
                                // Style header of the Table View
                                tv_header_ = table_view_->horizontalHeader();
                                tv_header_->setSectionResizeMode(QHeaderView::Interactive);     // Let the user resize the columns
                                tv_header_->setDefaultAlignment(Qt::AlignVCenter);              // Aligns the header text to the left
                                tv_header_->setStyleSheet("QHeaderView::section{background-color: #D9D9D9; border: none; border-top: 1px solid #999997; border-bottom: 1px solid #999997; border-right: 1px dashed #999997; padding-left: 3px;}");
                                tv_header_->setFont(font);
                            
                            • Now to the second and important part: the resizeEvent(QResizeEvent* event) function. We need to implement this so the columns get resized everytime the window itself gets resized. This is important because of two reasons:
                              1 - When we initialize the QTableView the QHeaderView etc. the window isnt open yet (at least this is the case in my code). This is bad because the QTableView doesnt know its size and we cant resize the columns properly.
                              2 - When the user resizes the whole window a scrollbar will appear at the bottom because every column keeps their size. I dont want this so its a win-win. If you dont want this then you need to find a way around that. Good luck then!

                            Enough text. Here is the code of the resizeEvent() function:

                            void UserSite::resizeEvent(QResizeEvent* event)
                            {
                                // Resize columns manually - this is to keep the columns stretched but resizable for the user
                                for (int i = 0; i < sql_model_->columnCount(); i++) tv_header_->resizeSection(i, table_view_->width() / sql_model_->columnCount());     // This resizes every column to the same size
                            
                                // Sets the ResizeMode of the last column to stretched so that the user can resize it. Otherwise the user can move it out of the max width and the scrollbar appears.
                                table_view_->horizontalHeader()->setSectionResizeMode(4, QHeaderView::Stretch);                                                         
                            
                                // Handle everything else
                                QWidget::resizeEvent(event);
                            }
                            

                            Now you should have a working QTableView header that is resizable by the user but stretched at the same time. If this didnt work or you have a problem feel free to reopen this thread or send me a private message. You can do this here in the forum or on Discord: VogelPapa | Finn#0442
                            Have a nice day <3

                            // Edit: Just realized, thanks to @Christian-Ehrlicher that you dont need a "new" QHeaderView because the QTableView already has one. I changed the code slightly so but it works the same way.

                            Christian EhrlicherC Offline
                            Christian EhrlicherC Offline
                            Christian Ehrlicher
                            Lifetime Qt Champion
                            wrote on last edited by
                            #20

                            @VogelPapaFinn said in Make QHeaderView interactive but keep it stretched to the full available width.:

                            tv_header_ = new QHeaderView(Qt::Horizontal);
                            tv_header_->setModel(sql_model_);
                            

                            This is not needed, every view has a header.

                            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
                            1

                            • Login

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