7

In my layout, my dynamically generated QTableViews seem to get resized to only show one row. I want to have the container of the table views to have a scrollbar instead of the individual table views, which should show full contents.

savolai ᯓ
  • 666
  • 5
  • 20

3 Answers3

12

Qt doesn't have anything built in for this apparently, you need to calculate and set the size manually.

This is how I'm doing it for vertical sizing (Qt 5.8). You might want to add setMaximumHeight/width.

To develop it further, it should check for presence of a horizontal scrollbar before adding that to the size. This suffices for my usage though.

Edit 2018-03: You may want to call tableView->resizeRowsToContents(); before this function to have the sizes actually correspond to actual heights of contents.

void verticalResizeTableViewToContents(QTableView *tableView)
{
    int count=tableView->verticalHeader()->count();
    int scrollBarHeight=tableView->horizontalScrollBar()->height();
    int horizontalHeaderHeight=tableView->horizontalHeader()->height();
    int rowTotalHeight=0;
    for (int i = 0; i < count; ++i) {
        // 2018-03 edit: only account for row if it is visible
        if (!tableView->verticalHeader()->isSectionHidden(i)) {
            rowTotalHeight+=tableView->verticalHeader()->sectionSize(i);
        }
    }
    tableView->setMinimumHeight(horizontalHeaderHeight+rowTotalHeight+scrollBarHeight);
}
savolai ᯓ
  • 666
  • 5
  • 20
9

@savolai Thank you very much for your code, it works well for me. I just do additional checks:

void verticalResizeTableViewToContents(QTableView *tableView)
{
    int rowTotalHeight=0;

    // Rows height
    int count=tableView->verticalHeader()->count();
    for (int i = 0; i < count; ++i) {
        // 2018-03 edit: only account for row if it is visible
        if (!tableView->verticalHeader()->isSectionHidden(i)) {
            rowTotalHeight+=tableView->verticalHeader()->sectionSize(i);
        }
    }

    // Check for scrollbar visibility
    if (!tableView->horizontalScrollBar()->isHidden())
    {
         rowTotalHeight+=tableView->horizontalScrollBar()->height();  
    }

    // Check for header visibility
    if (!tableView->horizontalHeader()->isHidden())
    {
         rowTotalHeight+=tableView->horizontalHeader()->height();  
    }
    tableView->setMinimumHeight(rowTotalHeight);
}
Ratah
  • 299
  • 3
  • 11
1

The answers above work like a charm. Adding a Python3 version:

from PyQt5.QtWidgets import QTableWidget


def calc_table_height(table: QTableWidget) -> int:
    """Calculate table height."""
    res = 0
    for i in range(table.verticalHeader().count()):
        if not table.verticalHeader().isSectionHidden(i):
            res += table.verticalHeader().sectionSize(i)
    if table.horizontalScrollBar().isHidden():
        res += table.horizontalScrollBar().height()
    if not table.horizontalHeader().isHidden():
        res += table.horizontalHeader().height()
    return res


def vertical_resize_table_to_content(table: QTableWidget) -> None:
    """Resize table height to content."""
    content_height = calc_table_height(table)
    table.setMaximumHeight(content_height)
Elad Weiss
  • 3,662
  • 3
  • 22
  • 50