Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Subclass QItemDelegate not working
Forum Updated to NodeBB v4.3 + New Features

Subclass QItemDelegate not working

Scheduled Pinned Locked Moved Solved General and Desktop
5 Posts 2 Posters 354 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • ? Offline
    ? Offline
    A Former User
    wrote on last edited by
    #1

    Hi,
    I have the following. My FungusSqlRelationalDelegate.h

    #ifndef FUNGUSSQLRELATIONALDELEGATE_H
    #define FUNGUSSQLRELATIONALDELEGATE_H
    
    #include <QSqlRelationalDelegate>
    #include <nulldelegate.h>
    
    class FungusSqlRelationalDelegate : public QSqlRelationalDelegate
    {
        Q_OBJECT
    public:
        explicit FungusSqlRelationalDelegate(QObject *parent = 0);
        QWidget *createEditor(QWidget *aParent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
        void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
        void setEditorData(QWidget *editor, const QModelIndex &index) const;
    };
    
    #endif // FUNGUSSQLRELATIONALDELEGATE_H
    

    And my FungusSqlRelationalDelegate.cpp:

    FungusSqlRelationalDelegate::FungusSqlRelationalDelegate(QObject *parent) : QSqlRelationalDelegate (parent)
    {}
    
    QWidget *FungusSqlRelationalDelegate::createEditor(QWidget *aParent, const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
        const QSqlRelationalTableModel *sqlModel = qobject_cast<const QSqlRelationalTableModel*>(index.model());
        QSqlTableModel *childModel = sqlModel ? sqlModel->relationModel(index.column()) : 0;
    
        if (!childModel ) {
            const QSortFilterProxyModel *proxyModel = qobject_cast<const QSortFilterProxyModel *>(index.model());
            if (proxyModel){
                sqlModel = qobject_cast<const QSqlRelationalTableModel *>(proxyModel->sourceModel());
                childModel = sqlModel ? sqlModel->relationModel(index.column()) : 0;
            }
        }
        if (!childModel) {
            return QItemDelegate::createEditor(aParent, option, index);
        }
    
        QComboBox *combo = new QComboBox(aParent);
        combo->setModel(childModel);
        combo->setModelColumn(childModel->fieldIndex(sqlModel->relation(index.column()).displayColumn()));
        combo->installEventFilter(const_cast<FungusSqlRelationalDelegate*>(this));
    
        return combo;
    }
    
    void FungusSqlRelationalDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
    {
        if (!index.isValid())
            return;
    
        QSqlRelationalTableModel *sqlModel = qobject_cast<QSqlRelationalTableModel *>(model);
    
        QSortFilterProxyModel *proxyModel = NULL;
        if (!sqlModel )
        {
            proxyModel = qobject_cast<QSortFilterProxyModel *>(model);
            if (proxyModel)
                sqlModel = qobject_cast<QSqlRelationalTableModel *>(proxyModel->sourceModel());
        }
    
        QSqlTableModel *childModel = sqlModel ? sqlModel->relationModel(index.column()) : 0;
    
        QComboBox *combo = qobject_cast<QComboBox *>(editor);
    
        if (!childModel || !combo) {       
            QItemDelegate::setModelData(editor, model, index); // HERE I WANT DO THIS: NullDelegate::setModelData(editor, model, index);
            return;
        }
        int currentItem = combo->currentIndex();
    
        int childColIndex = childModel->fieldIndex(sqlModel->relation(index.column()).displayColumn());
        int childEditIndex = childModel->fieldIndex(sqlModel->relation(index.column()).indexColumn());
    
        if (proxyModel) {
            proxyModel->setData(index, childModel->data(childModel->index(currentItem, childEditIndex), Qt::DisplayRole), Qt::DisplayRole);
            proxyModel->setData(index, childModel->data(childModel->index(currentItem, childEditIndex), Qt::EditRole), Qt::EditRole);
        } else {
            sqlModel->setData(index, childModel->data(childModel->index(currentItem, childColIndex), Qt::DisplayRole), Qt::DisplayRole);
            sqlModel->setData(index, childModel->data(childModel->index(currentItem, childEditIndex), Qt::EditRole), Qt::EditRole);
        }
    }
    
    void FungusSqlRelationalDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
    {
        QString strVal = "";
        const QSqlRelationalTableModel *sqlModel = qobject_cast<const QSqlRelationalTableModel *>(index.model());
        if (!sqlModel )
        {
            const QSortFilterProxyModel *proxyModel = qobject_cast<const QSortFilterProxyModel *>(index.model());
            if (proxyModel) {
                strVal = proxyModel->data(index).toString();
            }
        } else {
            strVal = sqlModel->data(index).toString();
        }
    
        QComboBox *combo = qobject_cast<QComboBox *>(editor);
    
        if (strVal.isEmpty() || !combo) {
            QItemDelegate::setEditorData(editor, index); // HERE I WANT DO THIS: NullDelegate::setEditorData(editor, model, index);
            editor->setProperty("text", index.data());
            return;
        }
    
        combo->setCurrentIndex(combo->findText(strVal));
    }
    

    In the code you can see my comments "// HERE I WANT DO THIS: NullDelegate::setEditorData(editor, model, index);" and " // HERE I WANT DO THIS: NullDelegate::setModelData(editor, model, index);"

    I have created a nulldelegate class this looks like this:

    nulldelegate.h

    #ifndef NULLDELEGATE_H
    #define NULLDELEGATE_H
    
    #include <QItemDelegate>
    #include <QStyledItemDelegate>
    
    class NullDelegate : public QAbstractItemDelegate
    {
    
        Q_OBJECT
    public:
        explicit NullDelegate(QObject *parent = nullptr);
        void setEditorData(QWidget *editor, const QModelIndex &index) const override ;
        void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override;
    private:
    
    };
    
    #endif // NULLDELEGATE_H
    

    and my nulldelegate.cpp

    #include "nulldelegate.h"
    
    NullDelegate::NullDelegate(QObject *parent) :  QItemDelegate(parent)
    {
    
    }
    
    void NullDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
    {
        editor->setProperty("text", index.data());
    }
    
    void NullDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
    {
        model->setData(index, editor->property("text") == "" ? QVariant() : editor->property("text"));
    }
    

    My problem now is this:

    When I try to call NullDelegate::setModelData(editor, model, index) it tells me the following:

    "error: call to non-static member function without an object argument".

    Somehow I am too stupid to get this to work. Nulldelegate inherits from QItemDelegate. But in QItemDelegate I didn't find a static setModelData method can someone help me please?

    Why did I create a nulldelegate class?
    I don't want to insert empty string in my database but store "null" when my QLineEdits are empty.

    JonBJ 1 Reply Last reply
    0
    • ? A Former User

      Hi,
      I have the following. My FungusSqlRelationalDelegate.h

      #ifndef FUNGUSSQLRELATIONALDELEGATE_H
      #define FUNGUSSQLRELATIONALDELEGATE_H
      
      #include <QSqlRelationalDelegate>
      #include <nulldelegate.h>
      
      class FungusSqlRelationalDelegate : public QSqlRelationalDelegate
      {
          Q_OBJECT
      public:
          explicit FungusSqlRelationalDelegate(QObject *parent = 0);
          QWidget *createEditor(QWidget *aParent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
          void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
          void setEditorData(QWidget *editor, const QModelIndex &index) const;
      };
      
      #endif // FUNGUSSQLRELATIONALDELEGATE_H
      

      And my FungusSqlRelationalDelegate.cpp:

      FungusSqlRelationalDelegate::FungusSqlRelationalDelegate(QObject *parent) : QSqlRelationalDelegate (parent)
      {}
      
      QWidget *FungusSqlRelationalDelegate::createEditor(QWidget *aParent, const QStyleOptionViewItem &option, const QModelIndex &index) const
      {
          const QSqlRelationalTableModel *sqlModel = qobject_cast<const QSqlRelationalTableModel*>(index.model());
          QSqlTableModel *childModel = sqlModel ? sqlModel->relationModel(index.column()) : 0;
      
          if (!childModel ) {
              const QSortFilterProxyModel *proxyModel = qobject_cast<const QSortFilterProxyModel *>(index.model());
              if (proxyModel){
                  sqlModel = qobject_cast<const QSqlRelationalTableModel *>(proxyModel->sourceModel());
                  childModel = sqlModel ? sqlModel->relationModel(index.column()) : 0;
              }
          }
          if (!childModel) {
              return QItemDelegate::createEditor(aParent, option, index);
          }
      
          QComboBox *combo = new QComboBox(aParent);
          combo->setModel(childModel);
          combo->setModelColumn(childModel->fieldIndex(sqlModel->relation(index.column()).displayColumn()));
          combo->installEventFilter(const_cast<FungusSqlRelationalDelegate*>(this));
      
          return combo;
      }
      
      void FungusSqlRelationalDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
      {
          if (!index.isValid())
              return;
      
          QSqlRelationalTableModel *sqlModel = qobject_cast<QSqlRelationalTableModel *>(model);
      
          QSortFilterProxyModel *proxyModel = NULL;
          if (!sqlModel )
          {
              proxyModel = qobject_cast<QSortFilterProxyModel *>(model);
              if (proxyModel)
                  sqlModel = qobject_cast<QSqlRelationalTableModel *>(proxyModel->sourceModel());
          }
      
          QSqlTableModel *childModel = sqlModel ? sqlModel->relationModel(index.column()) : 0;
      
          QComboBox *combo = qobject_cast<QComboBox *>(editor);
      
          if (!childModel || !combo) {       
              QItemDelegate::setModelData(editor, model, index); // HERE I WANT DO THIS: NullDelegate::setModelData(editor, model, index);
              return;
          }
          int currentItem = combo->currentIndex();
      
          int childColIndex = childModel->fieldIndex(sqlModel->relation(index.column()).displayColumn());
          int childEditIndex = childModel->fieldIndex(sqlModel->relation(index.column()).indexColumn());
      
          if (proxyModel) {
              proxyModel->setData(index, childModel->data(childModel->index(currentItem, childEditIndex), Qt::DisplayRole), Qt::DisplayRole);
              proxyModel->setData(index, childModel->data(childModel->index(currentItem, childEditIndex), Qt::EditRole), Qt::EditRole);
          } else {
              sqlModel->setData(index, childModel->data(childModel->index(currentItem, childColIndex), Qt::DisplayRole), Qt::DisplayRole);
              sqlModel->setData(index, childModel->data(childModel->index(currentItem, childEditIndex), Qt::EditRole), Qt::EditRole);
          }
      }
      
      void FungusSqlRelationalDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
      {
          QString strVal = "";
          const QSqlRelationalTableModel *sqlModel = qobject_cast<const QSqlRelationalTableModel *>(index.model());
          if (!sqlModel )
          {
              const QSortFilterProxyModel *proxyModel = qobject_cast<const QSortFilterProxyModel *>(index.model());
              if (proxyModel) {
                  strVal = proxyModel->data(index).toString();
              }
          } else {
              strVal = sqlModel->data(index).toString();
          }
      
          QComboBox *combo = qobject_cast<QComboBox *>(editor);
      
          if (strVal.isEmpty() || !combo) {
              QItemDelegate::setEditorData(editor, index); // HERE I WANT DO THIS: NullDelegate::setEditorData(editor, model, index);
              editor->setProperty("text", index.data());
              return;
          }
      
          combo->setCurrentIndex(combo->findText(strVal));
      }
      

      In the code you can see my comments "// HERE I WANT DO THIS: NullDelegate::setEditorData(editor, model, index);" and " // HERE I WANT DO THIS: NullDelegate::setModelData(editor, model, index);"

      I have created a nulldelegate class this looks like this:

      nulldelegate.h

      #ifndef NULLDELEGATE_H
      #define NULLDELEGATE_H
      
      #include <QItemDelegate>
      #include <QStyledItemDelegate>
      
      class NullDelegate : public QAbstractItemDelegate
      {
      
          Q_OBJECT
      public:
          explicit NullDelegate(QObject *parent = nullptr);
          void setEditorData(QWidget *editor, const QModelIndex &index) const override ;
          void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override;
      private:
      
      };
      
      #endif // NULLDELEGATE_H
      

      and my nulldelegate.cpp

      #include "nulldelegate.h"
      
      NullDelegate::NullDelegate(QObject *parent) :  QItemDelegate(parent)
      {
      
      }
      
      void NullDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
      {
          editor->setProperty("text", index.data());
      }
      
      void NullDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
      {
          model->setData(index, editor->property("text") == "" ? QVariant() : editor->property("text"));
      }
      

      My problem now is this:

      When I try to call NullDelegate::setModelData(editor, model, index) it tells me the following:

      "error: call to non-static member function without an object argument".

      Somehow I am too stupid to get this to work. Nulldelegate inherits from QItemDelegate. But in QItemDelegate I didn't find a static setModelData method can someone help me please?

      Why did I create a nulldelegate class?
      I don't want to insert empty string in my database but store "null" when my QLineEdits are empty.

      JonBJ Online
      JonBJ Online
      JonB
      wrote on last edited by
      #2

      @Gabber said in Subclass QItemDelegate not working:

      When I try to call NullDelegate::setModelData(editor, model, index) it tells me the following:

      You need an instance of NullDelegate to call it on.

      1 Reply Last reply
      1
      • ? Offline
        ? Offline
        A Former User
        wrote on last edited by
        #3

        @JonB said in Subclass QItemDelegate not working:

        You need an instance of NullDelegate to call it on.

        Oddly enough, this had not worked for two days....

        Unfortunately, my NullDelegate still does not work. Maybe you can help me. I am with my beginner knowledge unfortunately at the end and also do not know for what I can still look...

        Here again some info why I derived this from QItemDelegate. In my code example above, a QItemDelegate::setModelData is called, so I thought I have to derive from QItemDelegate. If I am wrong please correct me.

        The next info that is important to implement this is the following. I want to insert "NULL" into my database if my QLineEdit or my QPlainTextEdit is empty. You had sent me this link once.

        What have I already been able to find out?

        To get the data from the widget QPlainTextEdit you have to use the property("plainText") instead of property("text") to display the data. Unfortunately the paste and paste NULL does not work.

        I would need urgent help or tips.

        Thanks :)

        1 Reply Last reply
        0
        • ? Offline
          ? Offline
          A Former User
          wrote on last edited by
          #4

          I have been able to find out something. My setModelData from NullDelegate looks like this:

          void NullDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
          {
              const QVariant textWidget = editor->property("text");
              if(textWidget.isValid()){
                  model->setData(index, editor->property("text") == "" ? QVariant() : editor->property("text"));
              } else {
                  model->setData(index, editor->property("plainText") == "" ? QVariant() : editor->property("plainText"));
              }
          }
          

          Now I can save my data to the database except when my QLineEdit is empty. It does not want to save that to the database. Strangely enough, it works fine with my QPlainTextEdit. If there is something in this field it is saved, if I delete the content from QPlainTextEdit it saves "NULL" to the database.

          Any Idea?

          1 Reply Last reply
          0
          • ? Offline
            ? Offline
            A Former User
            wrote on last edited by
            #5

            I have found the error. The error was in the database. Here "not null" was set. The following code now works as expected:

            void NullDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
            {
                const QByteArray name = editor->metaObject()->userProperty().name();
                if(!name.isEmpty()){
                    if(editor->property(name).toString().isEmpty()){
                        model->setData(index, QVariant(), Qt::EditRole);
                    } else {
                        model->setData(index, editor->property(name), Qt::EditRole);
                    }
                }
            
            void NullDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
            {
                QVariant data = index.data(Qt::EditRole);
                const QByteArray name = editor->metaObject()->userProperty().name();
            
                if (!name.isEmpty()) {
                    if (!data.isValid())
                        data = QVariant(editor->property(name).userType(), (const void *)0);
                    editor->setProperty(name, data);
                }
            }
            
            1 Reply Last reply
            1

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved