Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Changing the graphic engine changes the way a path is drawn
Forum Updated to NodeBB v4.3 + New Features

Changing the graphic engine changes the way a path is drawn

Scheduled Pinned Locked Moved Solved QML and Qt Quick
qtquickqmldashed linesgraphicsengine
2 Posts 1 Posters 680 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Offline
    J Offline
    jeanmilost
    wrote on 25 Jan 2021, 15:05 last edited by
    #1

    Using Qt Quick 5.15.2, I need to draw a dashed rounded rectangle outline. As unfortunately it's not possible to reach a such drawing with the Rectangle.border properties, I created my own shape path to reach the rendering I needed.

    However the path I created is sometimes broken, and so inconsistent. First of all, I needed to introduce kind of compensatory values in my path, because sometimes the position was shifted by 1 pixel in relation to the expected one, for a reason I cannot figure out. And after reaching the expected drawing, it may become broken again if I change the graphic engine used by Qt, e.g by using or not OpenGLES.

    For that reason I wrote 2 different paths, which I switch depending on which graphic engine I use. However, although all is fine on my computer, several of my clients complain that the rectangle is drawn completely broken, which makes me suppose that Qt may change the graphic engine internally, depending on the target computer capabilities.

    This is a very annoying issue, and I would like to know what I'm doing wrong, as well as how a such path should be written to work correctly on ALL computers.

    Here is my qml code:

    import QtQuick 2.15
    import QtQuick.Window 2.15
    import QtQuick.Controls 2.15
    import QtQuick.Shapes 1.15
    import QtGraphicalEffects 1.15
    import QtQuick.Templates 2.15 as T
    
    /**
    * Dashed border
    *@author JMR
    */
    T.Control
    {
        // advanced properties
        property int    m_StrokeWidth: 1
        property int    m_Radius:      5
        property string m_FillColor:   "transparent"
        property string m_StrokeColor: "#bac1db"
        property bool   m_UseOpenGLES: true//false
    
        /**
        * Background rectangle
        */
        Rectangle
        {
            // common properties
            anchors.fill: parent
            color: m_FillColor
            radius: m_Radius
    
            /**
            * Dashed outline shape (OpenGLES version)
            */
            Shape
            {
                // common properties
                id: shDashedBorderOGLES
                anchors.fill: parent
                anchors.margins: 0
                //layer.enabled: true
                //layer.samples: 8
                smooth: true
                visible: m_UseOpenGLES
    
                /**
                * Dashed outline shape path
                */
                ShapePath
                {
                    // common properties
                    fillColor: "transparent"
                    strokeColor: m_StrokeColor
                    strokeWidth: m_StrokeWidth
                    strokeStyle: ShapePath.DashLine
                    dashPattern: [5, 5]
                    startX: m_Radius
                    startY: 0
    
                    // path commands
                    PathLine {x: shDashedBorderOGLES.width - m_Radius; y: 0;}
                    PathQuad {x: shDashedBorderOGLES.width;            y: m_Radius;                              controlX: shDashedBorderOGLES.width; controlY: 0;}
                    PathLine {x: shDashedBorderOGLES.width;            y: shDashedBorderOGLES.height - m_Radius;}
                    PathQuad {x: shDashedBorderOGLES.width - m_Radius; y: shDashedBorderOGLES.height - 1;        controlX: shDashedBorderOGLES.width; controlY: shDashedBorderOGLES.height;}
                    PathLine {x: m_Radius;                             y: shDashedBorderOGLES.height - 1;}
                    PathQuad {x: 0;                                    y: shDashedBorderOGLES.height - m_Radius; controlX: 0;                         controlY: shDashedBorderOGLES.height;}
                    PathLine {x: 1;                                    y: m_Radius;}
                    PathQuad {x: m_Radius;                             y: 0;                                     controlX: 0;                         controlY: 0;}
                }
            }
    
            /**
            * Dashed outline shape (non-OpenGLES version)
            */
            Shape
            {
                // common properties
                id: shDashedBorderNOGLES
                anchors.fill: parent
                anchors.margins: 0
                //layer.enabled: true
                //layer.samples: 8
                smooth: true
                visible: !m_UseOpenGLES
    
                /**
                * Dashed outline shape path
                */
                ShapePath
                {
                    // common properties
                    fillColor: "transparent"
                    strokeColor: m_StrokeColor
                    strokeWidth: m_StrokeWidth
                    strokeStyle: ShapePath.DashLine
                    dashPattern: [5, 5]
                    startX: m_Radius
                    startY: 1
    
                    // path commands
                    PathLine {x: shDashedBorderNOGLES.width - m_Radius; y: 1;}
                    PathQuad {x: shDashedBorderNOGLES.width;            y: m_Radius;                               controlX: shDashedBorderNOGLES.width; controlY: 0;}
                    PathLine {x: shDashedBorderNOGLES.width;            y: shDashedBorderNOGLES.height - m_Radius;}
                    PathQuad {x: shDashedBorderNOGLES.width - m_Radius; y: shDashedBorderNOGLES.height;            controlX: shDashedBorderNOGLES.width; controlY: shDashedBorderNOGLES.height;}
                    PathLine {x: m_Radius;                              y: shDashedBorderNOGLES.height;}
                    PathQuad {x: 0;                                     y: shDashedBorderNOGLES.height - m_Radius; controlX: 0;                          controlY: shDashedBorderNOGLES.height;}
                    PathLine {x: 1;                                     y: m_Radius;}
                    PathQuad {x: m_Radius;                              y: 0;                                      controlX: 0;                          controlY: 0;}
                }
            }
        }
    }
    

    And below is the graphic engine I may enable or disable:

    QCoreApplication::setAttribute(Qt::ApplicationAttribute::AA_UseOpenGLES, true);
    
    1 Reply Last reply
    0
    • J Offline
      J Offline
      jeanmilost
      wrote on 28 Jan 2021, 15:02 last edited by
      #2

      So as nobody answered this question, I found a workaround which seems to resolve my issue. I changed the stroke width from 1 to 1.5. However this unfortunately doesn't explain what happened here, and why the ShapePath object behaves this way. I have my own idea about that: I think it's a kind of pen alignment, as in GDI+ (https://docs.microsoft.com/en-us/windows/win32/api/gdiplusenums/ne-gdiplusenums-penalignment), however I found absolutely no way to configure that.

      So below is my solution, which works correctly in all situations on my side:

      import QtQuick 2.15
      import QtQuick.Window 2.15
      import QtQuick.Controls 2.15
      import QtQuick.Shapes 1.15
      import QtGraphicalEffects 1.15
      import QtQuick.Templates 2.15 as T
      
      /**
      * Dashed border
      *@author JMR
      */
      T.Control
      {
          // advanced properties
          property real   m_StrokeWidth: 1.5
          property int    m_Radius:      5
          property string m_FillColor:   "transparent"
          property string m_StrokeColor: "#bac1db"
      
          /**
          * Background rectangle
          */
          Rectangle
          {
              // common properties
              anchors.fill: parent
              color: m_FillColor
              radius: m_Radius
      
              /**
              * Dashed outline shape
              */
              Shape
              {
                  // common properties
                  id: shDashedBorder
                  anchors.fill: parent
                  anchors.margins: 0
                  //layer.enabled: true
                  //layer.samples: 8
                  smooth: true
                  clip: true
      
                  /**
                  * Dashed outline shape path
                  */
                  ShapePath
                  {
                      // common properties
                      fillColor: "transparent"
                      strokeColor: m_StrokeColor
                      strokeWidth: m_StrokeWidth
                      strokeStyle: ShapePath.DashLine
                      dashPattern: [5, 5]
                      startX: m_Radius
                      startY: 0
      
                      // path commands
                      PathLine {x: shDashedBorder.width - m_Radius; y: 0;}
                      PathQuad {x: shDashedBorder.width;            y: m_Radius;                         controlX: shDashedBorder.width; controlY: 0;}
                      PathLine {x: shDashedBorder.width;            y: shDashedBorder.height - m_Radius;}
                      PathQuad {x: shDashedBorder.width - m_Radius; y: shDashedBorder.height;            controlX: shDashedBorder.width; controlY: shDashedBorder.height;}
                      PathLine {x: m_Radius;                        y: shDashedBorder.height;}
                      PathQuad {x: 0;                               y: shDashedBorder.height - m_Radius; controlX: 0;                    controlY: shDashedBorder.height;}
                      PathLine {x: 0;                               y: m_Radius;}
                      PathQuad {x: m_Radius;                        y: 0;                                controlX: 0;                    controlY: 0;}
                  }
              }
          }
      }
      
      1 Reply Last reply
      1

      2/2

      28 Jan 2021, 15:02

      • Login

      • Login or register to search.
      2 out of 2
      • First post
        2/2
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • Users
      • Groups
      • Search
      • Get Qt Extensions
      • Unsolved