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. QTableWidget "Shrink to Fit"
Forum Updated to NodeBB v4.3 + New Features

QTableWidget "Shrink to Fit"

Scheduled Pinned Locked Moved General and Desktop
11 Posts 6 Posters 19.1k 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.
  • R Offline
    R Offline
    RSFJ
    wrote on last edited by
    #1

    I have a QTableWidget displayed in a dialog as one widget among several. This table will always have exactly three columns and five rows. It works fine, but I'm not happy with the appearance. The table is laid out in such a way that it consumes more space than is strictly necessary to show only the 5 rows and 3 columns -- the widget's frame is larger than the actual table, so there's white space along the right edge and bottom to make up the difference. No doubt there is some way to construct the widget so that it must take a specific number of pixels in each direction, but I'm hoping there's some switch I don't know about to tell the table "make yourself as large as necessary, but no larger." Is there?

    Second question: how can one get rid of the frame that appear around most widgets? For instance, on Windows, the QTableWidget appears in a "shadow box" (as though you are looking at it through a rectangular hole in a piece of cardboard). Likewise, the row and column headings appear in such a way that they look like buttons. How can they appear simply as text -- more like a QLabel?

    I'm new to Qt as of about 10 days ago, and liking it a lot.

    Randall

    1 Reply Last reply
    0
    • Q Offline
      Q Offline
      qxoz
      wrote on last edited by
      #2

      Hi! And welcome to DevNet.
      For your first question you can create function which resize the qtablewidget:
      @void MainWindow::adjustTableSize()
      {
      ui->tableWidget->resizeColumnsToContent();
      ui->tableWidget->resizeRowsToContent();

      QRect rect = ui->tableWidget->geometry();
      int tableWidth = 2 + ui->tableWidget->verticalHeader()->width();
      for(int i = 0; i < ui->tableWidget->columnCount(); i++){
          tableWidth += ui->tableWidget->columnWidth(i);
      }
      rect.setWidth(tableWidth);
      int tableHeight = 2 + ui->tableWidget->horizontalHeader()->height();
      for(int i = 0; i < ui->tableWidget->rowCount(); i++){
          tableHeight += ui->tableWidget->rowHeight(i);
      }
      rect.setHeight(tableHeight);
      
      ui->tableWidget->setGeometry(rect);
      

      }@
      and about your second question. You can use qss for that. Start point for you:
      @QHeaderView::section {
      color: black;
      border: 1px solid #6c6c6c;
      }@
      set this qss with:
      @ui->tableWidget->setStyleSheet ( const QString & styleSheet )@

      1 Reply Last reply
      0
      • C Offline
        C Offline
        ChrisW67
        wrote on last edited by
        #3

        QTableWidget is-a QFrame (ultimately) so you can call setFrameStyle() and other QFrame functions to adjust the frame.

        1 Reply Last reply
        0
        • R Offline
          R Offline
          RSFJ
          wrote on last edited by
          #4

          qxoz, when I apply the setGeometry() method, it has no effect. Even if I use explicit values, like
          @tableWidget->setGeometry(0,0,100,100);@

          there is still no effect. I've tried variations on that theme, involving making changes to the QRect obtained from tableWidget->geometry(). Again, no effect on the widget's appearance whatsoever.

          Does the code in your example work for you? It might not since it won't compile -- there is no resizeColumnsToContent() method; it's called resizeColumnsToContents().

          Here's a stripped-down version of the code involved. This is the constructor for a class that extends QDialog:

          @
          TestDialog::TestDialog(QWidget *parent) : QDialog(parent)
          {
          // Set up the spreadsheet for input.
          testSheet = new QTableWidget();
          testSheet->setRowCount(5);
          testSheet->setColumnCount(3);

          testSheet->setColumnWidth(0,70);
          testSheet->setColumnWidth(1,70);
          testSheet->setColumnWidth(2,70);

          for (int i = 0; i < 5; i++)
          testSheet->setRowHeight(i,25);

          testSheet->setAlternatingRowColors(true);
          testSheet->setCornerButtonEnabled(false);

          // Thank you, ChrisW67
          testSheet->setFrameStyle(QFrame::NoFrame);

          QTableWidgetItem *item = new QTableWidgetItem(QString("1.987493"));
          testSheet->setItem(0,0,item);

          // This has no effect. The appearance is the same whether I
          // comment this out or not.
          QRect tableRect = testSheet->geometry();
          tableRect.setWidth(300);
          tableRect.setHeight(300);
          testSheet->setGeometry(tableRect);

          // I thought that adding stretch in the layout might help...it does not.
          sheetLayout = new QHBoxLayout();
          sheetLayout->addStretch();
          sheetLayout->addWidget(testSheet);
          sheetLayout->addStretch();

          // Blah, blah...add some buttons...code omitted.

          // Bring everything together.
          topLayout = new QVBoxLayout();
          topLayout->addLayout(sheetLayout);
          topLayout->addStretch();
          topLayout->addLayout(buttonLayout);

          // All done.
          this->setLayout(topLayout);

          setWindowTitle(tr("QTableWidget Problem"));
          }@

          1 Reply Last reply
          0
          • R Offline
            R Offline
            RSFJ
            wrote on last edited by
            #5

            I have a solution. qxoz is basically correct, after making two changes.

            Here is the TestDialog constructor again, but this time it works as desired.
            @
            TestDialog::TestDialog(QWidget *parent) : QDialog(parent)
            {
            // Set up the spreadsheet for input.
            testSheet = new QTableWidget();
            testSheet->setRowCount(5);
            testSheet->setColumnCount(3);

              testSheet->setColumnWidth(0,70);
              testSheet->setColumnWidth(1,70);
              testSheet->setColumnWidth(2,70);
             
              for (int i = 0; i < 5; i++)
                testSheet->setRowHeight(i,25);
             
              testSheet->setAlternatingRowColors(true);
              testSheet->setCornerButtonEnabled(false);
             
              // Thank you, ChrisW67
              testSheet->setFrameStyle(QFrame::NoFrame);
             
              QTableWidgetItem *item = new QTableWidgetItem(QString("1.987493"));
              testSheet->setItem(0,0,item);
            
              // I added this to make the widget recalculate its dimensions
              // before trying to adjust them.
              sheet->hide();
              sheet->show();
             
              // This is from qxoz, with some small changes. I don't seem to need
              // the '+2' in his version. It makes the widget too large.
              int tableWidth = sheet->verticalHeader()->width();
              for (int i = 0; i < sheet->columnCount(); i++)
                tableWidth += sheet->columnWidth(i);
            
              int tableHeight = sheet->horizontalHeader()->height();
              for (int i = 0; i < sheet->rowCount(); i++)
                tableHeight += sheet->rowHeight(i);
            
              // I still don't see why qxoz's suggestion to use setGeometry() does
              // not work, but this does work.
              sheet->setMaximumHeight(tableHeight);
              sheet->setMinimumHeight(tableHeight);
              sheet->setMaximumWidth(tableWidth);
              sheet->setMinimumWidth(tableWidth);
             
              // I thought that adding stretch in the layout might help...it does not.
              sheetLayout = new QHBoxLayout();
              sheetLayout->addStretch();
              sheetLayout->addWidget(testSheet);
              sheetLayout->addStretch();
             
              // Blah, blah...add some buttons...code omitted.
             
              // Bring everything together.
              topLayout = new QVBoxLayout();
              topLayout->addLayout(sheetLayout);
              topLayout->addStretch();
              topLayout->addLayout(buttonLayout);
             
              // All done.
              this->setLayout(topLayout);
             
              setWindowTitle(tr("QTableWidget Problem"));
            }
            

            @

            The above gets the output I want, even if the code to do it is sort of a hack. There really ought to be a way of telling the widget to do this itself.

            Concerning my other question about changing the appearance of the table's headers, it turns out that you have to sub-class QHeaderView and reimplement the paintSection() method. You can't do it by changing the delegate for the header because, even though the framework to do that seems to be there in the relevant classes, the documentation of QHeaderView says that "calling a header's setItemDelegate() function will have no effect."

            Thanks for the help.

            1 Reply Last reply
            0
            • Q Offline
              Q Offline
              qxoz
              wrote on last edited by
              #6

              [quote author="RSFJ" date="1367519882"]
              @// I still don't see why qxoz's suggestion to use setGeometry() does
              // not work, but this does work.
              sheet->setMaximumHeight(tableHeight);
              sheet->setMinimumHeight(tableHeight);
              sheet->setMaximumWidth(tableWidth);
              sheet->setMinimumWidth(tableWidth);@
              [/quote]
              Thats because layout change the geometry when you add tableWidget to it. You can setGeometry after settings layouts but every changes of form size will broke your geometry settings. I tryed play with sizepolicy of widget but there are no useful effect. So i think settings minimum and maximums is only solution for this case.

              1 Reply Last reply
              0
              • Q Offline
                Q Offline
                qxoz
                wrote on last edited by
                #7

                About your second question. Probably i don't understand you correctly can you explain your goal and why qss not enough for you?

                1 Reply Last reply
                0
                • R Offline
                  R Offline
                  RSFJ
                  wrote on last edited by
                  #8

                  Yes, I see now. Your suggestion is much cleaner than sub-classing QHeaderView (which isn't that hard). If you say
                  @QString style = "::section{"
                  "padding-right: 3px;"
                  "border: 0px; }";

                  sheet->horizontalHeader()->setStyleSheet(style);
                  @

                  then you get headers without any sort of border. I'm new to Qt, but I'm getting the hang of it.

                  Thanks

                  1 Reply Last reply
                  0
                  • K Offline
                    K Offline
                    Komgcn
                    wrote on last edited by
                    #9

                    thanks for the post, it really helps. 5 years now and Qt still remain unaware of this issue, QTableWidget is a really badly designed class indeed.

                    VRoninV 1 Reply Last reply
                    0
                    • K Komgcn

                      thanks for the post, it really helps. 5 years now and Qt still remain unaware of this issue, QTableWidget is a really badly designed class indeed.

                      VRoninV Offline
                      VRoninV Offline
                      VRonin
                      wrote on last edited by
                      #10

                      Since Qt 5.2 (Dec 2013) you can use tableWidget->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents); to achieve this

                      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                      ~Napoleon Bonaparte

                      On a crusade to banish setIndexWidget() from the holy land of Qt

                      1 Reply Last reply
                      4
                      • J Offline
                        J Offline
                        james b-s
                        wrote on last edited by
                        #11

                        Thanks for the solution. I'm going to give it a try. But shouldn't the solutions take into account whether or not a column is hidden?

                        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