我有一张图片需要显示为QLabel
的背景。这是我的代码(从Qt文档here中挑选出来):
#include <QtWidgets>
#include "imageviewer.h"
ImageViewer::ImageViewer()
{
imageLabel = new QLabel;
imageLabel->setBackgroundRole(QPalette::Base);
imageLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
imageLabel->setScaledContents(true);
setCentralWidget(imageLabel);
createActions();
createMenus();
resize(570,357);
}
bool ImageViewer::loadFile(const QString &fileName)
{
QImageReader reader(fileName);
const QImage image = reader.read();
if (image.isNull()) {
QMessageBox::information(this, QGuiApplication::applicationDisplayName(),
tr("Cannot load %1.").arg(QDir::toNativeSeparators(fileName)));
setWindowFilePath(QString());
imageLabel->setPixmap(QPixmap());
imageLabel->adjustSize();
return false;
}
imageLabel->setPixmap(QPixmap::fromImage(image).scaled(size(),Qt::KeepAspectRatio,Qt::SmoothTransformation));
return true;
}
void ImageViewer::open()
{
QStringList mimeTypeFilters;
foreach (const QByteArray &mimeTypeName, QImageReader::supportedMimeTypes())
mimeTypeFilters.append(mimeTypeName);
mimeTypeFilters.sort();
const QStringList picturesLocations = QStandardPaths::standardLocations(QStandardPaths::PicturesLocation);
QFileDialog dialog(this, tr("Open File"),
picturesLocations.isEmpty() ? QDir::currentPath() : picturesLocations.last());
dialog.setAcceptMode(QFileDialog::AcceptOpen);
dialog.setMimeTypeFilters(mimeTypeFilters);
dialog.selectMimeTypeFilter("image/jpeg");
while (dialog.exec() == QDialog::Accepted && !loadFile(dialog.selectedFiles().first())) {}
}
void ImageViewer::createActions()
{
openAct = new QAction(tr("&Open..."), this);
openAct->setShortcut(tr("Ctrl+O"));
connect(openAct, SIGNAL(triggered()), this, SLOT(open()));
}
void ImageViewer::createMenus()
{
fileMenu = new QMenu(tr("&File"), this);
fileMenu->addAction(openAct);
menuBar()->addMenu(fileMenu);
}
标题文件:
#ifndef IMAGEVIEWER_H
#define IMAGEVIEWER_H
#include <QMainWindow>
class QAction;
class QLabel;
class QMenu;
class QScrollArea;
class QScrollBar;
class ImageViewer : public QMainWindow
{
Q_OBJECT
public:
ImageViewer();
bool loadFile(const QString &);
private slots:
void open();
private:
void createActions();
void createMenus();
QLabel *imageLabel;
QAction *openAct;
QMenu *fileMenu;
};
#endif
主:
#include <QApplication>
#include <QCommandLineParser>
#include "imageviewer.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QGuiApplication::setApplicationDisplayName(ImageViewer::tr("Image Viewer"));
ImageViewer imageViewer;
imageViewer.show();
return app.exec();
}
正如你所看到的,视口大小是570乘357.我使用的图像是this(大小是2560乘1600,两者的宽高比几乎都是1.6,太大了,无法在这里上传,所以将上传图片的截图:
但是当我打开应用程序并在那里添加图像时,我在QLabel
中获得的图像非常模糊:
如何使标签中的图像定义为实际图像(它是bmp格式,因此您必须在Mac中的文件打开对话框中将mime类型更改为bmp
?< / p>
当我通过QPainter
执行此任务时,即从图像文件中取出QImage
,然后将其传递给画家并调用update
它就可以了。但是我需要能够在点击时内联缩放图像(我正在resize()
上调用QLabel
),而QPainter
方式不允许我缩放图像。
平台 - OS X 10.10(Retina显示),Qt 5.3.1,32位。
答案 0 :(得分:2)
您在Qt 5.3中的Retina显示Mac上遇到QLabel中的已知错误: https://bugreports.qt.io/browse/QTBUG-42503
从您的图像来看,当您使用QLabel时,看起来您只是获得图像的非视网膜版本,但如果您在QPainter中手动编码,则您将获得源QImage的完整分辨率。如果是这样的话,那确实是由这个错误引起的。
您有两种解决方案:
滚动您自己的解决方案,不要使用QLabel。没有理由你不能在不使用QLabel的情况下轻松“缩放图像内联”(只需使用带有覆盖的PaintEvent的自定义QWidget类)。
升级到已修复此错误的Qt版本。无论如何,这可能是正确的解决方案,除非最新版本中存在导致应用程序出现问题的任何回归。根据错误报告,这个问题已在v5.5.0中修复,因此最新的v5.5.1应该可以正常工作。
第一种方法的一个例子(为了简洁,我会将标题保留在头文件中,非常简单):
void ImageWidget::setImage(QImage image)
{
//Set the image and invalidate our cached pixmap
m_image = image;
m_cachedPixmap = QPixmap();
update();
}
void ImageWidget::paintEvent(QPaintEvent *)
{
if ( !m_image.isNull() )
{
QSize scaledSize = size() * devicePixelRatio();
if (m_cachedPixmap.size() != scaledSize)
{
QImage scaledImage = m_image.scaled(scaledSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
m_cachedPixmap = QPixmap::fromImage(scaledImage);
m_cachedPixmap.setDevicePixelRatio(devicePixelRatio());
}
QPainter p(this);
p.drawPixmap(0, 0, m_cachedPixmap);
}
}
这只是一个非常基本的小部件,只需将QImage绘制为完整大小,尊重DevicePixelRatio,从而利用Retina分辨率。注意:在非视网膜机器上编码,所以我不能保证它适用于Retina,但我从Qt 5.5.1修复了QLabel的基本实现。与QLabel一样,它也会缓存Pixmap,因此每次调用paintEvent时都不必重新缩放,除非实际调整了窗口小部件的大小。
答案 1 :(得分:0)
你压缩图像的次数超过4倍(2560 - > 570),看起来图像中的小细节在肆无忌惮之后无法保留。
实际上,在缩小图像之后,你会得到更多或更少的东西。