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.
Related
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);
I have a qwt plot in my application. I want to show a small tool tip to show the value of the point at which mouse is pointed on the curve. I found that I have to use QwtPlotPicker for this, but couldn't find any proper example to implement this in my code. I am new to Qwt so it would be great if anyone could help me solve this problem.
Thanks, Rakesh.
The author himself says here:
A QwtPlotPicker gives you the current position of the mouse ( in screen and plot coordinates ). Then you need to find the closest points of your curves. You can use QwtPlotCurve::closestPoint(), but in most cases you can find a much faster implementation depending on the characteristics of your data.
When you need to compare the mouse position with the lines between the points you need the pixel position of these points ( use QwtPlot::canvasMap ).
Maybe looking at the CanvasPicker of the eventfilter example helps.
I implemented it in my own class, which is a subclass of QwtPlot. In the constructor I have the following:
QwtPlotPicker* plotPicker = new QwtPlotPicker(this->xBottom, this->yLeft, QwtPicker::CrossRubberBand, QwtPicker::AlwaysOn, this->canvas());
QwtPickerMachine* pickerMachine = new QwtPickerClickPointMachine();
plotPicker->setStateMachine(pickerMachine);
connect(plotPicker, SIGNAL(selected(const QPointF&)), this, SLOT(onSelected(const QPointF&)));
Now in my class (where the this pointer refers to) I should implement the slot onSelected(const QPointF&) which will give the plot coordinates.
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.
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
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.