我已经阅读了Qt 官方文档以及 StackOverflow 上关于 Qt 中高 DPI 支持的许多文章和问题。他们都专注于移植旧应用程序并使它们以尽可能少的更改工作。
但是,如果我要启动一个全新的应用程序,以支持每个显示器的 DPI 感知应用程序,那么最好的方法是什么?
如果我理解正确,Qt::AA_EnableHighDpiScaling
这与我想要的完全相反。我实际上应该禁用 HighDpiScaling 并在运行时手动计算所有尺寸吗?
许多建议说根本不使用尺寸,而是使用浮动布局。但在许多情况下,至少需要存在最小宽度和/或最小高度。由于 Qt Designer 只允许我将值放在绝对像素中,那么正确的方法是什么?如果显示器分辨率发生变化,我应该在哪里放置代码以重新计算尺寸?
还是我应该使用自动缩放?
我以前 Qt 应用程序的解决方案(未经过充分测试)
在我尝试添加 HighDPI 支持的一个较旧的应用程序中,我使用了这种方法 - 列出 DOM 的所有子级,并在给定某个比率的情况下一一调整它们的大小。Ratio = 1 将产生与我在 Qt Designer 中指定的尺寸相同的尺寸。
void resizeWidgets(MyApp & qw, qreal mratio)
{
// ratio to calculate correct sizing
qreal mratio_bak = mratio;
if(MyApp::m_ratio != 0)
mratio /= MyApp::m_ratio;
// this all was done so that if its called 2 times with ratio = 2, total is not 4 but still just 2 (ratio is absolute)
MyApp::m_ratio = mratio_bak;
QLayout * ql = qw.layout();
if (ql == NULL)
return;
QWidget * pw = ql->parentWidget();
if (pw == NULL)
return;
QList<QLayout *> layouts;
foreach(QWidget *w, pw->findChildren<QWidget*>())
{
QRect g = w->geometry();
w->setMinimumSize(w->minimumWidth() * mratio, w->minimumHeight() * mratio);
w->setMaximumSize(w->maximumWidth() * mratio, w->maximumHeight() * mratio);
w->resize(w->width() * mratio, w->height() * mratio);
w->move(QPoint(g.x() * mratio, g.y() * mratio));
}
foreach(QLayout *l, pw->findChildren<QLayout*>())
{
if(l != NULL && !(l->objectName().isEmpty()))
layouts.append(l);
}
foreach(QLayout *l, layouts) {
QMargins m = l->contentsMargins();
m.setBottom(m.bottom() * mratio);
m.setTop(m.top() * mratio);
m.setLeft(m.left() * mratio);
m.setRight(m.right() * mratio);
l->setContentsMargins(m);
l->setSpacing(l->spacing() * mratio);
if (l->inherits("QGridLayout")) {
QGridLayout* gl = ((QGridLayout*)l);
gl->setHorizontalSpacing(gl->horizontalSpacing() * mratio);
gl->setVerticalSpacing(gl->verticalSpacing() * mratio);
}
}
QMargins m = qw.contentsMargins();
m.setBottom(m.bottom() * mratio);
m.setTop(m.top() * mratio);
m.setLeft(m.left() * mratio);
m.setRight(m.right() * mratio);
// resize accordingly main window
qw.resize(qw.width() * mratio, qw.height() * mratio);
qw.setContentsMargins(m);
qw.adjustSize();
}
从 main 调用:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MyApp w;
// gets DPI
qreal dpi = a.primaryScreen()->logicalDotsPerInch();
MyApp::resizeWidgets(w, dpi / MyApp::refDpi);
w.show();
return a.exec();
}
我不认为这是一个好的解决方案。鉴于我刚开始,我可以根据最新的 Qt 标准完全自定义我的代码,我应该使用什么方法来获取 HighDPI 应用程序?