QLabel定位问题

发布于 2025-01-07 09:22:51 字数 4899 浏览 0 评论 0原文

我在 Qt 中制作了以下基本图像查看器,但是它的行为并不符合预期,出于对神圣事物的热爱,我无法找出问题所在。基本上,它是一个 QLabel,我将电影设置为 jpeg/gif,然后调整大小并将其居中于屏幕上。问题是,当它启动时,它既不会调整大小也不会在屏幕上居中,而是填充窗口并拉伸图像。

例如:https://i.sstatic.net/YJf2x.jpg

如果我把它放在QVBoxLayout,也是一样的。 但是,如果我执行缩放/缩放(通过按 keyRelease 事件中定义的“+”或“-”),它会将图像居中并完美调整其大小。

例如:https://i.sstatic.net/1uqd4.png

所以问题似乎只是当它加载图像时,但我不知道在哪里。我知道它一定很简单,但我搜索了 Qt 文档、谷歌,尝试了注释行的组合并添加不同的功能,但我什么也没想到。

顺便说一句, loadImage 函数底部的输出打印了正确的尺寸和位置,但它似乎不尊重它们。

#include <QtGui>
#include "imageviewer.h"

ImageViewer::ImageViewer(QString imagePath)
{
    setWindowTitle(imagePath + " - Simple Image Viewer");
    currentImageSize=new QSize(0,0);

    fillScreen();

    imageLabel = new QLabel;
    imageLabel->setBackgroundRole(QPalette::Base);
    imageLabel->setScaledContents(true);

    QVBoxLayout* layout=new QVBoxLayout();
    layout->addWidget(imageLabel);

    QFrame* frame=new QFrame();
    frame->setLayout(layout);
    //setCentralWidget(frame);

    setCentralWidget(imageLabel);

    loadImage(imagePath);
}

void ImageViewer::loadImage(QString imagePath){
    currentImagePath=imagePath;
    open(imagePath);
    fitImage();
    centerImage();
    QTextStream out(stdout) ;

    //for debugging:
    out << QString("size: %1 %2 pos: %3 %4")
              .arg(imageLabel->width())
              .arg(imageLabel->height())
              .arg(imageLabel->x())
              .arg(imageLabel->y());
}

void ImageViewer::open(QString imagePath){
      if (!imagePath.isEmpty()) {
        QImage image(imagePath);

        currentImageSize=new QSize(image.size().width(),image.size().height());

        if (image.isNull()) {
            QMessageBox::information(this, tr("Image Viewer"),
                                     tr("Cannot load %1.").arg(imagePath));
            return;
        }

        imageLabel->resize(currentImageSize->width(),
                           currentImageSize->height());
        QMovie* movie=new QMovie(imagePath);
        imageLabel->setMovie(movie);
        movie->start();

        scaleFactor = 1.0;

        imageLabel->adjustSize();
      }
}

void ImageViewer::fitImage(){
    int windowHeight, windowWidth;
    int imageHeight, imageWidth;

    windowHeight = this->height();
    windowWidth = this->width();
    imageHeight = currentImageSize->height();
    imageWidth = currentImageSize->width();

    if(imageHeight > windowHeight || imageWidth > windowWidth){
        imageLabel->resize((windowHeight-40)*imageWidth/imageHeight, 
                            windowHeight-40);
    }
}

void ImageViewer::centerImage(){
    int windowHeight, windowWidth;
    int imageHeight, imageWidth;

    windowHeight = this->height();
    windowWidth = this->width();
    imageHeight = imageLabel->height();
    imageWidth = imageLabel->width();

    int x,y;
    x=(windowWidth-imageWidth)/2;
    y=(windowHeight-imageHeight)/2;
    imageLabel->move(x,y);
}

void ImageViewer::fillScreen(){
    this->showMaximized();
}

void ImageViewer::scaleImage(double factor)
{
    double newScale = scaleFactor + factor;

    if(newScale>MAX_SCALE || newScale<MIN_SCALE){
        return;
    }
    else{
        scaleFactor=newScale;
    }

    QTextStream out(stdout);
    imageLabel->resize(scaleFactor * currentImageSize->width(), 
                       scaleFactor * currentImageSize->height());

    out<< scaleFactor << " " 
       << imageLabel->height() << "," 
       << imageLabel->width() <<endl;

    centerImage();
}


void ImageViewer::keyReleaseEvent(QKeyEvent *event){
    if(event->key()==Qt::Key_Plus){
        scaleImage(SCALE_STEP);
    }
    if(event->key()==Qt::Key_Minus){
        scaleImage(0-(SCALE_STEP));
    }
}

其标题为:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QLabel>
#include <QMainWindow>

class ImageViewer : public QMainWindow
{
    Q_OBJECT

public:
    ImageViewer(QString imagePath);
    void open(QString imagePath);
    void loadImage(QString imagePath);
private:
    void fitImage();
    void centerImage();
    void fillScreen();
    void scaleImage(double);
    void adjustScrollBar(QScrollBar*,double);
    void keyReleaseEvent(QKeyEvent *);
private:
    QLabel* imageLabel;
    double scaleFactor;
    QSize* currentImageSize;
    QString currentImagePath;
    QString currentDir;
    QStringList neighbourImages;
    static const double MAX_SCALE=2.0;
    static const double MIN_SCALE=0.2;
    static const double SCALE_STEP=0.1;
};

#endif // MAINWINDOW_H

编辑:这是首次加载后的 QLabel 与放大一次后的 QLabel 之间的差异:diffchecker.com/1uDcb83

I have made the following basic image viewer in Qt, however it does not behave as expected and for the love of what is holy, I cannot find out what the problem is. Basically, it's a QLabel for which I have set the movie as a jpeg/gif and then resized and centered it on the screen. The problem is, when it starts up, it neither resizes nor centers it on the screen, but instead it fills the window and stretches the image.

