PDA

View Full Version : How to Transparent QGraphicsView widget Background?



ashukla
9th December 2007, 07:43
Dear Everyone!
How to Transparent QGraphicsView widget background?

jpn
9th December 2007, 09:36
What did you try so far?

graphicsView->setStyleSheet("background: transparent");

ashukla
9th December 2007, 09:57
What did you try so far?

graphicsView->setStyleSheet("background: transparent");
I have tried this one earlier as you suggested.But It sets the Background WHITE not a Tranparent.

jpn
9th December 2007, 10:17
Works for me with Qt 4.3.2.

ashukla
9th December 2007, 10:32
Works for me with Qt 4.3.2.
Dear Sir!

I am using the following code in Qt 4.3.2.


QGraphicsTextItem *scrItem = new QGraphicsTextItem(scrText);
scrItem->setDefaultTextColor(QColor(Qt::red));

QGraphicsScene *scene=new QGraphicsScene();

QGraphicsItemAnimation *animation = new QGraphicsItemAnimation;
QGraphicsItemAnimation *animation1 = new QGraphicsItemAnimation;
animation->setItem(scrItem);
float n;
screen=QApplication::desktop()->screenGeometry();
int yLoc=screen.height()-(scrFont.pointSize()+40);
wScroller->setGeometry(0,yLoc,wScroller->width(),scrFont.pointSize()+40);
view=new QGraphicsView(scene,wScroller);
view->setWindowFlags (Qt::FramelessWindowHint);
view->setStyleSheet("background: transparent");
scene->addItem(ship);
scene->addItem(scrItem);

view->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
view->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
view->setCacheMode(QGraphicsView::CacheBackground);

scene->setSceneRect(0,0,wScroller->width(),scrFont.pointSize()+40);
n=scrWidth;/*Width of scrText*/

qreal sh=scene->height()/2-ship->boundingRect().height()/2;
qreal h=scene->height()/2-scrItem->boundingRect().height()/2; /*Calculating the eaxact mid Y cordinate position of scrItem (Text)*/


register int scrItembrw=scrItem->boundingRect().width();
register int velNum=16;
register int velocity=(((velNum-scrSpeed)*3)-2);
register int tl=(n+scrItembrw)*velocity;
scrTime=tl;

timer = new QTimeLine(tl);
timer->setCurveShape(QTimeLine::LinearCurve);
timer->setLoopCount(0);
animation->setTimeLine(timer);
animation1->setTimeLine(timer);


for (int i=0; i<(n+scrItem->boundingRect().width()); i=i+1)
{
QPointF p(0,h);
p.setX(n-i);
p.setY(h);
ps.setX(n-i-imgbrw);
ps.setY(sh);
animation->setPosAt(i/(n+scrItem->boundingRect().width()),p);

}//end for

view->setFixedWidth(wScroller->width());
view->setFixedHeight(scene->height());
view->show();
timer->start();


but it is not working.

jpn
9th December 2007, 10:46
Give the following example a try:


#include <QtGui>

int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QMainWindow window;

QGraphicsScene* scene = new QGraphicsScene(&window);
QGraphicsItem* item = scene->addText("QGraphicsTextItem");
item->setFlags(QGraphicsItem::ItemIsMovable);

QGraphicsView* view = new QGraphicsView(&window);
view->setStyleSheet("background: transparent");
view->setScene(scene);

window.setCentralWidget(view);
window.setStyleSheet("background: green");
window.show();
return app.exec();
}

As you can see, the background of the main window shows through the view.





view=new QGraphicsView(scene,wScroller);
view->setWindowFlags (Qt::FramelessWindowHint);


What are you trying to accomplish with this? You pass a parent so it's not a top level widget you could remove window frames from. If you actually want to adjust transparency of a top level widget, take a look at QWidget::setWindowOpacity() (http://doc.trolltech.com/latest/qwidget.html#windowOpacity-prop) but make sure you read the notes in docs.

ashukla
9th December 2007, 11:14
Give the following example a try:


#include <QtGui>

int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QMainWindow window;

QGraphicsScene* scene = new QGraphicsScene(&window);
QGraphicsItem* item = scene->addText("QGraphicsTextItem");
item->setFlags(QGraphicsItem::ItemIsMovable);

QGraphicsView* view = new QGraphicsView(&window);
view->setStyleSheet("background: transparent");
view->setScene(scene);

window.setCentralWidget(view);
window.setStyleSheet("background: green");
window.show();
return app.exec();
}

As you can see, the background of the main window shows through the view.


What are you trying to accomplish with this? You pass a parent so it's not a top level widget you could remove window frames from. If you actually want to adjust transparency of a top level widget, take a look at QWidget::setWindowOpacity() (http://doc.trolltech.com/latest/qwidget.html#windowOpacity-prop) but make sure you read the notes in docs.
Dear Sir!
Actually, I have designed three QX11EmbedContainer widget (as a child namely f1,f2,f3 dynamically) of QX11Container parent widget. I am playing in f1 & f2 frames different movies and in the third f3 child widget I want to play scrolling text like news with transparent background.
for which I am using the above code.


