PDA

View Full Version : Dymamic Painting outside paintEvent on mouse movement in QT4



shivam.priyadarshi
6th June 2009, 22:22
Hi Every body ,

I am porting my application fron QT3.3 to QT4.5. In my application all the paintings are done on viewport widget of QScrollView(Q3ScrollView in support class). In this application virtual function paintEvent is not implemented. I am trying to port this code to QT4.5 which require all the paintings done in paintEvent function. For the time being i don't want to change my code much so i am using : Qt::WA_PaintOutsidePaintEvent flag. I running my application on Linux but some how this flag is showing expected effect.

Following is pseudo code :


QucsView::QucsView(QWidget *parent) : Q3ScrollView(parent) // Constructor
{
setVScrollBarMode(Q3ScrollView::AlwaysOn);
setHScrollBarMode(Q3ScrollView::AlwaysOn);
viewport()->setPaletteBackgroundColor(QucsSettings.BGColor);
viewport()->setMouseTracking(true);
viewport()->setAttribute(Qt::WA_PaintOutsidePaintEvent, true);
}

void QucsView::MMoveWire2(QMouseEvent *Event) // Called on movement of mouse
// Basically drawing a line on mouse movement
{
setAttribute(Qt::WA_PaintOutsidePaintEvent, true);
QPainter painter(viewport());
painter.setPen(Qt::DotLine);
painter.setCompositionMode(QPainter::RasterOp_NotS ource);
painter.drawLine(----);
}

When i run this it give warning like
QPainter::setPen: Painter not active and it don't draw as expected....

This code is working completely fine with QT3.3 except PaintOutsidePaintEvent flag.

Any ideas what might be wrong here. I will be thankful for ur help

thx
shivam

wysota
7th June 2009, 02:00
You shouldn't paint outside paint events in Qt4. You have to call update() and do the painting in the proper place.

If you really have to paint outside the paint event, set the attribute in the constructor and not in the place where you want to paint.

shivam.priyadarshi
7th June 2009, 02:59
Hi,

Thank you very much for replying back.

I have set that attribute in constructor as well [viewport()->setAttribute(Qt::WA_PaintOutsidePaintEvent, true);] But this is also not working out. I get the same warning : painter not active.

I have tried one other approach as well..
On one of the forum link i have read that we can draw QImage or QPixmap on widget in paintEvent function and then rest of the painting can be done on QImage outside paintEvent. I have tried this approach and able to get rid of those warnings like painter not active. But i am facing problem in dynamic painting on mouse movement.

Following is the modified pseudo code:


// Constructor
QucsView::QucsView(QWidget *parent) : Q3ScrollView(parent) // Constructor
{
setVScrollBarMode(Q3ScrollView::AlwaysOn);
setHScrollBarMode(Q3ScrollView::AlwaysOn);
viewport()->setPaletteBackgroundColor(QucsSettings.BGColor);
viewport()->setMouseTracking(true);
}

// paint Event Function
void QucsView::paintEvent(QPaintEvent *event) Draw Image on viewport
{
QPainter p (this);
main_image = QImage(viewport()->size(), QImage::Format_ARGB32_Premultiplied);
p.drawImage(0,0,main_image);
}

// Painting on mouse movement. Called after mouse is moving without any button pressed.. to draw a line on mouse movement.

void QucsView::MMoveWire2(QMouseEvent *Event)
{
QPainter painter(&main_image); // Painting on QImage
painter.setPen(Qt::DotLine);
painter.setCompositionMode(QPainter::RasterOp_NotS ource);
painter.drawLine(----);
update();
}

This code execute without any warning. But i am not able to see drawing of line dynamically on movement of mouse. First I left click on QImage to start drawing from a point and then release left click and simply drag mouse to draw line and finally left click at stopping point. When i left click at stopping point, Line get drawn but I cannot see drawing of line dynamically while movement of mouse.

Is this problem of transparency of widget or buffering or something else. I will really appreciate your help.

Sorry for such a long post.

thx
shivam

nish
7th June 2009, 07:57
this happens because u always destroy the image in the paintEvent(). so the paintevent always draws a blank image..

try this


void QucsView:: paintEvent(QPaintEvent *event) Draw Image on viewport
{
QPainter p (this);

//This line gives u a fresh empty image to draw :-(.. delete it :-))
//main_image = QImage(viewport()->size(), QImage::Format_ARGB32_Premultiplied);

p.drawImage(0,0,main_image);
}

//resizeEvent will invalidate the rect
void QucsView:: resizeEvent(QResizeEvent *event)
{
drawMainImage();
}

void QucsView::MMoveWire2(QMouseEvent *Event)
{
drawMainImage();
}

void QucsView::drawMainImage()
{
//create a fresh image
main_image = QImage(viewport()->size(), QImage::Format_ARGB32_Premultiplied);
//draw it
QPainter painter(&main_image); // Painting on QImage
painter.setPen(Qt:otLine);
painter.setCompositionMode(QPainter::RasterOp_NotS ource);
painter.drawLine(----);
update();
}

this should work,...
I too did the same thing when i was porting my Qt3 app to Qt4.
but finally we decided to go with the Qt4 way and do everything in paintevent, because we had some other complexities. if your painting code is simple enough and do not do stupid things like mine code than go for it .

nish
7th June 2009, 08:05
PS-> add CODE tags to your posts... that will attract more ppl who will read and provide a better solution..:)

shivam.priyadarshi
8th June 2009, 19:56
Hi,
Thank you very much for replying back. I have tried the above also but some how it is also not working. I am not able to see dynamic drawing. It seems something is related to transparency of viewport of Q3ScrollView.

Thanks again. I will use tag from next time.

regards:
shivam

shivam.priyadarshi
8th June 2009, 22:23
Hi ,

It seems i got the problem. Actually class Qucsview is inherited from Q3ScrollView. Q3ScrollView has a virtual function called drawContents. In code of QT3.3 there is some painting done in drawContents [ painting of grid structure]. Now when i draw a QImage on this widget then that QImage go below to that grid painting and that is why anything is not visible on mouse movement.

Following is drawContents code:


void QucsView::drawContents(QPainter*p,int,int,int,int)
{
Some code for drawing grid
}

Now in paintEvent function when i draw QImage by following:

void QucsView::paintEvent(QPaintEvent *event)
{
QPainter p(this);
this.drawImage(0,0,main_image);
}

The QImage goes below the grid painting. So any action on QImage on mouse movement is not visible. Any suggestions how to deal with this issue.

thanks
shivam

davids81
30th June 2012, 08:07
Hi Shivam,
did you got the solution, if yes please share the solution, me too facing the similar issue.

Regards,
Dav