[SOLVED] iOS retina



  • Hi.
    on Iphone with Retina this simple script shows that screen width is 320 pixels. Is it possible to draw Rectangle with real pixels (so real screen with must be 640 pixels) or with density independent pixels (I mean something like cm or mm ), so the GUI design will be the same on Retina Iphone and Android devices ?

    @import QtQuick 2.2
    import QtQuick.Controls 1.1
    import QtQuick.Dialogs 1.2

    ApplicationWindow {
    visible: true
    width: 720
    height: 1280

    Rectangle{
        id: red_rect
        anchors.left: parent.left
        anchors.right: parent.right
        width: 100
        height: 100
        color:"red"
        Text {
            id: red_text
            text: red_rect.width
            anchors.centerIn: parent
        }
    }
    

    }
    @



  • On iOS the dimension that you get is the logical dimension of the iOS screens.
    This happens also if you program natively with Xcode on iOS.
    So, when you create a Rectangle of 320 logical pixel, on non-Retina iOS devices it will use 302 real pixel, but on retina iOS devices it will use the double of pixel (640).
    And also Qt handles a lot of things for supporting retina displays (also for high-density display on Android devices) and to work with an independent system (like cm or mm or inches).

    I'll share some of my tricks (on the forum you can find out other tricks):

    Define a QML global variable representing one millimeter:

    • one main.cpp write the follow:
      @
      // calculate how many pixel (roughly) there are in 1 mm
      qreal mm = app.primaryScreen()->physicalDotsPerInch()/25.4;
      // make it globally visible to QML
      viewer.rootContext()->setContextProperty( "mm", mm );
      @
    • on the QML side use simply like this:
      @
      Rectangle {
      width: 7mm
      height: 12
      mm
      }
      @
      and it generates a rectangle of 7x12 mm on any device

    Use of high-density images with suffix '@2x':

    • for any icon and/or images of your app create a version with double size with the suffix '@2x': homeIcon.png (48x48) and homeIcon@2x.png (96x96)
    • set the source of Image using the '@2x' version on high-dpi displays:
      @
      Image {
      source: (isRetinaDisplay ? homeIcon@2x.png : homeIcon.png)
      }
      @
      You can know if you are on a high-dpi (retina) display using Screen. I use this code in the main.cpp for export a variable to indicate if the device is retina-like:
      @
      if ( qApp->primaryScreen()->devicePixelRatio() >= 2 ) {
      imageVariant = "@2x";
      } else {
      imageVariant = "";
      }
      @
    • The Qt Image (and QPixmap) make the magic: when it encounter an image where the name has '@2x' suffix, it automatically set the pixel density to '2' and the image will be rendered with an high-density way. For example, if you set the source "homeIcon@2x.png" the logical size will be 48x48 (so the Image item width and height will be 48x48), but the image will be rendered using all 96x96 pixel without scaling but using the properties of the retina display.


  • Thank you for such informative answer !

    For my needs I found how to get device independent sizes for GUI elements, this is mostly the same you speak about.
    @void ApplicationUI::measureScreen()
    {
    // qDebug()<QGuiApplication::primaryScreen()-physicalDotsPerInch();
    // qDebug()<QGuiApplication::primaryScreen()-devicePixelRatio();
    virtual_dpi=QGuiApplication::primaryScreen()->physicalDotsPerInch()/(QGuiApplication::primaryScreen()->devicePixelRatio()*25.4);
    LoadMainPage();
    }@

    Here is additional parameter - devicePixelRatio, because on Retina display we can use logical pixels and devicePixelRatio is 2 but physicalDotsPerInch return real pixels density.

    For translation mm to pixels I'm using C++ invokable methods

    @int ApplicationUI::dp(float l){
    return (int) virtual_dpi*l;
    }@

    Also one have to know that on Android physicalDotsPerInch is infinity before any drawings happend, so you have to show initial screen and only then you can set up conversion from mm to pixels



  • [quote author="profi-S" date="1405020462"]
    Also one have to know that on Android physicalDotsPerInch is infinity before any drawings happend, so you have to show initial screen and only then you can set up conversion from mm to pixels[/quote]

    OOhhhh !!! I got now because on some Android device my UI does not appear well. !!!
    Unfortunately, what you noticed does not happens on all android devices, in fact, in all my testing devices physicalDotsPerInch is available from the start. But on some devices used by the test team the GUI appear completely wrong and I was puzzled on why until your answer !!
    THANK YOU.


  • Lifetime Qt Champion

    Hi guys !

    Interesting posts, you could maybe create a Wiki entry to have a common fixed place with all of this :)



  • What about Screen.pixelDensity?

    Have a look http://qt-project.org/doc/qt-5/qml-qtquick-window-screen.html#pixelDensity-prop

    Screen.pixelDensity*10 //should be 10mm of screen pixels



  • [quote author="Maxim Kim" date="1405317377"]What about Screen.pixelDensity?

    Have a look http://qt-project.org/doc/qt-5/qml-qtquick-window-screen.html#pixelDensity-prop

    Screen.pixelDensity*10 //should be 10mm of screen pixels[/quote]

    Yes, it's right!



  • @Image {
    source: "foo.png"
    }@

    will try to load "foo@2x.png" on iOS retina screens automatically, no need for custom logic there.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.