直到用户事件,Qt窗口大小不正确

我正在创建一个屏幕,用户可以在编辑器中添加某些图块,但添加图块时,该窗口无法正确调整大小以适应内容。 除了当我拖动窗口或调整它的大小时,它会立即捕捉到正确的大小。

在这里输入图像描述
当只是拖动窗口时,它会捕捉到正确的大小。

在这里输入图像描述

我尝试使用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时,它将立即调整大小,但用户无法再调整窗口大小。 我在这里做错了什么,我在哪里开始解决它?

编辑最小验证示例和.ui文件。 selected_layout的类型为Flowlayout flowlayout_placeholder_1仅存在,因为我无法直接将流布局放置到设计器中。

Edit2这是一个最小的Visual Studio示例。 我使用Visual Studio进行Qt开发。 我尝试在Qt Creator中创建一个项目,但我没有得到那个工作。

Edit3添加了一个小视频(80 KB)。

Edit4这是更新的Visual Studio示例。 它有jpo38提出的新变化。 它修复了重新调整大小的问题。 尽管现在试图缩小窗户会导致问题。 即使有更多行的空间,如果尝试减少水平空间,它们也不会正确填充垂直空间。


伟大的MCVE,正是需要轻松调查问题。

看起来这个FlowLayout类没有被设计成在用户操作上具有最小尺寸变化。 移动窗口时,布局会被QWidget内核“偶然”更新。

我可以通过修改FlowLayout::minimumSize()行为来巧妙地工作,下面是我做的更改:

  • 增加了QSize minSize; 属性为FlowLayout
  • 修改FlowLayout::minimumSize()以简单返回此属性
  • 增加了第三个参数QSize* pMinSize doLayout函数。 这将用于更新此minSize属性
  • 修改了doLayout以将计算的大小保存到pMinSize参数(如果指定)
  • 如果最小大小发生更改, FlowLayout::setGeometryminSize属性传递给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;
    }
    
    链接地址: http://www.djcxy.com/p/41373.html

    上一篇: Qt Window incorrect size until user event

    下一篇: Nested generic with type bound results in compile error