user1703942
user1703942

Reputation: 327

Access pointer to QWidget(Combobox) of the customdelegate

I have derived a class from QStyledItemDelegate. I am using a QComboBox in this delegate. This delegate is used in QTableView.

My question is, how can i change the index of the Combobox in the delegate programatically i.e how to access the pointer to that widget outside the delegate class ? I have checked that CreateEditor, SetEditorData, SetModelData functions (of QStyledItemDelegate) are called automatically when we click on the combobox and we cannot call them manually to maniplate the data in the model.

Upvotes: 1

Views: 717

Answers (2)

Nejat
Nejat

Reputation: 32665

You can have the contents of your combobox as a class member of your delegate in a QStringList. Your item delegate can be like :

#include <QStyledItemDelegate>

#include <QComboBox>

class ComboBoxDelegate: public QStyledItemDelegate
{
 Q_OBJECT
public:
    ComboBoxDelegate(QObject *parent = 0);

    QWidget *createEditor( QWidget *parent,
                            const QStyleOptionViewItem &option,
                            const QModelIndex &index ) const;

    void setEditorData( QWidget *editor,
                            const QModelIndex &index ) const;

    void setModelData( QWidget *editor,
                            QAbstractItemModel *model,
                            const QModelIndex &index ) const;

    void updateEditorGeometry( QWidget *editor,
                            const QStyleOptionViewItem &option,
                            const QModelIndex &index ) const;

    QStringList comboItems;

    mutable QComboBox *combo;

private slots:

    void setData(int val);

};

ComboBoxDelegate::ComboBoxDelegate(QObject *parent ):QStyledItemDelegate(parent)
{
}

QWidget *ComboBoxDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    combo = new QComboBox( parent );
    QObject::connect(combo,SIGNAL(currentIndexChanged(int)),this,SLOT(setData(int)));
    combo->addItems(comboItems);
    combo->setMaxVisibleItems(comboItems.count());
    return combo;
}

void ComboBoxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
    QString text = index.model()->data( index, Qt::DisplayRole ).toString();

    int comboIndex = comboItems.indexOf(QRegExp(text));

    if(comboIndex>=0)
        (static_cast<QComboBox*>( editor ))->setCurrentIndex(comboIndex);
}

void ComboBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
    model->setData( index, static_cast<QComboBox*>( editor )->currentText() );
}


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

void ComboBoxDelegate::setData(int val)
{
    emit commitData(combo);
    //emit closeEditor(combo);
}

When you want to update the items in combobox somewhere in your code just get a pointer to the item delegate by calling itemDelegateForColumn and access the comboItems member :

ComboBoxDelegate * itemDelegate = qobject_cast<ComboBoxDelegate *>(ui->tableView->itemDelegateForColumn(columnIndex));

//Updating combobox items
itemDelegate->comboItems.append("newItem");
...

Upvotes: 0

Zaiborg
Zaiborg

Reputation: 2522

afaik any time you start editing and the combobox is shown, it will allocate a new one. if you want to have a permanent combobox, you should look at

QTableView::setIndexWidget(const QModelIndex&, QWidget*)

so you could access the combobox with the following code:

const QMoodelIndex idx = model->index(row, column);
QWidget* wid = view->indexWidget(idx);
QComboBox* box = qobject_cast<QComboBox*>(wid);
if (box)
    // do your thing

Upvotes: 1

Related Questions