PDA

View Full Version : Using QPainter to 'erase' an area of widget?



altec42lansing
16th June 2011, 19:33
I have a qpainter painting a certain image over an entire area. Now, i want to erase part of it completely so i can basically see the desktop behind it kind of thing. i am currently using:

painter.eraseRect(0, 0, width()/2, height()/2)

and it just makes a white background in that part of the ui. I have tried looking around to forums on setbackground or setattribute:

setBackgroundRole(QPalette::Base);
setAttribute(Qt::WA_NoSystemBackground);

but these seem to have no effect, and I can't seem to get that white 'erased' area to be completely gone or transparent. Might be a simple fix, any ideas?

Santosh Reddy
16th June 2011, 21:19
I would suggest to not paint at all, then no need to erase it. I mean don't paint the area which you want to erase. I hope you got it :cool:

wysota
17th June 2011, 09:41
Qt::WA_TranslucentBackground

altec42lansing
17th June 2011, 13:20
hmm, still cant seem to get this working, basically i have a screen that i draw, and i need to get ride of a portion of it completely, including that 'white box' that is left behind when i erase rect. I basically want to get ride of that white area and any remnants left over after erasing, so i can see whats behind the application, since my widgets are painted over top of everything else.
(here is my current code for erasing it:)

painter.eraseRect(0,0,width()/2,height()/2);
this->setBackgroundRole(QPalette::Base);
this->setAttribute(Qt::WA_TranslucentBackground);

Rachol
17th June 2011, 13:32
Try to test this:


#include <QtGui>
#include <QLabel>

//! [main function]
int main(int argc, char *argv[])
{
QApplication app(argc, argv);

QLabel widget("TEST");
QFont f = widget.font();
f.setPointSize(100);
widget.setFont(f);
widget.setWindowFlags(Qt::WindowFlags(Qt::Frameles sWindowHint));
widget.setAttribute(Qt::WA_TranslucentBackground);
widget.show();

return app.exec();
}
//! [main function]

altec42lansing
17th June 2011, 13:40
this worked and painted text with a transparent background over my windows, allowing me to see behind it where the text was not, but im not sure how to apply this to my problem

Rachol
17th June 2011, 13:51
Does this help? Use your widget as I have used MyWidget in code below. You don't have to erease anything in your paintEvent


#include <QtGui>
#include <QWidget>

class MyWidget : public QWidget
{
public:
explicit MyWidget(QWidget *parent = 0):QWidget(parent){};

protected:
void paintEvent ( QPaintEvent * );

};

void MyWidget::paintEvent ( QPaintEvent * )
{
QPainter p(this);
p.setPen(QPen(Qt::red,5));

p.drawRect(rect());
}

//! [main function]
int main(int argc, char *argv[])
{
QApplication app(argc, argv);

MyWidget widget;
widget.setFixedSize(300,200);
widget.setWindowFlags(Qt::WindowFlags(Qt::Frameles sWindowHint));
widget.setAttribute(Qt::WA_TranslucentBackground);
widget.show();

return app.exec();
}
//! [main function]

altec42lansing
17th June 2011, 14:03
I hate attached a small file which hopefully demonstrates what i am trying to do

Rachol
17th June 2011, 14:17
void MyWidget::paintEvent ( QPaintEvent * )
{
QPainter p(this);
p.setPen(QPen(Qt::red,5));

p.fillRect(rect(), Qt::white);
p.drawText(0,0,width(), height(),Qt::AlignCenter || Qt::TextWordWrap, "THIS IS THE AREA WHERE I DRAW IMG");

p.setCompositionMode(QPainter::CompositionMode_Sou rce);
p.fillRect(rect().adjusted(0,0,-width()/2,-height()/2), Qt::transparent);
}

altec42lansing
17th June 2011, 15:21
awesome, thank you!

Added after 56 minutes:

One more problem i am having though, now that i can see whatever is behind it on the desktop, i do not want to be able to click on that area, otherwise i'd lose focus of my current application, i just want to be able to see it, like a 'window' in the middle of my app. i tried changing the mode and redrawing a transparent rect on top but that didnt work:

painter.setCompositionMode(QPainter::CompositionMo de_SourceIn);
painter.fillRect(pipRect, Qt::transparent);
painter.setCompositionMode(QPainter::CompositionMo de_DestinationAtop);
painter.fillRect(pipRect, Qt::transparent);

Rachol
17th June 2011, 15:39
I don't know anything else but something like this:


void MyWidget::paintEvent ( QPaintEvent * )
{
QPainter p(this);
p.setPen(QPen(Qt::red,5));

p.fillRect(rect(), Qt::white);
p.drawText(0,0,width(), height(),Qt::AlignCenter || Qt::TextWordWrap, "THIS IS THE AREA WHERE I DRAW IMG");

p.setCompositionMode(QPainter::CompositionMode_Sou rce);
p.fillRect(rect().adjusted(0,0,-width()/2,-height()/2), QColor(255,255,255,1));
}

instead of Qt:transparent use something with low alfa value, so the user can't even notice that there is something. QColor(255,255,255,1) works well for such purpose.

wysota
17th June 2011, 15:46
Maybe it will easier for you if you use QPixmap::grabWindow() or QPixmap::grabWidget() on your desktop and simply set that as the background of your widget.

Rachol
17th June 2011, 15:51
Well, as long as nothing in the background changes. Also positioning of such pixmap gets complicated.

wysota
17th June 2011, 16:19
You can't eat the cake and still have the cake.