【问题标题】:When the window resize keep the aspect ratio当窗口调整大小时保持纵横比
【发布时间】:2021-10-05 12:33:33
【问题描述】:

我正在使用 Qt5。

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

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

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

【问题讨论】:

    标签: qt


    【解决方案1】:

    我们通过拦截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 非常稳定,这应该适用于所有相当旧的版本。

    【讨论】:

    • 保持窗口的纵横比,但高度不等于宽度。
    • 然后更改heightForWidth()widthForHeight() 约束。
    • 我知道,只需编辑您的答案,而您忘记提及包含windows.h,如果您编辑您的答案,我会将其标记为答案。
    猜你喜欢
    • 1970-01-01
    • 2013-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-23
    相关资源
    最近更新 更多