如何使用 QPushButton 以编程方式将 QGraphicsView 上的图像传递给 QTableView

How to pass images on QGraphicsView to QTableView programmatically using QPushButton

我一直在研究如何以编程方式使用 QPushButtonQGraphicsView 上加载的图像存储到 QTableView 的行中,但我发现的信息是这样的远没有那么多。

我有 1 个 QGraphicsView、一个 QPushButton(发送按钮)、一个 QTableView 和一个 QLineEdit。当我使用加载按钮上传图像时,我会在 QGraphicsViewQLineEidt 上显示它们(我显示图像的路径),如果我单击发送按钮,QLineEdit 应该添加到 QTableView 的第一行(正在发生)并且图像应该存储在 QTableView 中。

但是,QGraphicsView 上的图像没有存储到 QTableView 中,也没有传递任何内容。

目前是这样的:

预期的行为是:

我创建了一个 ItemDelegate class,负责调整 QGraphicsView 上要存储在 QTableView 中的图像大小 该部分如下所示:

这是mainwindow.h

#include <QGraphicsView>
#include <QGraphicsScene>
#include "imagedelegate.h"

namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    void addData();
    void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const;

private slots:
    void on_sendBtn_clicked();
    void on_loadBtn_clicked();
private:
    Ui::MainWindow *ui;
    QStandardItemModel *model;
    QGraphicsScene *leftScene;
};
#endif // MAINWINDOW_H

这里是 mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "imagedelegate.h"
#include <QGraphicsPixmapItem>
#include <QBuffer>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    leftScene = new QGraphicsScene(this);
    ui->graphicsView->setScene(leftScene);
    ui->graphicsView->show();
    model = new QStandardItemModel();
    ui->tableView->setModel(model);
}

MainWindow::~MainWindow()
{
    delete ui;
}
void MainWindow::addData()
{
    // Path on the first column
    QStandardItem *pathAItem = new QStandardItem(ui->lineEdit->text());

    // Image on the second column - not working yet
    //QStandardItem *image1 = new QStandardItem(/*ui->graphicsView->*/);

    QPixmap image1;
    QByteArray img1Array;
    QBuffer buffer1(&img1Array);
    buffer1.open(QIODevice::WriteOnly);
    image1.save(&buffer1, "PNG");

    QList<QStandardItem*> row;
    row << pathAItem;
    model->setColumnCount(1);
    model->appendRow(row);
}

void MainWindow::on_sendBtn_clicked()
{
    addData();
}



void MainWindow::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const
{
    QString colName = index.model()->headerData(index.column(), Qt::Horizontal).toString();
    if(colName == "image1")
    {
        QPixmap iconPix;
        if(!iconPix.loadFromData(index.model()->data(index).toByteArray())) {
        }
        iconPix = iconPix.scaledToHeight(32);
        painter->drawPixmap(option.rect.x(),option.rect.y(),iconPix);
    } else {
//        QStyledItemDelegate::paint(painter, option, index);
    }
}

如果您复制并粘贴整个代码将编译,以便您可以看到我遇到的问题。

请说明此事。

我想回答这个问题,希望对其他人也有用。正如 Jeremy Friesner 所建议的那样,使用 QPushButton 将图像发送到 QTableView 的最佳方式(与 QItemDelegate 相比速度更快)是通过以下方式修改 void MainWindow::addData() 函数使用 QImage 并将其传递给 setData(QVariant(QPixmap::fromImage), Qt::DecorationRole) 以便整个函数可以编写如下:

第一个选项

void MainWindow::on_sendBtn_clicked()
{
    addData();
}

void MainWindow::addData()
{
    QStandardItem *pathAItem = new QStandardItem(ui->pathLineEdit_A->text());
    QStandardItem *pathBItem = new QStandardItem(ui->pathLineEdit_B->text());

    QImage image1(ui->graphicsViewLeft->grab().toImage());
    QStandardItem *item1 = new QStandardItem();
    item1->setData(QVariant(QPixmap::fromImage(image1.scaled(42,42, Qt::KeepAspectRatio,Qt::SmoothTransformation))), Qt::DecorationRole);
    ui->bookMarkTableView->setModel(model);

    QImage image2(ui->graphicsViewRight->grab().toImage());
    QStandardItem *item2 = new QStandardItem();
    item2->setData(QVariant(QPixmap::fromImage(image2.scaled(42,42, Qt::KeepAspectRatio,Qt::SmoothTransformation))), Qt::DecorationRole);
    ui->bookMarkTableView->setModel(model);

    QList<QStandardItem*> row;
    row << pathAItem << pathBItem << item1 << item2;
    model->appendRow(row);
}

第二个选项

如果有必要使用 QItemDelgate 我也发布了那部分代码(我已经尝试过了,它正在工作):

imagedelegate.h中有必要提供一个QSize如下:

class ImageDelegate : public QStyledItemDelegate
{
public:
    ImageDelegate(QObject * parent = nullptr);
    void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const;
    QSize sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const;

在你的 imagedelegate.cpp 之后,执行是:

#include "imagedelegate.h"
ImageDelegate::ImageDelegate(QObject * parent) : QStyledItemDelegate(parent)
{}

QSize ImageDelegate::sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const
{
    return QSize(32,32);
    Q_UNUSED(option);
    Q_UNUSED(index);
}

void ImageDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const
{
    qDebug() << (index.model()->headerData(index.column(), Qt::Horizontal).toString());
    QString colName = index.model()->headerData(index.column(), Qt::Horizontal).toString();

    if(colName == "image1" || colName == "image2")
    {
        QPixmap iconPix;
        if(!iconPix.loadFromData(index.model()->data(index).toByteArray())) {
        }
        iconPix = iconPix.scaledToHeight(32);
        painter->drawPixmap(option.rect.x(),option.rect.y(),iconPix);
    } else {
        QStyledItemDelegate::paint(painter, option, index);
    }
}

在我的例子中,我有两列需要在其中保存图像,因此您可以根据需要将其扩展为多少列,我还设置了 QSize(32,32) 但是这取决于开发人员。

我希望这会节省您的编程时间,this 是最终结果! :)