【问题标题】:How do I get a QMenu to react to text size changes on High DPI diplays如何让 QMenu 对高 DPI 显示器上的文本大小变化做出反应
【发布时间】:2015-07-22 09:52:15
【问题描述】:

当窗口从 96 dpi 屏幕移动到 192 dpi 屏幕时,菜单栏和菜单中的文本会自动改变大小。我天真地认为当菜单文本大小改变时 Qt 会自动调整菜单大小,但我显然错了。

  1. 当文本改变大小时,如何让 QMenuBar 和 QMenu 改变大小? (特别是当窗口被拖到 192 dpi 屏幕时)

仅当我将窗口移动到 192 dpi 屏幕时,文本大小才会发生变化。如果窗口最初显示在 192 屏幕上,它将绘制较小的 96 dpi 文本。

  1. 当主窗口在 192 dpi 屏幕上打开时,如何确保文本大小正确?

我已经测试过使用 QT_DEVICE_PIXEL_RATIO 环境变量,但这并不能解决任何问题。我可以通过将值设置为 2 来强制菜单变大,但我需要它们根据使用的屏幕更改大小。 并且该应用程序必须是 Windows 上的 Per-Monitor DPI Aware,因此不能将其留给窗口管理器自动缩放。

我还用 Fusion 风格对此进行了测试,以排除它与原生 Windows 风格有关。

一个简单的测试用例:

#include <QApplication>
#include <QMainWindow>
#include <QMenuBar>
#include <QStyle>
//#include <QStyleFactory>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    //a.setStyle((QStyleFactory::create(("Fusion"))));

    QMainWindow w;

    QMenuBar *menuBar = w.menuBar();

    QMenu *menuFile = menuBar->addMenu("File");
    QMenu *menuEdit = menuBar->addMenu("Edit");
    QMenu *menuCompany = menuBar->addMenu("&Company");
    QMenu *menuArrange = menuBar->addMenu("Arrange");

    // file menu
    menuFile->addAction(a.style()->standardIcon(QStyle::SP_DirOpenIcon), "Open", nullptr, nullptr, QKeySequence::Open);
    menuFile->addAction(a.style()->standardIcon(QStyle::SP_DriveFDIcon), "Save", nullptr, nullptr, QKeySequence::Save);
    QAction* actionQuit = menuFile->addAction("Quit");
    QObject::connect(actionQuit, &QAction::triggered, &w, &QMainWindow::close);
    // edit menu
    menuEdit->addAction(a.style()->standardIcon(QStyle::SP_ArrowLeft), "Undo", nullptr, nullptr, QKeySequence::Undo);
    menuEdit->addAction(a.style()->standardIcon(QStyle::SP_ArrowRight), "Redo", nullptr, nullptr, QKeySequence::Redo);
    // company menu
    menuCompany->addAction(a.style()->standardIcon(QStyle::SP_DriveNetIcon), "DB Connect", nullptr, nullptr, QKeySequence(Qt::SHIFT + Qt::Key_Insert));

    w.setCentralWidget(new QWidget);

    w.show();

    return a.exec();
}

【问题讨论】:

  • 这似乎是一个 Qt 错误。

标签: qt highdpi


【解决方案1】:

根据上面的图片,我们可以假设您使用的是 Windows。

我将如何尝试解决这个问题?让我们让应用程序对WM_DPICHANGED 做出反应。这可能需要您更加熟悉 SetProcessDPIAware、IsProcessDPIAware 和其他相关 API 函数。 Qt 在这种情况下也必须提供什么。

然后,在 DPI 更改被拦截后,我们可以利用 QWidget SaveGeometry / RestoreGeometry 调用以该 QMenu 对象为目标。这种方法应该使控件无效。

附:总的来说,Qt 小部件很好地适应了动态监视器尺寸变化,我同意评论者的观点,这可能是一个错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-12
    • 2014-04-12
    • 1970-01-01
    • 2018-10-14
    • 2020-05-11
    • 1970-01-01
    • 2021-05-13
    • 1970-01-01
    相关资源
    最近更新 更多