3
votes

The text in menubars and menues automatically change size when a window is moved from a 96 dpi screen to 192 dpi screen. I naively thought Qt would automatically resize menues when the menu text size changed but I'm obviously wrong here.

  1. How can I get QMenuBar and QMenu to change size when the text changes size? (Specifically when the window is dragged to the 192 dpi screen)

Text size only change when I move the window to a 192 dpi screen. If the window is initially shown on the 192 screen it will draw the smaller 96 dpi text.

  1. How do I ensure that the text is the correct size when the mainwindow opens on a 192 dpi screen?

I've tested playing around with the QT_DEVICE_PIXEL_RATIO env variable but this doesn't solve anything. I can force the menues to become larger by setting the value to 2, but I need them to change size depending on the screen in use. And the application must be Per-Monitor DPI Aware on Windows so leaving it to the window manager auto scale is not an option.

I've also tested this with the Fusion style to rule out it being related to the native Windows style.

enter image description here

A 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();
}
1
This seems to be a Qt bug.Kuba hasn't forgotten Monica

1 Answers

1
votes

From above images attached we can assume you deal with Windows.

How would I attempt to solve that? Let's make the app to react on WM_DPICHANGED. That is likely require you to become more familiar with SetProcessDPIAware, IsProcessDPIAware and other related API functions. And what Qt has to offer in this context as well.

Then, having DPI change intercepted we can take advantage of QWidget SaveGeometry / RestoreGeometry calls targeting that QMenu object. This approach should invalidate the control.

P.S. Qt Widgets in general are well adapted to dynamic monitor dimension changes and I agree with commenter that that is probably a bug.