[英]Is it possible to make a QLabel Pixmap image appear in a circle using stylesheet
[英]QLabel with pixmap image getting blurred
我有一张图片,需要显示为QLabel
的背景。 这是我的代码(从Qt文档扑杀这里 ):
#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 x357。我正在使用的图像是这个 (尺寸是2560 x 1600,两者的长宽比均接近1.6,太大而无法在此处上传,因此将上传图片的屏幕截图):
但是,当我打开应用程序并在其中添加图像时,我在QLabel
获得的图像非常模糊:
如何使标签中的图像与实际图像一样定义(为bmp格式,因此必须在Mac的“文件打开”对话框中将mime类型更改为bmp
)?
当我通过QPainter
进行此任务时,即从图像文件中制作一个QImage
,然后将其传递给绘画工具并调用update
它将很好。 但是我需要能够在单击时内联缩放图像(这是通过在QLabel
上调用resize()
实现的),并且QPainter
方式不允许我缩放图像。
平台-OS X 10.10(Retina显示屏),Qt 5.3.1,32位。
您正在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的Qt 5.5.1修复程序中获得了基本实现。 像QLabel一样,它也缓存Pixmap,因此不必每次调用paintEvent时都重新缩放,除非该窗口小部件实际上已调整大小。
您将图像压缩了4倍以上(2560-> 570),在震荡了这么多之后,似乎图像中的一些小细节无法保留。
实际上,在将图像缩小很多之后,您将获得或多或少的期望。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.