PDA

View Full Version : QItemDelegate for painting QComboBox in QTreeWidget



naturalpsychic
22nd May 2011, 17:44
I have a TreeWidget and i have managed to paint progress bar on one of column in QTreeWidget but i cannot get my head around painting combo box in (a different) column. Following is my QItemDelegate derived class:


#include "listviewdelegate.h"
#include "mainwindow.h"



ListViewDelegate::ListViewDelegate(MainWindow *parent):QItemDelegate(parent) {}



void ListViewDelegate::paint(QPainter *painter,const QStyleOptionViewItem &option,const QModelIndex &index) const
{

MainWindow* mw=static_cast<MainWindow*>(parent());

if (index.column() == 7)
{

createEditor(mw,option,index);
//this prints at wrong place

return;
}
else if (index.column()==4) //progress
{
QStyleOptionProgressBarV2 progressBarOption;
progressBarOption.state=QStyle::State_Enabled;
progressBarOption.direction = QApplication::layoutDirection();
progressBarOption.rect = option.rect;
progressBarOption.fontMetrics = QApplication::fontMetrics();
progressBarOption.minimum = 0;

try{
progressBarOption.maximum=mw->totalSize[index.row()];
}
catch(...){
}

progressBarOption.textAlignment = Qt::AlignCenter;
progressBarOption.textVisible = true;
if (index.row() == mw->currIdx){

int progress=mw->progress;

try{
progressBarOption.progress = progress < 0 ? 0 : progress;
}
catch(...){
}

progressBarOption.text = CMFile::getShortValue(progressBarOption.progress)+" / " +CMFile::getShortValue(progressBarOption.maximum);
}
else
{
progressBarOption.text=(index.row() < mw->currIdx)?"Completed":"Queued";

}
QApplication::style()->drawControl(QStyle::CE_ProgressBar,&progressBarOption,painter);
return;

}



QItemDelegate::paint(painter,option,index);

return;





}

QWidget* ListViewDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QComboBox *cmbBox=new QComboBox(parent);
cmbBox->insertItem(0,"YES");
cmbBox->insertItem(1,"NO");


cmbBox->setVisible(true);

return cmbBox;
}
void ListViewDelegate::setEditorData(QWidget *editor,
const QModelIndex &index) const
{
int value = index.model()->data(index, Qt::EditRole).toInt();

QComboBox *cmbBox = static_cast<QComboBox*>(editor);
cmbBox->setCurrentIndex(value);
}

void ListViewDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index) const
{
QComboBox *cmbBox = static_cast<QComboBox*>(editor);

int value = cmbBox->itemText(0).toInt();

model->setData(index, value, Qt::EditRole);
}

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




It does paint the combobox but it does it at 0,0 location on form. when i have set geometry to option's rect object already.

any idea? thanks

wysota
22nd May 2011, 22:05
paint() is supposed to paint and not create widgets.

naturalpsychic
23rd May 2011, 04:14
yes that make sense but why is it not painting it on TreeWidget column rect, why is it painting it on 0,0 location?

wysota
23rd May 2011, 07:19
Because you create a widget as a child of the main window so it is shown on there. What did you want to obtain by calling createEditor() there?

naturalpsychic
23rd May 2011, 08:49
i wanted to create combobox so user can select one of yes or no from that combo box for certain qtreewidgetitem

naturalpsychic
23rd May 2011, 11:50
whats up guys? no good delegate programmer around the world?

meazza
23rd May 2011, 11:54
You can try and take look at this http://doc.qt.nokia.com/4.7/itemviews-spinboxdelegate.html and replace the spinbox with a QComboBox.

wysota
23rd May 2011, 16:38
i wanted to create combobox so user can select one of yes or no from that combo box for certain qtreewidgetitem

This doesn't require reimplementing paint(). If you want to mimic the looks of a combobox, do it the same way you mimic the looks of progress bar.