Qt中如何锁定窗口缩放时的宽高比(以16/9为例)
在Qt中锁定窗口调整大小的宽高比(16:9示例)
方法1:重写resizeEvent事件(通用QWidget子类)
对于自定义QWidget或其派生类(如QDialog),重写resizeEvent是最直接的实现方式,能在窗口尺寸变化时强制修正为16:9比例。
示例代码:
#include <QWidget> #include <QResizeEvent> class MyWidget : public QWidget { Q_OBJECT public: explicit MyWidget(QWidget *parent = nullptr) : QWidget(parent) {} protected: void resizeEvent(QResizeEvent *event) override { const qreal targetRatio = 16.0 / 9.0; QSize newSize = event->size(); qreal currentRatio = static_cast<qreal>(newSize.width()) / newSize.height(); // 允许微小误差,避免无限递归调整 if (qAbs(currentRatio - targetRatio) > 0.01) { if (currentRatio > targetRatio) { // 宽度超标,按高度计算正确宽度 newSize.setWidth(static_cast<int>(newSize.height() * targetRatio)); } else { // 高度超标,按宽度计算正确高度 newSize.setHeight(static_cast<int>(newSize.width() / targetRatio)); } resize(newSize); return; } QWidget::resizeEvent(event); } };
方法2:使用QWindow的比例锁定(Qt 5.10+)
如果窗口基于QWindow(QWidget可通过windowHandle()获取对应对象),直接调用Qt提供的API就能实现比例锁定,无需手动重写事件。
示例代码:
#include <QMainWindow> #include <QWindow> int main(int argc, char *argv[]) { QApplication app(argc, argv); QMainWindow window; window.show(); QWindow *winHandle = window.windowHandle(); if (winHandle) { // 设置16:9比例,拉伸时保持比例锁定 winHandle->setAspectRatio(QSize(16, 9)); winHandle->setAspectRatioMode(Qt::KeepAspectRatio); } return app.exec(); }
注意:需调用show()后才能获取有效的windowHandle()。
方法3:QMainWindow的特殊处理
如果使用QMainWindow,且希望仅锁定中心部件的比例(窗口保留菜单栏、状态栏等区域的灵活性),可在resizeEvent中调整中心部件的尺寸。
示例代码:
#include <QMainWindow> #include <QWidget> #include <QResizeEvent> class MyMainWindow : public QMainWindow { Q_OBJECT public: explicit MyMainWindow(QWidget *parent = nullptr) : QMainWindow(parent) { QWidget *centralWidget = new QWidget(this); setCentralWidget(centralWidget); } protected: void resizeEvent(QResizeEvent *event) override { QMainWindow::resizeEvent(event); const qreal targetRatio = 16.0 / 9.0; // 获取窗口可用区域(去除菜单栏、状态栏等) QRect availableRect = centralWidget()->parentWidget()->contentsRect(); QSize targetSize = availableRect.size(); qreal currentRatio = static_cast<qreal>(targetSize.width()) / targetSize.height(); if (qAbs(currentRatio - targetRatio) > 0.01) { if (currentRatio > targetRatio) { targetSize.setWidth(static_cast<int>(targetSize.height() * targetRatio)); } else { targetSize.setHeight(static_cast<int>(targetSize.width() / targetRatio)); } // 居中放置中心部件 centralWidget()->setGeometry( (availableRect.width() - targetSize.width()) / 2, (availableRect.height() - targetSize.height()) / 2, targetSize.width(), targetSize.height() ); } } };
内容的提问来源于stack exchange,提问作者MEsc
相关产品推荐
相关产品推荐

