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

Save and restore Qt widgets on exact location on the screen

本文关键字:恢复 Qt 小部 保存 位置 屏幕      更新时间:2023-10-16

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

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

标签.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

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

主窗口.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();
}

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

注意:为了简化您的代码,我还进行了一些修改,因为您有冗余信息,这使解决方案复杂化。举两个:

  • 我已经删除了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)。