【问题标题】:Save and restore QLabels with images in Qt在 Qt 中保存和恢复带有图像的 QLabels
【发布时间】:2017-05-08 08:20:08
【问题描述】:

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

应用程序的要求是在应用程序关闭时恢复图像,以便用户不必再次输入图像,我正在努力想出一个解决方案。我正在尝试使用QBuffers 和QSettings 来恢复图像,但是有一行代码只会使应用程序崩溃。

ma​​inwindow.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();
}

label.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();
    }
}

【问题讨论】:

  • this->label->pixmap() 可能会返回 0,这可能会使您的应用程序崩溃。您能否检查是否返回了有效的像素图?

标签: c++ qt qpixmap qlabel


【解决方案1】:

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
}

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

几个标签

对于多个标签,我建议使用 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;
    }
}

【讨论】:

  • 嗨,感谢您的意见,我刚刚用加载的图像进行了尝试,但关闭应用程序时仍然崩溃
  • 嗯......它在我创建的一个小项目中为我工作......它是否在同一行崩溃?您可以提供任何其他信息吗?
  • 顺便说一句,mouseDoubleClickEvent 中的QImage image(fileName); 是不必要的,你根本没有使用它。
  • 我已经评论了“this->label->pixmap()->save(&buffer, "PNG");"这一行在 writeSettings() 中,不幸的是它仍然崩溃。会不会是 closeEvent() 部分中的某些东西导致它崩溃?
  • 我将尝试获得一个代码解决方案,该解决方案可以直接在用户将图像放在屏幕上的位置恢复图像,并在应用程序上提供坐标。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-04
  • 1970-01-01
  • 2013-05-01
  • 1970-01-01
  • 2023-03-31
相关资源
最近更新 更多