当窗口调整大小时保持纵横比

时间:2021-07-29 21:20:59

标签: qt

我使用的是 Qt5。

当我调整窗口大小时,我想保持窗口的纵横比,所以高度必须等于宽度。

我没有使用布局,我在 resizeEvent 类中实现了我自己的 MainWindow,当我调整窗口大小时,所有内容都会随之调整。

我已经阅读了以下 stackoverflow 问题,但它们对我没有帮助:

1 个答案:

答案 0 :(得分:2)

我们通过拦截 nativeEvent 得到了解决方案:

#include <Windows.h>

// Utility Functions
int rectWidth(RECT* r)
{
    return r->right - r->left;
}

int rectHeight(RECT *r)
{
    return r->bottom - r->top;
}

// these functions should have the same resulting aspect ratio
int MainWindow::heightForWidth(int width) const
{
    return width / 1 / 1; // /aspect ratio
}

// these functions should have the same resulting aspect ratio
int MainWindow::widthForHeight(int height) const
{
    return height * 1 / 1; // *aspectRatio
}

bool MainWindow::nativeEvent(const QByteArray &eventType, void *message, long *result)
{
    // Intercept Windows event
    if(eventType == "windows_generic_MSG")
    {
        MSG* msg = static_cast<MSG*>(message);

        if(msg->message == WM_SIZING)
        {
            RECT *rect = (RECT*)(msg->lParam);

            // Overwrite the right parameter with the calculated value:
            switch(msg->wParam)
            {
            case WMSZ_BOTTOMRIGHT:
                if(rectWidth(rect) < rectHeight(rect)) goto wmsz_bottom;
                else goto wmsz_right; // Always wanted to use goto
                break;
            case WMSZ_BOTTOM:
                wmsz_bottom:
                rect->right = rect->left + widthForHeight(rectHeight(rect));
                break;
            case WMSZ_RIGHT:
                wmsz_right:
                rect->bottom = rect->top + heightForWidth(rectWidth(rect));
                break;
            case WMSZ_TOPLEFT:
                if(rectWidth(rect) < rectHeight(rect)) goto wmsz_top;
                else goto wmsz_left; // goto away, wheeeeee
                break;
            case WMSZ_TOP:
                wmsz_top:
                rect->left = rect->right - widthForHeight(rectHeight(rect));
                break;
            case WMSZ_LEFT:
                wmsz_left:
                rect->top = rect->bottom - heightForWidth(rectWidth(rect));
                break;
            }
        }
    }

    // Pass the modified Windows Message to the original event handler
    return QMainWindow::nativeEvent(eventType, message, result);
}

使用 Qt5.15.2 和 Windows 10 进行测试。但由于 Windows API 和 Qt5 API 非常稳定,因此应该适用于所有合理的旧版本。