【发布时间】:2020-12-13 04:17:21
【问题描述】:
我有一个自定义布局 BoardLayout,它继承了 QLayout。类比 BorderLayout 示例 (https://doc.qt.io/qt-5/qtwidgets-layouts-borderlayout-example.html) 编写,setGeometry() 方法如下:
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});
}
}
}
它也有一个改变的BoardLayout::calculateSize 方法,但是由于它应用的小部件是一个窗口的centralWidget,它可能无关紧要;在运行时的问题部分也不会调用此方法)。
我为一个窗口设置了这个布局,并在其中(在Board的位置)添加了一个BoardView类的实例,(BoardView继承QGraphicsView):
auto lt = new BoardLayout();
setLayout(lt);
board_view_ = new BoardView(config_, this);
lt->addWidget(board_view_, BoardLayout::Board);
我没有在布局中添加任何其他对象,所以它可能写得更简单,但BoardLayout 的结构和 API 保持不变,以保持与工作示例的类比。
这个BoardView 类有一个重写方法resizeEvent,以便在每次调整大小时通过改变比例来保持内部对象占据视口的所有空间:
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);
}
}
问题在于,在这样的设置中,当我启动应用程序时,BoardView::resizeEvent 会被一对不同的 QSize 一个接一个地调用,即使窗口(以及因此包含以BoardLayout 作为布局的小部件)未调整大小。
在此期间,BoardLayout::setGeometry 没有被调用,所以我不知道这个调整大小事件可能来自哪里。
另外,如果我从BoardView::resizeEvent 中删除scale(k, k);,它会按预期正常工作(调整大小事件仅在调整窗口大小后发生,由BoardLayout::setGeometry 中的e->item->setGeometry 触发)。
如果我将布局更改为标准布局之一,或者为e->item->setGeometry({50, 50, d, d}); 选择一些不同的矩形,也会发生同样的事情。
所以,如果有人能解释这个架构有什么问题,以及如何触发不必要的resizeEvents,我将不胜感激。
【问题讨论】:
标签: qt qgraphicsview qlayout qevent