0
votes

enter image description hereI am trying to add a QPushButton in my GUI, such that the pushbutton is party outside the window frame. A good comparison is the scan button in CleanMyMac (see attached image).

I have tried making the main window transparent, then adding a background image that is transparent only in the bottom, making the window look smaller than it is. However, this creates a lot of other complications such as window frame shadow (which does not seem to disappear entirely with:

mainWindow->setWindowFlags(Qt::FramelessWindowHint | 
                           Qt::NoDropShadowWindowHint)

Furthermore, with the mentioned approach, the window cannot be expanded fully, I'd rather have a small part of the button being outside of display (as CleanMyMac).

Any suggestions?

2

2 Answers

3
votes

You could use QWidget::setMask. By way of an example consider the following class...

class widget: public QWidget {
  using super = QWidget;
public:
  explicit widget (QWidget *parent = nullptr)
    : super(parent)
    , m_button("Just hanging here...")
    {
      setLayout(&m_layout);
      m_layout.addWidget(&m_button, 1, 1);
      m_layout.setRowStretch(0, 1);
      m_layout.setColumnStretch(0, 1);
      m_layout.setColumnStretch(2, 1);
    }
protected:
  virtual void resizeEvent (QResizeEvent *event) override
    {
      super::resizeEvent(event);
      QRect r(rect());
      r.setBottom(m_button.geometry().top());
      QRegion region(r);
      region |= m_button.geometry();
      setMask(region);
    }
private:
  QGridLayout m_layout;
  QPushButton m_button;
};

The above gives something like...

enter image description here

Not terribly useful as it stands but it demonstrates the technique.

2
votes

I'd make the "scan" button a top level widget (i.e. button->setWindowFlags(Qt::Window); ) make it frameless and borderless, assign a mask to the widget if you want it round and then updating its geometry when the main window moves.

So it's basically 2 windows on top of each other that move together