example:https://i.sstatic.net/YJf2x.jpg

If I put it in the QVBoxLayout, it's the same thing. However, if I perform a scaling/zoom (by pressing "+" or "-", as defined in the keyRelease event), it centers the image and resizes it perfectly.

example:https://i.sstatic.net/1uqd4.png

So the problem only seems to be when it loads the image, but I can't find out where. I know it must be something simple, but I've searched the Qt docs, google, tried combinations of commenting lines and adding different functions and I've come up with nothing.

By the way, the output from the bottom of the loadImage function prints the correct size and position, but it doesn't seem to respect them.

#include <QtGui>
#include "imageviewer.h"

ImageViewer::ImageViewer(QString imagePath)
{
    setWindowTitle(imagePath + " - Simple Image Viewer");
    currentImageSize=new QSize(0,0);

    fillScreen();

    imageLabel = new QLabel;
    imageLabel->setBackgroundRole(QPalette::Base);
    imageLabel->setScaledContents(true);

    QVBoxLayout* layout=new QVBoxLayout();
    layout->addWidget(imageLabel);

    QFrame* frame=new QFrame();
    frame->setLayout(layout);
    //setCentralWidget(frame);

    setCentralWidget(imageLabel);

    loadImage(imagePath);
}

void ImageViewer::loadImage(QString imagePath){
    currentImagePath=imagePath;
    open(imagePath);
    fitImage();
    centerImage();
    QTextStream out(stdout) ;

    //for debugging:
    out << QString("size: %1 %2 pos: %3 %4")
              .arg(imageLabel->width())
              .arg(imageLabel->height())
              .arg(imageLabel->x())
              .arg(imageLabel->y());
}

void ImageViewer::open(QString imagePath){
      if (!imagePath.isEmpty()) {
        QImage image(imagePath);

        currentImageSize=new QSize(image.size().width(),image.size().height());

        if (image.isNull()) {
            QMessageBox::information(this, tr("Image Viewer"),
                                     tr("Cannot load %1.").arg(imagePath));
            return;
        }

        imageLabel->resize(currentImageSize->width(),
                           currentImageSize->height());
        QMovie* movie=new QMovie(imagePath);
        imageLabel->setMovie(movie);
        movie->start();

        scaleFactor = 1.0;

        imageLabel->adjustSize();
      }
}

void ImageViewer::fitImage(){
    int windowHeight, windowWidth;
    int imageHeight, imageWidth;

    windowHeight = this->height();
    windowWidth = this->width();
    imageHeight = currentImageSize->height();
    imageWidth = currentImageSize->width();

    if(imageHeight > windowHeight || imageWidth > windowWidth){
        imageLabel->resize((windowHeight-40)*imageWidth/imageHeight, 
                            windowHeight-40);
    }
}

void ImageViewer::centerImage(){
    int windowHeight, windowWidth;
    int imageHeight, imageWidth;

    windowHeight = this->height();
    windowWidth = this->width();
    imageHeight = imageLabel->height();
    imageWidth = imageLabel->width();

    int x,y;
    x=(windowWidth-imageWidth)/2;
    y=(windowHeight-imageHeight)/2;
    imageLabel->move(x,y);
}

void ImageViewer::fillScreen(){
    this->showMaximized();
}

void ImageViewer::scaleImage(double factor)
{
    double newScale = scaleFactor + factor;

    if(newScale>MAX_SCALE || newScale<MIN_SCALE){
        return;
    }
    else{
        scaleFactor=newScale;
    }

    QTextStream out(stdout);
    imageLabel->resize(scaleFactor * currentImageSize->width(), 
                       scaleFactor * currentImageSize->height());

    out<< scaleFactor << " " 
       << imageLabel->height() << "," 
       << imageLabel->width() <<endl;

    centerImage();
}


void ImageViewer::keyReleaseEvent(QKeyEvent *event){
    if(event->key()==Qt::Key_Plus){
        scaleImage(SCALE_STEP);
    }
    if(event->key()==Qt::Key_Minus){
        scaleImage(0-(SCALE_STEP));
    }
}

for which the header is:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QLabel>
#include <QMainWindow>

class ImageViewer : public QMainWindow
{
    Q_OBJECT

public:
    ImageViewer(QString imagePath);
    void open(QString imagePath);
    void loadImage(QString imagePath);
private:
    void fitImage();
    void centerImage();
    void fillScreen();
    void scaleImage(double);
    void adjustScrollBar(QScrollBar*,double);
    void keyReleaseEvent(QKeyEvent *);
private:
    QLabel* imageLabel;
    double scaleFactor;
    QSize* currentImageSize;
    QString currentImagePath;
    QString currentDir;
    QStringList neighbourImages;
    static const double MAX_SCALE=2.0;
    static const double MIN_SCALE=0.2;
    static const double SCALE_STEP=0.1;
};

#endif // MAINWINDOW_H

EDIT: this is the difference between the QLabel after it first loads and the QLabel after zoomed in once: diffchecker.com/1uDcb83

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

心是晴朗的。 2025-01-14 09:22:52

我相信问题是您正在尝试在主窗口构造函数中计算您的大小。目前这些尺寸尚未确定。您需要覆盖 QWidget::resizeEvent() (在 ImageViewer 中)并在那里进行尺寸计算。该函数在小部件的几何形状设置后调用。

I believe the problem is that you are trying to calculate your sizes in the main window constructor. These sizes are not established at this point. You need to override QWidget::resizeEvent() (in ImageViewer) and do your sizing calculations there. That function is called after the geometry for the widget has been set.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文