Unsolved How do you handle Zooming in QTableView/QTreeView?
-
In a subclass of
QTableView
, I've this:void ZoomTable::wheelEvent(QWheelEvent *event) { if(event->modifiers().testFlag(Qt::ControlModifier)){ if(event->angleDelta().y() > 0){ if(fontSize < 30){ setFont(QFont(fontInfo().family(), ++fontSize)); } } else if(fontSize > 12){ setFont(QFont(fontInfo().family(), --fontSize)); } } else QTableView::wheelEvent(event); }
When I increase the
fontSize
, this is how it looks:
on the right the tablecells
don't resize automatically and if I call these functions in thewheelEvent
:resizeColumnsToContents(); resizeRowsToContents();
application freezes.
EDIT
I'm having same trouble with
QTreeView
so instead of creating a new topic I've added it here. In a subclass ofQTreeView
, I've used the same technique to zoom in and out inwheelEvent
and this is how it's rendered:
It appears that the root nodes are taking the whole space BUT when I increase the font size those text are elided. In a HD screen, the default font size is ok and readable BUT when I run Qt app in 4k screen all those texts are too small to read. -
@Emon-Haque
Purely a guess. Get rid of the two lines which you say cause freeze in thewheelEvent()
slot. TryupdateGeometry()
? Or evenscheduleDelayedItemsLayout()
? Something to make the whole table view/viewport redraw? -
@JonB, tried both of those after
setFont(...)
call, doesn't work. -
Hi,
Did you change the section resize mode ?
-
@SGaist, no I didn't. It's not only the column header, none of the row header as well as table cells resize when I increase the font size:
Here is how I've defined the Custom Header:CustomHeader::CustomHeader(QTableView * parent) : QHeaderView(Qt::Orientation::Horizontal, parent) { setDefaultAlignment(Qt::AlignTop | Qt::AlignHCenter); connect(this, &CustomHeader::sectionResized, this, &CustomHeader::updateGeometries); connect(parent->horizontalScrollBar(), &QScrollBar::valueChanged, this, &CustomHeader::updatePosition); } CustomHeader::~CustomHeader() {} void CustomHeader::showEvent(QShowEvent *e) { qDeleteAll(lineEdits); for (int i = 0; i < count(); i++) { auto edit = new QLineEdit(this); lineEdits.append(edit); connect(edit, &QLineEdit::textChanged, this, &CustomHeader::textChanged); edit->setGeometry(sectionViewportPosition(i), height() / 2, sectionSize(i), height() / 2); edit->show(); } QHeaderView::showEvent(e); } QSize CustomHeader::sizeHint() const { int width = 0; int height = 0; for (int i = 0; i < count(); i++){ width += sectionSize(i); auto size = sectionSizeFromContents(i); width += size.width(); height = size.height(); } return QSize(width, height * 2); } QList<QString> CustomHeader::getQueries() { return queries; } void CustomHeader::updateGeometries() { if(!lineEdits.size()) return; for (int i = 0; i < count(); i++) { auto edit = lineEdits.at(i); edit->setGeometry(sectionViewportPosition(i), height() / 2, sectionSize(i), height() / 2); } } void CustomHeader::updatePosition() { int height = QHeaderView::sizeHint().height(); for (int i = 0; i < count(); i++){ auto edit = lineEdits.at(i); edit->move(sectionPosition(i) - offset(), height); } } void CustomHeader::textChanged() { queries.clear(); for (int i = 0; i < count(); i++){ auto edit = lineEdits.at(i); queries.append(edit->text()); } emit queryChanged(); }
-
@SGaist. In the
CustomHeader
's constructor if I addsetSectionResizeMode(ResizeMode::ResizeToContents)
, it resizes the columns and there's only 10 columns so it works fine and it doesn't affect the row height. So for rows, if do like this in the subclass of QTableView's constructor:auto rowHeader = new QHeaderView(Qt::Orientation::Vertical, this); rowHeader->setSectionResizeMode(QHeaderView::ResizeMode::ResizeToContents); setVerticalHeader(rowHeader);
application freezes. There's only less than 130k rows in that table.
-
Are you using your CustomHeader as well for the row headers ? If so then you have an issue, you will be creating 130k QLineEdits which is a wrong thing to do.
-
@SGaist, No, that
CustomHeader
has been used only for column header. For rows I've tried a default newQHeaderView
like this:auto rowHeader = new QHeaderView(Qt::Orientation::Vertical, this); rowHeader->setSectionResizeMode(QHeaderView::ResizeMode::ResizeToContents); setVerticalHeader(rowHeader);
and later instead of the 3 lines above I've tried this:
verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
either way, the application freezes.
-
What happens if you do that after populating the model and setting the view on it ?
-
@SGaist, How do you set view on model? The last thing I've to get the table is:
void ZoomTable::resetModel(const QString &query) { db.open(); model->setQuery(query); while (model->canFetchMore()) model->fetchMore(); db.close(); filterModel = new ProxyModel(this); filterModel->setSourceModel(model); setModel(filterModel); //verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); }
So the last line is
setModel
, Do I have to do anything, like setView, after that? I've tried by removing the commented line from the constructor and adding it aftersetModel
, it still freezes. -
Do you have the same issue if you use a dummy QStandardItemModel with a couple of entries ?
-
@SGaist, no. for small dataset it works as expected with this
verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
in constructor or these
resizeColumnsToContents(); resizeRowsToContents();
in
wheelEvent
. But for medium/large dataset none of these works. Application just freezes. Someone in other forum mentioned that from ~20k rows this becomes an issue in Qt .I mentioned about font size issue in 4k screen BUT at that time I was working on HD screen and I was wrong. Right now I'm on a 4k screen and with Qt 6.2 and 200% zoom in Windows 10, it's ok. May be that was an issue of earlier versions of Qt which I noticed when using app like OBS Studio, DB Browser for SQLite, etc.
EDIT
This zooming feature is necessary for apps that use mixed Arabic and English languages. It's too hard to read Arabic with normal font size.
-
Ok, what if you do it like word processors by selecting the size from a drop down menu ?
That said, if you have big models, I would also consider using a sliding window rather than handling so many entries that are not visible anyway.
-
@SGaist, hmm.