在屏幕上的确切位置保存和恢复Qt小部件

时间:2017-05-29 11:32:47

标签: c++ qt

我一直在尝试使用现有代码来保存和恢复标签,以及将来Qt小部件放在用户放置它的屏幕上的确切位置。我尝试这样做的方法是在QPoint position头文件中使用Label变量。

到目前为止,保存和恢复代码运行良好。唯一的事情是导入的标签图像保存在左上角的屏幕上。我似乎无法破解保存并将其恢复到用户使用QPoint position变量放置的位置。

label.h

#ifndef LABEL_H
#define LABEL_H

#include "mainwindow.h"

#include <QtGui>
#include <QLabel>
#include <QFileDialog>
#include <QBoxLayout>
#include <QVariant>
#include <QGraphicsItem>
#include <QPoint>

class Label : public QLabel
{
public:
    // Constructor
    Label();

    Label(QWidget* aParentWidget)
        : QLabel(aParentWidget)
        , m_nMouseClick_X_Coordinate(0)
        , m_nMouseClick_Y_Coordinate(0)
    {
        m_pParentWidget = aParentWidget;
    }

    ~Label();

    void mousePressEvent(QMouseEvent* event);
    void mouseMoveEvent(QMouseEvent* event);
    void mouseDoubleClickEvent(QMouseEvent* event);

    QPoint position;  // Exact location debugged on console

private:
    int  m_nMouseClick_X_Coordinate;
    int  m_nMouseClick_Y_Coordinate;
    QWidget* m_pParentWidget;
};

#endif // LABEL_H

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();

    // Display coordinates in qDebug
    //position = event->pos();

    position = event->pos();
    //qDebug() << event->pos();
    qDebug() << position;
}

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

mainwindow.cpp

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

void MainWindow::writeSettings()
{
  // Save location
  //https://www.ics.com/designpatterns/book/qsettings.html

  int i = 1;
  Q_FOREACH(auto label, labels)
  {
    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)
    {
      // Restore position
      // Need to find a way to find coordinates of x and y from label
      QPoint pos = settings.value("pos", QPoint(Label.position)).toPoint();

      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;
      ++i;
    }
}

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

1 个答案:

答案 0 :(得分:0)

您必须记下并阅读该位置才能添加还原功能。下面的代码只是这个想法的草稿,我还没有测试过,但希望能引导你找到最终的解决方案。

注意:我还包括一些修改以简化您的代码,因为您有冗余信息会使解决方案复杂化。提到两个:

  • 我已移除m_nMouseClick_X_Coordinatem_nMouseClick_Y_Coordinateposition,您可以起诉内置的pos()而不是

  • 您可以使用QWidget::parentWidget访问父

修改后的Label

class Label : public QLabel
{
public:    
    // Constructor
    Label();

    Label(QWidget* aParentWidget)
        : QLabel(aParentWidget)
    {
        // for this solution aParentWidget CANNOT be null
    }

    ~Label();

    void mousePressEvent(QMouseEvent* event);
    void mouseMoveEvent(QMouseEvent* event);
    void mouseDoubleClickEvent(QMouseEvent* event);
};

在.cpp文件中(为简洁起见,删除了明显的代码)

void Label::mousePressEvent(QMouseEvent *event)
{
    move(parentWidget()->mapFromGlobal(event->globalPos()));
}

void Label::mouseMoveEvent(QMouseEvent *event)
{
    move(parentWidget()->mapFromGlobal(event->globalPos()));
}

void MainWindow::writeSettings()

settings.setValue(QString("image-%1-pos").arg(i), label->pos());

void MainWindow::readSettings()

this->labels.back()->setPixmap(pixmap);
this->labels.back()->move(settings.value(QString("image-%1-pos").arg(i), QPoint(0, 0)).toPoint()); // default position (0, 0)

标签的位置现在取决于父母的位置。如果你想让它完全全局改变各自的行:

// write
settings.setValue(QString("image-%1-pos").arg(i), mapToGlobal(label->pos()));

// read
this->labels.back()->move(mapFromGlobal(settings.value(QString("image-%1-pos").arg(i)).toPoint()));

恢复标签时可能会出现小的闪烁,因为您显示标签后会移动它们。要修复它,您可以先读取位置,然后将其作为参数传递给创建标签的函数。要使其与按钮兼容,请将其设为默认值(0,0)。