简体   繁体   English

QT 包含图片 window 每隔几个像素就会停止调整大小

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM