How to get QMenu to react to text size changes in high DPI modes

Menu and menu text automatically resizes when the window is moved from a 96 dpi screen to a 192 dpi screen. I naively thought that Qt would automatically resize the menu when the menu text resizes, but I am obviously wrong here.

  • How can I get the QMenuBar and QMenu to resize when the text is resized? (Specifically when a window is dragged onto a 192 dpi screen)

The text resizes only when the window is moved to a 192 dpi screen. If the window is initially displayed on screen 192, it will draw 96dpi smaller text.

  1. How do I ensure that the text is sized correctly when the main window is opened on a 192 dpi screen?

I tested the game with the QT_DEVICE_PIXEL_RATIO env variable, but that doesn't solve anything. I can make the menus grow larger by setting the value to 2, but I need them to resize depending on the screen I'm using. And the application must be Per-Monitor DPI Aware for Windows, so leaving it at the automatic scale of the window manager is not an option.

I also tested this with the Fusion style to rule out that it is related to the native Windows style.

enter image description here

Trivial test case:

#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();
}

      

+3


source to share


1 answer


From the above images, it can be assumed that you are dealing with Windows.

How do I try to solve this? Let the application react to WM_DPICHANGED . This will likely require you to become more familiar with the SetProcessDPIAware, IsProcessDPIAware, and other related API functions. And what Qt has to offer in this context too.



Then, if the DPI hooking is intercepted, we can use the QWidget SaveGeometry / RestoreGeometry , causing the targeting to the QMenu object. This approach should nullify control.

PS Qt Widgets are generally well adapted for dynamic monitor resizing, and I agree with the commenter that this is probably a bug.

+1


source







All Articles