[英]QT containing picture window resizing stops every few pixels
I have a simple dialog window with horizontal layout and QLable in it.我有一个简单的对话框 window,其中包含水平布局和 QLable。 QLable contains image. QLable 包含图像。 I use resize event to scale this image to fit window size.我使用调整大小事件来缩放此图像以适合 window 大小。
I used code from QT example.我使用了 QT 示例中的代码。 Header: Header:
#ifndef SCALEIMGDIALOG_H
#define SCALEIMGDIALOG_H
#include <QDialog>
#include <QLabel>
namespace Ui {
class ScaleImgDialog;
}
class ScaleImgDialog : public QDialog
{
Q_OBJECT
public:
explicit ScaleImgDialog(QWidget *parent = 0);
~ScaleImgDialog();
protected:
void resizeEvent(QResizeEvent *event) override;
private:
Ui::ScaleImgDialog *ui;
QPixmap testImg;
};
#endif
and source file:和源文件:
#include <QDebug>
#include "scaleImgDialog.h"
#include "ui_scaleImgDialog.h"
// main dialog window name is ScaleImgDialog ui_scaleImgDialog.h is generated automatically
ScaleImgDialog::ScaleImgDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::ScaleImgDialog),
testImg(":/images/testImg.jpeg")
{
ui->setupUi(this);
setWindowFlags(windowFlags() ^ Qt::WindowContextHelpButtonHint);
setWindowFlags(windowFlags() | Qt::WindowMaximizeButtonHint);
}
ScaleImgDialog::~ScaleImgDialog()
{
delete ui;
}
void ScaleImgDialog::resizeEvent(QResizeEvent *)
{
int newHeight = height();
newHeight -= newHeight / 10; // to prevent recursive resizing
// Image heigh is much bigger then width so i use scaling by it
ui->imgDisplayLabel->setPixmap(testImg.scaledToHeight(newHeight));
}
Size increase works well.尺寸增加效果很好。 But I faced next problem: when I try to make window smaller it doesn't work properly.但是我遇到了下一个问题:当我尝试使 window 更小时,它无法正常工作。 Window shrinks a little and resizing stops. Window 缩小一点并停止调整大小。 On next try it shrinks a little more and stops again and so on:在下一次尝试时,它会缩小一点并再次停止,依此类推: And second strange thing: if you don't release mouse button it is possible to resize window freely until it is bigger than size on beginning.第二个奇怪的事情:如果您不释放鼠标按钮,则可以自由调整 window 的大小,直到它大于开始时的大小。 Maximize window button and return to previous size also works well.最大化 window 按钮并返回到以前的大小也很好用。 How to fix this and make window resing normal?如何解决此问题并使 window 恢复正常?
I would drop the resizeEvent
altogether, and override paintEvent
instead, to use the dialog itself as a paint device and draw the pixmap directly on it (which makes a QLabel
unnecessary).我会完全放弃resizeEvent
并覆盖paintEvent
,以将对话框本身用作绘图设备并直接在其上绘制像素图(这使得QLabel
不必要)。
Something like:就像是:
#include <QPainter>
void ScaleImgDialog::paintEvent(QPaintEvent *event)
{
QSize size(width() - 20, height() - 20);
QPixmap pixmap = testImg.scaled(size, Qt::KeepAspectRatio);
QRect area(rect().center() - pixmap.rect().center(), pixmap.rect().size());
QPainter painter(this);
painter.drawPixmap(area, pixmap);
}
So, look like I found an answer: to use paintEvent() instead of changing image in resizeEvent():所以,看起来我找到了答案:使用 paintEvent() 而不是在 resizeEvent() 中更改图像:
class ScaleImgDialog : public QDialog {
Q_OBJECT
public:
explicit ScaleImgDialog(QWidget *parent = 0);
~ScaleImgDialog();
protected:
void paintEvent(QPaintEvent *) override;
void resizeEvent(QResizeEvent *) override;
private:
Ui::ScaleImgDialog *ui;
QPixmap testImg;
int imageWidth;
int imageHeight;
int widthOffset;
int heightOffset;
};
And Source:和来源:
ScaleImgDialog::ScaleImgDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::ScaleImgDialog),
testImg(":/images/testImg.jpeg")
{
ui->setupUi(this);
setWindowFlags(windowFlags() ^ Qt::WindowContextHelpButtonHint);
setWindowFlags(windowFlags() | Qt::WindowMaximizeButtonHint);
resizeEvent(nullptr);
}
ScaleImgDialog::~ScaleImgDialog()
{
delete ui;
}
void ScaleImgDialog::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.drawPixmap(widthOffset, heightOffset, imageWidth, imageHeight, testImg);
}
void ScaleImgDialog::resizeEvent(QResizeEvent *) {
QSize winSize = size();
imageHeight = testImg.height();
imageWidth = testImg.width();
if (testImg.height() > winSize.height()) {
double heightRatio = (double)winSize.height() / testImg.height();
imageHeight = (int)(testImg.height() * heightRatio);
imageWidth = (int)(testImg.width() * heightRatio);
}
if (imageWidth > winSize.width()) {
double widthRatio = (double)winSize.width() / imageWidth;
imageHeight = (int)(imageHeight * widthRatio);
imageWidth = (int)(imageWidth * widthRatio);
}
widthOffset = winSize.width() > imageWidth ? ((winSize.width() - imageWidth) / 2) : 0;
heightOffset = winSize.height() > imageHeight ? ((winSize.height() - imageHeight) / 2) : 0;
}
So all size calculations are done in resizeEvent() (only when they needed) and drawing itself is happening in paintEvent().所以所有的尺寸计算都在 resizeEvent() 中完成(仅在需要时),并且绘制本身发生在 paintEvent() 中。 This code keeps image size ratio and adds some "white spaces" to borders if necessary:此代码保持图像大小比例,并在必要时向边框添加一些“空白”:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.