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 mask a widget by a single color for transparency

How to mask a widget by a single color for transparency

Scheduled Pinned Locked Moved Solved General and Desktop
14 Posts 3 Posters 3.0k 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.
  • L Offline
    L Offline
    lachdanan
    wrote on last edited by lachdanan
    #1

    Hi,

    I draw a hollow circle as progress bar, and it works well. I set the background of the control to pink. I want to mask the control/widget using this color so the pink area becomes transparent. Is this possible? When I try this, it crashes saying you can't destroy paint event or something:

    # Draw ring
    pen = QPen(QBrush(self.gradient), self.thickness)
    pen.setCapStyle(Qt.FlatCap)
    p.setPen(pen)
    rect2 = QRectF(self.thickness/2, self.thickness/2, self.radius - self.thickness, self.radius - self.thickness)
    p.drawArc(rect2, 180 * 16, -angle * 16);
    
    # Draw text
    f = QFont("Eras Bold ITC")
    f.setPointSize(10)
    p.setFont(f)
    p.setPen(self.textColor)
    p.drawText(self.rect, Qt.AlignCenter, "{0}%".format(self.currentValue))
    
    painter = QPainter(self)
    painter.drawImage(0, 0, img)
    
    #pixmap = QPixmap()
    #mask = pixmap.createMaskFromColor(self.bgColor, Qt.MaskOutColor)
    #p.setMask(mask)
    
    p.end()
    painter.end()
    

    How can I achieve this?

    Also if I use Qt.transparent then I get this kind of artifact:
    alt text

    Thanks in advance.

    1 Reply Last reply
    0
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi
      Normally there is no issue paint with a transparent color.
      The QColor ctor takes a 4 argument ( the 100 here)

      alt text

      However, the image you show seems a bit like its not working normally.
      What platform is this on?

      Do you use the widget inside your app or is it like a window ?

      D 1 Reply Last reply
      0
      • L Offline
        L Offline
        lachdanan
        wrote on last edited by
        #3

        Thanks, this is on win10 64bit. I am using the widget directly by calling .show(), but it's parented to another app written in C++ but also uses qt.

        For another widget I used setMash to set rectangular masks and it did work. So maybe transparent color doesn't work but if I can create a proper mask from my bg color, then that's better.

        1 Reply Last reply
        0
        • L Offline
          L Offline
          lachdanan
          wrote on last edited by
          #4

          I found this QGraphicsOpacityEffect. Do you guys think it might help me? It seems to allow some sort of alpha masking. There should be a simple way to have my drawn image to create an opacity mask and use this for transparency? For example a single color I paint my bg so it will have varying opacity.

          1 Reply Last reply
          0
          • mrjjM Offline
            mrjjM Offline
            mrjj
            Lifetime Qt Champion
            wrote on last edited by mrjj
            #5

            Hi
            Is the widget within your app so you want to see the mainwin through it
            or is it a window and you want to see the desktop through it ?

            It a loader like ?
            alt text

            For a loader type, i did this in widget

            LoadingOverlay::LoadingOverlay(QWidget *parent)
                : OverlayWidget(parent)
            {
                setAttribute(Qt::WA_TranslucentBackground);
                setAttribute(Qt::WA_TransparentForMouseEvents);
            }
            
            void LoadingOverlay::paintEvent(QPaintEvent *)
            {
                QPainter p(this);
                p.fillRect(rect(), QColor(100, 100, 100, 128));
                p.setPen(QColor(200, 200, 255, 255));
                p.setFont(QFont("arial,helvetica", 48));
                p.drawText(rect(), "Loading...", Qt::AlignHCenter | Qt::AlignVCenter);
            }
            
            L 1 Reply Last reply
            1
            • mrjjM mrjj

              Hi
              Is the widget within your app so you want to see the mainwin through it
              or is it a window and you want to see the desktop through it ?

              It a loader like ?
              alt text

              For a loader type, i did this in widget

              LoadingOverlay::LoadingOverlay(QWidget *parent)
                  : OverlayWidget(parent)
              {
                  setAttribute(Qt::WA_TranslucentBackground);
                  setAttribute(Qt::WA_TransparentForMouseEvents);
              }
              
              void LoadingOverlay::paintEvent(QPaintEvent *)
              {
                  QPainter p(this);
                  p.fillRect(rect(), QColor(100, 100, 100, 128));
                  p.setPen(QColor(200, 200, 255, 255));
                  p.setFont(QFont("arial,helvetica", 48));
                  p.drawText(rect(), "Loading...", Qt::AlignHCenter | Qt::AlignVCenter);
              }
              
              L Offline
              L Offline
              lachdanan
              wrote on last edited by
              #6

              @mrjj Thanks a lot, it's the first option you mentioned.

              mrjjM 1 Reply Last reply
              0
              • L lachdanan

                @mrjj Thanks a lot, it's the first option you mentioned.

                mrjjM Offline
                mrjjM Offline
                mrjj
                Lifetime Qt Champion
                wrote on last edited by mrjj
                #7

                @lachdanan
                Ok. that should work then when widget is inside.
                try with
                setAttribute(Qt::WA_TranslucentBackground);

                Do note that the sample uses
                setGraphicsEffect(new QGraphicsBlurEffect);
                to give that blur effect but its not needed.

                However, the pixel artifacts in your image kinda seem like there might
                be some driver issue.

                Is it Intel GFX ?

                Also, can you run c++ code ?
                (To inspect the example)

                1 Reply Last reply
                1
                • L Offline
                  L Offline
                  lachdanan
                  wrote on last edited by lachdanan
                  #8

                  Thanks I tried all these like this in my constructor:

                          self.setAttribute(Qt.WA_NoSystemBackground)
                          self.setAttribute(Qt.WA_TranslucentBackground)
                          self.setAttribute(Qt.WA_PaintOnScreen)
                          self.setStyleSheet("background-color: rgba(0,0,0,0)")
                  

                  then did my painting of the hollow circle, but still I am getting black background or artifact, depending on whether I fill the background. Mine is rtx 2080. Not sure why this happens.

                  Masking works fine but like I mentioned it's 1bit so it's very harsh and looks aliased. I wanted to have a photoshop like transparency by setting a mask color or painting over a transparent BG. Maybe qt can't do this?

                  Also can't run C++ code, have to convert it to python/pyside2.

                  1 Reply Last reply
                  0
                  • L Offline
                    L Offline
                    lachdanan
                    wrote on last edited by
                    #9

                    Ok I tried this now:

                    window = QtWidgets.QWidget()
                    window.setWindowFlags(QtCore.Qt.FramelessWindowHint)
                    window.setAttribute(QtCore.Qt.WA_TranslucentBackground)
                    window.show()
                    
                    layout = QtWidgets.QVBoxLayout(window)
                    layout.addWidget(myWidgetControl)
                    

                    Even now, I am getting the whole thing semi transparent. I removed the the link that paints the whole background, and also tried Qt.transparent, but then I get the artifact in the first post.

                    This line:

                    p.fillRect(img.rect(), Qt.transparent)
                    

                    If I am not wrong, when I create my own window, the actual app I am running this qt code shouldn't interfere if anything.

                    1 Reply Last reply
                    0
                    • mrjjM mrjj

                      Hi
                      Normally there is no issue paint with a transparent color.
                      The QColor ctor takes a 4 argument ( the 100 here)

                      alt text

                      However, the image you show seems a bit like its not working normally.
                      What platform is this on?

                      Do you use the widget inside your app or is it like a window ?

                      D Offline
                      D Offline
                      Dnyaneshwar
                      wrote on last edited by
                      #10

                      @mrjj just replace rgb() to rgba()

                      L 1 Reply Last reply
                      0
                      • D Dnyaneshwar

                        @mrjj just replace rgb() to rgba()

                        L Offline
                        L Offline
                        lachdanan
                        wrote on last edited by
                        #11

                        @Dnyaneshwar where?

                        1 Reply Last reply
                        0
                        • L Offline
                          L Offline
                          lachdanan
                          wrote on last edited by
                          #12

                          Also I did the same Qt.transparency thing and placed the window outside the actual app, so I can see regular windows env in the background, and I still see the artifact in the first post. I can see some of the background, a bit readible but still under this massive noisy pink artifact.

                          1 Reply Last reply
                          0
                          • L Offline
                            L Offline
                            lachdanan
                            wrote on last edited by lachdanan
                            #13

                            Also another thing that might help or not is, I have been able to create a QFrame and it perfectly shows what's underneath, inside the frame. So how does that work? How can that control achieve through transparency inside? Is it masks? If so, that makes sense and doesn't help my case.

                            This is what I get, when I stack both the frame and my widget with semi transparent BG:
                            alt text

                            L 1 Reply Last reply
                            0
                            • L lachdanan

                              Also another thing that might help or not is, I have been able to create a QFrame and it perfectly shows what's underneath, inside the frame. So how does that work? How can that control achieve through transparency inside? Is it masks? If so, that makes sense and doesn't help my case.

                              This is what I get, when I stack both the frame and my widget with semi transparent BG:
                              alt text

                              L Offline
                              L Offline
                              lachdanan
                              wrote on last edited by lachdanan
                              #14

                              @lachdanan Ok I managed to solve this issue.

                              Instead of QPainter(img), I used QPainter(self) and it works great.

                              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