QLabel定位问题
我在 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我相信问题是您正在尝试在主窗口构造函数中计算您的大小。目前这些尺寸尚未确定。您需要覆盖 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.