QStyledItemDelegate with Custom Widget: setModelData function never gets called



  • 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.



  • @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



  • @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.



  • 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

Log in to reply
 

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