34

I'm not sure how to ask this, so, feel free to ask for more information.

It seems that tableView->resizeColumnsToContents() will only resize all the columns based on data in current view. Which means that if I have more data below (which is longer in terms of counts of words), those words will be wrapped down (if the wordWrap property is set to true).

The weird thing is, if I scroll down to the bottom and refresh the data, tableView will resize those columns correctly. It seems as if tableView didn't know there are longer text below.

So, my question is, how can I make sure those columns are resized to the max based on all of the data?

My codes

QSqlTableModel *model = new QSqlTableModel;
model->setTable("item");
model->setEditStrategy(QSqlTableModel::OnManualSubmit);
model->select();    
tableResult->setModel(model);    
tableResult->setEditTriggers(QAbstractItemView::NoEditTriggers);    
tableResult->setSelectionBehavior(QAbstractItemView::SelectRows);
tableResult->setSelectionMode(QAbstractItemView::SingleSelection);    
tableResult->resizeColumnsToContents();
tableResult->resizeRowsToContents();

Update 1

I've tried tableResult->scrollToBottom() and it will only resize based on items at the bottom. So, if there are longer words in the middle, those words will get wrapped.

Update 2

If anyone would like to understand what I'm talking about, just download this example. You'll see that clicking the PushButton will generate a data that's not resized correctly.

Update 3

Possibly a bug: https://bugreports.qt.io/browse/QTBUG-9352

MBach
  • 1,647
  • 16
  • 30
Amree
  • 2,890
  • 3
  • 30
  • 51
  • I'm having this problem as well. only the rows that are visible resize. Did you ever find a fix for this? – CompEng88 Aug 14 '12 at 16:34
  • Since Qt 5.2 you can call setResizeContentsPrecision(n) on the QHeaderView, where n is the number of rows it considers when resizing (or -1 for all rows). https://doc.qt.io/qt-5/qheaderview.html#setResizeContentsPrecision – Jonathan Owens Jul 28 '20 at 20:02

3 Answers3

45

I managed to find a workaround for this issue, you just need to hide the table before calling resizeColumnsToContents().

For an example:

tableResult->setVisible(false);
tableResult->resizeColumnsToContents();
tableResult->setVisible(true);
Amree
  • 2,890
  • 3
  • 30
  • 51
  • 1
    Strangely, `table.resizeColumnsToContents()` works without hiding/showing the table with PyQt5 – zdimension Jun 05 '16 at 11:17
  • 2
    In Qt 5.6 also `table.resizeColumnsToContents()` works without hiding/showing the table – Indraraj Feb 18 '17 at 06:16
  • 1
    Here in qt5.6, still need this tableResult->setVisible(false); the hiding/showing to let it work, in my scenario we hide or show columns in different cases, if not doing hide/show, this resize not work. – vivi May 29 '17 at 08:27
6

I think that is because QSqlTableModel loads data on demand and the view calculates the column widths based only on data that is available. If you don't need your columns to be user-resizable, you can try this:

tableResult->horizontalHeader()->setResizeMode(QHeaderView::ResizeToContents);
andref
  • 4,460
  • 32
  • 45
  • It's not working. The column is still not resizing correctly. I put the code at the end of the function. I've also tried QList as the source of the data with QStandardItemModel as the model. – Amree Aug 09 '10 at 08:41
5

I used the same workaround as described by amree, which worked great for the column widths, but tableView->resizeRowsToContents() wasn't working correctly if any offscreen columns had multiline cells that should have caused a row's height to increase.

I looked into the Qt source and it appears that some of the calculations depend on the viewport geometry. This seems to make everything work correctly for both columns and rows:

#include <limits>

tableView->setVisible(false);
QRect vporig = tableView->viewport()->geometry();
QRect vpnew = vporig;
vpnew.setWidth(std::numeric_limits<int>::max());
tableView->viewport()->setGeometry(vpnew);
tableView->resizeColumnsToContents();
tableView->resizeRowsToContents();
tableView->viewport()->setGeometry(vporig);
tableView.setVisible(true);
dougg3
  • 1,249
  • 11
  • 9
  • 2
    amree's answer helped me, but I ran into a problem with auto-sizing row heights at the same time and thought it would be helpful to future readers to post my solution to that closely-related problem. A little more than "essentially nothing", I'd say. – dougg3 Apr 11 '15 at 05:27