Search code examples
c++qt5qwidgetqpushbutton

How to make invisible button on widget with background image?


I want to make a simple application with invisible button.

I set background image for my widget by UI property styleSheet and Resources -
border-image:url(:/image.jpg). I always get something like this

this

and then I try to add button on it

I was trying with

ui->pushButton->setStyleSheet("QPushButton{background: transparent;}");
ui->pushButton->setStyleSheet("background-color: rgba(255, 255, 255, 0);");

and it works with buttons on default background, but not in my case.

Every button that I add takes default parent background image. I dont want to see any hints of a button, but when I click on an area to be able to perform some functionality.

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->centralWidget->setStyleSheet("background-image:url(:image.jpg)");
    ui->pushButton->setStyleSheet("QPushButton{border:none;}");
}

Code an above makes button flat, but it duplicate background image from parent widget anyway.

Have you any idea how to resolve it?


Solution

  • Cause

    A common misconception is that when a stylesheet without a selector is applied to an element, then it is used only for that element. In fact all element's children are styled as well. Thus a selector should be used to achieve the expected result.

    Solution

    I would suggest you to change this line in your code

    ui->centralWidget->setStyleSheet("background-image:url(:image.jpg)");
    

    to

    ui->centralWidget->setStyleSheet(".QWidget { background-image:url(:image.jpg) }");
    

    Important: Note the dot before QWidget. It means style the QWidget, but exclude the subclasses. This is necessary because QPushButton is a subclass of QWidget and otherwise would be affected as well.

    Then you can set the pushButton's backgroung color to transparent as you do with

    ui->pushButton->setStyleSheet("QPushButton{background: transparent;}");
    

    Example

    Here is a simple example I have prepared for you in order to demonstrate the proposed solution (requires cat.png in the resource file under pix/images):

    #include <QMainWindow>
    #include <QWidget>
    #include <QPushButton>
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    public:
        explicit MainWindow(QWidget *parent = nullptr) :
            QMainWindow(parent) {
            auto *widget = new QWidget(this);
            auto *button = new QPushButton(widget);
    
            widget->setStyleSheet(".QWidget {"
                                  " background-image:url(':/pix/images/cat.png');"
                                  " background-repeat: no-repeat;"
                                  "}");
    
            button->setStyleSheet(".QPushButton {"
                                  " background-color: transparent"
                                  "}");
            button->move(100, 100);
            button->resize(100, 100);
    
            connect(button, &QPushButton::clicked, [](){
                qDebug("clicked");
            });
    
            setCentralWidget(widget);
            resize(600, 480);
        }
    };
    

    Result

    The given example produces a window with a background and a 100x100px invisible clickable area positioned at (100, 100):

    Window with a background and an invisible button