2013-10-24 6 views
8

Ich habe folgende qml Anwendung:Was ist notwendig, um QtQuick 2's Canvas Element HiDPI- (Retina-) bewusst zu machen?

import QtQuick 2.1 
import QtQuick.Controls 1.0 
import QtQuick.Layouts 1.0 
import QtQuick.Window 2.0 

ApplicationWindow { 
    id: window 
    width: 480 
    height: 240 


    RowLayout { 

     Rectangle { 
      width: window.height 
      height: window.height 
      radius: window.height/2 
      color: "black" 
     } 

     Canvas { 
      id: canvas 
      width: window.height 
      height: window.height 

      onPaint: { 
       var ctx = canvas.getContext('2d'); 
       var originX = window.height/2 
       var originY = window.height/2 
       var radius = window.height/2 

       ctx.save(); 

       ctx.beginPath(); 
       ctx.arc(originX, originY, radius, 0, 2 * Math.PI); 
       ctx.fillStyle = Qt.rgba(0, 0, 0, 1); 
       ctx.fill(); 

       ctx.restore(); 
      } 

     } 
    } 
} 

Dies erzeugt zwei schwarze Kreise nebeneinander. Der linke (der Rectangle) ist knackig auf einem Retina-Display, während der rechte (der Canvas) ziemlich verschwommen ist. Wenn ich

   antialiasing: false 

zum Canvas hinzufügen, erzeugt es grobe verschwommene Pixel.

Was muss ich tun, um die Canvas HiDPI-aware zu machen?

(Ich bin mit Qt 5.2.0 beta 1 auf Mac OS X 10,8)


Edit: Die Abhilfe kam ich mit war die Canvas in einem Item zu wickeln, Skala alles im Inneren onPaint und dann verwenden Sie eine transform auf der Canvas die Waage es wieder runter.

Canvas { 
     id: canvas 
     x: 0 
     y: 0 
     width: parent.width * 2 // really parent.width after the transform 
     heigth: parent.height * 2 // really parent.height after the transform 

     /* ... */ 

     // This scales everything down by a factor of two. 
     transform: Scale { 
      xScale: .5 
      yScale: .5 
     } 

     onPaint: { 
      var ctx = canvas.getContext('2d'); 
      ctx.save(); 
      ctx.scale(2, 2)  // This scales everything up by a factor of two. 

      /* ... */ 
     } 
    } 

Antwort

7

Wir haben den gleichen Trick von der Größe verdoppeln und dann für die ProgressCircle in qml-material Verkleinerung. Es gibt jedoch einige Verbesserungen, die Sie vornehmen können:

  1. Verwenden Sie scale statt transform.
  2. Verwenden Sie Screen.devicePixelRatio aus dem -Modul, anstatt den Skalierungsfaktor bei 2/0,5 zu codieren.

Code kann also vereinfacht werden:

Canvas { 
    property int ratio: Screen.devicePixelRatio 

    width: parent.width * ratio 
    heigth: parent.height * ratio 
    scale: 1/ratio 

    onPaint: { 
     var ctx = canvas.getContext('2d'); 
     ctx.save(); 
     ctx.scale(ratio, ratio) 

     // ... 
    } 
}