问题描述
我有一个自定义布局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
没有被调用,所以我不知道此调整大小事件可能来自何处。
此外,如果我从scale(k,k);
中删除BoardView::resizeEvent
,它会按预期正常工作(调整大小的事件仅在调整窗口大小之后,由e->item->setGeometry
中的BoardLayout::setGeometry
触发)。 / p>
如果我将布局更改为标准布局之一,或者为e->item->setGeometry({50,d});
选择了一些不同的矩形,也会发生同样的事情。
因此,如果有人能解释此架构有什么问题以及如何触发不必要的resizeEvents
,我将不胜感激。
解决方法
事实证明,事件是由两个QScrollBar
发出的,它们在视口对于场景而言太小时出现。但是,只有当对象位于适合场景和不适合场景之间的边缘并且滚动条实际上出现和消失并且事件周期中发生了一些我无法理解的复杂事件时,这种情况才会发生,因为很难找到发生了什么情况以及何时发生的文档
但是,如果我们更改比例系数以使滚动条始终显示或始终不显示,则一切正常。可能这不是一个正确的解决方案,只能在实践中起作用,因为某些事件总是得到足够快的处理,而这并不能保证。