Domanda

I am new to Qt. I have a table with a delegate combo box as the second column. I wanted to detect click on the combo box.

I thought of one approach : add the combo box as a private variable in the ComboBoxDelegate and adding a public slot as

void on_cb_currentIndexChanged ( const QString & text );

However, since createEditor is const and I cannot re-assign the variable cb in this method. Is there any alternative way this can be done?

class ComboBoxDelegate : public QItemDelegate
{
     Q_OBJECT

 public:
     ComboBoxDelegate(std::vector<std::string> values, QObject *parent = 0);
     ~ComboBoxDelegate();
     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;

   private:
    std::vector<std::string> values;
  }
È stato utile?

Soluzione

As you said, you can have the combobox as a member of delegate class and connect the currentIndexChanged signal of combobox to some slot when creating the combobox in createEditor. You should declare combobox as mutable for newing it in createEditor which is constant. If a data member is declared mutable, then it is legal to assign a value to this data member from a const member function :

#include <QItemDelegate>

#include <QComboBox>

class ComboBoxDelegate: public QItemDelegate
{
 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 ):QItemDelegate(parent)
{
        comboItems<<"Item 1"<<"Item 2"<<"Item 3";
}

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);
}

Here i connect the currentIndexChanged signal of combobox to setData slot which commits the data to the model. You can also connect that signal to any slot you wish.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top