我正在创建一个屏幕,用户可以在其中添加某些图块以在编辑器中使用,但在添加图块时,窗口无法正确调整大小以适应内容。除非我拖动窗口或调整窗口大小,然后立即将其捕捉到正确的大小。
我尝试使用resize(sizeHint());这给了我一个不正确的大小和以下错误,但在调整大小/拖动时仍然会发生正确尺寸的捕捉。
QWindowsWindow::setGeometry: Unable to set geometry 299x329+991+536 on QWidgetWindow/'TileSetterWindow'. Resulting geometry: 299x399+991+536 (frame: 8, 31, 8, 8, custom margin: 0, 0, 0, 0, minimum size: 259x329, maximum size: 16777215x16777215).
我也尝试过使用updateGeometry()和update(),但是如果有的话,它似乎没什么用。
将窗口设置为fixedSize时,它会立即调整大小,但用户无法再调整窗口大小。我在这里做错了什么,我在哪里开始解决它?
修改 Minimal verifiable example和.ui file。 selected_layout的类型为Flowlayout flowlayout_placeholder_1仅在那里,因为我无法将flowlayout直接放入设计器中。
EDIT2 这是一个minimal Visual Studio example。我使用Visual Studio进行Qt开发。我尝试在Qt Creator中创建一个项目,但我没有让它工作。
EDIT3 添加了little video(80 KB)。
Edit4 这是updated Visual Studio example。它有jpo38提出的新变化。它解决了调整错误的问题。虽然现在试图缩小窗口的尺寸会导致问题。如果你试图减少水平空间,即使有更多行的空间,它们也不能正确填充垂直空间。
答案 0 :(得分:3)
伟大的MCVE,正是需要轻松调查此问题。
看起来这个FlowLayout
课程的目的不是让用户操作的最小尺寸更改。布局随时更新'移动窗口时通过QWidget内核。
我可以通过修改FlowLayout::minimumSize()
行为来巧妙地使用它,以下是我所做的更改:
QSize minSize;
属性添加到FlowLayout
类FlowLayout::minimumSize()
以简单地返回此属性QSize* pMinSize
功能添加了第三个参数doLayout
。这将用于更新此minSize
属性doLayout
将计算出的大小保存到pMinSize
参数(如果已指定)FlowLayout::setGeometry
将minSize
属性传递给doLayout
,如果最小尺寸发生变化,布局无效然后布局按预期运行。
int FlowLayout::heightForWidth(int width) const {
const int height = doLayout(QRect(0, 0, width, 0), true,NULL); // jpo38: set added parameter to NULL here
return height;
}
void FlowLayout::setGeometry(const QRect &rect) {
QLayout::setGeometry(rect);
// jpo38: update minSize from here, force layout to consider it if it changed
QSize oldSize = minSize;
doLayout(rect, false,&minSize);
if ( oldSize != minSize )
{
// force layout to consider new minimum size!
invalidate();
}
}
QSize FlowLayout::minimumSize() const {
// jpo38: Simply return computed min size
return minSize;
}
int FlowLayout::doLayout(const QRect &rect, bool testOnly,QSize* pMinSize) const {
int left, top, right, bottom;
getContentsMargins(&left, &top, &right, &bottom);
QRect effectiveRect = rect.adjusted(+left, +top, -right, -bottom);
int x = effectiveRect.x();
int y = effectiveRect.y();
int lineHeight = 0;
// jpo38: store max X
int maxX = 0;
for (auto&& item : itemList) {
QWidget *wid = item->widget();
int spaceX = horizontalSpacing();
if (spaceX == -1)
spaceX = wid->style()->layoutSpacing(QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal);
int spaceY = verticalSpacing();
if (spaceY == -1)
spaceY = wid->style()->layoutSpacing(QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Vertical);
int nextX = x + item->sizeHint().width() + spaceX;
if (nextX - spaceX > effectiveRect.right() && lineHeight > 0) {
x = effectiveRect.x();
y = y + lineHeight + spaceY;
nextX = x + item->sizeHint().width() + spaceX;
lineHeight = 0;
}
if (!testOnly)
item->setGeometry(QRect(QPoint(x, y), item->sizeHint()));
// jpo38: update max X based on current position
maxX = qMax( maxX, x + item->sizeHint().width() - rect.x() + left );
x = nextX;
lineHeight = qMax(lineHeight, item->sizeHint().height());
}
// jpo38: save height/width as max height/xidth in pMinSize is specified
int height = y + lineHeight - rect.y() + bottom;
if ( pMinSize )
{
pMinSize->setHeight( height );
pMinSize->setWidth( maxX );
}
return height;
}