【问题标题】:How to pass images on QGraphicsView to QTableView programmatically using QPushButton如何使用 QPushButton 以编程方式将 QGraphicsView 上的图像传递给 QTableView
【发布时间】:2019-03-20 02:04:00
【问题描述】:

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

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

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

目前情况如下:

预期的行为是:

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

这是 ma​​inwindow.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

这里是 ma​​inwindow.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);
    }
}

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

请解释一下这个问题。

【问题讨论】:

  • 我想知道,您是否可以通过在您的QStandardItem 对象上调用setIcon(QIcon(myLoadedPixmap)) 来获得您想要的行为,而不是编写自定义委托?无论哪种方式都可以工作,但setIcon() 方法要容易得多。
  • @JeremyFriesner 感谢您抽出宝贵时间阅读问题。如何修改我根据您的建议编写的代码?
  • 去掉ImageDelegate类,但是使用你写的iconPixmap代码(iconPixmap-&gt;loadFromData()等)设置一个包含你的图像的QPixmap对象,然后调用pathAItem-&gt;setIcon(iconPixmap);
  • 好的,我将问题编辑到最低限度。不使用Delegate 是个好主意。该程序仍然无法编译。我在void MainWindow::paint() 函数中设置图像,但没有任何反应。
  • 您不需要任何 paint() 方法 AFAIK。请将您的代码放在 addData() 中。

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


【解决方案1】:

我想回答这个问题,希望对其他人也有用。正如 Jeremy Friesner 所建议的,使用QPushButton 将图像发送到QTableView 的最佳(与QItemDelegate 相比更快)方法是使用QImage 修改void MainWindow::addData() 函数并传递它到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);
    }
}

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-12
    • 1970-01-01
    • 1970-01-01
    • 2013-02-07
    • 2016-09-21
    • 2012-01-04
    相关资源
    最近更新 更多