2015-05-13 2 views
1

Моя проблема заключается в следующем:dataChanged сигнал не работает с ComboBoxDelegate

Существует QTableView и QStandardItemModel используется таким образом:

ui->tableView->setModel(model); 
model->setItem(myrow, mycolumn, myQStandardItem); 

и comboboxdelegate:

ComboBoxDelegate* mydelegate = new ComboBoxDelegate(); 
ui->tableView->setItemDelegateForColumn(mycolumn,mydelegate); 

Каждый раз, когда значение ячейки таблицы изменяется (в поле со списком), мне нужно поймать новое значение и только что измененный индекс ячейки. Я использую сигнал dataChaged связана с моделью таким образом:

connect(model,SIGNAL(dataChanged(QModelIndex&,QModelIndex&)),this,SLOT(GetChangedValue(QModelIndex&))); 

, но он не работает, он никогда не вызывает метод GetChangedValue хотя комбо-бокс изменил свое значение. Я пропускаю любой шаг?

Здесь ниже кода ComboBoxDelegate:

class ComboBoxDelegate : public QStyledItemDelegate 
{ 
    Q_OBJECT 
public: 

    ComboBoxDelegate(QVector<QString>& ItemsToCopy,QObject *parent = 0); 
    ~ComboBoxDelegate(); 
    void setItemData(QVector<QString>& ItemsToCopy); 

    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: 
    QVector<QString> Items; 

}; 

ComboBoxDelegate::ComboBoxDelegate(QVector<QString>& ItemsToCopy,QObject *parent) 
:QStyledItemDelegate(parent) 
{ 
    setItemData(ItemsToCopy); 
} 


ComboBoxDelegate::~ComboBoxDelegate() 
{ 
} 


QWidget *ComboBoxDelegate::createEditor(QWidget *parent, const  QStyleOptionViewItem &option, const QModelIndex &index) const 
{ 

    QComboBox* editor = new QComboBox(parent); 
    editor->setEditable(true); 



    for (int i = 0; i < Items.size(); ++i) 
    { 
     editor->addItem(Items[i]); 
    } 


    editor->setStyleSheet("combobox-popup: 0;"); 

    return editor; 
} 




void ComboBoxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const 
{ 
    QComboBox *comboBox = static_cast<QComboBox*>(editor); 
    QString currentText = index.data(Qt::EditRole).toString(); 
    int cbIndex = comboBox->findText(currentText); 
    comboBox->setCurrentIndex(cbIndex); 
} 



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

} 



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

} 



void ComboBoxDelegate::setItemData(QVector<QString>& ItemsToCopy) 
{ 
    for (int row = 0; row < ItemsToCopy.size(); ++row) 
    { 

     Items.push_back(ItemsToCopy[row]); 


    } 

}

+0

Вы видите новое значение, заданное вашим редактором в виде таблицы? Возвращает ли функция 'connect'' true'? – hank

ответ

1

Проблема с реализацией делегата является то, что вы не испускают commitData сигнал, когда индекс комбо изменяется. Об этом говорится в документации Qt:

Этот сигнал должен быть испускается, когда виджет-редактор завершил редактирования данных, и хочет, чтобы записать его обратно в модель.

Вы можете иметь комбо-бокс в качестве члена класса делегата и подключить currentIndexChanged сигнал комбо-бокс какой-то слот, который излучает commitData:

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

Как вы видите currentIndexChanged сигнал комбо -box подключен к слоту setData, который передает данные модели. Также вы должны объявить combo-box как изменчивый для его добавления в createEditor, который является постоянным. Если член данных объявлен изменчивым, тогда законно назначить значение этому элементу данных из функции-члена const.

Теперь сигнал dataChanged будет излучаться при изменении индекса комбинированного блока.

+0

Отличный !! Благодарим вас за поддержку, сейчас она работает. –

Смежные вопросы