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

时间:2019-03-20 02:04:01

标签: c++ c++11 qt5 qtableview qgraphicsview

一段时间以来,我一直在研究如何使用QGraphicsView以编程方式将加载在QTableView上的图像存储到QPushButton的行中,但是到目前为止,我发现的信息是没有那么多。

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

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

当前正在发生的事情:

wrong

预期的行为是:

expected

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

这是 mainwindow.h

QTableView

这是 mainwindow.cpp

#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

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

请阐明这件事。

1 个答案:

答案 0 :(得分: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是最终的结果! :)