So i trying to do paint and i run into some problems. When i try to draw QGraphicsRectItem it doesnt get positioned where i want it.
QColor neki1(23, 145, 195);
QPen pen1(neki1, 2, Qt::DashLine, Qt::RoundCap, Qt::RoundJoin);
QGraphicsRectItem* sel = new QGraphicsRectItem(0,0,100,100);
sel->setPen(pen1);
sel->setBrush(Qt::transparent);
addItem(sel);
this is the code and picture and you can see it get position like somewhere in the middle of the screen. On the begining of the program i set scene->setSceneRect(QRectF(0, 0, 1000, 1000)); but cordinates in top left corner of scene are not 0,0. Is there anyway to solve this?
Thank you for your help.
Oh, that's common mistake. You had set scene's bounding rect. But QGraphcsView can scroll about and zoom into that scene.
It "aims" at top left corner of scene, so 0,0 is somewhere near middle. You have to match view to the scene's bounding rect, e.g. with setAlignment, fitInView, etc.
Related
In my paintEvent method for a custom widget for a game I'm writing, After calling the various model objects' render() methods to render them to the widget, I am trying to render the "Hi-Score" text. Here's the general code for just the text drawing:
painter.fillRect(event->rect(), QColor(0, 0, 0));
painter.drawImage(QRectF(event->rect().x(), event->rect().y() + 30, 512, 512), getGameBoardImage());
//...rendering other model components
painter.setBrush(QBrush(QColor(255, 255, 255)));
//painter.setFont(getGameFont());
painter.setFont(QFont("Times New Roman", 16, QFont::Bold));
painter.drawText(0, 0, "HI-SCORE");
I 'was' trying to draw the text in a custom font loaded from resource (I found an answer on here for that) but it wouldn't even display, even with a white brush. I thought maybe it was because it was because I didn't 'set' a font, but setting it to Times New Roman doesn't display anything either. What might I be doing wrong? As you can see the background is a black background with the game board painted on top but leaving a small buffer at the top and bottom. Do I need to do something special to display the text? Please don't suggest using a QLabel because I am trying to keep it all in one widget if possible. If I must, I will split the Hi-Score and 1-Ups into 2 other label sets with specialty fonts.
you code look ok, but you are drawing at 0,0 which is the top left corner of the widget canvas AND the text is actually there but not visible...
draw instead at
painter.drawText(margin, y+margin, "HI-SCORE");
where y is the high of the font used to draw the text and margin is you know a little margin border to make it look better something like 5 units
update
you can get the value of the text you are painting doing somthing like
QFont font("times", 25);
QFontMetrics fm(font);
int pixelsW{fm.width("HI-SCORE")};
int pixelsH{fm.height()};
I am using Qt Graphics Framework for displaying an image. I have opened a raw image in subclassed QGraphicsScene in QGraphicsView using addPixmap(). I have added zoom feature by using scale function and drag mode is set as scroll hand drag. Now, I need to get the pixel coordinates within the scene on mouse hover such that the x and y value show the pixel in the image (drawn by pixmap) the mouse is currently pointing to. I tried using pos() but it didn't work.
Here is the code from Widget.cpp:
img = openImage(dirPath2.toLocal8Bit().data(),
sizeX,sizeY,file_heade,scan_heade,bpp,sign);
QPixmap x = QPixmap(sizeX,sizeY);
x.convertFromImage(img,Qt::AutoColor);
scene->addPixmap(x);
ui->disp_img->setDragMode(QGraphicsView::ScrollHandDrag);
GraphicsScene.h:
class GraphicsScene : public QGraphicsScene {
public:
GraphicsScene(QWidget *parent) : QGraphicsScene(parent){}
};
(preferably the pixmap coordinates but even that doesn't happen and if the values change when zoomed I will use scale factor to get the original values)
I suggest you start by reading about Qt's Graphics Coordinate System.
There are various layers of coordinate systems and you need to think about those with which you dealing with. At the top layer is the screen (or view), which is where the mouse coordinates reside.
The next layer from the view is the graphics scene. Graphics items, such as the QGraphicsPixmapItem which you added with addPixmap, reside here. The graphics scene can be visualised as a world of items, each with there own position and orientation.
Moving to the last coordinate system is an item's local coordinate system. If, for example, we take a rectangle, it may have local coordinates of (-5, -5, 10, 10) for (x, y, w, h). This item is then placed in the scene at some position. If its position is the origin of the scene (0,0), then the item's local coordinates would read the same as its scene coordinates.
However, if we move the rectangle +5 units in x-axis, its local coordinates are the same, but its scene coordinates would now be (0, -5, 10, 10).
Likewise, the view (QGraphicsScene) is a window into the scene and can be looking at the whole scene, or just part of it. As the view's top left coordinate is (0,0), it may map onto (0,0) of the scene, or may not, depending on what area of the scene the view is looking at.
So, by getting a mouse position you're starting in the view's coordinates and need to convert to the scene's coordinate system. Fortunately, Qt provides lots of useful functions for this at every level.
To convert the mouse coordinates from the view to the scene, you can use the view's mapToScene function.
Using the scene coordinates you can then get an item and map that to the local coordinate's of the item with the item's mapFromScene.
I inherited from the QGraphicsObject and created a new class that has a pixmap and sets its transform origin point to:
setTransformOriginPoint(boundingRect().center());
But when I call setRotation() on the my class (which is added to a QGraphicsView using the scene), the rotation doesn't use the center as the rotation anchor. How can I set the center to be the anchor of the rotation ? Thanks !
More information: calling setRotation() outside of a sceneEvent function it works, but inside a sceneEvent, upon a pinch gesture, the origin point doesn't work.
Draw pixmap at QRect(0, 0, pixmap.width(), pixmap.height(). Use this rectangle for bounding rect also. Use setPos to move the item around the scene. Use setTransformOriginPoint(pixmap.width() / 2, pixmap.height() / 2) to set the origin point. These coordinates are in the item coordinates, so they should point at the pixmap's center regardless of the item's position.
Can anyone provide some basic pointers on placing CCSprites on screen?
Example:
CCSize s = CCDirector::sharedDirector()->getWinSize();
With s, say I wanted to position a sprite on the very bottom of the screen starting at 0, think something like grass.
if I am running at 1024 x 768, middle is:
setPosition( ccp(s.width/2, s.height/2) );
so starting all the way left and middle would be:
setPosition( ccp(0, s.height/2) );
So how do I get farther down?
setPosition( 0, s.height) );
This puts me starting at the top left and staying along the top of the screen.
Any help would be appreciated.
Position is relative to the sprite's parent, as well as its anchorPoint.
anchorPoint generally ranges from 0 to 1 for each coordinate, with a default of 0.5. I say "generally" because it can really be any value, but ranges outside of 0-1 place you outside of the bounds of the sprite.
For example, an anchorPoint of (0,0) makes positions relative to the bottom left. (1,0) is the bottom right, (0,1) is the top left and (1,1) is the top right. (0.5,0.5) is the very center of the sprite, which is the default.
Basically you just multiple the value by the width to get the relative position.
If you want to place a sprite at the very bottom of the screen (the bottom left corner aligned with the bottom left corner of the screen), you can do it multiple ways, based on the anchorPoint alone.
With the default anchorPoint of (0.5,0.5), the position would be (sprite.contentSize.width/2, sprite.contentSize.height/2).
If you set the anchorPoint to (0,0), the same position is obtained by simply (0,0).
If you wanted to move that sprite to the very center of the screen (the center of the sprite right in the middle), with an anchorpoint of (0.5, 0.5), the position would be (s.width/2, s.height/2).
This is all assuming you are adding a sprite to a parent the size of the screen, which is where the 2nd part of positioning comes in.
Position is also relative to the sprite's parent - which could be any other CCNode (CCLayer, another CCSprite, etc).
The way to think of that is not much different than adding a full screen node - except think in terms of the parent's size and position, not the screen.
Also Just to add something, all buttons start out in the middle of the screen then you can move them from there. if you wanted to button at (0,0):
CCLabelTTF *label1 = [CCLabelTTF labelWithString:#"Press Me!" fontName:#"Marker Felt" fontSize:20];
CCMenuItemLabel *button1 = [CCMenuItemLabel itemWithLabel:label1 block:^(id sender) { NSLog(#"button1 pressed"); }];
button1.position = ccp(-(s.width/2) , -(s.height/2)); // <---
I have a graphics scene and view, and then I'm adding a single element. But no matter what x/y coordinate I give, it always appears at the center of the graphics view.
Why does this happen, and how can I make it appear at, say, the upper left corner?
This is my code:
scene = new QGraphicsScene(this);
ui->graphicsView->setScene(scene);
QGraphicsEllipseItem *ellipseItem = scene->addEllipse(150, 150, 10, 10);
The reason for this is that by default, QGraphicsScene computes its sceneRect by adding all the item rectangles together. When you add the first item, it automatically uses it as the scene rect. And by default QGraphicsView scales and centers on the scene rect.
If you know the final or desired scene rect, set it before you add any item:
scene->setSceneRect(0, 0, 800, 600);
scene->addEllipse(150, 150, 10, 10);
You probably want to define a scene-rectangle that is shown by the QGraphicsView. I think the default view just shows the centered bounding rectangle of the current scene, which is just your ellipse. You can use QGraphicsView::fitInView to define the area to be shown explicitly.