Как передать изображения в QGraphicsView в QTableView программным способом, используя QPushButton - PullRequest
0 голосов
/ 20 марта 2019

Я некоторое время изучал, как сохранять изображения, загруженные на QGraphicsView, в строки QTableView с помощью QPushButton программным способом, но информации, которую я нашел до сих пор, не так много.

У меня есть 1 QGraphicsView, QPushButton (кнопка отправки) и QTableView и QLineEdit. Когда я загружаю изображения с помощью кнопки загрузки, я показываю их как на QGraphicsView, так и на QLineEidt (я показываю путь к изображению), если я нажимаю кнопку «Отправить», следует добавить текст QLineEdit в первом ряду QTableView (что происходит), и изображение должно храниться внутри QTableView.

Однако изображение на QGraphicsView не сохраняется на QTableView и ничего не передается.

В настоящее время происходит следующее:

wrong

Ожидаемое поведение будет:

expected

Я создал класс 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);
    }
}

Весь код будет скомпилирован, если вы скопируете и вставите его, чтобы вы могли увидеть возникшую у меня проблему.

Пожалуйста, пролите свет на этот вопрос.

1 Ответ

0 голосов
/ 26 марта 2019

Я хотел ответить на этот вопрос, надеясь, что это также будет полезно для других.Как предложил Джереми Фризнер, лучший (и быстрый по сравнению с 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), но это зависит от разработчика.

Я надеюсь, что это сэкономит ваше время на программирование, и это - конечный результат!:)

...