Студент
Группа: Участник
Сообщений: 93
Регистрация: 21.10.2009
Из: Нижний Новгород
Пользователь №: 1168
Спасибо сказали: 9 раз(а)
Репутация: 0
|
Вообщем, приблизительно сделал так: delegate.h : #ifndef DELEGATE_H #define DELEGATE_H
#include <QtGui>
//! Универсальный делегат для ввода любых значний в зависимости от UserRole // 0 - строка ввода // 1 - чекбокс // 2 - спинбокс // 3 - комбобокс // 4 - ввод денег // 5 - ввод дробных и целых чисел // 6 - ввод целых чисел // 7 - пустрой делегат, нередактируемый
class UniversalDelegate : public QItemDelegate { Q_OBJECT public: UniversalDelegate(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; void paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const; void setComboValuesForCell(const QModelIndex index,const QList< QPair<int,QString> > aValues); void setComboValuesForColumn(const int aColumn,const QList< QPair<int,QString> > aValues); void setColumnDelegate(const int aColumn,const int aDelegate) {aColumnDelegate[aColumn] = aDelegate;} void setCellDelegate(const QModelIndex index,const int aDelegate) {aCellDelegate[index] = aDelegate;}
QList< QPair<int,QString> > getComboValuesForCell(const QModelIndex index) const; int getCurrentDelegate(const QModelIndex index) const;
void Clear();
private slots: void ChangeComboBoxText(int);
private: QMap <QModelIndex,QList< QPair<int,QString> > > aValuesOfComboForCell; QMap <QModelIndex,QVector<int> > aIndexesOfComboForCell;
QMap <int,QList< QPair<int,QString> > > aValuesOfComboForColumn; QMap <int,QVector<int> > aIndexesOfComboForColumn;
QMap <int,int> aColumnDelegate; QMap <QModelIndex,int> aCellDelegate; };
#endif
delegate.cpp : #include "delegate.h"
//! Универсальный делегат для ввода любых значний в зависимости от UserRole UniversalDelegate::UniversalDelegate(QObject *parent) : QItemDelegate(parent) { }
QWidget *UniversalDelegate::createEditor( QWidget *parent, const QStyleOptionViewItem& /* option */, const QModelIndex& index) const { //Для начала построю делегат для всего столбца int aCurUserRole; aCurUserRole = aColumnDelegate.value(index.column(),-1); if (aCurUserRole == -1) //А если все-таки делегат для конкретной ячейки, тогда узнаю из нее, какой нужен aCurUserRole = aCellDelegate.value(index,0);
if (aCurUserRole==1) //чекбокс { QCheckBox *editor = new QCheckBox(parent); connect(editor,SIGNAL(stateChanged(int)),this,SLOT(ChangeComboBoxText(int))); return editor; }
if (aCurUserRole==2) //спинбокс { QSpinBox *editor = new QSpinBox(parent); editor->setMinimum(0); editor->setMaximum(100);
return editor; }
if (aCurUserRole==3) //комбобокс { QComboBox *editor = new QComboBox(parent);
QList< QPair<int,QString> > aValues;
if (aColumnDelegate.contains(index.column())) aValues = aValuesOfComboForColumn.value(index.column()); else aValues = aValuesOfComboForCell.value(index);
QList< QPair<int,QString> >::const_iterator it=aValues.begin(); while (it != aValues.end()) { const QPair <int,QString> aPair = *it; editor->addItem(aPair.second); ++it; } return editor; }
if (aCurUserRole==4) //ввод денег { QDoubleSpinBox *editor = new QDoubleSpinBox(parent); editor->setMinimum(0.00); editor->setMaximum(999999999); editor->setDecimals(2); editor->setSingleStep(0.1); return editor; }
if (aCurUserRole==5) //ввод дробных и целых чисел { QLineEdit *editor = new QLineEdit(parent); return editor; }
if (aCurUserRole==6) //ввод целых чисел { QLineEdit *editor = new QLineEdit(parent); return editor; }
if (aCurUserRole==7) //пустрой делегат, нередактируемый { QLineEdit *editor = new QLineEdit(parent); editor->setReadOnly(true); return editor; }
//строка ввода QLineEdit *editor = new QLineEdit(parent); return editor; }
void UniversalDelegate::setEditorData( QWidget *editor, const QModelIndex &index) const {
//Для начала построю делегат для всего столбца int aCurUserRole; aCurUserRole = aColumnDelegate.value(index.column(),-1); if (aCurUserRole == -1) //А если все-таки делегат для конкретной ячейки, тогда узнаю из нее, какой нужен aCurUserRole = aCellDelegate.value(index,0);
if (aCurUserRole==0) //строка ввода { if (index.model()->data(index, Qt::EditRole).isNull()) return; const QString value = index.model()->data( index, Qt::EditRole).toString(); QLineEdit *lineEdit = static_cast<QLineEdit*>(editor); lineEdit->setText(value); }
if (aCurUserRole==1) //чекбокс { QCheckBox *checkBox = static_cast<QCheckBox*>(editor); if (index.model()->data(index, Qt::EditRole).toInt()!=1) { checkBox->setChecked(false); checkBox->setText(QString::fromUtf8("Нет")); } else { checkBox->setChecked(true); checkBox->setText(QString::fromUtf8("Да")); } }
if (aCurUserRole==2) //спинбокс { const int value = index.model()->data(index, Qt::EditRole).toInt();
QSpinBox *spinBox = static_cast<QSpinBox*>(editor); spinBox->setValue(value); }
if (aCurUserRole==3) //комбобокс { QComboBox *comboBox = static_cast<QComboBox*>(editor);
const int value = index.model()->data(index, Qt::EditRole).toInt();
QVector<int> aIndexes; if (aColumnDelegate.contains(index.column())) aIndexes = aIndexesOfComboForColumn.value(index.column()); else aIndexes = aIndexesOfComboForCell.value(index);
comboBox->setCurrentIndex(aIndexes.indexOf(value)); }
if (aCurUserRole==4) //ввод денег { const double value = index.model()->data( index, Qt::EditRole).toDouble(); QDoubleSpinBox *doubleSpinBox = static_cast<QDoubleSpinBox*>(editor); doubleSpinBox->setValue(value); }
if (aCurUserRole==5) //ввод дробных и целых чисел { if (index.model()->data(index, Qt::EditRole).isNull()) return; const QString value = index.model()->data( index, Qt::EditRole).toString(); QLineEdit *lineEdit = static_cast<QLineEdit*>(editor); lineEdit->setText(value); }
if (aCurUserRole==6) //ввод целых чисел { if (index.model()->data(index, Qt::EditRole).isNull()) return; const QString value = index.model()->data( index, Qt::EditRole).toString(); QLineEdit *lineEdit = static_cast<QLineEdit*>(editor); lineEdit->setText(value); }
if (aCurUserRole==7) //пустрой делегат, нередактируемый { return; }
}
void UniversalDelegate::setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex& index) const {
//Для начала построю делегат для всего столбца int aCurUserRole; aCurUserRole = aColumnDelegate.value(index.column(),-1); if (aCurUserRole == -1) //А если все-таки делегат для конкретной ячейки, тогда узнаю из нее, какой нужен aCurUserRole = aCellDelegate.value(index,0);
if (aCurUserRole==0) //строка ввода { QLineEdit *lineEdit = static_cast<QLineEdit*>(editor); model->setData(index, lineEdit->text()); }
if (aCurUserRole==1) //чекбокс { QCheckBox *checkBox = static_cast<QCheckBox*>(editor); if (checkBox->isChecked()) model->setData(index, "1"); else model->setData(index, "0"); }
if (aCurUserRole==2) //спинбокс { QSpinBox *spinBox = static_cast<QSpinBox*>(editor); spinBox->interpretText(); const int value = spinBox->value();
model->setData(index, value, Qt::EditRole); }
if (aCurUserRole==3) //комбобокс { QComboBox *comboBox = static_cast<QComboBox*>(editor);
QVector<int> aIndexes; if (aColumnDelegate.contains(index.column())) aIndexes = aIndexesOfComboForColumn.value(index.column()); else aIndexes = aIndexesOfComboForCell.value(index);
model->setData(index, aIndexes.at(comboBox->currentIndex()), Qt::EditRole); } if (aCurUserRole==4) //ввод денег { QDoubleSpinBox *doubleSpinBox = static_cast<QDoubleSpinBox*>(editor); doubleSpinBox->interpretText(); model->setData(index, doubleSpinBox->text()); }
if (aCurUserRole==5) //ввод дробных и целых чисел { QLineEdit *lineEdit = static_cast<QLineEdit*>(editor);
if (lineEdit->text().isEmpty()) { model->setData(index, QVariant(QString::null)); return; }
const QString aValue = QString::number(lineEdit->text().toDouble()); model->setData(index, aValue); }
if (aCurUserRole==6) //ввод целых чисел { QLineEdit *lineEdit = static_cast<QLineEdit*>(editor);
if (lineEdit->text().isEmpty()) { model->setData(index, QVariant(QString::null)); return; }
const QString aValue = QString::number(lineEdit->text().toInt()); model->setData(index, aValue); }
if (aCurUserRole==7) //пустрой делегат, нередактируемый { return; }
}
void UniversalDelegate::updateEditorGeometry( QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex& /* index */) const { editor->setGeometry(option.rect); }
void UniversalDelegate::paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const {
int aCurUserRole; aCurUserRole = aColumnDelegate.value(index.column(),-1); if (aCurUserRole == -1) //А если все-таки делегат для конкретной ячейки, тогда узнаю из нее, какой нужен aCurUserRole = aCellDelegate.value(index,0);
if (aCurUserRole==0 || aCurUserRole==2 || aCurUserRole==4 || aCurUserRole==5 || aCurUserRole==6) //строка ввода { if (option.state & QStyle::State_Editing) return; //Передаю управление QLineEdit
if (index.data(Qt::EditRole).isNull()) return; //Пустая ячейка
//Прорисовываю текст редактируемой ячейки const QString aText = index.data(Qt::EditRole).toString(); painter->drawText( QRect(option.rect.left()+1,option.rect.top(),option.rect.width(),option.rect.hei ght()), Qt::AlignLeft | Qt::AlignVCenter, aText );
}
if (aCurUserRole==1) //чекбокс { if (option.state & QStyle::State_Selected) { return; //Передаю управление QCheckBox }
QString aText; if (index.model()->data(index, Qt::EditRole).toInt()!=1) aText = QString::fromUtf8("Нет"); else aText = QString::fromUtf8("Да");
painter->drawText( QRect(option.rect.left()+1,option.rect.top(),option.rect.width(),option.rect.hei ght()), Qt::AlignLeft | Qt::AlignVCenter, aText );
}
if (aCurUserRole==3) //комбобокс {
if (option.state & QStyle::State_Editing) return; //Передаю управление QComboBox
if (index.data(Qt::EditRole).isNull()) return; //Пустая ячейка
QString aText; const int aIntValue = index.data(Qt::EditRole).toInt();
QList< QPair<int,QString> > aValues;
if (aColumnDelegate.contains(index.column())) aValues = aValuesOfComboForColumn.value(index.column()); else aValues = aValuesOfComboForCell.value(index);
QList< QPair<int,QString> >::const_iterator it=aValues.begin(); while (it != aValues.end()) { const QPair <int,QString> aPair = *it; if (aPair.first == aIntValue) { aText = aPair.second; break; } ++it; }
painter->drawText( QRect(option.rect.left()+1,option.rect.top(),option.rect.width(),option.rect.hei ght()), Qt::AlignLeft | Qt::AlignVCenter, aText );
}
if (aCurUserRole==7) //пустрой делегат, нередактируемый { return; }
}
void UniversalDelegate::setComboValuesForCell(const QModelIndex index,const QList< QPair<int,QString> > aValues) { aValuesOfComboForCell[index] = aValues;
QVector<int> aIndexes; QList< QPair<int,QString> >::const_iterator it=aValues.begin(); while (it != aValues.end()) { const QPair <int,QString> aPair = *it; aIndexes.append(aPair.first); ++it; } aIndexesOfComboForCell[index] = aIndexes;
}
void UniversalDelegate::setComboValuesForColumn(const int aColumn,const QList< QPair<int,QString> > aValues) { aValuesOfComboForColumn[aColumn] = aValues;
QVector<int> aIndexes; QList< QPair<int,QString> >::const_iterator it=aValues.begin(); while (it != aValues.end()) { const QPair <int,QString> aPair = *it; aIndexes.append(aPair.first); ++it; } aIndexesOfComboForColumn[aColumn] = aIndexes;
}
QList< QPair<int,QString> > UniversalDelegate::getComboValuesForCell(const QModelIndex index) const { QList< QPair<int,QString> > aValues; return aValuesOfComboForCell.value(index,aValues); }
int UniversalDelegate::getCurrentDelegate(const QModelIndex index) const { return aCellDelegate.value(index,0); }
void UniversalDelegate::Clear() { aValuesOfComboForCell.clear(); aIndexesOfComboForCell.clear(); aValuesOfComboForColumn.clear(); aIndexesOfComboForColumn.clear(); aCellDelegate.clear(); aColumnDelegate.clear(); }
void UniversalDelegate::ChangeComboBoxText(int aValue) { QCheckBox* aCheckBox = qobject_cast<QCheckBox*>(sender()); if (aValue != 0) { aCheckBox->setText(QString::fromUtf8("Да")); } else aCheckBox->setText(QString::fromUtf8("Нет")); }
Работает неплохо, при этом можно назначить делегат для ячейки или целого столбца. Один минус - не могу прорисовать делегат в неактивном состоянии. Вылетает программа, try ... catch не спасает. Поэтому например при прорисовке чекбокса в неактивном состоянии получаю просто текст Да или Нет, а сам флажок можно установить при редакции ячейки. В целом нормально...
|