2015-05-13 78 views
1

工作,我的問題是這樣的:dataChanged信號不ComboBoxDelegate

有以這種方式使用一個QTableViewQStandardItemModel

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插槽。你也應該聲明組合框是可變的,在createEditor這是恆定的。如果一個數據成員聲明爲mutable,那麼從const成員函數中爲這個數據成員賦值是合法的。

現在dataChanged信號將在組合框的索引改變時發出。

+0

太棒了!感謝您的支持,現在確實有效。 –