0

I have a simple widget which uses an image as background and contains some child widgets. When I create it without a parent (as a dialogue) everything is perfect. But if I create it as a child of some other widget, I can't see the background.

Can I use QWidget::setPalette to set the background for a child widget?

If not, how would you accomplish this?

#include <QWidget>
#include <QPixmap>
#include <QPalette>
#include <QLabel>

class Panel : public QWidget
{
    Q_OBJECT
public:
    explicit Panel(QWidget *parent = 0)  QWidget(parent)
    {
        bgnd_ = new QPixmap(":/path/to/image.png");
        PaintBackground();

        QLabel* lbl = new QLabel("SomeChild",this);
    }

private:
    void PaintBackground()
    {
        QPixmap bgnd = bgnd_->scaled(this->size(), Qt::IgnoreAspectRatio);

        QPalette palette;
        palette.setBrush(QPalette::Background, bgnd);
        this->setPalette(palette);
    }
protected:
    void resizeEvent(QResizeEvent *event)
    {
        QWidget::resizeEvent(event);
        PaintBackground();
    }

private:
    QPixmap* bgnd_;
};

If I create this widget as an independent object with no parent, then it will render fine. I see the background and the child widget. If I create this widget as a child of another widget, then I see the lowest-level child, but the background is empty.

#include <QMainWindow>
#include "panel.h"

class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = 0) :
        QMainWindow(parent)
    {
        Panel* solo = new Panel();
        solo->show();

        Panel* child = new Panel(this);
    }
};

The above class instantiates the widget in 2 ways: solo gives me a dialogue with everything looking perfect. child lets me see Panel's child widgets, but the background is white.

Troubleshooting details

I thought this could be a bug in Qt as described here so I tried filtering out ThemeChange events by reimplementing the following in both Panel and MainWindow.

bool event(QEvent *event) override
{
    if (event->type() != QEvent::ThemeChange)
    {
        return QWidget::event(event);
    }
    return true;
}

That didn't help.

1
  • 1
    If you want to set the background of your mainwindow, than set the palette IN the mainwindow. Also, use "setCentralWidget(panel);" If you only want the image appear in a child window, use paintEvent. Commented Jun 20, 2018 at 11:08

1 Answer 1

0

Instead of painting my background with a QPalette in resizeEvent I found that the answer was to paint it with QPainter in paintEvent.

#include <QWidget>
#include <QPixmap>
#include <QPainter>
#include <QLabel>

class Panel : public QWidget
{
    Q_OBJECT
public:
    explicit Panel(QWidget *parent = 0) : QWidget(parent)
    {
        bgnd_ = new QPixmap(":/path/to/image.png");

        QLabel* lbl = new QLabel("Hello",this);
    }

protected:
    void paintEvent( QPaintEvent* e )
    {
        QPainter painter( this );
        painter.drawPixmap( 0, 0, bgnd_->scaled(size(), Qt::IgnoreAspectRatio));

        QWidget::paintEvent( e );
    }

private:
    QPixmap* bgnd_;
};
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.