For application I was using some different mechanism to create button inside custom item delegate, but now I found better way to create custom item delegate with QPushButton. So thought to share code.
Following is code for custom item delegate derived from QItemDelegate.
Update: I have uploaded following code to gitorous, Please visit this link if you want a working sample code.
#include <QItemDelegate> class CustomItemDelegate : public QItemDelegate { Q_OBJECT public: CustomItemDelegate(QObject *parent = 0); virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const ; virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const ; bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index); signals: void buttonClicked(const QModelIndex &index); private: QStyle::State _state; }; #include "customitemdelegate.h" ... CustomItemDelegate::CustomItemDelegate(QObject *parent) : QItemDelegate(parent) { _state = QStyle::State_Enabled; } void CustomItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { const QStandardItemModel* model = static_cast<const QStandardItemModel*>(index.model()); QStandardItem* item = model->item(index.row()); QString text = item->text(); QRect rect = option.rect; QRect textRect( rect); textRect.setHeight( 30); painter->drawText(textRect,text); QRect buttonRect( rect); buttonRect.setY(textRect.y()+ 35); buttonRect.setHeight( 30); QStyleOptionButton button; button.rect = buttonRect; button.text = text; button.state = _state | QStyle::State_Enabled; QApplication::style()->drawControl (QStyle::CE_PushButton, &button, painter); } QSize CustomItemDelegate::sizeHint(const QStyleOptionViewItem &/*option*/, const QModelIndex &/*index*/) const { //hard coding size for test purpose, //actual size hint can be calculated from option param return QSize(800,70); } bool CustomItemDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) { if( event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonRelease ) { } else { //ignoring other mouse event and reseting button's state _state = QStyle::State_Raised; return true; } QRect buttonRect( option.rect); buttonRect.setY(option.rect.y()+ 35); buttonRect.setHeight( 30); QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event); if( !buttonRect.contains( mouseEvent->pos()) ) { _state = QStyle::State_Raised; return true; } if( event->type() == QEvent::MouseButtonPress) { _state = QStyle::State_Sunken; } else if( event->type() == QEvent::MouseButtonRelease) { _state = QStyle::State_Raised; emit buttonClicked( index); } return true; }Basically in above code, I am calculating rect where I want to draw my button and drawing QPushButton on list item using QStyleOptionButton class.
And in editor event on mouse press and release event, I am checking if mouse position on click falls into my button's rect or not. If it falls inside my button's rect then I am emitting signal.
I am using item's signal as shown in below code.
CustomList::CustomList(QWidget *parent) : QWidget(parent),_view(0) { _view = new QListView(); _view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); _view->setEditTriggers(QAbstractItemView::NoEditTriggers); //creating custom item delegate and setting it to view CustomItemDelegate* itemDelegate = new CustomItemDelegate(_view); _view->setItemDelegate( itemDelegate ); _view->setModel(&_model); //connecting delegate's signal to this class's slot connect(itemDelegate,SIGNAL(buttonClicked(QModelIndex)), this,SLOT(listButtonClicked(QModelIndex))); QHBoxLayout* mainLayout = new QHBoxLayout(this); mainLayout->addWidget( _view); //creating and adding data to model QStandardItem* item = new QStandardItem; item->setText("testing"); QStandardItem* item1 = new QStandardItem; item1->setText("testing1"); _model.appendRow(item); _model.appendRow(item1); } // following slot will be invoked when delegate's button is clicked void CustomList::listButtonClicked(const QModelIndex &index) { qDebug() << "######### listbutton clicked ######### " << index.row(); }Following is snap of how custom item delegate looks.