Ich verwende QPixmap als Render-Cache. Dies führt zu Skalierungsproblemen bei Verwendung mehrerer Bildschirme mit unterschiedlichen Skalierungsfaktoren (getestet unter Windows).Bei Verwendung von QPixmap als Rendering-Cache korrekte GUI-Skalierung beibehalten
Ich habe ein kleines Widget zu Demonstrationszwecken geschrieben. Das Zeichnen kann entweder direkt oder auf einer QPixmap erfolgen, die dann auf dem Gerät gezeichnet wird. (In der realen Anwendung wird die Pixmap zwischengespeichert, um unnötige Paint() - Aufrufe zu vermeiden. Aber das ist der Einfachheit halber hier weggelassen). Falls jemand will das volle Beispiel: https://github.com/the-yeti/qpixmap-scaling-demo
void RenderWidget::paintEvent(QPaintEvent *event)
{
if (m_usePixmap) {
QPixmap pm(width(), height());
paint(&pm);
QPainter(this).drawPixmap(0, 0, pm);
} else {
paint(this);
}
}
void RenderWidget::paint(QPaintDevice *pd)
{
QPainter p(pd);
p.fillRect(0, 0, pd->width(), pd->height(), QColor(192, 192, 192));
QFontMetrics fm = p.fontMetrics();
int h = fm.height();
for (int i=1; i<6; i++) {
p.drawLine(0, i*h, width(), i*h);
}
p.drawText(4, fm.ascent(), m_usePixmap ? "using QPixmap draw" : "using direct draw");
p.drawText(8, h+ fm.ascent(), QString("font pointsize: %1").arg(p.font().pointSize()));
p.drawText(8, 2*h + fm.ascent(), QString("font height: %1").arg(h));
p.drawText(8, 3*h + fm.ascent(), QString("physicalDpiY: %1").arg(pd->physicalDpiY()));
p.drawText(8, 4*h + fm.ascent(), QString("logicalDpiY: %1").arg(pd->logicalDpiY()));
}
Zur Demonstration habe ich zwei Instanzen der Widgets Seite an Seite angeordnet. Links ist direkt gezeichnet, rechts verwendet die QPixmap.
Alles funktioniert gut auf einem einzigen Monitor.
Wenn jedoch I mehreren Bildschirmen mit verschiedenen Skalierungen haben, unterscheiden sich die Ergebnisse. Das direkte Zeichnen passt sich korrekt an und rendert bei der aktuellen Bildschirmauflösung. Die Pixmap wird immer mit der primären Bildschirmauflösung gerendert.
Fenster auf Sekundär Bildschirm mit 150% Skalierung, Hauptbildschirm mit 100% Skalierung:
Bisher das ist verständlich. Die Pixmap kennt keine Bildschirme, daher ist es sinnvoll, dass sie die Skalierung des primären Bildschirms verwendet. Meine Frage ist jetzt:
Gibt es eine Möglichkeit, die Skalierung des Pixmap-Renderings abzustimmen?
Ich fühle mich wie ich die logicalDpiX/Y
der Pixmap ändern sollte. Aber das scheint ab Qt 5.6.1 unmöglich zu sein.