Reading image from QSqlTableModel
-
@gabor53
2 reasons your csetModelData() isn't called:- the correct signatur for setModelData() would be:
void setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const setModelData()is used as the name implies to set data in the model. Means when the editor has finished editing and wants to save
the correct method to reimplement is the delegates
paint()andsizeHint()methods. In there you check if the column is your image column and do the work appropriately, else just call the base class implementation.@raven-worx
Thank you. I'm working on it. - the correct signatur for setModelData() would be:
-
@gabor53
2 reasons your csetModelData() isn't called:- the correct signatur for setModelData() would be:
void setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const setModelData()is used as the name implies to set data in the model. Means when the editor has finished editing and wants to save
the correct method to reimplement is the delegates
paint()andsizeHint()methods. In there you check if the column is your image column and do the work appropriately, else just call the base class implementation.@raven-worx
I believe in the paint() method I need to usevoid QPainter::drawPixmap(const QRectF &target, const QPixmap &pixmap, const QRectF &source)How can I get the pixmap out of the model?
- the correct signatur for setModelData() would be:
-
@raven-worx
I believe in the paint() method I need to usevoid QPainter::drawPixmap(const QRectF &target, const QPixmap &pixmap, const QRectF &source)How can I get the pixmap out of the model?
-
@gabor53 of course. Model's data() method returns QVariant, you can get QByteArray this way.
-
@gabor53 of course. Model's data() method returns QVariant, you can get QByteArray this way.
@artwaw
The delegate's paint looks like this:void FixViewDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const {I can get the index of the item from QModelIndex& index, but as there is no model, how can I get the QByteArray from the db (or model)?
Thank you. -
@gabor53 of course. Model's data() method returns QVariant, you can get QByteArray this way.
-
Index is your point of access to the model. See QModelIndex::data.
-
Index is your point of access to the model. See QModelIndex::data.
@SGaist
I tried the following:QVariant fixImg; fixImg = index.data (Qt::DisplayRole); QPixmap pixMap2; pixMap2 = fixImg.value<QPixmap>(); qDebug() << "pixMap2 size: " << pixMap2.size (); qDebug() << "pixMap2 width: " << pixMap2.width ();No error message, but the size is 0. Did I miss a step?
Thank you. -
Do you store a QPixmap in your model for that role ?
-
@gabor53 said in Reading image from QSqlTableModel:
It's a QByteArray.
QByteArray of what? What and how are you storing in the DB? What is the data type of the corresponding column?
-
@gabor53 said in Reading image from QSqlTableModel:
It's a QByteArray.
QByteArray of what? What and how are you storing in the DB? What is the data type of the corresponding column?
-
@gabor53
i asked in a post before:QByteArray ba = fixModel->record (1).value ("Pic").toByteArray (); qDebug() << ba.size() << ba;in your delegates paint() method (if really a QByteArray is returned) do the following:
if( index.column() == NUMBER_OF_PIXMAP_COLUMN ) { QByteArray ba = index.data( ROLE_USED_IN_MODEL ).toByteArray(); QPixmap pix; pix.loadFromData ( ba ); painter->save(); painter->translate( option.rect.topLeft() ); painter->drawPixmap( pix ); painter->restore(); }I you should probably post your model code to avoid further guessing.
-
@gabor53
i asked in a post before:QByteArray ba = fixModel->record (1).value ("Pic").toByteArray (); qDebug() << ba.size() << ba;in your delegates paint() method (if really a QByteArray is returned) do the following:
if( index.column() == NUMBER_OF_PIXMAP_COLUMN ) { QByteArray ba = index.data( ROLE_USED_IN_MODEL ).toByteArray(); QPixmap pix; pix.loadFromData ( ba ); painter->save(); painter->translate( option.rect.topLeft() ); painter->drawPixmap( pix ); painter->restore(); }I you should probably post your model code to avoid further guessing.
- I don't like
index.column() == NUMBER_OF_PIXMAP_COLUMNas it ties the delegate to a single model so I consider it bad design,view->setItemDelegateForColumn()should be used instead. index.data( ROLE_USED_IN_MODEL )it's aQSqlTableModelso just deleteROLE_USED_IN_MODELand use the default- It's a
QStyledItemDelegateso let's use style
void FixViewDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { QPixmap loadedImage; loadedImage.loadFromData(index.data().toByteArray()); const QWidget *widget = option.widget; QStyle *style = widget ? widget->style() : QApplication::style(); style->drawItemPixmap(painter,option.rect,Qt::AlignCenter,loadedImage); } - I don't like
-
- I don't like
index.column() == NUMBER_OF_PIXMAP_COLUMNas it ties the delegate to a single model so I consider it bad design,view->setItemDelegateForColumn()should be used instead. index.data( ROLE_USED_IN_MODEL )it's aQSqlTableModelso just deleteROLE_USED_IN_MODELand use the default- It's a
QStyledItemDelegateso let's use style
void FixViewDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { QPixmap loadedImage; loadedImage.loadFromData(index.data().toByteArray()); const QWidget *widget = option.widget; QStyle *style = widget ? widget->style() : QApplication::style(); style->drawItemPixmap(painter,option.rect,Qt::AlignCenter,loadedImage); } - I don't like
-
- I don't like
index.column() == NUMBER_OF_PIXMAP_COLUMNas it ties the delegate to a single model so I consider it bad design,view->setItemDelegateForColumn()should be used instead. index.data( ROLE_USED_IN_MODEL )it's aQSqlTableModelso just deleteROLE_USED_IN_MODELand use the default- It's a
QStyledItemDelegateso let's use style
void FixViewDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { QPixmap loadedImage; loadedImage.loadFromData(index.data().toByteArray()); const QWidget *widget = option.widget; QStyle *style = widget ? widget->style() : QApplication::style(); style->drawItemPixmap(painter,option.rect,Qt::AlignCenter,loadedImage); } - I don't like
-
How do you save your image in the database? do you save it via Qt? can you show us the save part of the code?
@VRonin
Sure. I also addedqDebug() << "loadedImage size: " << loadedImage.size ();and the result is
loadedImage size: QSize(0, 0)I save the image via Qt like this:
#include "review.h" #include "ui_review.h" Review::Review(QWidget* parent) : QDialog(parent), ui(new Ui::Review) { ui->setupUi(this); connect(this, &Review::RecAdded, this, &Review::updateTable); } Review::~Review() { delete ui; } void Review::dispRev(QString sID, QString& name, QString& whatChosen, QString& fileNameChosen, QString& materialChosen, QString& colorChosen, QString& description, QDate& adoptDate, QString& SignedbyChosen, QString& history, QString& age, QString& notesTemp) { name = name.simplified (); description = description.simplified (); ui->ID_display_Label->setText (sID); ui->Name_Disp_Label->setText (name); ui->What_Display_Label->setText (whatChosen); ui->MadeOf_Disp_Label->setText (materialChosen); ui->Color_Disp_Label->setText (colorChosen); ui->textBrowser_Descr->setText (description); adoptDateStr = adoptDate.toString ("MM/dd/yyyy"); ui->AdoptionDate_Disp_Label->setText (adoptDateStr); ui->SignedBy_Disp_label->setText (SignedbyChosen); ui->textBrowser_History->setText (history); ui->Age_Display_Label_2->setText (age); ui->textBrowser_Notes->setText (notesTemp); QPixmap pix2(fileNameChosen); int w = 0; int h = 0; w = ui->Image_Display_Label->width (); h = ui->Image_Display_Label->height (); ui->Image_Display_Label->setPixmap (pix2.scaled(w, h, Qt::KeepAspectRatio)); QFile fileReview(fileNameChosen); if(fileReview.open (QIODevice::ReadOnly)) { fileByteArray = fileReview.readAll (); } nameReview = name; whatReview = whatChosen; fileNameReview = fileNameChosen; materialReview = materialChosen; colorReview = colorChosen; descriptionReview = description; adoptDateReview = adoptDate; SignedbyReview = SignedbyChosen; historyReview = history; sIDReview = sID; ageReview = age; notesReview = notesTemp; } void Review::on_pushButton_Add_to_DB_clicked() { // date = adoptDateReview.toString ("MM/dd/yyyy"); qDebug() << "date in review.cpp: " << date; QSqlDatabase db = QSqlDatabase::addDatabase ("QSQLITE", "writedb"); db.setDatabaseName (fileQstring); QSqlQuery querys(db); if(!db.open ()) { qDebug() << "The database is not open (submit)!"; } else { qDebug() << "The database is open (submit)!"; } querys.prepare("INSERT INTO Items (ID, Name, Pic, Description, AdoptDate, History, Age, Notes, Color, Material, Signed, What) VALUES(:ID, :Name, :Pic, :Description, :AdoptDate, :History, :Age, :Notes, :Color, :Material, :Signed, :What)" ); querys.bindValue (":ID", sIDReview); querys.bindValue (":Name", nameReview); querys.bindValue (":Pic", fileByteArray); querys.bindValue (":Description", descriptionReview); querys.bindValue (":AdoptDate", adoptDateStr); querys.bindValue (":History", historyReview); querys.bindValue (":Age", ageReview); querys.bindValue (":Notes", notesReview); querys.bindValue (":Color", colorReview); querys.bindValue (":Material", materialReview); querys.bindValue (":Signed", SignedbyReview); querys.bindValue (":What", whatReview); bool result = querys.exec (); if(!result) { qDebug() << "Error inserting into the main db!" << querys.lastError (); QMessageBox::warning (this, "Add to Database Warning", "<b><font size='16' color='red'>Error 1002: The Friend was not added to the database."); } else { qDebug() << "Entered FunctAdd OK loop."; QMessageBox::information (this, "Confirmation", "<b><font size = '16' color = 'green'>The Friend was added to the database.</font>"); emit RecAdded (); } } void Review::on_pushButton_Fix_clicked() { Additem* mAdditem = new Additem(this); mAdditem->FixFriend (sIDReview, nameReview, whatReview, fileNameReview, materialReview, colorReview, descriptionReview, date, SignedbyReview, historyReview, ageReview, notesReview); mAdditem->show (); } void Review::updateTable() { qDebug() << "Entered updateTable!"; MainWindow* mMainWindow = new MainWindow(this); mMainWindow->Addview (); mMainWindow->show (); }Data in the db is stored as BLOB.
-
You don't do anything in case
fileReview.openfails so you might be storing empty QByteArrays in your database.