Здравствуйте, Аноним
Я так понял, надо чтобы в QTableWidget были разные виджеты при редактировании.
На самом деле за редактирование отвечает не модель а делегат, вот его-то и надо дописать.
Берем QItemDelegate и переопределяем у него методы
createEditor,
setEditorData,
setModelData
Например вот так:
class QComboDelegate:public QItemDelegate
{
virtual QWidget * createEditor ( QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index ) const
{
if(index.row() % 2)
return QItemDelegate::createEditor(parent,option,index);
QComboBox * pRes = new QComboBox(parent);
pRes->addItem("a");
pRes->addItem("b");
pRes->addItem("c");
// это строка нужна для того чтобы по enter и esc завершалось редактирование итд
pRes->installEventFilter(const_cast<QComboDelegate*>(this));
return pRes;
}
virtual void setEditorData ( QWidget * editor, const QModelIndex & index ) const
{
if(index.row() % 2)
{
QItemDelegate::setEditorData(editor,index);
return;
}
QComboBox* pRes = dynamic_cast<QComboBox*>(editor);
if(pRes)
{
QString str = index.model()->data(index,Qt::EditRole).toString();
int index = pRes->findText(str);
if(index == -1)
index = 0;
pRes->setCurrentIndex(index);
}
}
virtual void setModelData ( QWidget * editor, QAbstractItemModel * model, const QModelIndex & index ) const
{
if(index.row() % 2)
{
QItemDelegate::setModelData(editor,model,index);
return;
}
QComboBox* pRes = dynamic_cast<QComboBox*>(editor);
if(pRes)
{
QString str = pRes->currentText();
model->setData(index,str,Qt::EditRole);
}
}
};
Этот делегат редактирует нечетные строки комбиками.
Потом где-нибудь в коде пишем что-то вроде
ui.tableWidget->setItemDelegate(new QComboDelegate());
Подробности в assist-е
Здравствуйте, Матвей Жданович,
спасибо за ответ.
мне нужно отображать разные widgetы в разных ячейках.
причем непредсказуемо (в одной и той же колонке/строке) могут быть разные widgetы (в зависимости от типа данных).
конечно, я могу использовать setCellWidget, но это будет выглядеть некрасиво и придется оч.много сигналов устанывливать и обрабатывать.
а я еще новичек Qt (неделя), да еще все это приходится на PyQt реализовывать ...
насколько я понял, при реализации на одних только делегатах, нет возможности узнать тип данных при создании widget (в createEditor) —
из "потенциально-информационно полезных" параметров в createEditor передается только QModelIndex, из которого можно получить QAbstractItemModel
(column & row для меня значения не имеют). есть у него еще data, но оно должно быть кем-то ужЕ заполнено.
вопрос — кака предварительно заполнить QModelIndex в data (до вызова createEditor).
но как это сделать ?
1. установить
delegate = CMyGuiDelegate1()
table.setItemDelegate(delegate)
2. повставлять QTableWidgetItem вручную и вызывыть им setData(..)
а там — в setData(..) в каким-н. role записать свои данные и класс, который должен формировать widget в createEditor.
попробовал — можно. правда, как-то .. эээ .. странно
в общем — можно как-то выкрутиться...
смотрел еще как сделано в QSqlTableModel, QSqlRelationalDelegate итд — сложно и непонятно. слишком долго разбираться.
Здравствуйте, Матвей Жданович, Вы писали:
МЖ>Здравствуйте, Аноним, Вы писали:
А>>насколько я понял, при реализации на одних только делегатах, нет возможности узнать тип данных при создании widget (в createEditor) —
А>>из "потенциально-информационно полезных" параметров в createEditor передается только QModelIndex, из которого можно получить QAbstractItemModel
А>>(column & row для меня значения не имеют).
МЖ>Я как-то немного не понимаю: другими словами нет возможности по строке и столбцу сказать что там лежит и как это надо редактировать?
МЖ>Возможен такой вариант: в какой-то внешней мапке хранить соответствие (строка,столбец)->тип эдита и передать укзатель на эту мапку делегату.
прошу прощения. я в пред.письме не совсем верно выразился в начале
(перед отправкой письмА я его не перечитал — вот и получилась у меня такая ерунда).
а к концу я ведь предложил вполне работоспособный для себя вариант.
delegate = CMyGuiDelegate1()
table.setItemDelegate(delegate)
for(..row++ .. clmn++.)
{
item = QTableWidgetItem()
item.setData(32,my_data_type[row][clmn])
}
createEditor()
{
vardata = index.data(32)
switch(vardata)
{
case __check__:
editor = checkbox()
......
}
....
}
ну, типа того...
этот вариант я ужЕ проверил
МЖ>Есть еще одна возможность: если эдиты зависят только от типа который хранится в ячейке (в смсле что на самом дел хранит Variant) то можно взтять QItemDelegate и
МЖ>назначить ему свою фабрику эдитов setItemEditorFactory. Я таким способом не пользовался так что помочь тут не смогу.
спасибо. интересная мысль.