Search code examples
c++qtqtstylesheetsqt5.6

QWidget's background applied to all its QWidget children


I chose to use Qt to manage the GUI of a project I am working on.

After finding how to apply a picture at the bottom of my QWidget, I noticed that it has an impact on all the components that are added to it.

Whatever the style applied through the setStyleSheet method or even with a QPixmap, the background of these elements is always the image defined for the QWidget container.

How can I avoid this behavior ?

Here is my code :

MainMenu::MainMenu(QWidget* Parent, const QPoint& Position, const QSize& Size) : QWidget(Parent) {

    QString qwidgetStyle = "QWidget {background-image: url(background.jpg); border: 5px solid rgba(3, 5, 28, 1);}";
    QString buttonStyle = "color: rgba(73, 123, 176, 1); font-size:30px; background-color: rgba(73, 123, 176, 1);";

    move(Position);
    resize(Size);   
    setStyleSheet(qwidgetStyle);

    // Menu title
    QLabel *title = new QLabel(this);
    title->setText("Menu");
    title->setStyleSheet(buttonStyle);
    title->setAlignment(Qt::AlignCenter);

    // Menu buttons
    // Play
    buttonPlay = new QPushButton("Play");
    (*buttonPlay).setEnabled(true);
    (*buttonPlay).setStyleSheet(buttonStyle);
    connect(buttonPlay, SIGNAL(clicked()), this, SLOT(handleButton()));
    // Option
    buttonOptions = new QPushButton("Options", this);
    (*buttonOptions).setEnabled(true);
    (*buttonOptions).setGeometry(250, 175, 100, 50);
    (*buttonOptions).setStyleSheet(buttonStyle);
    connect(buttonOptions, SIGNAL(clicked()), this, SLOT(handleButton()));
    // Quit
    buttonQuit = new QPushButton("Quit", this);
    (*buttonQuit).setEnabled(true);
    (*buttonQuit).setGeometry(250, 275, 100, 50);
    (*buttonQuit).setStyleSheet(buttonStyle);
    connect(buttonQuit, SIGNAL(clicked()), this, SLOT(handleButton()));

    // Layout
    QGridLayout *layout = new QGridLayout;
    layout->setMargin(50);
    layout->addWidget(title, 0, 0, 1, 5);
    layout->addWidget(buttonPlay, 3, 1, 2, 3);
    layout->addWidget(buttonOptions, 4, 1, 2, 3);
    layout->addWidget(buttonQuit, 5, 1, 2, 3);
    setLayout(layout);

    show();
}

Solution

  • The behavior you encountered is perfectly normal, because of the following lines :

    QString qwidgetStyle = "QWidget {background-image: url(background.jpg); border: 5px solid rgba(3, 5, 28, 1);}";
    ...
    setStyleSheet(qwidgetStyle);
    

    Here, you just told Qt to apply qwidgetstyle to every QWidget of your application, with the keyword QWidget. That's why in Qt, you better set a name to your object if you want to apply a style to this particular object.

    In your code, QLabel and QPushButton both inherit from QWidget, so they will have the style you defined for a QWidget, unless you name them or you specify the style for each one.

    If you want to set style sheet for your MainMenu which inherits directly from QWidget (which is what you are doing in the first place), you have to set a name, and then apply the style :

    setObjectName("MainMenu");
    QString qwidgetStyle = "QWidget#MainMenu {background-image: url(background.jpg); border: 5px solid rgba(3, 5, 28, 1);}";
    setStyleSheet(qwidgetStyle);  // here, only your MainMenu will have the style "qwidgetstyle"
    

    Notice that you can, for example, set the same style sheet for every QWidget, and only add a particular color for your MainMenu :

    // this is in a CSS, but you can apply it directly from the MainMenu constructor of course
    QWidget, QWidget#MainMenu {
        background-image: url(background.jpg); 
        border: 5px solid rgba(3, 5, 28, 1);
    } // aplied to all QWidget
    
    QWidget#MainMenu { 
        color : #9b9b9b; // a nice grey, only applied to MainMenu
    }
    

    Again, be specific when using style sheets or you will end up having strange colors/alignments everywhere in your application.