You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 04:40:29