Qt4: как в tableView/Widget отобразить разные widget-ы?
От: Аноним  
Дата: 15.09.06 10:18
Оценка:
Qt4: как в одной и той же tableView/Widget отобразить разные widget-ы ?
для этого что — надо весь QAbstractItemModel дописывать ?
заранее спасибо
Re: Qt4: как в tableView/Widget отобразить разные widget-ы?
От: Матвей Жданович Беларусь  
Дата: 15.09.06 17:54
Оценка: 4 (1)
Здравствуйте, Аноним

Я так понял, надо чтобы в 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-е
Re[2]: Qt4: как в tableView/Widget отобразить разные widget-
От: Аноним  
Дата: 18.09.06 09:19
Оценка:
Здравствуйте, Матвей Жданович,
спасибо за ответ.
мне нужно отображать разные 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 итд — сложно и непонятно. слишком долго разбираться.
Re[3]: Qt4: как в tableView/Widget отобразить разные widget-
От: Матвей Жданович Беларусь  
Дата: 19.09.06 11:30
Оценка:
Здравствуйте, Аноним, Вы писали:

А>насколько я понял, при реализации на одних только делегатах, нет возможности узнать тип данных при создании widget (в createEditor) —

А>из "потенциально-информационно полезных" параметров в createEditor передается только QModelIndex, из которого можно получить QAbstractItemModel
А>(column & row для меня значения не имеют).
Я как-то немного не понимаю: другими словами нет возможности по строке и столбцу сказать что там лежит и как это надо редактировать?

Возможен такой вариант: в какой-то внешней мапке хранить соответствие (строка,столбец)->тип эдита и передать укзатель на эту мапку делегату.

Есть еще одна возможность: если эдиты зависят только от типа который хранится в ячейке (в смсле что на самом дел хранит Variant) то можно взтять QItemDelegate и
назначить ему свою фабрику эдитов setItemEditorFactory. Я таким способом не пользовался так что помочь тут не смогу.
Re[4]: Qt4: как в tableView/Widget отобразить разные widget-
От: Аноним  
Дата: 19.09.06 12:56
Оценка:
Здравствуйте, Матвей Жданович, Вы писали:

МЖ>Здравствуйте, Аноним, Вы писали:


А>>насколько я понял, при реализации на одних только делегатах, нет возможности узнать тип данных при создании 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. Я таким способом не пользовался так что помочь тут не смогу.

спасибо. интересная мысль.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.