QScrollerViewPlayer::QScrollerViewPlayer(QString file, int width, int height, QWidget *wscr)
{
scrHeight = height;
scrWidth = width;
scrFileName = file;
wScroller=wscr;
}

what should I do for trasprenting widget in that context.

wysota
9th December 2007, 11:35
and in the third f3 child widget I want to play scrolling text like news with transparent background.

I have a widget for that...

ashukla
9th December 2007, 11:51
I have a widget for that...

Dear Sir!

What is the full feature of that widget?
How to get this widget?

wysota
9th December 2007, 11:57
It's a widget that scrolls a QTextDocument. I haven't tried it with a transparent background, but it's probably possible :)

The widget is not available for public, I have some issues with speed stability I need to fix before releasing it. But in general I render the document to a pixmap and then render the pixmap to the widget with different offsets, depending on the step of the animation.

ashukla
9th December 2007, 12:08
It's a widget that scrolls a QTextDocument. I haven't tried it with a transparent background, but it's probably possible :)

The widget is not available for public, I have some issues with speed stability I need to fix before releasing it. But in general I render the document to a pixmap and then render the pixmap to the widget with different offsets, depending on the step of the animation.
OK Sir!
But In my context; How a way I set the transparency of widget.

wysota
9th December 2007, 17:40
I think J-P already gave you some hints. Did you follow them?

ashukla
10th December 2007, 04:59
I think J-P already gave you some hints. Did you follow them?
Yes! I have followed them. But I am not getting the desired output.

wysota
10th December 2007, 09:38
What is the desired output? Do you want to show it over another widget or over desktop?

ashukla
10th December 2007, 10:45
What is the desired output? Do you want to show it over another widget or over desktop?
Dear Sir!
I have explained earlier as follows
I have designed three QX11EmbedContainer widget (as a child namely f1,f2,f3 dynamically) of QX11Container parent widget. I am playing in f1 & f2 frames different movies and in the third f3 child widget I want to play scrolling text like news with transparent background.
for which I am using the above code.
I want to play scroll text upon the running movie background.
That means I want to play text scroller with tranparent background.
What should I do for that?
Thanking in advance to give suggestion!

ashukla
10th December 2007, 10:46
I want to show it over another widget.

wysota
10th December 2007, 11:19
It might not work, because the embedded widget is really another application, so drawing over it might be difficult. And because that other widget is a movie, it might be even more difficult - usually one uses overlays for that. I suggest you find some other solution (for example don't embed external applications).

pbutterworth
24th April 2009, 05:00
Hi, I am attempting the same thing, but simpler.
I would like to place a QGraphicsView over the top of (a child of) another plain QWidget. I have tried:


#include <QtGui>

int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QMainWindow window;

QGraphicsScene* scene = new QGraphicsScene(&window);
QGraphicsItem* item = scene->addText("QGraphicsTextItem");
item->setFlags(QGraphicsItem::ItemIsMovable);

QGraphicsView* view = new QGraphicsView(&window);
view->setStyleSheet("background: transparent");
view->setScene(scene);

window.setCentralWidget(view);
window.setStyleSheet("background: green");
window.show();
return app.exec();
}


but it results in a white window, not a green one. The QGraphicsView refuses to become transparent.

I've tried this in Qt for win32 4.4.0 and 4.4.3.
Anyone have any ideas? Thanks!

bowdar
27th September 2009, 03:26
QBrush brBrush;

QPalette palette(brBrush,brBrush,brBrush,brBrush,brBrush,br Brush,brBrush,brBrush,brBrush);

setPalette(palette);

setWindowFlags(Qt::FramelessWindowHint | Qt::WindowSystemMenuHint);

setAttribute(Qt::WA_TranslucentBackground);

setFrameShape(QFrame::NoFrame);

try this, with Qt 4.5

totem
11th January 2010, 15:03
Hi,

I encounter the same issue. Thanks to jpn answer i managed to see the mainwindow background under my graphicsview.
Now, is there an easy way to make the central widget transparent. I mean : to obtain a QMainWindow with toolbar and menubar and borders, but where we see desktop and other windows in place of central widget. I'm looking for a solution for some times now but can't find anything helpful

Note : in my app, this would allow the user to draw something, using the QGraphicsView as a tracing paper

wysota
11th January 2010, 15:34
Have a look at Qt::WA_TranslucentBackground widget attribute.

zuck
11th January 2010, 15:51
QGraphicsView view;
// ...
view.setAttribute(QT::WA_TranslucentBackground);
view.viewport()->setAutoFillBackground(false);

totem
11th January 2010, 16:41
Thank you for replying, but unfortunately i'm not sure I've been clear enough. What i want to obtain is described by attached picture


