2016-07-31 122 views
0

我正在使用QPixmap作爲渲染緩存。使用具有不同縮放因子的多個屏幕(在Windows上測試)時會導致縮放問題。使用QPixmap作爲渲染緩存時保持正確的GUI縮放

我寫了一個用於演示目的的小部件。繪圖既可以直接完成,也可以在設備上繪製的QPixmap上完成。 (在真實的應用程序中,pixmap被緩存以防止不必要的paint()調用,但爲簡單起見,這裏沒有提到)。如果有人想完整的例子: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())); 
} 

出於演示,我已經放在小部件並排側的兩個實例。左側直接繪製,右側使用QPixmap。

所有在單個監視器上正常工作。

enter image description here

然而,當我有不同的定標多個屏幕,結果不同。直接繪製正確地適應並且在當前屏幕分辨率下呈現。像素圖總是以主屏幕分辨率呈現。

窗口用150%縮放,主畫面用100%縮放次級屏幕上:

enter image description here

到目前爲止這是可以理解的。 Pixmap不瞭解屏幕,因此它使用主屏幕的縮放是合理的。我現在的問題是:

有沒有一種方法來調整像素圖渲染的縮放比例?

我覺得我應該修改Pixmap的logicalDpiX/Y。但從Qt 5.6.1開始,這似乎是不可能的。

回答

0

可能的解決方法是重新縮放字體大小而不是logicalDpiY。至少這似乎適用於字體。不知道是否還需要修改其他畫家設置,如線寬。

void RenderWidget::paint(QPaintDevice *pd) 
{ 
    QPainter p(pd); 

    if (m_usePixmap) { 
     QWidget *w = this; // widget on which the pixmap should be drawn later on 

     if (pd->logicalDpiY() != w->logicalDpiY()) { 
      // workaround the scaling by adapting the font 
      QFont f(p.font()); 
      f.setPointSizeF((f.pointSizeF() * w->logicalDpiY())/pd->logicalDpiY()); 
      p.setFont(f); 
     } 
    } 

    p.fillRect(0, 0, pd->width(), pd->height(), QColor(192, 192, 192)); 

    ... 
} 

如上:窗口用150%縮放,主畫面用100%縮放次級屏幕上:

enter image description here

注:更新GitHub庫與此代碼:https://github.com/the-yeti/qpixmap-scaling-demo