我已阅读官方Qt文档以及StackOverflow上关于Qt高DPI支持的许多文章和问题。所有这些都集中在移植旧应用程序并尽可能少地进行更改,但如果我要开始一个全新的应用程序,并打算支持每个监视器DPI感知应用程序,最佳方法是什么?
如果我理解正确,Qt :: AA_EnableHighDpiScaling
恰恰相反。实际上,我应该禁用HighDpiScaling并在运行时手动计算所有尺寸吗?
许多建议说根本不使用大小,而使用浮动布局。但在许多情况下,至少希望具有最小宽度和/或最小高度存在。由于Qt Designer只允许我放置绝对像素值,因此应该采取什么正确的方法?如果监视器分辨率发生变化,应将代码放在何处以重新计算尺寸?
还是应该选择自动缩放?
我之前Qt应用程序的解决方案(经过不充分测试)
在我尝试添加HighDPI支持的较旧应用程序之一中,我使用了此方法 - 列出DOM的所有子项,并按比例逐一调整其大小。比率= 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();
}
从主函数调用:
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应用程序?
QT_SCALE_FACTOR
以匹配。这里存在一些权衡。在Mac上,我们不需要做任何事情。你的情况可能会有所不同。 - selbiefont.pixelSize
进行设置,则字体可以很好地与QT_SCALE_FACTOR比例缩放。这不仅是一种调试工具,而且是在不必为每个文字数字污染QML代码的情况下发布QML应用程序的唯一方法。QT_SCREEN_SCALE_FACTORS也可以起作用。但是环境变量仅在Qt初始化时读取一次。 - selbie