在单击QT中单击图像时,尝试立即显示用户编辑操作的结果

Trying to display instantly the result of a user editing action when clicking an image in Qt

本文关键字:单击 用户 显示 编辑 操作 结果 QT 图像      更新时间:2023-10-16

我正在尝试使用QT图像类中不存在的一些自定义图像版工具来实现图像编辑器。当用户单击图像场景执行某些操作时,我希望在GUI应用程序中立即更新图像,并实时向用户显示更改(图形像素,缩放...(。问题在于,只能在单独的类中进行单击时(至少据我所知(进行编辑图像的操作(在我下面显示的示例中,该类称为GraphicsScene(,因此我不知道如何要将编辑的图像转移到MainWindow类。

简而在图像上执行每个用户操作后的实时时间。

为了清楚起见,我接下来显示我现在拥有的代码方案。

main.cpp

#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

mainWindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    Ui::MainWindow *ui;
private slots:
private:
};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFileDialog>
#include <QApplication>
#include <QMouseEvent>
#include <QGraphicsSceneMouseEvent>
#include "graphicsscene.h"
extern QImage Image_original, Image_modified;
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}
MainWindow::~MainWindow()
{
    delete ui;
}
void MainWindow::on_actionOpen_Image_triggered()
{
    QDir dir;
    QString filename=QFileDialog::getOpenFileName(this,
                                                  tr("Open Background"),
                                                  path,
                                                  tr("Images (*.png *.bmp *.jpg *.jpeg);;All files (*.*)"));
    Image_original.load(filename);
    GraphicsScene * img = new GraphicsScene( this );
    img->addPixmap(QPixmap::fromImage(Image_original));
    ui->preview->setScene(img);
}

为了在单击时能够跟踪坐标,并在网周围遵循一些建议,我创建了一个称为GraphicsScene的QgraphicsScene的子类,其标题为:

GraphicsScene.h

#ifndef GRAPHICSSCENE_H
#define GRAPHICSSCENE_H
#include <QGraphicsScene>
#include <QGraphicsSceneMouseEvent>
#include <QPointF>
#include <QList>
class GraphicsScene : public QGraphicsScene
{
    Q_OBJECT
public:
    explicit GraphicsScene(QObject *parent = 0);
    virtual void mousePressEvent(QGraphicsSceneMouseEvent * mouseEvent);
signals:
public slots:
private:
    int x, y;
};
#endif // GRAPHICSSCENE_H

最后,要执行图像版,关联的源文件是:

graphicsscene.cpp

#include "graphicsscene.h"
#include <iostream>
using namespace std;
extern QImage Image_original, Image_modified;
GraphicsScene::GraphicsScene(QObject *parent) :
    QGraphicsScene(parent)
{
    this->setBackgroundBrush(Qt::gray);
}
void GraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent * mouseEvent)
{
    QGraphicsScene::mousePressEvent(mouseEvent);
    if (mouseEvent->button()==Qt::LeftButton)
    {
        x=mouseEvent->scenePos().x();
        y=mouseEvent->scenePos().y();
    }
    Image_modified=some_custom_image_editing_code(Image_original, x, y);
}

理想情况下,我想在进行Mousepressevent之后在MainWindow中执行以下操作:

img->addPixmap(QPixmap::fromImage(Image_modified));
ui->preview->setScene(img);

我将高度感谢任何想法。

由于要单击包含pixMap的项目,因此不需要覆盖qgraphicsscene m m ousepressevent方法,因为您可以单击图像之外,因此最好在qgraphicspixmapixmapitem中覆盖该方法。

而不是使用外部访问图像,而是qt是更好的信号和插槽,但是只有从qObject继承的类才能具有这些属性,不幸的是,qgraphicspixmapitem不能从中继承,但是我们可以将其用作接口。<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

GraphicsPixmapitem.h

#ifndef GRAPHICSPIXMAPITEM_H
#define GRAPHICSPIXMAPITEM_H
#include <QGraphicsPixmapItem>
#include <QObject>
class GraphicsPixmapItem : public QObject, public QGraphicsPixmapItem
{
    Q_OBJECT
public:
    explicit GraphicsPixmapItem(QObject *parent=0);
protected:
    void mousePressEvent(QGraphicsSceneMouseEvent * event);
signals:
    void newPixmap(const QPixmap p);
};
#endif // GRAPHICSPIXMAPITEM_H

GraphicsPixmapitem.cpp

#include "graphicspixmapitem.h"
#include <QGraphicsSceneMouseEvent>
GraphicsPixmapItem::GraphicsPixmapItem(QObject * parent):QObject(parent)
{
}
void GraphicsPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    QPoint p = QPoint(event->pos().x(), event->pos().y());
    QPixmap pix = pixmap();
    if(!pix.isNull()){
        QRect rect(QPoint(), pix.rect().size()/2);
        rect.moveCenter(p);
        QPixmap modified = pix.copy(rect);
        modified = modified.scaled(pix.rect().size(), Qt::KeepAspectRatioByExpanding);
        emit newPixmap(modified);
    }
    QGraphicsPixmapItem::mousePressEvent(event);
}

在以前的代码中,我们创建了Signal NewPixMap,它使用MainWindow中的名为OnNewPixMap的插槽连接了。

mainWindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "graphicsscene.h"
#include "graphicspixmapitem.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
private slots:
    void on_actionOpen_triggered();
    void onNewPixmap(const QPixmap pixmap);
private:
    Ui::MainWindow *ui;
    GraphicsPixmapItem *item;
    GraphicsScene *scene;
    QPixmap original_pixmap;
    QPixmap new_pixmap;
};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QGraphicsView>
#include <QFileDialog>
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    scene = new GraphicsScene(this);
    ui->preview->setScene(scene);
    item = new GraphicsPixmapItem;
    /*ui->preview->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    ui->preview->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);*/
    scene->addItem(item);
    connect(item, &GraphicsPixmapItem::newPixmap, this, &MainWindow::onNewPixmap);
}
MainWindow::~MainWindow()
{
    delete ui;
}
void MainWindow::on_actionOpen_triggered()
{
    QString path = QDir::homePath();
    QString filename=QFileDialog::getOpenFileName(this,
                                                  tr("Open Background"),
                                                  path,
                                                  tr("Images (*.png *.bmp *.jpg *.jpeg);;All files (*.*)"));
    original_pixmap = QPixmap(filename);
    item->setPixmap(original_pixmap);
}
void MainWindow::onNewPixmap(const QPixmap pixmap)
{
    new_pixmap = pixmap;
    QFile file("new_file.png");
    file.open(QIODevice::WriteOnly);
    new_pixmap.save(&file, "PNG");
}

在该插槽中作为测试,我将图像保存在生成可执行文件的文件夹中。

在您的代码中,我看到您使用qimage,如果要继续使用它,则可以使用以下

new_pixmap.toImage()

完整的示例可在此处找到