That is to say, i want to see underlying windows in my view




4101

wysota
11th January 2010, 17:26
Did you even try the code you were given?

totem
11th January 2010, 18:35
yes :) obviously, i even tried that way before posting.

using for my QGraphicsView subclass :



MyView::MyView()
{
// constructor...
setAttribute(Qt::WA_TranslucentBackground);
viewport()->setAutoFillBackground(false);
}


//----------------------------------------------------------------------------------
void MyView::paintEvent(QPaintEvent * e)
{
QPainter p( viewport() );

p.save();
p.setCompositionMode(QPainter::CompositionMode_Sou rceOver);
p.fillRect(this->rect(), Qt::transparent);
p.restore();

// draw scene items
QGraphicsView::paintEvent(e);
}


and for my QMainWindow subclass :


setStyleSheet("background: red") ;




result : i would like to see my desktop where it's red in the view around the scene, but i see red background.
Question is : do i have to override my MainWindow::paintEvent() to be able to achieve this effect ?

4102

wysota
11th January 2010, 19:35
The top-level widget you want to be transparent needs to have that flag set, not its most-child one.

Note that you have to paint every area you want opaque yourself (you can see your image shines through over the calendar on the left).

4104


#include <QtGui>

int main(int argc, char **argv){
QApplication app(argc, argv);
QMainWindow mw;
mw.setAttribute(Qt::WA_TranslucentBackground);
QToolBar *tb = mw.addToolBar("xyz");
QGraphicsView *view = new QGraphicsView;
mw.setCentralWidget(view);
QDockWidget *dw = new QDockWidget;
dw->setWidget(new QCalendarWidget);
mw.addDockWidget(Qt::LeftDockWidgetArea, dw);
QGraphicsScene scene;
view->setScene(&scene);
QPalette p = view->viewport()->palette();
p.setColor(QPalette::Base, Qt::transparent);
view->viewport()->setPalette(p);
scene.addRect(10,10,50,20, QPen(Qt::red), Qt::blue);
mw.show();
return app.exec();
}

totem
12th January 2010, 11:05
Ok you solved my problem :)

I just paste a modified-version of your sample code, because Windows needs some extra-flag to be set :
Actually only Qt::FramelessWindowHint is needed (regarding documentation) but the others are usefull


#include <QtGui>
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QMainWindow mw;
mw.setAttribute(Qt::WA_TranslucentBackground);
mw.setWindowFlags( Qt::FramelessWindowHint|Qt::WindowSystemMenuHint|Q t::WindowStaysOnTopHint ) ;
QToolBar *tb = mw.addToolBar("xyz");
QGraphicsView *view = new QGraphicsView;
mw.setCentralWidget(view);
QDockWidget *dw = new QDockWidget;
dw->setWidget(new QCalendarWidget);
mw.addDockWidget(Qt::LeftDockWidgetArea, dw);
QGraphicsScene scene;
view->setScene(&scene);
QPalette p = view->viewport()->palette();
p.setColor(QPalette::Base, Qt::transparent);
view->viewport()->setPalette(p);
scene.addRect(10,10,50,20, QPen(Qt::red), Qt::blue);
mw.show();
return app.exec();
}

Now I will try to paint every area I want opaque, and voilà :D

thank you

manojmka
5th March 2010, 11:42
Thanks to all of you guys for this useful post!! It works great.

I want user to be able to peep through the whole UI and see something working behind application. henceforth, I tried doing:



void MotionAlarm::setThroughTransparent(QWidget *widget)
{
if(widget==NULL)
return;
widget->setAttribute(Qt::WA_TranslucentBackground);
setThroughTransparent(widget->parentWidget());
}

void MotionAlarm::somefunction()
{
setThroughTransparent(graphicsView);
}



It works but the problem is that even the blank areas on parent windows become transparent which should not happen! Is there any way, that I can make a hole in UI for a specific region (graphics view), see the desktop but still operate on graphics view?

I tried doing it in the following way:



void MotionAlarm::on_buttonReset_clicked()
{
QRegion region = graphicsView->visibleRegion();
region.translate(graphicsView->pos());
createHole(region);
}

void MotionAlarm::createHole(QRegion region)
{
QRegion widgetRegion = visibleRegion();
QRegion visibleReg = widgetRegion.subtracted(region);
this->setMask(visibleReg);
}


but then I lose all the control on graphics view and don't see any graphics items rendered as well as mouse events are lost!

wysota
5th March 2010, 11:50
Set a mask on the window (QWidget::setMask()).

manojmka
5th March 2010, 12:05
I did, but then I can not see Graphics items at all and mouse events are also not captured by application! Please see the function createHole()

wysota
5th March 2010, 13:26
Is "MotionAlarm" class object a top-level window?

manojmka
6th March 2010, 11:35
For my current test application, yes. It may not be the top level widget/window in real application, but all the test cases which I have described belong to the test application only.