I have a custom layout BoardLayout, which inherits QLayout. It is written in analogy to BorderLayout example (https://doc.qt.io/qt-5/qtwidgets-layouts-borderlayout-example.html), with a following setGeometry()
method:
void BoardLayout::setGeometry(const QRect &rect)
{
QLayout::setGeometry(rect);
int d = qMin(rect.width() - 175, rect.height() - 100);
for (auto e : list) {
if (e->position == Board) {
e->item->setGeometry({50, 50, d, d});
}
}
}
It also has an altered BoardLayout::calculateSize
method, but since the widget it is applied on is a centralWidget
of a window, it probably does not matter; this method is also not called in the problematic part of runtime).
I set this layout for a window, and added to it (in the position of Board
) an instance of a BoardView
class, (BoardView
inherits QGraphicsView
):
auto lt = new BoardLayout();
setLayout(lt);
board_view_ = new BoardView(config_, this);
lt->addWidget(board_view_, BoardLayout::Board);
I did not add any other objects into the layout, so it could maybe be written simpler, but the structure and the API of BoardLayout
are kept the same to maintain the analogy with the working example.
This BoardView
class has an overriden method resizeEvent
, in order to keep the inside objects to occupy all the space of the viewport by changing scale each time it is resized:
void BoardView::resizeEvent(QResizeEvent *event) {
if (event->oldSize().width() == -1) {
qreal k = (qreal)qMin(width(), height()) / ((config_->scene_cell_size + 4) * config_->board_size);
scale(k, k);
}
else {
qreal prev_w = event->oldSize().width(), prev_h = event->oldSize().height();
qreal w = event->size().width(), h = event->size().height();
qreal k = qMin(w, h) / qMin(prev_w, prev_h);
scale(k, k);
}
}
The problem is that, in such a setup, when I start the app, BoardView::resizeEvent
is called non-stop with a pair of different QSize
's, one after another, even though the window (and hence the containing widget, that has the BoardLayout
as a layout) is not being resized.
During this, BoardLayout::setGeometry
is not called, so I don't get where this resize events could come from.
Also, if I delete scale(k, k);
from BoardView::resizeEvent
it works normally as expected (resize events only come after resizing the window, triggered by e->item->setGeometry
in BoardLayout::setGeometry
).
Same thing happens if I change the layout to one of the standard ones, or choose some different rectangles for e->item->setGeometry({50, 50, d, d});
.
So, I would be grateful if someone could explain what is wrong with this architecture, and how are the unnecessary resizeEvents
triggered.