C++ QT包含图片窗口大小调整,每几个像素停止一次

C++ QT包含图片窗口大小调整,每几个像素停止一次,c++,qt,image-resizing,window-resize,C++,Qt,Image Resizing,Window Resize,我有一个带有水平布局和QLable的简单对话框窗口。 QLable包含图像。我使用resize事件缩放此图像以适应窗口大小 我使用了来自QT示例的代码。标题: #ifndef SCALEIMGDIALOG_H #define SCALEIMGDIALOG_H #include <QDialog> #include <QLabel> namespace Ui { class ScaleImgDialog; } class ScaleImgDialog : pu

我有一个带有水平布局和QLable的简单对话框窗口。 QLable包含图像。我使用resize事件缩放此图像以适应窗口大小

我使用了来自QT示例的代码。标题:

#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
\ifndef SCALEIMGDIALOG\H
#定义SCALEIMGDIALOG_H
#包括
#包括
名称空间用户界面{
类ScaleImgDialog;
}
类ScaleImgDialog:公共QDialog
{
Q_对象
公众:
显式ScaleImgDialog(QWidget*parent=0);
~ScaleImgDialog();
受保护的:
void resizeEvent(QResizeEvent*event)覆盖;
私人:
Ui::ScaleImgDialog*Ui;
qpixmg;
};
#恩迪夫
和源文件:

#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));
}
#包括
#包括“scaleImgDialog.h”
#包括“ui_scaleImgDialog.h”
//主对话框窗口名为ScaleImgDialog ui\u ScaleImgDialog.h是自动生成的
ScaleImgDialog::ScaleImgDialog(QWidget*父项):
QDialog(父级),
用户界面(新用户界面::ScaleImgDialog),
testImg(:/images/testImg.jpeg)
{
用户界面->设置用户界面(此);
setWindowFlags(windowFlags()^Qt::WindowContextHelpButtonHint);
setWindowFlags(windowFlags()| Qt::WindowMaximizeButtonHint);
}
ScaleImgDialog::~ScaleImgDialog()
{
删除用户界面;
}
void ScaleImgDialog::resizeEvent(QResizeEvent*)
{
int newHeight=高度();
newHeight-=newHeight/10;//防止递归调整大小
//图像的高度比宽度大得多,所以我用它来缩放
ui->imgdisplaylab->setPixmap(testImg.scaledToHeight(newHeight));
}
尺寸增加效果良好。但我面临的下一个问题是:当我试图缩小窗口时,它不能正常工作。窗口缩小一点,大小调整停止。下一次尝试时,它会缩小一点,然后再次停止,依此类推: 第二件奇怪的事情是:若你们不释放鼠标按钮,那个么你们可以自由调整窗口的大小,直到它比开始时的大小大。最大化窗口按钮,并返回到以前的大小也很好。
如何修复此问题并使窗口大小正常?

我将完全删除
resizeEvent
,并覆盖
paintEvent
,以将对话框本身用作绘制设备,并直接在其上绘制pixmap(这使得
QLabel
不必要)

比如:

#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);
}
#包括
void ScaleImgDialog::paintEvent(QPaintEvent*event)
{
Q尺寸(宽度()-20,高度()-20);
QPixmap pixmap=testImg.scaled(大小,Qt::keepasspectratio);
QRect区域(rect().center()-pixmap.rect().center(),pixmap.rect().size());
油漆工(本);
painter.drawPixmap(面积,pixmap);
}

看来我找到了答案:使用paintEvent()而不是在resizeEvent()中更改图像:

资料来源:

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;
}
因此,所有尺寸计算都是在resizeEvent()中完成的(仅当需要时),而图形本身是在paintEvent()中进行的。此代码保持图像大小比例,并在必要时向边框添加一些“空白”:

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;
}