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. Editing data in QStandardItemModel with tableView

Editing data in QStandardItemModel with tableView

Scheduled Pinned Locked Moved Solved General and Desktop
6 Posts 3 Posters 1.6k 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.
  • G Offline
    G Offline
    gabor53
    wrote on last edited by
    #1

    Hi,
    I have a working QStandardItemModel with tableView. Editing small fields with QLineEdit works fine. But I also have a date field. I used the following code to place a calendar widget in the field:

       QDateTimeEdit *editor = new QDateTimeEdit(parent);
        editor->setDisplayFormat ("dd/M/yyyy");
        editor->setCalendarPopup (true);
    
        connect(editor,&QDateTimeEdit::editingFinished ,this,&myDelegate::commitAndCloseEditor );
        return editor;
    

    It works great, but the calendar widget shows up in the top left corner of the dialog. Please help me to figure out how to keep it around the column which holds the dates.
    Thank you for your help.

    raven-worxR 1 Reply Last reply
    0
    • G gabor53

      Hi,
      I have a working QStandardItemModel with tableView. Editing small fields with QLineEdit works fine. But I also have a date field. I used the following code to place a calendar widget in the field:

         QDateTimeEdit *editor = new QDateTimeEdit(parent);
          editor->setDisplayFormat ("dd/M/yyyy");
          editor->setCalendarPopup (true);
      
          connect(editor,&QDateTimeEdit::editingFinished ,this,&myDelegate::commitAndCloseEditor );
          return editor;
      

      It works great, but the calendar widget shows up in the top left corner of the dialog. Please help me to figure out how to keep it around the column which holds the dates.
      Thank you for your help.

      raven-worxR Offline
      raven-worxR Offline
      raven-worx
      Moderators
      wrote on last edited by
      #2

      @gabor53
      i assume you are in your delegates createEditor() method?
      If so there is a QStyleOptionViewItem parameter passed, which has a rect member.
      Either move it to the rect's top-left or assign the rect to the editor directly.

      --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
      If you have a question please use the forum so others can benefit from the solution in the future

      G 1 Reply Last reply
      0
      • VRoninV Offline
        VRoninV Offline
        VRonin
        wrote on last edited by VRonin
        #3

        I implemented something identical and never had any similar problem. here is my code (i use QDateEdit instead of QDateTimeEdit)

        datedelegate.h

        #ifndef DATEDELEGATE_H
        #define DATEDELEGATE_H
        
        #include <QStyledItemDelegate>
        class QDate;
        class DateDelegatePrivate;
        class DateDelegate : public QStyledItemDelegate
        {
            Q_OBJECT
            Q_DECLARE_PRIVATE(DateDelegate)
        public:
            explicit DateDelegate(QObject *parent=nullptr);
            virtual ~DateDelegate();
            DateDelegate(const DateDelegate&) = delete;
            DateDelegate& operator=(const DateDelegate&) = delete;
            virtual QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
            virtual void setEditorData(QWidget *editor, const QModelIndex &index) const override;
            virtual void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override;
            virtual void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
            virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;
            void setCalendarPopup(bool val);
            bool calendarPopup() const;
            void setMaximumDate(const QDate& val);
            void setMinimumDate(const QDate& val);
            const QDate& maximumDate() const;
            const QDate& minimumDate() const;
        private:
            DateDelegatePrivate* d_ptr;
        };
        
        #endif // DATEDELEGATE_H
        

        datedelegate.cpp

        #include "datedelegate.h"
        #include <QDateEdit>
        #include <QApplication>
        
        class DateDelegatePrivate{
            Q_DECLARE_PUBLIC(DateDelegate)
            DateDelegatePrivate(DateDelegate* q);
            DateDelegatePrivate() = delete;
            DateDelegate* q_ptr;
            bool m_calendarPopUp;
            QDate m_minDate;
            QDate m_maxDate;
        };
        
        DateDelegatePrivate::DateDelegatePrivate(DateDelegate* q)
            :q_ptr(q)
            , m_calendarPopUp(true)
        {
        
        }
        
        DateDelegate::DateDelegate(QObject *parent)
            : QStyledItemDelegate(parent)
            , d_ptr(new DateDelegatePrivate(this))
        {
        
        }
        
        DateDelegate::~DateDelegate()
        {
            delete d_ptr;
        }
        
        QWidget * DateDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &) const
        {
            QDateEdit* result = new QDateEdit(parent);
            result->setCalendarPopup(calendarPopup());
            result->setMaximumDate(maximumDate());
            result->setMinimumDate(minimumDate());
            return result;
        }
        
        void DateDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
        {
            QDateEdit* dtEditor = qobject_cast<QDateEdit*>(editor);
            Q_ASSERT(dtEditor);
            if (index.data(Qt::EditRole).isNull())
                dtEditor->clear();
            else
                dtEditor->setDate(index.data(Qt::EditRole).toDate());
        }
        
        void DateDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
        {
            QDateEdit* dtEditor = qobject_cast<QDateEdit*>(editor);
            if(dtEditor->text().isEmpty())
                model->setData(index, QVariant(), Qt::EditRole);
            else 
                model->setData(index, dtEditor->date(), Qt::EditRole);
        }
        
        void DateDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &) const
        {
            editor->setGeometry(option.rect);
        }
        
        QSize DateDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
        {
            QVariant value = index.data(Qt::SizeHintRole);
            if (value.isValid())
                return qvariant_cast<QSize>(value);
        
            QStyleOptionViewItem opt = option;
            initStyleOption(&opt, index);
            const QWidget *widget = option.widget;
            const QStyle *style = widget ? widget->style() : QApplication::style();
            const QSize hint = style->sizeFromContents(QStyle::CT_ItemViewItem, &opt, QSize(), widget);
            QSize resultSize;
            Q_D(const DateDelegate);
        #ifdef Q_OS_MAC
            if (d->m_calendarPopUp) {
                QStyleOptionComboBox opt;
                resultSize = style->sizeFromContents(QStyle::CT_ComboBox, &opt, hint, widget);
            }
            else
        #endif
            {
                QStyleOptionSpinBox opt;
                if (d->m_calendarPopUp) {
                    opt.subControls = QStyle::SC_ComboBoxFrame | QStyle::SC_ComboBoxEditField
                        | QStyle::SC_ComboBoxArrow;
                }
                resultSize = style->sizeFromContents(QStyle::CT_SpinBox, &opt, hint, widget).expandedTo(QApplication::globalStrut());
            }
            return resultSize;
        }
        
        void DateDelegate::setCalendarPopup(bool val)
        {
            Q_D(DateDelegate);
            d->m_calendarPopUp = val;
        }
        
        bool DateDelegate::calendarPopup() const
        {
            Q_D(const DateDelegate);
            return d->m_calendarPopUp;
        }
        
        void DateDelegate::setMaximumDate(const QDate& val)
        {
            Q_D(DateDelegate);
            d->m_maxDate = val;
        }
        
        void DateDelegate::setMinimumDate(const QDate& val)
        {
            Q_D(DateDelegate);
            d->m_minDate = val;
        }
        
        const QDate& DateDelegate::maximumDate() const
        {
            Q_D(const DateDelegate);
            return d->m_maxDate;
        }
        
        const QDate& DateDelegate::minimumDate() const
        {
            Q_D(const DateDelegate);
            return d->m_minDate;
        }
        
        

        "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
        ~Napoleon Bonaparte

        On a crusade to banish setIndexWidget() from the holy land of Qt

        1 Reply Last reply
        3
        • raven-worxR raven-worx

          @gabor53
          i assume you are in your delegates createEditor() method?
          If so there is a QStyleOptionViewItem parameter passed, which has a rect member.
          Either move it to the rect's top-left or assign the rect to the editor directly.

          G Offline
          G Offline
          gabor53
          wrote on last edited by
          #4

          @raven-worx
          Yes, you are right.

          raven-worxR 1 Reply Last reply
          0
          • G gabor53

            @raven-worx
            Yes, you are right.

            raven-worxR Offline
            raven-worxR Offline
            raven-worx
            Moderators
            wrote on last edited by
            #5

            @gabor53
            anyway the more correct way is like in the example posted by @VRonin

            void DateDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &) const
            {
                editor->setGeometry(option.rect);
            }
            

            Since i am not sure in which cases the editor's geometry needs to be updated. This way we trust Qt.

            --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
            If you have a question please use the forum so others can benefit from the solution in the future

            G 1 Reply Last reply
            3
            • raven-worxR raven-worx

              @gabor53
              anyway the more correct way is like in the example posted by @VRonin

              void DateDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &) const
              {
                  editor->setGeometry(option.rect);
              }
              

              Since i am not sure in which cases the editor's geometry needs to be updated. This way we trust Qt.

              G Offline
              G Offline
              gabor53
              wrote on last edited by
              #6

              @raven-worx
              Thank you. This worked out well. I ended up using

              void myDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
              {
                  editor->setGeometry (option.rect);
              }
              
              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