我使用的是 Qt5。
当我调整窗口大小时,我想保持窗口的纵横比,所以高度必须等于宽度。
我没有使用布局,我在 resizeEvent
类中实现了我自己的 MainWindow
,当我调整窗口大小时,所有内容都会随之调整。
我已经阅读了以下 stackoverflow 问题,但它们对我没有帮助:
答案 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 非常稳定,因此应该适用于所有合理的旧版本。