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 remove weird graphic effects from widget?
Forum Updated to NodeBB v4.3 + New Features

How to remove weird graphic effects from widget?

Scheduled Pinned Locked Moved Solved General and Desktop
5 Posts 2 Posters 1.9k Views 2 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.
  • D Offline
    D Offline
    deleted385
    wrote on last edited by deleted385
    #1

    Here in the .png I've pinpointed some of these effects:

    cap1.png

    Holes, vertical/horizontal lines appear as I resize widgets in QSplitter. As soon as the MainWindow loses focus, those weird effects goes away! Here in the animation see each time I resized those widgets, weird effects appeared and after that I clicked somewhere else, not on the window, those weird effects vanished:

    x1.gif

    Here's the code for the RoundWidget, all child widgets inherits it and add contents via those functions:

    RoundWidget::RoundWidget(QWidget *parent) : QWidget(parent){
        layout = new QVBoxLayout(this);
        toolbar = new QHBoxLayout;
        layout->addLayout(toolbar);
        header = new QLabel(this);
        header->setFont(QFont(header->font().family(), -1, QFont::Bold, false));
        auto spacer = new QWidget(this);
        spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
        toolbar->addWidget(header);
        toolbar->addWidget(spacer);
        auto separator = new QFrame;
        separator->setFrameShape(QFrame::HLine);
        separator->setFrameShadow(QFrame::Sunken);
        layout->addWidget(separator);
        setPalette(QPalette(Qt::white));
        setAutoFillBackground(true);
        setLayout(layout);
    }
    void RoundWidget::addAction(QWidget * action) { toolbar->addWidget(action); }
    void RoundWidget::addContent(QWidget * content) { layout->addWidget(content); }
    void RoundWidget::setHeader(const QString & text) { header->setText(text); }
    void RoundWidget::resizeEvent(QResizeEvent*){
        int radius = 10;
        QPainterPath path;
        path.addRoundedRect(rect(), radius, radius);
        setMask(QRegion(path.toFillPolygon().toPolygon()));
    }
    

    in the top-level widget, these are the lines for graphics effect:

    auto effect = new QGraphicsDropShadowEffect;
    effect->setBlurRadius(15);
    effect->setColor(Qt::black);
    effect->setOffset(0,0);
    setGraphicsEffect(effect);
    

    How to fix?

    EDIT
    Same sharp edge problem for frameless rounded corner window:

    cap2.PNG

    and black border isn't visible on corners.

    1 Reply Last reply
    0
    • M Offline
      M Offline
      mpergand
      wrote on last edited by mpergand
      #4

      #define ShadowWidth 20
      
      class RoundedWidget : public QWidget
      {
          public:
              
              RoundedWidget(QWidget *parent=nullptr) : QWidget(parent)
              {
              setAutoFillBackground(false); 
              setContentsMargins(ShadowWidth,ShadowWidth,ShadowWidth,ShadowWidth);
              
              auto borderEffect = new QGraphicsDropShadowEffect;
              borderEffect->setBlurRadius(ShadowWidth);
              borderEffect->setColor(QColor(0,0,0,150));
              borderEffect->setOffset(0,0);
              setGraphicsEffect(borderEffect);
              }
              
          protected:
              
           void  paintEvent(QPaintEvent* ev)
              {
              QPainter painter(this);
              painter.setRenderHint(QPainter::Antialiasing);
              const QPalette& palette=this->palette();
              QColor backgroundColor=palette.color(QPalette::Window);
              QPainterPath path;
              path.addRoundedRect(contentsRect(), 10,10);
              painter.fillPath(path,backgroundColor);
              }
      };
      
      Widget::Widget(QWidget *parent) : QWidget(parent)
      {
          setWindowFlags(Qt::FramelessWindowHint|Qt::NoDropShadowWindowHint|Qt::Popup);
          setAttribute(Qt::WA_TranslucentBackground);
          
          // layout for InnerWidget
          auto vLayout=new QVBoxLayout;
          vLayout->setContentsMargins(0,0,0,0);
          setLayout(vLayout);
          
          // InnerWidget
          auto innerWidget=new RoundedWidget;
          vLayout->addWidget(innerWidget);
          
          // layout for splitter
          auto iLayout=new QVBoxLayout;
          iLayout->setContentsMargins(ShadowWidth,ShadowWidth,ShadowWidth,ShadowWidth);
          innerWidget-> setLayout(iLayout);
          
          // add splitter
          auto splitter=new QSplitter(Qt::Horizontal);
          splitter->setHandleWidth(14);
          iLayout->addWidget(splitter);
          
          // add widgets to splitter
          QTreeView *treeview = new QTreeView;
          QTextEdit *textedit = new QTextEdit;
          textedit->setText("Note: This function will apply the effect on itself and all its children.");
          splitter->addWidget(textedit);
          splitter->addWidget(treeview);
      
          // effect for splitter
          auto effect = new QGraphicsDropShadowEffect;
          effect->setBlurRadius(6);
          effect->setColor(QColor(0,0,0,150));
          effect->setOffset(1,1);
          
          splitter->setGraphicsEffect(effect);
      }
      

      No gliches :)
      Note: tested on MacOs only Qt 5.12

      D 1 Reply Last reply
      1
      • M Offline
        M Offline
        mpergand
        wrote on last edited by mpergand
        #2

        After some tests, the gliches appear when the effect is applied to the top level widget, disappear when applied to the splitter.

        For the frameless window, you need to set a contentsMargins for the shadow to draw correctly.
        See https://forum.qt.io/topic/98385/does-qt-support-mac-style-pop-out-widgets/4

        D 1 Reply Last reply
        1
        • M mpergand

          After some tests, the gliches appear when the effect is applied to the top level widget, disappear when applied to the splitter.

          For the frameless window, you need to set a contentsMargins for the shadow to draw correctly.
          See https://forum.qt.io/topic/98385/does-qt-support-mac-style-pop-out-widgets/4

          D Offline
          D Offline
          deleted385
          wrote on last edited by deleted385
          #3

          @mpergand, with that change, a solid line keeps blinking (in between Query/Log and Result sections) as I resize and when I release mouse solid black line remains there if I release it timely:

          x2.gif

          do you also get that blinking line/shadow?

          In the resizeEvent of both RoundWidget and toplevel round window I've these now:

          void RoundWidget::resizeEvent(QResizeEvent*){
              int radius = 10;
              QBitmap b(width(), height());
              b.fill(QColor(Qt::color0));
              QPainter painter(&b);
              painter.setRenderHint(QPainter::Antialiasing);
              painter.setBrush(Qt::color1);
              painter.drawRoundedRect(rect(), radius, radius);
              setMask(b);
          //    QPainterPath path;
          //    path.addRoundedRect(rect(), radius, radius);
          //    setMask(QRegion(path.toFillPolygon().toPolygon()));
          }
          

          I can see the black outer border around the top level window/widget BUT all those inner/outer rounded edges are still pixelated.

          1 Reply Last reply
          0
          • M Offline
            M Offline
            mpergand
            wrote on last edited by mpergand
            #4

            #define ShadowWidth 20
            
            class RoundedWidget : public QWidget
            {
                public:
                    
                    RoundedWidget(QWidget *parent=nullptr) : QWidget(parent)
                    {
                    setAutoFillBackground(false); 
                    setContentsMargins(ShadowWidth,ShadowWidth,ShadowWidth,ShadowWidth);
                    
                    auto borderEffect = new QGraphicsDropShadowEffect;
                    borderEffect->setBlurRadius(ShadowWidth);
                    borderEffect->setColor(QColor(0,0,0,150));
                    borderEffect->setOffset(0,0);
                    setGraphicsEffect(borderEffect);
                    }
                    
                protected:
                    
                 void  paintEvent(QPaintEvent* ev)
                    {
                    QPainter painter(this);
                    painter.setRenderHint(QPainter::Antialiasing);
                    const QPalette& palette=this->palette();
                    QColor backgroundColor=palette.color(QPalette::Window);
                    QPainterPath path;
                    path.addRoundedRect(contentsRect(), 10,10);
                    painter.fillPath(path,backgroundColor);
                    }
            };
            
            Widget::Widget(QWidget *parent) : QWidget(parent)
            {
                setWindowFlags(Qt::FramelessWindowHint|Qt::NoDropShadowWindowHint|Qt::Popup);
                setAttribute(Qt::WA_TranslucentBackground);
                
                // layout for InnerWidget
                auto vLayout=new QVBoxLayout;
                vLayout->setContentsMargins(0,0,0,0);
                setLayout(vLayout);
                
                // InnerWidget
                auto innerWidget=new RoundedWidget;
                vLayout->addWidget(innerWidget);
                
                // layout for splitter
                auto iLayout=new QVBoxLayout;
                iLayout->setContentsMargins(ShadowWidth,ShadowWidth,ShadowWidth,ShadowWidth);
                innerWidget-> setLayout(iLayout);
                
                // add splitter
                auto splitter=new QSplitter(Qt::Horizontal);
                splitter->setHandleWidth(14);
                iLayout->addWidget(splitter);
                
                // add widgets to splitter
                QTreeView *treeview = new QTreeView;
                QTextEdit *textedit = new QTextEdit;
                textedit->setText("Note: This function will apply the effect on itself and all its children.");
                splitter->addWidget(textedit);
                splitter->addWidget(treeview);
            
                // effect for splitter
                auto effect = new QGraphicsDropShadowEffect;
                effect->setBlurRadius(6);
                effect->setColor(QColor(0,0,0,150));
                effect->setOffset(1,1);
                
                splitter->setGraphicsEffect(effect);
            }
            

            No gliches :)
            Note: tested on MacOs only Qt 5.12

            D 1 Reply Last reply
            1
            • M mpergand

              #define ShadowWidth 20
              
              class RoundedWidget : public QWidget
              {
                  public:
                      
                      RoundedWidget(QWidget *parent=nullptr) : QWidget(parent)
                      {
                      setAutoFillBackground(false); 
                      setContentsMargins(ShadowWidth,ShadowWidth,ShadowWidth,ShadowWidth);
                      
                      auto borderEffect = new QGraphicsDropShadowEffect;
                      borderEffect->setBlurRadius(ShadowWidth);
                      borderEffect->setColor(QColor(0,0,0,150));
                      borderEffect->setOffset(0,0);
                      setGraphicsEffect(borderEffect);
                      }
                      
                  protected:
                      
                   void  paintEvent(QPaintEvent* ev)
                      {
                      QPainter painter(this);
                      painter.setRenderHint(QPainter::Antialiasing);
                      const QPalette& palette=this->palette();
                      QColor backgroundColor=palette.color(QPalette::Window);
                      QPainterPath path;
                      path.addRoundedRect(contentsRect(), 10,10);
                      painter.fillPath(path,backgroundColor);
                      }
              };
              
              Widget::Widget(QWidget *parent) : QWidget(parent)
              {
                  setWindowFlags(Qt::FramelessWindowHint|Qt::NoDropShadowWindowHint|Qt::Popup);
                  setAttribute(Qt::WA_TranslucentBackground);
                  
                  // layout for InnerWidget
                  auto vLayout=new QVBoxLayout;
                  vLayout->setContentsMargins(0,0,0,0);
                  setLayout(vLayout);
                  
                  // InnerWidget
                  auto innerWidget=new RoundedWidget;
                  vLayout->addWidget(innerWidget);
                  
                  // layout for splitter
                  auto iLayout=new QVBoxLayout;
                  iLayout->setContentsMargins(ShadowWidth,ShadowWidth,ShadowWidth,ShadowWidth);
                  innerWidget-> setLayout(iLayout);
                  
                  // add splitter
                  auto splitter=new QSplitter(Qt::Horizontal);
                  splitter->setHandleWidth(14);
                  iLayout->addWidget(splitter);
                  
                  // add widgets to splitter
                  QTreeView *treeview = new QTreeView;
                  QTextEdit *textedit = new QTextEdit;
                  textedit->setText("Note: This function will apply the effect on itself and all its children.");
                  splitter->addWidget(textedit);
                  splitter->addWidget(treeview);
              
                  // effect for splitter
                  auto effect = new QGraphicsDropShadowEffect;
                  effect->setBlurRadius(6);
                  effect->setColor(QColor(0,0,0,150));
                  effect->setOffset(1,1);
                  
                  splitter->setGraphicsEffect(effect);
              }
              

              No gliches :)
              Note: tested on MacOs only Qt 5.12

              D Offline
              D Offline
              deleted385
              wrote on last edited by deleted385
              #5

              @mpergand, First, I've removed the resizeEvent in mainwindow and RoundWidget, added your paintEvent in both of mainwindow and RoundWidget. In RoundWidget, ShadowWidth 2, 20 makes a huge gap in Windows 10. Added these:

              setWindowFlags(Qt::FramelessWindowHint | Qt::NoDropShadowWindowHint);
              setAttribute(Qt::WA_TranslucentBackground);
              

              in mainwindow and with these changes, those round edges are smooth, as expected, BUT I still have the blinking effect:

              x3.gif

              maybe it's a windows 10 problem or because of multiple splitter. Log and Query are inside splitter1 and splitter2 contains Objects, splitter1 and Result. No idea why does it blink on that spot, that spot is the end point of splitter1.

              Thanks for that paintEvent that smoothened those round edges.

              EDIT
              Got that! that's because both of those splitters had that effect. I've to remove effect from splitter1 like this split1->setGraphicsEffect(0) and with that line in QueryWidget it's perfect:

              x4.gif

              Thanks once again.

              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