Я прочитал официальную документацию Qt, а также множество статей и вопросов на StackOverflow о высоком разрешении на дюйм. поддержка в 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();
}
который вызывается из основного:
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 нам не нужно было ничего делать. YMMV. - person selbie   schedule 03.10.2016font.pixelSize
для установки. Это не просто инструмент отладки, это единственный способ отправить приложение QML без необходимости загрязнять код QML какой-то функцией масштабирования для каждого литерального числа. QT_SCREEN_SCALE_FACTORS тоже может работать. Но переменные среды считываются только один раз при инициализации Qt. - person selbie   schedule 03.10.2016