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. QStyledItemDelegate with Custom Widget: setModelData function never gets called
QtWS25 Last Chance

QStyledItemDelegate with Custom Widget: setModelData function never gets called

Scheduled Pinned Locked Moved Unsolved General and Desktop
4 Posts 2 Posters 2.1k 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.
  • T Offline
    T Offline
    tSarigat
    wrote on 5 Jun 2017, 03:43 last edited by tSarigat 6 May 2017, 03:44
    #1

    Hi Guys,

    I need to use QCheckBox inside one of the columns in my table View.

    By directly passing the checkbox through createEditor() in my custom delegate, i am able to get the functionality running, but the checkbox is always left alligned.
    So i created my own Custom Checkbox widget to get it center aligned.

    #include <QWidget>
     
    class QCheckBox;
     
    class MyCheckBoxWidget : public QWidget
    {
        Q_OBJECT
    public:
        MyCheckBoxWidget (QWidget *parent = 0);
     
        QCheckBox *checkBox() ;
     
    private:
        QCheckBox *checkbox;
     
    };
    
    ---------------------------------------------------------------------
    
    #include <mycheckboxwidget.h>
    #include <QtGui>
     
    MyCheckBoxWidget ::MyCheckBoxWidget (QWidget *parent) :
        QWidget(parent)
    {
        setContentsMargins(0, 0, 0, 0);
        setAutoFillBackground(true);
     
        QHBoxLayout *layout=new QHBoxLayout();
        checkbox=new QCheckBox();
        layout->addWidget(checkbox);
        layout->setAlignment(checkbox, Qt::AlignHCenter | Qt::AlignVCenter);
        layout->setContentsMargins(0, 0, 0, 0);
        layout->setSpacing(0);
     
        setLayout(layout);
     
        setFocusProxy(checkbox);
    }
     
    QCheckBox *MyCheckBoxWidget ::checkBox()
    {
        return checkbox;
    }
    

    Now when i use this custom widget inside my Item Delegate, The delegate function setModelData() is never called.
    Adding ItemDelegate code below.

    QWidget* SitesDelegate::createEditor( QWidget* 						iParent,
    											  const QStyleOptionViewItem&	iOption,
    											  const QModelIndex&			iIndex ) const
    {
    	Q_UNUSED( iOption );    
    	if ( index.isValid() )
    	{
                     if(index.column == 0)
                    {
    		               MyCheckBoxWidget*		checkBox = new MyCheckBoxWidget(iParent);
    
    		               checkBox->setStyleSheet("background-color: white");
    
                                    QObject::connect(
                    		                 checkBox->checkBox(),                       SIGNAL(stateChanged(int)),
                                                     this,                           SLOT(handleProcessSelectionActivated(int)) );
    
                                    return checkBox;
                       }
                       else
                       {
                                  return QStyledItemDelegate::createEditor( iParent, iOption, iIndex );
                        }
    
    	}
    	return NULL;
    }
    
    void SitesDelegate::setEditorData( QWidget* 			iEditor,
    										   const QModelIndex&	iIndex ) const
    {
    	MyCheckBoxWidget* checkBox= dynamic_cast<MyCheckBoxWidget*>(iEditor);
    	if ( checkBox )
    	{
            int index_i = iIndex.model()->data(iIndex, Qt::EditRole).toInt();
            checkBox->checkBox()->setChecked(index_i);
    	}
    }
    
    void SitesDelegate::setModelData( QWidget*				iEditor,
    										  QAbstractItemModel*	iModel,
    										  const QModelIndex&	iIndex ) const
    {
    	MyCheckBoxWidget* checkBox = dynamic_cast<MyCheckBoxWidget*> (iEditor);
    	if ( checkBox )
    	{
    		iny value = checkBox->checkBox()->isChecked();
    		iModel->setData(iIndex, value, Qt::EditRole);
    	}
    }
    
    void SitesDelegate::handleProcessSelectionActivated( int ) // slot
    {
    	MyCheckBoxWidget* checkBox= static_cast<MyCheckBoxWidget*>( sender() );
    	emit commitData (checkBox);
    }
    

    I can see that initially createEditor() and setEditorData() both functions are called for all items.
    But later while changing the QCheckBox state, even if i am calling commitData() on state change event, setModelData() is never called.

    Any help would be appriciated.

    Thanks.

    V 1 Reply Last reply 5 Jun 2017, 07:05
    0
    • T tSarigat
      5 Jun 2017, 03:43

      Hi Guys,

      I need to use QCheckBox inside one of the columns in my table View.

      By directly passing the checkbox through createEditor() in my custom delegate, i am able to get the functionality running, but the checkbox is always left alligned.
      So i created my own Custom Checkbox widget to get it center aligned.

      #include <QWidget>
       
      class QCheckBox;
       
      class MyCheckBoxWidget : public QWidget
      {
          Q_OBJECT
      public:
          MyCheckBoxWidget (QWidget *parent = 0);
       
          QCheckBox *checkBox() ;
       
      private:
          QCheckBox *checkbox;
       
      };
      
      ---------------------------------------------------------------------
      
      #include <mycheckboxwidget.h>
      #include <QtGui>
       
      MyCheckBoxWidget ::MyCheckBoxWidget (QWidget *parent) :
          QWidget(parent)
      {
          setContentsMargins(0, 0, 0, 0);
          setAutoFillBackground(true);
       
          QHBoxLayout *layout=new QHBoxLayout();
          checkbox=new QCheckBox();
          layout->addWidget(checkbox);
          layout->setAlignment(checkbox, Qt::AlignHCenter | Qt::AlignVCenter);
          layout->setContentsMargins(0, 0, 0, 0);
          layout->setSpacing(0);
       
          setLayout(layout);
       
          setFocusProxy(checkbox);
      }
       
      QCheckBox *MyCheckBoxWidget ::checkBox()
      {
          return checkbox;
      }
      

      Now when i use this custom widget inside my Item Delegate, The delegate function setModelData() is never called.
      Adding ItemDelegate code below.

      QWidget* SitesDelegate::createEditor( QWidget* 						iParent,
      											  const QStyleOptionViewItem&	iOption,
      											  const QModelIndex&			iIndex ) const
      {
      	Q_UNUSED( iOption );    
      	if ( index.isValid() )
      	{
                       if(index.column == 0)
                      {
      		               MyCheckBoxWidget*		checkBox = new MyCheckBoxWidget(iParent);
      
      		               checkBox->setStyleSheet("background-color: white");
      
                                      QObject::connect(
                      		                 checkBox->checkBox(),                       SIGNAL(stateChanged(int)),
                                                       this,                           SLOT(handleProcessSelectionActivated(int)) );
      
                                      return checkBox;
                         }
                         else
                         {
                                    return QStyledItemDelegate::createEditor( iParent, iOption, iIndex );
                          }
      
      	}
      	return NULL;
      }
      
      void SitesDelegate::setEditorData( QWidget* 			iEditor,
      										   const QModelIndex&	iIndex ) const
      {
      	MyCheckBoxWidget* checkBox= dynamic_cast<MyCheckBoxWidget*>(iEditor);
      	if ( checkBox )
      	{
              int index_i = iIndex.model()->data(iIndex, Qt::EditRole).toInt();
              checkBox->checkBox()->setChecked(index_i);
      	}
      }
      
      void SitesDelegate::setModelData( QWidget*				iEditor,
      										  QAbstractItemModel*	iModel,
      										  const QModelIndex&	iIndex ) const
      {
      	MyCheckBoxWidget* checkBox = dynamic_cast<MyCheckBoxWidget*> (iEditor);
      	if ( checkBox )
      	{
      		iny value = checkBox->checkBox()->isChecked();
      		iModel->setData(iIndex, value, Qt::EditRole);
      	}
      }
      
      void SitesDelegate::handleProcessSelectionActivated( int ) // slot
      {
      	MyCheckBoxWidget* checkBox= static_cast<MyCheckBoxWidget*>( sender() );
      	emit commitData (checkBox);
      }
      

      I can see that initially createEditor() and setEditorData() both functions are called for all items.
      But later while changing the QCheckBox state, even if i am calling commitData() on state change event, setModelData() is never called.

      Any help would be appriciated.

      Thanks.

      V Offline
      V Offline
      VRonin
      wrote on 5 Jun 2017, 07:05 last edited by
      #2

      @tSarigat said in QStyledItemDelegate with Custom Widget: setModelData function never gets called:

      But later while changing the QCheckBox state

      setModelData should not be called every time the editor is touched but only after the editing is finished so what you are experiencing is exactly the intended behaviour.

      On a separate note, you don't need a checkbox delegate as you can just set the flag to Qt::ItemIsUserCheckable from the model

      "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

      T 1 Reply Last reply 5 Jun 2017, 07:29
      3
      • V VRonin
        5 Jun 2017, 07:05

        @tSarigat said in QStyledItemDelegate with Custom Widget: setModelData function never gets called:

        But later while changing the QCheckBox state

        setModelData should not be called every time the editor is touched but only after the editing is finished so what you are experiencing is exactly the intended behaviour.

        On a separate note, you don't need a checkbox delegate as you can just set the flag to Qt::ItemIsUserCheckable from the model

        T Offline
        T Offline
        tSarigat
        wrote on 5 Jun 2017, 07:29 last edited by
        #3

        @VRonin said in QStyledItemDelegate with Custom Widget: setModelData function never gets called:

        setModelData should not be called every time the editor is touched but only after the editing is finished so what you are experiencing is exactly the intended behaviour.

        But if i pass directly QCheckBox in my createEditor(), i am able to get the call backs on every clicks. And setModelData being done. Its only when i pass my custom "MyCheckBoxWidget" this problem occurs.

        1 Reply Last reply
        0
        • V Offline
          V Offline
          VRonin
          wrote on 5 Jun 2017, 07:44 last edited by VRonin 6 May 2017, 07:45
          #4

          simply:

          • implement a signal in MyCheckBoxWidget: Q_SIGNAL void clicked(bool);
          • in MyCheckBoxWidget constructor add QObject::connect(checkbox,&QCheckBox::clicked,this,&MyCheckBoxWidget::clicked);
          • in the delegate createEditor add QObject::connect(checkBox,&MyCheckBoxWidget::clicked,this,&SitesDelegate::commitData);

          3 other notes on your code:

          • Q_UNUSED( iOption ); is misleading (even if it does not create any problem to the code) because then you use it.
          • The delegate should not have any idea of how your data looks like. avoid things like if(index.column == 0) and just use setItemDelegateForColumn on the view.
          • It's still more straightforward to just set the flag Qt::ItemIsUserCheckable in the model rather than going through all of this

          "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
          2
          • B bibasmall referenced this topic on 12 May 2023, 10:12

          4/4

          5 Jun 2017, 07:44

          • Login

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