commitData and closeEditor signals



  • Hi,
    I have a delegate:

    #include "fixviewdelegate.h"
    
    FixViewDelegate::FixViewDelegate(QObject* parent) : QStyledItemDelegate(parent) {
      qDebug() << "Entered fixViewDelegate (1).";
    }
    
    QWidget* FixViewDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const {
    
      qDebug() << "Entered createEditor";
      Q_UNUSED(option);
      Q_UNUSED(index);
    
    //  ImagePickButton* imgPick = qobject_cast<ImagePickButton*>(parent);
    //  connect (imgPick, SIGNAL(editingFinished()), this, SLOT(commitAndCloseEditor()));
      return new ImagePickButton(parent);
    
    }
    
    void FixViewDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const {
    
      QPixmap loadedImage;
    
      loadedImage.loadFromData (index.data ().toByteArray ()) ;
      loadedImage = loadedImage.scaled (100, 100, Qt::KeepAspectRatio);
    
      const QWidget* widget = option.widget;
    
    
      QStyle* style = widget ? widget->style() : QApplication::style();
      style->drawItemPixmap (painter, option.rect, Qt::AlignCenter, loadedImage);
    
    }
    
    void FixViewDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const {
      Q_UNUSED(index);
      editor->setGeometry(option.rect);
    }
    
    void FixViewDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const {
    
      qDebug() << "Entered setEditorData.";
      ImagePickButton* imgPick = qobject_cast<ImagePickButton*>(editor);
      Q_ASSERT(imgPick);
      imgPick->setSelectedFile(index.data(Qt::UserRole).toString());
      connect (imgPick, &ImagePickButton::editingFinished, this, FixViewDelegate::commitAndCloseEditor );
    }
    
    void FixViewDelegate::setModelData(QWidget* editor, QSqlTableModel* fixModel, const QModelIndex& index) const {
      qDebug() << "Entered setModelData. ";//Didn't come hee.
    
      ImagePickButton* imgPick = qobject_cast<ImagePickButton*>(editor);
      Q_ASSERT(imgPick);
    
      if(imgPick->selectedFile().isEmpty()) {
        fixModel->setData(index, QVariant(), Qt::UserRole);
        fixModel->setData(index, QVariant(), Qt::DecorationRole);
      } else {
        fixModel->setData(index, imgPick->selectedFile(), Qt::UserRole);
        fixModel->setData(index, QIcon(imgPick->selectedFile()), Qt::DecorationRole);
    
        qDebug() << "Selectedfile size: " << (imgPick->selectedFile ()).size ();
      }
    
    
    }
    
    void FixViewDelegate::commitAndCloseEditor() {
      ImagePickButton* imgPick = qobject_cast<ImagePickButton*>(sender ());
      qDebug() << "Entered commitandclose.";
      emit commitData(imgPick);
      emit closeEditor(imgPick);
    }
    

    When I close the editor the chosen new image appears on the editor, but the new image is not written back to the model and the db. I assume I'm supposed to use the closeEditor and commitData signals, but where am I supposed to put them?
    Thank you for your help.


  • Lifetime Qt Champion

    Hi,

    Add the override keyword to the methods you re-implement so you'll have a build time error when you write it with the wrong signature.

    Take a look at the original signature, the parameter is not QSqlTableModel.



  • @SGaist
    I made the recommended changes:

    void FixViewDelegate::setModelData(QWidget* editor, QAbstractItemModel* fixModel, const QModelIndex& index) const {
    

    This section works now.
    My next step would be to commit thecchanges to the model and the db.From which function am I supposed to call

      emit  commitData (editor);
      emit closeEditor (editor);
    

    ? Or should I do it differently?
    Thank you.


  • Lifetime Qt Champion

    setModelData is where you modify your model so what do you mean by "commit the changes" ?



  • @SGaist
    What am I supposed to use in setModelData to commit the changes to the model and the db?


  • Lifetime Qt Champion

    I can't answer, there's not enough data to ensure you have everything.



  • @SGaist
    I hope this helps.
    fixdb.cpp:

    #include "fixdb.h"
    #include "ui_fixdb.h"
    #include <QDebug>
    
    FixDb::FixDb(QWidget* parent) :
      QDialog(parent),
      ui(new Ui::FixDb) {
      ui->setupUi(this);
    
      correctFriend ();
    }
    
    FixDb::~FixDb() {
      delete ui;
    }
    
    void FixDb::correctFriend() {
    //  QSqlQuery query_fix;
    
    //  int recNum = 0;
    //  query_fix.prepare ("SELECT COUNT(*) FROM Items");
    //  query_fix.exec ();
    
    //  if(query_fix.next ()) {
    //    recNum = query_fix.value (0).toInt ();
    //  };
    
    //  qDebug() << "Record count in fixdb: " << recNum;
    
    
    
      QSqlDatabase db = QSqlDatabase::addDatabase ("QSQLITE");
      db.setDatabaseName ( "C:/Programming/Projects/Folkfriends_bzr/checkout/db.db");
      if(!db.open ())
        QMessageBox::information (this, "Error", "Couldn't open database.");
    
    
      QSqlTableModel* fixModel = new QSqlTableModel(this);
      fixModel->setTable ("Items");
      fixModel->setEditStrategy (QSqlTableModel::OnFieldChange);
      fixModel->setSort (2, Qt::DescendingOrder);
    
      fixModel->select ();
    
    
      ui->tableView_Fix->setModel (fixModel);
    
      ui->tableView_Fix->setItemDelegateForColumn(2, new FixViewDelegate(this));
    
     
      QSqlQuery fixQueryDisp;
      fixQueryDisp.prepare("SELECT * FROM Items");
      fixQueryDisp.exec ();
    
      for(int row1 = 0; fixQueryDisp.next (); row1++) {
        ui->tableView_Fix->setRowHeight (row1, 100);
    
      };
    
      ui->tableView_Fix->horizontalHeader ()->setStyleSheet ("QHeaderView{font: 14pt Arial; color: blue; font-weight: bold; text-decoration: underline;}");
      ui->tableView_Fix->verticalHeader ()->setVisible (false);
      ui->tableView_Fix->setAlternatingRowColors (true);
      ui->tableView_Fix->setStyleSheet ("alternate-background-color: rgb(224,255,248); background-color: white; font: 14pt Arial; ");
    
      fixModel->setHeaderData (0, Qt::Horizontal, QObject::tr ("ID"));
      fixModel->setHeaderData (1, Qt::Horizontal, QObject::tr ("Name"));
      fixModel->setHeaderData (3, Qt::Horizontal, QObject::tr ("What"));
      fixModel->setHeaderData (2, Qt::Horizontal, QObject::tr ("Image"));
      fixModel->setHeaderData (4, Qt::Horizontal, QObject::tr ("Material"));
      fixModel->setHeaderData (5, Qt::Horizontal, QObject::tr ("Color"));
      fixModel->setHeaderData (6, Qt::Horizontal, QObject::tr ("Description"));
      fixModel->setHeaderData (7, Qt::Horizontal, QObject::tr ("Adoption Date"));
      fixModel->setHeaderData (8, Qt::Horizontal, QObject::tr ("Signed by"));
      fixModel->setHeaderData (9, Qt::Horizontal, QObject::tr ("History"));
      fixModel->setHeaderData (10, Qt::Horizontal, QObject::tr ("Age"));
      fixModel->setHeaderData (11, Qt::Horizontal, QObject::tr ("Notes"));
    
    
      ui->tableView_Fix->setColumnWidth (0, 60);
      ui->tableView_Fix->setColumnWidth (1, 120);
      ui->tableView_Fix->setColumnWidth (2, 150);
      ui->tableView_Fix->setColumnWidth (3, 100);
      ui->tableView_Fix->setColumnWidth (4, 130);
      ui->tableView_Fix->setColumnWidth (5, 120);
      ui->tableView_Fix->setColumnWidth (6, 400);
      ui->tableView_Fix->setColumnWidth (7, 150);
      ui->tableView_Fix->setColumnWidth (8, 200);
      ui->tableView_Fix->setColumnWidth (9, 400);
      ui->tableView_Fix->setColumnWidth (10, 130);
      ui->tableView_Fix->setColumnWidth (11, 300);
    
      ui->tableView_Fix->setWordWrap (true);
    
    }//end of correctFriend
    

    fixviewdelegate.cpp:

    #include "fixviewdelegate.h"
    
    FixViewDelegate::FixViewDelegate(QObject* parent) : QStyledItemDelegate(parent) {
      qDebug() << "Entered fixViewDelegate (1).";
    }
    
    QWidget* FixViewDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const {
    
      qDebug() << "Entered createEditor";
      Q_UNUSED(option);
      Q_UNUSED(index);
    
    
      return new ImagePickButton(parent);
    
    }
    
    void FixViewDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const {
    
      QPixmap loadedImage;
    
      loadedImage.loadFromData (index.data ().toByteArray ()) ;
      loadedImage = loadedImage.scaled (100, 100, Qt::KeepAspectRatio);
    
      const QWidget* widget = option.widget;
    
    
      QStyle* style = widget ? widget->style() : QApplication::style();
      style->drawItemPixmap (painter, option.rect, Qt::AlignCenter, loadedImage);
    
    }
    
    void FixViewDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const {
      Q_UNUSED(index);
      editor->setGeometry(option.rect);
    }
    
    void FixViewDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const {
    
      qDebug() << "Entered setEditorData.";
      ImagePickButton* imgPick = qobject_cast<ImagePickButton*>(editor);
      Q_ASSERT(imgPick);
      imgPick->setSelectedFile(index.data(Qt::UserRole).toString());
    
    }
    
    void FixViewDelegate::setModelData(QWidget* editor, QAbstractItemModel* fixModel, const QModelIndex& index) const {
      qDebug() << "Entered setModelData. ";//Didn't come hee.
    
      ImagePickButton* imgPick = qobject_cast<ImagePickButton*>(editor);
      Q_ASSERT(imgPick);
    
      if(imgPick->selectedFile().isEmpty()) {
        fixModel->setData(index, QVariant(), Qt::UserRole);
        fixModel->setData(index, QVariant(), Qt::DecorationRole);
      } else {
        fixModel->setData(index, imgPick->selectedFile(), Qt::UserRole);
    
        fixModel->setData(index, QIcon(imgPick->selectedFile()), Qt::DecorationRole);
    
    
    
      }
    
    }
    
    void FixViewDelegate::commitAndCloseEditor() {
      qDebug() << "Entred commitAndCloseEditor.";
      ImagePickButton* editor = qobject_cast<ImagePickButton*>(sender());
    
      emit  commitData (editor);
      emit closeEditor (editor);
    
    }
    

    imagepickbutton.cpp:

    #include "imagepickbutton.h"
    
    ImagePickButton::ImagePickButton(QWidget* parent) : QWidget(parent) {
      m_mainButton = new QPushButton(tr("Select \n Image"), this);
    
      m_mainButton->setStyleSheet ("font: bold;"
                                   "font-size: 12px;"
                                   "background-color: rgba(255, 255, 255, 100);");
    
    
      m_mainButton->setMaximumWidth(100);
      m_mainButton->setMinimumWidth (100);
      m_mainButton->setMaximumHeight (100);
      m_mainButton->setMinimumHeight (100);
    
      m_mainButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    
      QGridLayout* mainLay = new QGridLayout(this);
      mainLay->setSpacing(0);
      mainLay->setContentsMargins(0, 0, 0, 0);
      mainLay->addWidget(m_mainButton, 1, 1);
      mainLay->addItem(new QSpacerItem(1, 1, QSizePolicy::Preferred, QSizePolicy::Expanding), 0, 1);
      mainLay->addItem(new QSpacerItem(1, 1, QSizePolicy::Preferred, QSizePolicy::Expanding), 2, 1);
      mainLay->addItem(new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Preferred), 1, 0);
      mainLay->addItem(new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Preferred), 1, 2);
    
      connect(m_mainButton, &QPushButton::clicked, this, &ImagePickButton::selectImageFile);
    }
    
    const QString& ImagePickButton::selectedFile() const {
      return  m_selectedFile;
    }
    
    void ImagePickButton::setSelectedFile(const QString& val) {
      if(m_selectedFile == val)
        return;
    
      m_selectedFile = val;
    
      if(m_selectedFile.isEmpty()) {
        m_mainButton->setText(tr("Select Image"));
        QFont buttonFont = m_mainButton->font();
        buttonFont.setPointSize(5);
        m_mainButton->setIcon(QIcon());
      } else {
        m_mainButton->setText(QString());
        m_mainButton->setIcon(QIcon(m_selectedFile));
        m_mainButton->setMaximumWidth(100);
        m_mainButton->setMinimumWidth(100);
      }
      emit selectedFileChanged(m_selectedFile);
      emit editingFinished ();
      FixViewDelegate* fixView = new FixViewDelegate;
      fixView->commitAndCloseEditor ();
    
    }
    
    void ImagePickButton::selectImageFile() {
      const QString newFile = QFileDialog::getOpenFileName(this, tr("Open Image"), QString(), tr("Images (*.png *.xpm *.jpg)"));
    
      if(!newFile.isEmpty())
        setSelectedFile(newFile);
    }
    

    Thank you for your help.



  • @SGaist
    The new image is displayed at the correct location, but when the focus moves from the changed image the image disappears. I assume it is not really saved in the model and the db is not updated either. I'm trying to fix these two issues. Thank you for any help.


  • Lifetime Qt Champion

    Looks like you are using custom roles with a QSqlTableModel, you should subclass it to handle custom roles properly the way you want it.



  • @SGaist
    Am I supposed to subclass it in setModelData?


  • Lifetime Qt Champion

    That question doesn't make sense. The suggestion is to make your own class inheriting from QSqlTableModel.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.