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

问题描述 投票:0回答:1

我一直在研究如何使用QGraphicsView以编程方式将加载在QTableView上的图像存储到QPushButton的行中,但到目前为止我发现的信息并不多。

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

然而,QGraphicsView上的图像没有被存储到QTableView并且没有任何传递。

目前这是发生的事情:

预期的行为是:

我创建了一个ItemDelegate类,它负责调整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);
    }
}

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

请详细说明这件事。

c++ c++11 qt5 qtableview qgraphicsview
1个回答
0
投票

我想回答这个问题,希望这对其他人也有用。正如Jeremy Friesner所建议的那样,使用QItemDelegate将图像发送到QTableView的最好(并且与QPushButton比较快)的方法是使用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是最终的结果! :)

© www.soinside.com 2019 - 2024. All rights reserved.