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 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