Я прочитал официальную Qt-документацию и много статей и вопросов о StackOverflow о высокой поддержке DPI в Qt. Все они сосредоточены на переносе старых приложений и обеспечении их работы с минимальными изменениями.
Но если я должен был создать совершенно новое приложение, с намерением поддержать приложение с поддержкой 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?