QLabel rotation - c++

I am having a label set from a pixmap as follow:
QLabel* label_image;
label_image= new QLabel (this);
label_image->setGeometry(0, 0, 500, 30);
QPixmap pm;
pm ...
label_image->setPixmap(pm);
I would like now to rotate it by 90 degrees. How to do so?

You have two options here. The first is to subclass QLabel and provide the rotation functionality that you require. Alternatively, you can use QTransform to rotate the QPixmap that you set on the QLabel.
Rather than regurgitating the answer, this link explains how to do the rotation and maintain the original size of the image.
Update due to invalid link...
Essentially, you can't rotate the actual label, but you can rotate the pixmap, then set this on the label widget
QPixmap pm;
...
QTransform trans;
trans.rotate(90);
label_image->setPixmap(pm.transformed(trans));
If you keep rotating the same image, it will distort, so ensure any rotation is always from a stored, non-rotated pixmap.

Related

How to set QPixmap in a specific coordinates of QLabel?

I want to display an image in a QLabel in a specific position with covering a particular area so that I can use the rest of the QLabel part by other images. By the following, I was able to display image with my set size.
QPixmap pix("....image_path..../image.png");
ui->label->setPixmap(pix);
int width = 300;
int height = 320;
ui->label->setPixmap(pix.scaled(width,height));
But I am curious to know how to set the position of Image in QLabel. Are the any function in Qt by using which I can set my image coordinates in a QLabel?
Appreciate your help. Thanks in advance.
You can do this by painting a new pixmap in layers. Pseudo code
QPixmap map;
QPainter p(&map)
p.drawImage(w1,h1,img_1)
...
p.drawImage(wn,hn,img_n)
label.setPixmap(map)

Interactively editing an existing rectangle on a QPixmap?

I'm trying to creat a Dicom GUI Toolkit where the user selects some dicom images and the image of first dicom image from the selected ones will be shown. Then the user clicks on the image and the image pops out with bigger image window. In this shown bigger image, the image will consist of a red colored rectangle that contains necessary regions of the Dicom image while the unnecessary region is outside the rectangle. The user should then have the option to change the rectangle by mouse.
Until now, I have been able to show the big dicom image with the rectangle in it using QLabel which is by the following code snippets.
void MainWindow::showBigImage()
{
QPixmap bigimage;
bigimage.load(imageName.c_str());
QPainter painter(&bigimage);
painter.setPen(Qt::red);
QRectF rect(xmin, ymin, xmax, ymax);
painter.drawRect(rect);
QSize bigsize = ui->bigImageLabel->size();
ui->bigImageLabel->setPixmap(bigimage.scaled(bigsize, Qt::IgnoreAspectRatio, Qt::FastTransformation));
ui->bigImageLabel->show();
}
and the big image on the app looks like the following:
Can you please suggest me how I should now make the rectangle editable by the user where the user can set the existing red rectangle as per his or her wish?
I also tried similar thing using QGraphicsView and QGraphicsScene with the following code:
void MainWindow::showBigImage()
{
QGraphicsScene* scene = new QGraphicsScene;
scene->addPixmap(bigimage);
ui->bigImageView->setScene(scene);
ui->bigImageView->show();
}
And this code gives me the following look:
As you can see, I could not fit the image to the boundaries of QGraphicsView, could you suggest me how to do it? Could you also suggest me how to add the red rectangle(that I showed in the example using QLabel) on the QGraphicsView without adding the rectangle on the QPixmap?
In order to get the red selection rectangle, Qt provides the class QRubberBand. The docs state:
The QRubberBand class provides a rectangle or line that can indicate a selection or a boundary.
By subclassing the image object and implementing the mouse handling functions, to create the rubber band on mousePressEvent, update its position on mouseMoveEvent and grab its final rect on mouseReleaseEvent, the QRubberBand will simplify the problem.
If you want the QRubberBand to show all the time, just create it when you display the enlarged image and don't hide it on releasing the mouse button.
As for displaying the image in the QGraphicsView, the code you displayed doesn't set the geometry of the QGraphicsScene and QGraphicsView, so you're seeing a border. If you don't want that, you should set them accordingly. Also note that QGraphicsView has a function fitInView, which you could use, after having retrieved an area from the QRubberBand, in order to zoom into the selected area.

Drawing a scalable QIcon using QPainter

I want to design a new QIcon and want it to look like a fixed text with a rounded rectangle around it
.-----.
| Phy |
`-----ยด
The icon is supposed to scale without the "pixel-blocks" effect when painting on a QPainter that eventually has a scale transformation applied (for example when I paint into a widget that is part of a QGraphicsView with a scale applied on its scene).
Therefor, I have difficulties knowing how I should paint my QIcon. If I do it in the following way, I will paint a QPixmap that always has a fixed amount of pixels, thus introducing the pixel-blocks effect inevitably when the scale is large enough
void MyWidget::drawIcon(QPainter *painter, QPoint pos) {
QPixmap pixmap = icon.pixmap(QSize(22, 22),
isEnabled() ? QIcon::Normal
: QIcon::Disabled,
isChecked() ? QIcon::On
: QIcon::Off);
painter->drawPixmap(pos, pixmap);
}
What I am looking for is a way similar to how QFont with drawText works. Regardless on how large my scale is, when I draw fonts it always looks sharp and I cannot detect individual pixels.
I imagine that I could tell QPainter to paint my icon into a given pixel rectangle, and QPainter transforms the rectangle itself before letting my QIconEngine::paint render the item into a possibly larger rectangle or pixmap. But I see no way how I could do something like this.
Am I just being stupid and not seeing the obvious solution?
I was indeed completely dump. I can just use QIcon::paint and pass it the rectangle. It will correctly delegate the request to the icon engine.
I do this by creating my icons/images as SVG files, and using QSvgRenderer to paint them onto a QPainter. The required classes are in the SVG module.

Why do the first added item always appear at the center in a graphics scene/view in Qt?

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.

QGraphicsView not repainting on scroll event

QT 4.7
I have a QGraphicsView / QGraphicsScene. The scene has a custom QGraphicsItem the whole scene is not displayed at one time, so it has a viewport.
I'm overriding the paint() method of my QGraphicsItem as follows:
void paint(QPainter *painter,
const QStyleOptionGraphicsItem *option,
QWidget *widget)
{
painter->setClipRect(option->exposedRect);
painter->save();
// Default identity matrix
QTransform transform;
// Apply some transform later
// The next line breaks stuff
painter->setTransform(transform);
// m_image is just a preloaded pixmap (i.e. watermark on all of these items).
painter->drawImage(QPoint(0,0), this->m_image);
painter->restore();
// Snip, do more drawing...
}
If I ever try to setTransform on the QPainter (i.e. if I'm trying to rotate the item), the view stops repainting the scene as a response to the horizontal or vertical scrollbars used to pan. The view also stops resizing the scene when I zoom in or zoom out.
The view will refresh if I resize the window or drag the window offscreen and then back onscreen. I've been looking over the QPainter Documentation as well as the examples and I can't quite figure out what I'm doing wrong. I'm assuming it's something to do with the coordinate system.
A guess:
The QPainter that comes to your paint method already has a transform on it that takes into account the viewport attributes (scale, rotation, etc.). When you call setTransform within your paint method you are blowing all that away. You probably want to perform a matrix operation on the existing transform rather than creating a new one.
Since you are calling setClipRect on your painter but then trying to paint under a completely different transform, you are painting outside your clip rect and nothing is happening.
It works when you resize or drag the window off screen because that forces a "redraw everything," so your clip rect includes your painting area in your alternate transform. Although I'm surprised it would appear in the correct location.