Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

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