c++ - 在 Qt 中保存和恢复带有图像的 QLabel

标签 c++ qt qpixmap qlabel

目前我正在使用 QLabel 在我正在开发的 GUI 应用程序上显示图像。它的工作原理是当用户单击“添加图形”按钮时,将创建一个新的动态标签并显示在窗口中。当用户双击标签时,文件对话框打开,用户可以选择要显示的图像,效果很好。

应用的要求是在应用关闭时恢复图像,这样用户就不用再输入图像了,我正在苦苦思索解决方案。我正在尝试使用 QBufferQSettings 来恢复图像,但是有一行代码只会使应用程序崩溃。

主窗口.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    readSettings();
    ui->setupUi(this);

    // Set up the window size
    this->setWindowTitle(QString::fromUtf8("Raspberry PI GUI v1.0"));

    this->resize(800, 400);

    // Add label Button
    button = new QPushButton("Add Graphic", this);
    button->setGeometry(QRect(QPoint(10, 20), QSize(200, 50)));
    button->show();
    QObject::connect(button, SIGNAL(pressed()), this, SLOT(input_label()));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::input_label()
{
    Label *label = new Label(this);
    label->setText("New Graphic");
    label->show();
}

void MainWindow::writeSettings()
{
    QByteArray bArray;
    QBuffer buffer(&bArray);
    buffer.open(QIODevice::WriteOnly);
    this->label->pixmap()->save(&buffer, "PNG"); // This line of code is crashing everything

    QSettings settings("Save state", "GUIApp");
    settings.beginGroup("MainWindow");
    settings.setValue("image", bArray);
}

void MainWindow::readSettings()
{
     QSettings settings("Save state", "GUIApp");

     settings.beginGroup("MainWindow");
     QByteArray image = settings.value("image", QByteArray()).toByteArray();
}

void MainWindow::closeEvent(QCloseEvent *event)
{
    writeSettings();
    event->accept();
}

标签.cpp

#include "label.h"

//---------------------------------------
// Deconstructor
//---------------------------------------
Label::~Label()
{
}

void Label::mousePressEvent(QMouseEvent *event)
{
    // Move the coordinates on the main window
    m_nMouseClick_X_Coordinate = event->x();
    m_nMouseClick_Y_Coordinate = event->y();
}

void Label::mouseMoveEvent(QMouseEvent *event)
{
    //-------------------------------------------------------------
    // Allow the user to drag the graphics on the Display
    //-------------------------------------------------------------
    move(event->globalX()-m_nMouseClick_X_Coordinate-m_pParentWidget->geometry().x(),

        event->globalY()-m_nMouseClick_Y_Coordinate-m_pParentWidget->geometry().y());
}

void Label::mouseDoubleClickEvent(QMouseEvent *event)
{
    //QByteArray bArray;
    //QBuffer buffer(&bArray);
    //buffer.open(QIODevice::WriteOnly);

    //--------------------------------
    // Open file dialog
    //--------------------------------
    QFileDialog dialog(this);
    dialog.setNameFilter(tr("Images(*.png, *.dxf, *.jpg"));
    dialog.setViewMode(QFileDialog::Detail);
    QString fileName = QFileDialog::getOpenFileName(this,
        tr("Open Images"),
        "/home",
        tr("Image Files (*.png *.jpg *.bmp)"));

    if (!fileName.isEmpty())
    {
        QImage image(fileName);
        Label::setPixmap(fileName);
        Label::adjustSize();
    }
}

最佳答案

QLabel::pixmap 如果没有设置像素图,则返回一个空指针。同样,您应该检查您的属性文件是否有 image条目集,并且只有在这种情况下才能恢复图像。

void MainWindow::writeSettings()
{
    if (this->label->pixmap() != nullptr) {
        QByteArray bArray;
        QBuffer buffer(&bArray);
        buffer.open(QIODevice::WriteOnly);
        this->label->pixmap()->save(&buffer, "PNG");

        QSettings settings("Save state", "GUIApp");
        settings.beginGroup("MainWindow");
        settings.setValue("image", bArray);
    }
}

void MainWindow::readSettings()
{
    QSettings settings("Save state", "GUIApp");

    settings.beginGroup("MainWindow");
    QByteArray image = settings.value("image").toByteArray();
    if (!image.isNull()) {
        QPixmap pixmap;
        if (pixmap.loadFromData(image)) {
            this->label->setPixmap(pixmap);
        }
    }
}

更新

当您创建 QLabel您将它存储在局部变量中,但它从未分配给 this->label ,因此您在执行任何 this->label->... 时可能正在访问垃圾操作。

void MainWindow::input_label()
{
    Label *label = new Label(this);
    label->setText("New Graphic");
    label->show();
    this->label = label; // try with this
}

这是一种解决方法,如果可行,您必须检查其余逻辑,然后您可以添加多个 QLabel s,但只保存最后一个...恢复状态时相同:this->label可能不会被创建,所以你必须创建它,以及初始化 this->labelnullptr在构造函数中。

几个标签

对于多个标签,我建议使用 QList<QLabel*>容器而不是单个 QLabel成员,并保存所有这些。恢复时,只需在恢复图像之前以编程方式插入新标签即可。

class MainWindow ... {
  // ...
  QList<QLabel*> labels;
  // ...
}

void MainWindow::input_label()
{
    QLabel *label = new QLabel(this);
    label->setText("New Graphic");
    label->show();
    this->labels.append(label);
}

void MainWindow::writeSettings()
{
    int i = 1;
    Q_FOREACH(auto label, labels) { // save all existing labels with an image
      if (label->pixmap() != nullptr) {
        QByteArray bArray;
        QBuffer buffer(&bArray);
        buffer.open(QIODevice::WriteOnly);
        label->pixmap()->save(&buffer, "PNG");

        QSettings settings("Save state", "GUIApp");
        settings.beginGroup("MainWindow");
        settings.setValue(QString("image-%1").arg(i), bArray);
        ++i;
      }
    }
}

void MainWindow::readSettings()
{
    QSettings settings("Save state", "GUIApp");

    settings.beginGroup("MainWindow");
    int i = 1;
    while (true) {
      QByteArray image = settings.value(QString("image-%1").arg(i)).toByteArray();
      if (!image.isNull()) {
        QPixmap pixmap;
        if (pixmap.loadFromData(image)) {
          input_label(); // add new label
          this->labels.back()->setPixmap(pixmap);
        }
      } else break; // no more images
      ++i;
    }
}

关于c++ - 在 Qt 中保存和恢复带有图像的 QLabel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43842905/

相关文章:

c++ - 当我不输出变量时代码中断;当我这样做的时候工作。什么?

c++ - 如何在 C++ 中获取类型的大小?

c++ - 子类特征类型

c++ - 程序在运行时崩溃,但在单步执行时不会崩溃

c++ - 将一个 Qlabel 的 QPixmap 复制到另一个 Qlabel

c++ - 为什么我的窗口没有显示任何 QPixmap 图片?

c++ - Boost.Serialization 是否释放加载指针期间创建的内存?

c++ - 摆脱重复代码?

qt - 下载短文件期间阻止 Qt 应用程序

c++ - Qt中线程间共享的像素图