PDA

View Full Version : Setting background image for Central Widget



xfurrier
9th September 2009, 14:27
I want to create something that looks like a typical email application (thunderbird, mac mail, …) - one column on the left and two panes, one above the other, on the right. In addition, I want a single, large, continuous background image spreading across all the panes.

I'm trying to set the background image for the Central Widget of QMainWindow, but to no avail.

Is it actually possible to do something like that?

wysota
9th September 2009, 16:53
Yes, it's possible. Just set the background for the central widget using stylesheets or QPalette.

xfurrier
11th September 2009, 15:01
I had another go, and still no luck. If you say it's possible, then it must the case.

I'm using stylesheets and the css file is picked up for QLabels, but no luck with the background image. Any idea what am I doing wrong? Thanks again.




#include "CentralContainer.h"


CentralContainer::CentralContainer(QWidget *parent) : QWidget(parent)
{
this->setObjectName("CentralContainer");

QLabel *titleLabel = new QLabel("Central Container");
titleLabel->setObjectName("CentralContainerTitle");

leftPanel = new LeftPanel(this);
topPanel = new TopPanel(this);
bottomPanel = new BottomPanel(this);

QGridLayout *layout = new QGridLayout();
layout->addWidget(titleLabel, 0, 0, 1, 2);
layout->addWidget(leftPanel, 1, 0, 2, 1);
layout->addWidget(topPanel, 1, 1);
layout->addWidget(bottomPanel, 2, 1);

setLayout(layout);
}






QWidget#CentralContainer {
background-image: url(images/background.png);
}

QLabel#CentralContainerTitle {
background-color: aqua;
color: purple;
}

CentralContainer QLabel {
background-color: transparent;
color: blue;
}

victor.fernandez
11th September 2009, 16:24
You have to call setStyleSheet() (http://doc.trolltech.com/4.5/qwidget.html#styleSheet-prop) in the constructor of CentralContainer passing the contents of mystyle.css.


CentralContainer::CentralContainer(QWidget *parent) : QWidget(parent)
{
this->setObjectName("CentralContainer");

QLabel *titleLabel = new QLabel("Central Container");
titleLabel->setObjectName("CentralContainerTitle");

leftPanel = new LeftPanel(this);
topPanel = new TopPanel(this);
bottomPanel = new BottomPanel(this);

QGridLayout *layout = new QGridLayout();
layout->addWidget(titleLabel, 0, 0, 1, 2);
layout->addWidget(leftPanel, 1, 0, 2, 1);
layout->addWidget(topPanel, 1, 1);
layout->addWidget(bottomPanel, 2, 1);

setLayout(layout);

QFile cssFile("mystyle.css");
if(cssFile.open(QIODevice::ReadOnly)) {
QString css = QString::fromLocal8Bit(cssFile.readAll());
setStyleSheet(css);
cssFile.close();
}
}

xfurrier
11th September 2009, 17:19
I was actually calling setStyleSheet() in main.cpp, but moving it to CentralContainer() doesn't make any difference. Still failing badly. :(

wysota
11th September 2009, 22:02
#include <QtGui>

int main(int argc, char **argv){
QApplication app(argc, argv);
QMainWindow mw;
QWidget *w = new QWidget;
mw.setCentralWidget(w);
w->setAutoFillBackground(true);
w->setStyleSheet("background-color: red;");
mw.show();
return app.exec();
}
or...

#include <QtGui>

int main(int argc, char **argv){
QApplication app(argc, argv);
QMainWindow mw;
QWidget *w = new QWidget;
mw.setCentralWidget(w);
w->setAutoFillBackground(true);
// w->setStyleSheet("background-color: red;");
QPalette p = w->palette();
p.setColor(QPalette::Background, Qt::yellow);
w->setPalette(p);
mw.show();
return app.exec();
}

xfurrier
12th September 2009, 19:35
Thanks for all your replies. However, despite my efforts and I'm still struggling and there are lots of things I need to learn.

I'm still on the backgrounds and stylesheets (need to use them rather than QPalette). Could you please explain what's the difference between 1) which gives me red background and 2) with the default (grey) background. :confused:

1)


MainWindow::MainWindow()
{
QWidget *w = new QWidget;
setCentralWidget(w);
w->setAutoFillBackground(true);
w->setStyleSheet("background-color: red; ");
}


2)


MainWindow::MainWindow()
{
CentralContainer *w = new CentralContainer();
setCentralWidget(w);
w->setAutoFillBackground(true);
w->setStyleSheet("background-color: red; ");
}

CentralContainer::CentralContainer() : QWidget()
{
}

QAlex
16th December 2009, 17:46
Hi,
a question:
is it possible to resize automatically a background image inserted with the style sheet instruction
background-image url("..."); ?????
I searched in the documentation, but I found nothing about this issue!

Thanks a lot,
Alex

rvgrouik
25th February 2010, 10:14
I created a BackgroundWidget class that does what you want:



#ifndef BACKGROUNDWIDGET_H
#define BACKGROUNDWIDGET_H

#include <QWidget>
#include <QPixmap>
#include <QString>
#include <QSize>
#include <QPaintEvent>

class BackgroundWidget: public QWidget
{
Q_OBJECT

public:
BackgroundWidget(QWidget* parent, QString bgImagePath);
~BackgroundWidget();


void setPicture(const QString& bgImagePath);
void setPixmap(QPixmap* bgImage);

QSize sizeHint() const;

signals:
void backgroundPainted();

protected:
void paintEvent(QPaintEvent *event);

private:
QPixmap Image;
QBrush Brush;
};


#endif // BACKGROUNDWIDGET_H

First Ctor arg is your widget (QMainWindow for example), second arg is the path to the picture, possibly stored as resource.

Here is the implementation:


#include "BackgroundWidget.h"
#include <QWidget>
#include <QPixmap>
#include <QString>
#include <QSize>
#include <QPaintEvent>
#include <QPainter>

BackgroundWidget::BackgroundWidget(QWidget *parent, QString bgImagePath): QWidget(parent), Image(), Brush()
{
parentWidget()->stackUnder(this);
setPicture(bgImagePath);
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
lower();
Brush = QBrush(Image);
}


BackgroundWidget::~BackgroundWidget()
{

}


QSize BackgroundWidget::sizeHint() const
{
return parentWidget()->visibleRegion().boundingRect().size();
}

void BackgroundWidget::setPicture(const QString& bgImagePath)
{
Image = QPixmap(bgImagePath);
}

void BackgroundWidget::setPixmap(QPixmap* bgImage)
{
if (! bgImage)
return;
Image = QPixmap(*bgImage);
}

void BackgroundWidget::paintEvent(QPaintEvent *event)
{
resize(parentWidget()->visibleRegion().boundingRect().size());
QPainter painter(this);
painter.setBrush(Brush);
int x = (width() - Image.width()) / 2;
int y = (height() - Image.height()) / 2;
painter.drawPixmap(x, y, Image.width(), Image.height(), Image);
emit backgroundPainted();
}


See attachment for complete code

rvgrouik