PDA

View Full Version : Drawing problem



boss_bhat
22nd January 2007, 09:53
Hi all,

I am using Qt 4 on linux. I am trying to support drag and drop to a triangle that is drawn using QPainter. I am using a QImage and drawing the triangle in it. But while dragging
triangle the problem is we can drag the triangle even pressing the surrouding area. Can
some body explain how to solve this problem? So that we can drag the triangle only when
the mouse is only on triangle.

I am attaching the source files too.


//Here is the drawing stuff
QImage image(90,90, QImage::Format_ARGB32_Premultiplied);
image.fill(qRgba(0, 0, 0, 0));

QPainter pain;
pain.begin(&image); //begin on image

pain.setRenderHint(QPainter::Antialiasing);
pain.setRenderHint(QPainter::SmoothPixmapTransform );
Qt::BrushStyle style = Qt::LinearGradientPattern;

QLinearGradient linearGradient(0, 0, 100, 100);
linearGradient.setColorAt(0.0, Qt::white);
linearGradient.setColorAt(0.2, Qt::green);
linearGradient.setColorAt(1.0, Qt::black);

QPen pen;
pen.setStyle(Qt::DotLine);
pen.setColor(QColor( 0,255, 0));
pain.setPen(QPen(Qt::black,0, Qt::SolidLine,Qt::FlatCap, Qt::MiterJoin));
pain.setBrush(linearGradient);
QPointF p1(80,40);
QPointF p2(0,80);
QPointF p3(80,80);

pain.drawPolygon(QPolygonF() << p1 << p2 << p3);


setPixmap(QPixmap::fromImage(image));




Thanks in advance,
prasanna Bhat
--

jpn
22nd January 2007, 10:28
That's a pure mathematical problem. You have to calculate whether the pressed point is inside the triangle. You could make use of QPainterPath::contains().



void SomeWidget::mousePressEvent(QMouseEvent* event)
{
QPointF p1(80,40);
QPointF p2(0,80);
QPointF p3(80,80);

QPainterPath path;
path << p1 << p2 << p3;
if (path.contains(event->pos())
{
// is inside the triangle
}
}


EDIT: Oh, and to make it more generic.. I'm not sure what would be a good way. If the triangle is filled with a color distinct from the background color, maybe simply accessing the corresponding pixel in the image and comparing it to the background would do the trick. Otherwise it starts to sound like a really complex task requiring identifying of the drawn shape in the image.

ghorwin
22nd January 2007, 12:19
For a more generic solution (irregular shapes with many colors, for instance a person in a photograph) you can use a second image with the same dimensions with a shadow map, basically with every pixel that is part of a specific selection painted in a uniform color. When the drag starts, simple use the reported coordinates in your shadow map to look up the color (you could possibly have several distinct shapes and colors defined there) to identify which object to drag and drop.

Andreas

boss_bhat
22nd January 2007, 12:45
QPainterPath path;
path << p1 << p2 << p3;

This stuff is not compiling it gives following error ??

DragLabel::mousePressEvent(QMouseEvent*)':
draglabel.cpp:49: parse error before `<<' token

Is somthing wrong here??

jpn
22nd January 2007, 13:01
Forgot #include <QPainterPath>?

EDIT: Oops, sorry the piece of code was written on the fly. I meant:


QPainterPath path;
path.addPolygon(QPolygonF() << p1 << p2 << p3);

boss_bhat
23rd January 2007, 16:40
Hi all,

I am little bit of struggling here, can some body explain how to rotate the triangle in this sample on right mouse click, here is the code I have written in the :mousePressEvent of
DragLabel class,



QImage tempImage = (*pixmap()).toImage();
if(event->button()==Qt::RightButton)
{
//rotate abt 60 degrees
QMatrix matrix;
matrix.rotate(60);
tempImage = tempImage.transformed(matrix);
QPainter painter;
painter.begin(&tempImage);
painter.fillRect(tempImage.rect(), QColor(127, 127, 127, 127));
painter.end();
drag->setPixmap(QPixmap::fromImage(tempImage));
show();
}
else{
hide();

if (drag->start(Qt::MoveAction) == Qt::MoveAction)
close();
else
show();

}

It doesnt work, for multiple right clicks, Can somebody explain what is the right way to implement this

Thanks in advance,
Prasanna Bhat

jpn
23rd January 2007, 16:50
As mentioned in some previous thread, I suggest you to store the original image. Well, check out the example. ;)

boss_bhat
24th January 2007, 13:54
hi all,

I am bit struck here, the problem is when I use multiple triangles, assume one triangle overlaps the another say like in the picture, the lower triangle wont display properly as it's clipped by the QImage dimension of the upper triangle. Even I can't access the lower triangle exposed with drag and drop because the dimension of QImage of the top triangle is overlapping and even though the unpainted area is disabled I cant access exposed area of the lower triangle, Can some body explain how to solve this problem.

Thanks in advance,
Prasanna Bhat

jpn
24th January 2007, 14:05
Open up the triangle image in your favourite image editor application and make the white background transparent.

boss_bhat
24th January 2007, 14:09
But I am drawing the triangle programatically :(

jpn
24th January 2007, 14:32
Ah :) ..well, maybe you could fill the image with a transparent color after constructing it but before painting the triangle.

QImage::fill()
QColor::rgba()

boss_bhat
24th January 2007, 17:06
I tried,

QImage image(80,80, QImage::Format_ARGB32_Premultiplied);
//image.fill(qRgba(0, 0, 0, 0)); this also doesnt work
image.fill(Qt::transparent);
it didnt work, I am using Using Qt version 4.0.1 is there any difference?

jpn
24th January 2007, 17:37
Could you test this?

aamer4yu
25th January 2007, 04:12
Just a thought....
wont all this drawing be more easier if using Graphics View Framework ?? I mean making the triangle as QGraphicsItem ??

just curious....what is the need that you are using QLabel ??

jpn
25th January 2007, 05:52
Just a thought....
wont all this drawing be more easier if using Graphics View Framework ?? I mean making the triangle as QGraphicsItem ??

just curious....what is the need that you are using QLabel ??
Indeed, but GV was introduced in Qt 4.2 and he's using 4.0. Anyway, updating to a recent version would be highly recommended.

boss_bhat
25th January 2007, 06:27
I will try to upgrade to recent version of Qt!! By the way does QGraphicsItem support drag n drop??

Thanks guyz

aamer4yu
25th January 2007, 07:24
sure it does... its inbuilt !!
u dont even need to write the drag & drop code unless u want to move items from one view to another...

check the 40000 chips program in Qt Demo -> Demonstrations :)
i bet u will be tempted to workin in the GV model

check the attachment... so simple work :D

boss_bhat
28th January 2007, 10:37
solved overlapping problem :)

subclassing QPolygonGraphicsItem will work.

Gopala Krishna
28th January 2007, 11:26
The mistake in the previous case was wrong boundingRect().
Change it to return QRectF(0, 0, 80,80) and also defining member shape() as follows it works perfectly !!!


QPainterPath Shapes::shape() const
{
QPainterPath path;
path.moveTo(40,0);
path.lineTo(0,80);
path.lineTo(80,80);
path.lineTo(40,0);
return path;
}