Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. How to calculate setPen+drawPath dimensions?
Forum Updated to NodeBB v4.3 + New Features

How to calculate setPen+drawPath dimensions?

Scheduled Pinned Locked Moved Unsolved General and Desktop
6 Posts 2 Posters 1.4k Views 1 Watching
  • 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.
  • P Offline
    P Offline
    porsol
    wrote on last edited by
    #1

    I want to paint outline around text in QLabel.
    I can't start with x=0, because left side of the outline will be lost, I also have to add few pixels to y, otherwise outline at the bottom will be lost. But how do I calculate this offset precisely?
    Adding outline_width to all sides is taking up unnecessary space because of 10px brush only 3-5 goes into outline, the rest is hidden behind/inside letters; I need QLabel to take up space as little as possible.

    N = ?
    N2 = ?
    
    self.setFixedSize(self.fontMetrics().width(self.text) + N*2, self.fontMetrics().height() + N2*2)
    
    x = 0 + N
    y = self.fontMetrics().ascent() + N2
    
    outline_width = 10
    
    painter = QPainter(self)
    text_path = QPainterPath()
    text_path.addText(x, y, font, text)
    
    outline_brush = QBrush(QColor(0, 0, 0, alpha), Qt.SolidPattern)		
    outline_pen = QPen(outline_brush, outline_width, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)
    
    painter.setPen(outline_pen)
    painter.drawPath(text_path)
    
    painter.setPen(QColor(255, 255, 255, 255))
    painter.drawText(x, y, text)
    
    raven-worxR 2 Replies Last reply
    0
    • P porsol

      I want to paint outline around text in QLabel.
      I can't start with x=0, because left side of the outline will be lost, I also have to add few pixels to y, otherwise outline at the bottom will be lost. But how do I calculate this offset precisely?
      Adding outline_width to all sides is taking up unnecessary space because of 10px brush only 3-5 goes into outline, the rest is hidden behind/inside letters; I need QLabel to take up space as little as possible.

      N = ?
      N2 = ?
      
      self.setFixedSize(self.fontMetrics().width(self.text) + N*2, self.fontMetrics().height() + N2*2)
      
      x = 0 + N
      y = self.fontMetrics().ascent() + N2
      
      outline_width = 10
      
      painter = QPainter(self)
      text_path = QPainterPath()
      text_path.addText(x, y, font, text)
      
      outline_brush = QBrush(QColor(0, 0, 0, alpha), Qt.SolidPattern)		
      outline_pen = QPen(outline_brush, outline_width, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)
      
      painter.setPen(outline_pen)
      painter.drawPath(text_path)
      
      painter.setPen(QColor(255, 255, 255, 255))
      painter.drawText(x, y, text)
      
      raven-worxR Offline
      raven-worxR Offline
      raven-worx
      Moderators
      wrote on last edited by raven-worx
      #2

      @porsol
      translating (adding for top/left, subtracting for bottom/right) by the half stroke width should do it:

      qFloor( pen.widthF() / 2.0 )
      

      See Qt's coordinate system.

      --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
      If you have a question please use the forum so others can benefit from the solution in the future

      P 1 Reply Last reply
      2
      • raven-worxR raven-worx

        @porsol
        translating (adding for top/left, subtracting for bottom/right) by the half stroke width should do it:

        qFloor( pen.widthF() / 2.0 )
        

        See Qt's coordinate system.

        P Offline
        P Offline
        porsol
        wrote on last edited by
        #3

        @raven-worx said in How to calculate setPen+drawPath dimensions?:

        translating (adding for top/left, subtracting for bottom/right) by the half stroke width should do it:

        Unfortunately no, it doesn't. Out of the width of the brush less than half goes to actual outline, the rest goes under the text and inside the letters. So when N2 == qFloor( pen.widthF() / 2.0 ) - it gobbles up some free space on top taking it from the bottom, N == qFloor( pen.widthF() / 2.0 ) does the same horizontally.

        raven-worxR 1 Reply Last reply
        0
        • P porsol

          @raven-worx said in How to calculate setPen+drawPath dimensions?:

          translating (adding for top/left, subtracting for bottom/right) by the half stroke width should do it:

          Unfortunately no, it doesn't. Out of the width of the brush less than half goes to actual outline, the rest goes under the text and inside the letters. So when N2 == qFloor( pen.widthF() / 2.0 ) - it gobbles up some free space on top taking it from the bottom, N == qFloor( pen.widthF() / 2.0 ) does the same horizontally.

          raven-worxR Offline
          raven-worxR Offline
          raven-worx
          Moderators
          wrote on last edited by
          #4

          @porsol
          i am afraid i don't quite understand your issue then. can you post a screenshot?

          --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
          If you have a question please use the forum so others can benefit from the solution in the future

          P 1 Reply Last reply
          0
          • raven-worxR raven-worx

            @porsol
            i am afraid i don't quite understand your issue then. can you post a screenshot?

            P Offline
            P Offline
            porsol
            wrote on last edited by porsol
            #5

            @raven-worx alt text

            I switched the brush to red and put another smaller black brush for visibility.
            To see the difference you should zoom the pic like 1000% in non-browser image-viewer.
            green vLine is separator between QLabels

            pen.width() == 10
            N = N2 = pen.width() / 2 # int still
            x = 0 + N
            y = self.fontMetrics().ascent() + N2
            
            # top example in pic
            # not enough pixels in width, too much in height
            self.setFixedSize(self.fontMetrics().width(self.text) + N*2,text_height + N*2)
            text_path.addText(x, y, font, text)
            painter.drawText(x, y, text)
            
            # bottom example in pic
            # adding/subtracting arbitrary pixels shows how it looks whole
            self.setFixedSize(self.fontMetrics().width(self.text) + N*2 + 10,text_height + N*2)
            text_path.addText(x+5, y-5, font, text)
            painter.drawText(x+5, y-5, text)
            

            I can with trial and error find the exact number of px I should add/subtract for a specific font and outline_width - but that doesn't work for me. Font and outline should be adjustable.

            1 Reply Last reply
            0
            • P porsol

              I want to paint outline around text in QLabel.
              I can't start with x=0, because left side of the outline will be lost, I also have to add few pixels to y, otherwise outline at the bottom will be lost. But how do I calculate this offset precisely?
              Adding outline_width to all sides is taking up unnecessary space because of 10px brush only 3-5 goes into outline, the rest is hidden behind/inside letters; I need QLabel to take up space as little as possible.

              N = ?
              N2 = ?
              
              self.setFixedSize(self.fontMetrics().width(self.text) + N*2, self.fontMetrics().height() + N2*2)
              
              x = 0 + N
              y = self.fontMetrics().ascent() + N2
              
              outline_width = 10
              
              painter = QPainter(self)
              text_path = QPainterPath()
              text_path.addText(x, y, font, text)
              
              outline_brush = QBrush(QColor(0, 0, 0, alpha), Qt.SolidPattern)		
              outline_pen = QPen(outline_brush, outline_width, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)
              
              painter.setPen(outline_pen)
              painter.drawPath(text_path)
              
              painter.setPen(QColor(255, 255, 255, 255))
              painter.drawText(x, y, text)
              
              raven-worxR Offline
              raven-worxR Offline
              raven-worx
              Moderators
              wrote on last edited by
              #6

              @porsol said in How to calculate setPen+drawPath dimensions?:

              I need QLabel to take up space as little as possible.

              according to your screenshot you can calculate the values which take up the inner padding by the following:

              int labelMargin = label->margin();
              int labelIndent = label->indent();
              int frameWidth = label->frameWidth();
              
              // see http://doc.qt.io/qt-5/qlabel.html#indent-prop
              if( labelIndent < 0 )
              {
                  if( frameWidth <= 0 )
                      labelIndent = 0;
                  else
                  {
                      QFontMetrics fm(label->font());
                      labelIndent = ( fm.width("x") / 2.0 );
                  }
              }
              

              --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
              If you have a question please use the forum so others can benefit from the solution in the future

              1 Reply Last reply
              0

              • Login

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