如何使用 QPushButton 以编程方式将 QGraphicsView 上的图像传递给 QTableView
How to pass images on QGraphicsView to QTableView programmatically using QPushButton
我一直在研究如何以编程方式使用 QPushButton
将 QGraphicsView
上加载的图像存储到 QTableView
的行中,但我发现的信息是这样的远没有那么多。
我有 1 个 QGraphicsView
、一个 QPushButton
(发送按钮)、一个 QTableView
和一个 QLineEdit
。当我使用加载按钮上传图像时,我会在 QGraphicsView
和 QLineEidt
上显示它们(我显示图像的路径),如果我单击发送按钮,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 是最终结果! :)
我一直在研究如何以编程方式使用 QPushButton
将 QGraphicsView
上加载的图像存储到 QTableView
的行中,但我发现的信息是这样的远没有那么多。
我有 1 个 QGraphicsView
、一个 QPushButton
(发送按钮)、一个 QTableView
和一个 QLineEdit
。当我使用加载按钮上传图像时,我会在 QGraphicsView
和 QLineEidt
上显示它们(我显示图像的路径),如果我单击发送按钮,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 是最终结果! :)