This question already has an answer here:
Draw an item in a static location relative to the QGraphicsView
(1 answer)
Closed 9 years ago.
I have a QGraphicsScene that is filled with QGraphicsItems, and the user is able to pan and zoom around to inspect all of the various QGraphicsItems. However, I would like to have a QGraphicsTextItem label that always stays put at the top left of the screen. Ignoring the zooms is easy, as I can just setFlags(QGraphicsItem::ItemIgnoresTransformations), but I've yet to figure out how to force the position to stay at the top-left. What's the best way to make my label "float" in the same place?
I think the only (realiable) way to do that is to recalculate position for your text item every frame. To do this, simply subclass QGraphicsView, override paintEvent and use QGraphicsView::mapToScene() to calculate new position. Something like:
void MyGraphicsView::paintEvent(QPaintEvent*)
{
QPointF scenePos = mapToScene(0,0); // map viewport's top-left corner to scene
m_textItem->setPos(scenePos);
}
I have done this many many times and it has worked very well.
Of course you could just create normal QLabel like Arnold Spence mentions in his answer. However, this won't work in many situations (e.g. if you really want to place label on top of graphics view and you are using OpenGL-accelerated viewport).
Perhaps you just want to put a regular QLabel right on the view instead of trying to make a part of the scene stay in one place as discussed in this question.
Note: As mentioned in another answer, this trick will often not work with hardware accelerated views. In these cases, you will need to make the text items a part of the scene.
Related
This question already has answers here:
Use the same widget in two different layouts in Qt
(3 answers)
Closed 6 years ago.
I have a QMainWindow with a large number of graphs (I am using QCustomPlot for those). As a result, each graph is inevitably rather small in size. All the graphs in this page are drawn on the 1st page of a QStackedWidget.
To provide a clearer view for each graph (one at a time), I want to show a larger view of a graph when the user clicks on one.
A potential solution is to have a 2nd page on the QStackedWidget in which the larger graph can be shown. The question is how do I go about assigning the selected graph to the 2nd page of a QStackedWidget?
Alternatively, is there a better way to enlarge a specific QWidget so that it occupies the mainwindow from end to end?
How can I let the 2nd page of the QStackedWidget update its contents directly from the selected graph?
Is there an example I could see to understand what I should do?
In addition to the linked question, at this point you may be focusing on premature micro-optimizations. The smaller graph will be rendered on a much lower resolution, so it wouldn't look too good if you blow it up.
If it was your own custom widget with some complex drawing, you could easily draw onto a pixmap, then draw the big pixmap onto the big graph, and downscale it for the small graph. But then again, you'd be doing a whole lot of extra drawing for all those small graphs on the odd chance they get to the center position. You can optimize that, but will increase complexity.
It would still be possible to do it for QCustomPlot, but it won't be that easy, and I doubt the effort to do it will see worthy returns. So just create an extra big graph when you need it and don't worry about performance before you run into problems with it. The difference will be negligible, as graphs aren't too complex to draw. You won't be updating one graph from another, you will simply be using the same data set in two graphs.
I want to make a menu that will take an undetermined quantity of labels and spread them out horizontally so that 3 are visible on screen at once. When pressing left/right it will go to the next one, the one that is selected is always in the center of the screen horizontally with the other two on the left/right of the screen.
The problem is that I also want a smooth transition not just a replacement. They need to wrap endlessly.
Not sure where to begin, not finding examples on google.
The concept you are talking about was popularized by Apple under the name "Cover Flow".
There is a widget like that available under a permissive license here: https://code.google.com/p/pictureflow/
I take it you want something a bit simpler (only show three labels, less fancy 3D effect), but I assume this is a good starting point.
Another one is the PathView QML element:
http://qt-project.org/doc/qt-5/qml-qtquick-pathview.html#details
It is even closer to what you like to do, feature-wise. It is also available in Qt4 and there is a tutorial here: http://qt-project.org/doc/qt-4.8/declarative-modelviews-pathview.html
This is a follow-up question of Making an editable flowchart in Qt/C++.
I want to add a QGraphicsItem to a QGraphicsGridLayout in a way that the item takes up its own spot in the grid and then automatically centers in its 'cell'.
I am using QGraphicsView and QGraphicsScene, and drag-and-drop to any location works, but it's looking messy, and could prove to be problematic in future development.
What do I have to do so the item snaps to the grid and centers in its cell?
PS: I have taken a look at http://qt-project.org/doc/qt-4.8/graphicsview-basicgraphicslayouts.html as an example but this didn't help me to solve my problem.
Also, it'd be ideal to have this layout and its data be savable to a text file, etc. I'm assuming a 2D array would be the best way to do this. Should I somehow make the QGraphicsGridLayout based on that array, or is there a better solution?
This is related to one of my other questions.
If I am tiling a large image by creating a separate QGraphicsItem (with the raster data as its pixmap), how do I keep track of the QGraphicsItem's position within the scene? Obviously for raster data, it is important to keep all the tiles "touching" to make a continuous image and they also have to be in the right place so the image doesnt look jumbled.
Does each tile have to have positioning methods that move it in relation to it's neighbors on the top/left/bottom/right? This seems kind of clunky. Is there a better way to make them all move together?
In other words, if I pan the scene with scroll bars, or pick up the image and drag/move it around in the scene, I want all the tiles to also move and stay in the right position relative to each other.
What is the best approach for controlling the layout, which tiles need to be rendered (i.e. only the visible ones), and populating the data only once it is needed? Also, once a tile has been rendered, is the data from it ever dropped, and repopulated from the image file, say if it stays out of view for a while, then comes back later if someone pans to that section?
There are (more than) 2 ways of doing this:
Use QGraphicsItemGroup which
handles grouping of your tile items
for you. It moves, selects, updates
it's group members as if they are
one. I've never used it but from the
doc, it seems to work with typical
applications.
Paint the tiles yourself in the
paint() of one custom item. This
gives you total control on how to
place and draw the tiles while the
item truly acts as one item since it
is, well, one item. This is what I
do.
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.