QGraphicsPolygonItem drawing a open(not closed) polygon - c++

I am using a QGraphicsPolygonItem and I have noticed that it always connects the end-point with the start-point.
I know that the polygon terms means exactly that, and what I am looking for is "polyline" or "polygonal chain". I didnt found nothing like that in QGraphicsItem subclasses.
How do I draw a polygonal chain in QGraphics Framework? Is there a property of QGraphicsPolygonItem or a class that does that?

I had a similar problem, and I solved it by using the QGraphicsPathItem class. In the following code, polygon is a non-closed QPolygonF object (i.e. a QPolygonF which start-point is different from its end-point):
QPainterPath path = new QPainterPath();
path.addPolygon(polygon);
QGraphicsPathItem contour = new QGraphicsPathItem(path);
contour.setPen(new QPen(QColor.black));
When displaying this QGraphicsPathItem object, the start-point is (in theory) disconnected from its end-point.
I'm sorry this example code is in Java; but the mechanisms should be the same as in C++.

You can use QPainterPath and use lineTo method to input yors polyline points, then just use QGraphicsPathItem to make it graphics item.
Alternatively you also might think about combining several QGraphicsLineItem into one QGraphicsItemGroup, but that's more difficult as you need to pay attention to aligning lines together.
Is this what you are looking for?
EDIT:
QPainterPath is apparently closing paths, then you are left with group of lines only.
EDIT2:
Sorry for confusing you, but HostileFork seem to be right - you just use QPainterPath and call pathItem->setBrush(QBrush(Qt::transparent)); to keep your path unfilled.

Related

Show a curve in Qt5 using C++

Now, I have geometry information of some curves, which are given with the following format.
<LineString><coordinates>-43.276042355627,-32.8022614460173,0.0 -43.9683944443137,-31.9135623685828,0.0 -44.4979806584518,-31.1926527722131,0.0</coordinates></LineString>
I would like to show them in my scene. I know I can do this by creating multiple QGraphicsLineItems one by one. But is there any other easy way to do this, like one curve item?
You can use QGraphicsPathItem along with QPainterPath.
Reimplement the QGraphicsPathItem, add a method that receives your original points. Create a QPainterPath and iterate over points. Use moveTo on the first point and lineTo for the next points. Then call setPath of QGraphicsPathItem to redraw the new curve.

How to draw Convex Rectangle in combination with ellipsoids by using Qt4.8 (C++)? (top view of a boat)

I'm currently trying to draw the top view of a boat by using Qt 4.8 (C++).
I want to implement a QWidget in which a boat moves around.
Therefore I need to draw the top view of a boat, it should look similiar to this (only need the outer boarders):
(source: 4vector.com)
Currently I'm experimenting with QPainter in combination with QPainterPath but I can't figure out how to combine the ellipsoids and rectangles correctly. Another option would be to draw it as an polygon but I would need a lot of points to let it look good.
Besides I think a solution by using only a rectangle and two ellipsoids or simliar solutions would be more beautiful.
Many thanks in advance for your help!

Color the area defined by Items intersection in Qt

I have some custom QGraphicsItems in a QGraphicsView of a QGraphicsScene. With items(QPoint(x, y)) method I retrieve all the items at given scene point.
Once these items are drawn they will not be moved, rotated or scaled, so their shapes will not change.
I would to know if there is a way to change the color of the overlapping area only (if I have at least two items, of course).
A different way to write my question is: given a starting point, color the scene until some borders are found.
I have not enough reputation to post an image, so I uploaded three examples of desired results here.
Edit 1: solution from Nejat works if I select a point that actually is within two Items' shapes, but it doesn't work if the point belongs to only one Item or to no Items (I uploaded an example of this case here).
Maybe should I use a different approach? Once painted, I don't need to change an item, so I will be interested also in a "flat/static" pixel-oriented solution. Could I use QImage class?
Edit 2: Nejat's answer was right for the original question. Btw, for my purpose I used a QImage, drawing on it all the shapes and finally using a "flood fill" algorithm to fill the area I wanted.
You can use the QGraphicsItem::shape () which returns a QPainterPath to retrieve the shape of an item. For taking the intersection path this can be used :
QPainterPath QPainterPath::intersected ( const QPainterPath & p ) const;
So you can get the intersection path of two items like:
QPainterPath intersectedPath = item1->shape()->intersected(item2->shape());
Now you can fill the intersected area by :
painter->setBrush(QColor(122, 163, 39));
painter->drawPath(intersectedPath);

Display custom image and have the ability to catch mouse input

I am trying to display several images in the MainWindow and have the ability to perform certain actions when these images receive mousePressEvent.
For this, I thought I would create a new class, derived from QWidget, which had a QImage private member. With this, I as able to override the paintEvent and the mousePressEvent to both display the image and catch mouse input.
However, the problem is that the image drawn in the MainWindow has the widget size and its form (rectangular), and the image does not possess the same form (not even a regular form). This causes some problems because I am able to catch the mousePressEvent on parts that do not belong to my Image, but do belong to the Widget area.
Does anyone have any ideas on how to solve this?
I am still very new to QT, so don't please don't mind any huge mistake :)
Update:
Ok, I tried another approach.
I now have a graphicView on my MainWindow, with a graphicScene linked to it. To this scene, I added some graphicItems.
To implement my graphicItems I had to overload the boundingRect and paint method. As far as the documentation goes, my understanding is that QT uses shape method (which calls boundingRect) to determine the shape of the object to draw. This could possibly be the solution to my problem, or at least one solution to improve the accuracy of the drawn shape.
As of now, i am returning a square with my image size in boundingRect. Does anyone know how I can "adapt" the shape to my image (which resembles a cylinder)?
If you want to use QWidget you should take look at the mask concept to refine the space occupied by your images (be careful about the performance of this implementation).
If you decide to go with the QGraphicsItems you can re-implement the virtual method QPainterPath QGraphicsItem::shape () const to return a path representing as well as possible the boundary of your images.
The Qt documentation says :
The shape is used for many things, including collision detection, hit tests, and for the QGraphicsScene::items() functions.
I encourage you to go with the QGraphics system, it's sounds more appropriate in your case.
What I understand is that you want to shrink/expand/transform your image to fit a custom form (like a cylinder).
What I suggest is to use the OpenGL module QGLWidget and to map each coordinate of your rectangular image (0,0) (0,1) (1,0) (1,1) to a custom form created in OpenGL.
It will act as a texture mapping.
Edit: you can still catch mouse input in OpenGL

Coordinate confusion

I subclassed QGraphicsItem and reimplemented paint.
In paint I wrote something like this for labeling the item:
painter->drawText("Test",10,40);
After some time I think It may be useful to handle labeling with seperate item. So I wrote something like this.
QGraphicsTextItem *label = new QGraphicsTextItem("TEST",this);
setPos(10,40);
But two "TEST" drawing do not appear in the same place on screen. I guess difference may be related with item coordinates - scene coordinates. I tried all mapFrom... and mapTo... combinations inside QGraphicsItem interface but no progress. I want to drawings to appear in the same place on screen.
What I miss?
I assume that you are using the same font size and type in both cases. If the difference in position is very small the reason can be the QGraphicTextItem is using some padding for the text it contains. I would try to use QGraphicsSimpleTextItem that is not going to add fancy stuff internally and see if you still have the same problem. The coordinates system is the same one if you use painter or setPost so that is not the problem. If this doesn't help I will suggest to specify the same rect for both to avoid Qt adding it owns separation spaces.