QPixmap 在 Qt 中加载许多图像
Posted
技术标签:
【中文标题】QPixmap 在 Qt 中加载许多图像【英文标题】:QPixmap load many images in Qt 【发布时间】:2018-09-10 21:27:33 【问题描述】:我正在尝试从文件夹加载图像并通过单击GUI
上的按钮(类似于 Windows 图像查看器)查看上一个和下一个图像。此文件夹中的图片名称为xxxx_00.jpg
到xxxx_99.jpg
,因此我使用index++
和index--
在单击按钮时更改文件名。
我的代码可以很好地显示第一张图片,但是当我单击按钮查看上一张或下一张图片时,它总是显示
QPixmap::scaled: Pixmap 是一个空像素图
并返回一个空图像(第一个图像消失但没有显示新图像)。
这是我的代码:
在 mainwindow.cpp 中
void MainWindow::on_pushButton_4_clicked() //previous image
if (index < 1)
index = 99;
QLabel label;
label.setText("Go back");
label.show();
else
index--;
RefreshFilename();
loadimage();
void MainWindow::on_pushButton_5_clicked() //next image
if (index > 98)
index = 0;
QLabel label;
label.setText("ALL SET");
label.show();
else
index = index + 1;
RefreshFilename();
loadimage();
void MainWindow::loadimage()
// image.load(filename);
// im = image.scaled(500,500,Qt::KeepAspectRatio);
imageObject = new QImage();
imageObject->load(filename);
image = QPixmap::fromImage(*imageObject);
im = image.scaled(400,400,Qt::KeepAspectRatio);
scene = new QGraphicsScene(this);
scene->addPixmap(image);
scene->setSceneRect(image.rect());
ui->mainimage->setScene(scene);
我花了整整 2 天的时间来调试这个,但仍然不知道。我期待任何建议和支持!
顺便说一句,Refreshfilename
函数工作正常,所以我没有在这里粘贴它。
【问题讨论】:
你有 QLabel * label 类的成员,然后在构造函数中初始化它: label = new QLabel;然后重用标签:label->setPixmap();标签-> 显示();。请记住,函数完成时会删除局部变量。你不觉得你声明的 QLabels 是本地的吗? 是的,但我没有使用 Qlabel 来显示图像。单击按钮时,我仅使用 QLabel 打印一些注释。我使用 imageObject、image、scene 等来显示图像,这些变量都是 Mainwindow 类中的公共成员。 同样的事情可以做,只需将label->setPixmap(...)改为label->setText(...) 是的,但我使用 *scene 显示图像的原因是我希望图像显示在主窗口上,如果我使用标签,它会显示在新窗口中。是不是因为主窗口无法重新加载场景? 你说的场景我没有看到,如果你需要帮助你应该提供一个minimal reproducible example,你能做到吗? 【参考方案1】:原因
由于我不知道RefreshFilename();
做了什么,所以我不能确切地知道原因是什么。
但是,我发现您的代码中有一个重大缺陷,即每次调用 MainWindow::loadimage
时都会创建一个新场景,这会导致内存泄漏。
当你提供更多细节时,我会在这里更具体。
解决方案
设置一次场景并添加一个QGraphicsPixmapItem,然后在loadImage
中更新该项目的像素图。
将当前编号保留在类属性中。
再次,一旦添加详细信息,我将更加具体。
示例
无论如何(等你提供MVCE),我已经根据你的任务描述准备了一个工作示例:
#define IMAGE_COUNT 99
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
m_imgNum(0),
m_item(new QGraphicsPixmapItem())
auto *widget = new QWidget(this);
auto *layoutMain = new QVBoxLayout(widget);
auto *layoutButtons = new QHBoxLayout();
auto *btnPrev = new QPushButton(tr("Previous"), this);
auto *btnNext = new QPushButton(tr("Next"), this);
auto *view = new QGraphicsView(this);
view->setScene(new QGraphicsScene(this));
view->scene()->addItem(m_item);
layoutButtons->addStretch();
layoutButtons->addWidget(btnPrev);
layoutButtons->addWidget(btnNext);
layoutButtons->addStretch();
layoutMain->addWidget(view);
layoutMain->addLayout(layoutButtons);
setCentralWidget(widget);
resize(640, 480);
loadImage();
connect(btnPrev, &QPushButton::clicked, [this]()
if (m_imgNum > 0)
m_imgNum--;
else
m_imgNum = IMAGE_COUNT;
loadImage();
);
connect(btnNext, &QPushButton::clicked, [this]()
if (m_imgNum < IMAGE_COUNT)
m_imgNum++;
else
m_imgNum = 0;
loadImage();
);
void MainWindow::loadImage()
m_item->setPixmap(QString("images/image_%1.jpg").arg(m_imgNum, 2, 10, QChar('0')));
其中m_imgNum
、m_item
和loadImage
在标头中声明为:
private:
inline void loadImage();
int m_imgNum;
QGraphicsPixmapItem *m_item;
【讨论】:
以上是关于QPixmap 在 Qt 中加载许多图像的主要内容,如果未能解决你的问题,请参考以下文章
无法在 Qt5/cmake 项目中加载 Qt 资源文件中指定的图像