Reputation: 23
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
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?
Upvotes: 2
Views: 1889
Reputation: 6805
I think it's better to answer here than in comments.
You just have to set the following stylesheet for your QPushButton
to make it invisible:
QPushButton
{
border: none;
}
I've made the test and it worked well.
For the tests, I have set the wrapping widget's background-image
property. I also did another test with the background-color
property instead. It worked in both cases (whether the background is a plain color or a picture/photo).
I hope it helps.
EDIT:
I have written a widget that performs what you want. And I also provided a windows in order to make the below example minimal and complete so that you can reproduce it.
I have tested it and it worked well.
test.h:
#ifndef TEST_H
#define TEST_H
#include <QMainWindow>
#include <QPushButton>
class WidgetWithHiddenButton : public QWidget
{
Q_OBJECT
protected:
QPushButton * invisible_button;
public:
WidgetWithHiddenButton(QWidget * parent = nullptr);
QPushButton * getButton();
protected:
void paintEvent(QPaintEvent *) override;
};
class TestWindow final : public QMainWindow
{
Q_OBJECT
private:
WidgetWithHiddenButton * widget;
public:
TestWindow();
};
#endif // TEST_H
test.cpp:
#include "test.h"
#include <QApplication>
#include <QStyleOption>
#include <QPainter>
#include <QVBoxLayout>
WidgetWithHiddenButton::WidgetWithHiddenButton(QWidget * parent) : QWidget(parent)
{
// build your widget as you want.
invisible_button = new QPushButton("Here is a button", this);
QVBoxLayout * lay = new QVBoxLayout;
QHBoxLayout * inner_lay = new QHBoxLayout;
inner_lay->addStretch();
inner_lay->addWidget(invisible_button);
inner_lay->addStretch();
lay->addLayout(inner_lay);
this->setLayout(lay);
this->setStyleSheet("WidgetWithHiddenButton {background-image: url(path_to_image/image.jpg);}");
invisible_button->setStyleSheet("QPushButton {border: none;}");
}
QPushButton * WidgetWithHiddenButton::getButton()
{
return invisible_button;
}
void WidgetWithHiddenButton::paintEvent(QPaintEvent *)
{
QStyleOption opt;
opt.init(this);
QPainter p(this);
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}
TestWindow::TestWindow()
{
resize(500, 300);
widget = new WidgetWithHiddenButton;
this->setCentralWidget(widget);
connect(widget->getButton(), &QPushButton::clicked, qApp, &QApplication::quit);
}
int main(int argc, char ** argv)
{
QApplication app(argc, argv);
TestWindow tw;
tw.show();
return app.exec();
}
Feel free to adapt it (especially by changing the class name because WidgetWithHiddenButton
is very ugly :) ).
Notes:
QPushButton::clicked()
signal to the QApplication::quit()
slot in order to perform an action when we click on the area of the button.paintEvent()
method because it is needed when using Q_OBJECT
macro alongside stylesheets over a custom QWidget
as the documentation mentioned.Upvotes: 2
Reputation: 8419
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.
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;}");
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);
}
};
The given example produces a window with a background and a 100x100px invisible clickable area positioned at (100, 100):
Upvotes: 4