Russian Qt Forum

Qt => Model-View (MV) => Тема начата: nata267 от Май 18, 2010, 15:08



Название: QComboBox+QDataWidgetMapper
Отправлено: nata267 от Май 18, 2010, 15:08
Здесь уже обсуждалась эта тема, может быть даже неоднократно, но все равно хочу поделиться опытом.....

вот делегат:

Код:
class QTaskTypesDelegate : public QItemDelegate
{

    public:
        QTaskTypesDelegate(QObject *parent)
                : QItemDelegate(parent)
        {

        }

        void setEditorData(QWidget *editor,
                        const QModelIndex &index) const
        {
            if(index.column()==8) {
                QVariant value = index.model()->data(
                     index, Qt::EditRole);

                 QComboBox *combo = static_cast<QComboBox*>(editor);
                 combo->setCurrentIndex(combo->findData(value));
             } else {
                 QItemDelegate::setEditorData(editor, index);
             }
        }

        void setModelData(QWidget *editor,
                        QAbstractItemModel *model,
                        const QModelIndex &index) const
        {
            if(index.column()==8) {
                QComboBox *combo = static_cast<QComboBox*>(editor);
                QVariant value = combo->itemData(combo->currentIndex());
                model->setData(index, value);
            } else {
                QItemDelegate::setModelData(editor,model,index);
            }
        }

};

Вот так заполняю комбобокс:

Код:
QSqlQueryModel *taskTypeModel = new QSqlQueryModel();
taskTypeModel->setQuery("SELECT * FROM task_types");

for(int row=0; row<taskTypeModel->rowCount(); ++row) {
        QSqlRecord record = taskTypeModel->record(row);
        comboBoxType->addItem(record.value("name").toString(), record.value("id"));
}

вызываю методы мэппера:

Код:
mapper->setItemDelegate(new QTaskTypesDelegate(this));
mapper->addMapping(comboBoxType,8);


Если есть лучше вариант - пишите....



Название: Re: QComboBox+QDataWidgetMapper
Отправлено: crossly от Май 18, 2010, 15:11
как минимум...
Код:
void QComboBox::setModel ( QAbstractItemModel * model )


Название: Re: QComboBox+QDataWidgetMapper
Отправлено: nata267 от Май 18, 2010, 15:16
crossy, если я вас правильно поняла, то вы предлагаете упростить заполнение комбо, но как передать таким образом идшники в качестве данных, так и не смогла с этим разобраться


Название: Re: QComboBox+QDataWidgetMapper
Отправлено: crossly от Май 18, 2010, 15:21
findText(...) и вообще не пойму для чего этот костыль если есть QSqlRelationalTableModel??


Название: Re: QComboBox+QDataWidgetMapper
Отправлено: nata267 от Май 18, 2010, 15:23
я не использую QSqlRelationalTableModel, так как согласна с вами это костыль, использую только QSqlQueryModel, вы наверно заметили что я использую свой делегат...


Название: Re: QComboBox+QDataWidgetMapper
Отправлено: nata267 от Май 18, 2010, 15:25
причем здесь findText, если мне потом нужны идшники, ладно, вы наверно не в курсе проблемы


Название: Re: QComboBox+QDataWidgetMapper
Отправлено: crossly от Май 19, 2010, 08:45
лан.... давай тогда разберемся.... в каком месте тебе нужны id... и в чем проблема при использовании модели??


Название: Re: QComboBox+QDataWidgetMapper
Отправлено: nata267 от Май 19, 2010, 15:07
вот это
Код:
QSqlQueryModel *taskTypeModel = new QSqlQueryModel();
taskTypeModel->setQuery("SELECT * FROM task_types");

for(int row=0; row<taskTypeModel->rowCount(); ++row) {
        QSqlRecord record = taskTypeModel->record(row);
        comboBoxType->addItem(record.value("name").toString(), record.value("id"));
}

заменить на

Код:
QSqlQueryModel *taskTypeModel = new QSqlQueryModel();
taskTypeModel->setQuery("SELECT id,name FROM task_types");

comboBoxType->setModel(taskTypeModel);
comboBoxType->setModelColumn(1);

а id передать туда, чтобы их можно было выбирать combo->itemData(combo->currentIndex());


Название: Re: QComboBox+QDataWidgetMapper
Отправлено: nata267 от Май 19, 2010, 15:10
проблемы нет, яы же написала что хочу поделиться опытом, но если есть варианты сделать лучше, пишите...


Название: Re: QComboBox+QDataWidgetMapper
Отправлено: crossly от Май 19, 2010, 15:36
id можно получить примерно так
Код:
model->data(model->index(combo->currentIndex(),0)).toInt()


Название: Re: QComboBox+QDataWidgetMapper
Отправлено: nata267 от Май 21, 2010, 10:13
спасибо, надо проверить


Название: Re: QComboBox+QDataWidgetMapper
Отправлено: crossly от Май 21, 2010, 10:16
а вообще посмотрите реализацию QSqlRelationalTbaleModel....


Название: Re: QComboBox+QDataWidgetMapper
Отправлено: nata267 от Май 31, 2010, 10:36
а можно если я использую QSqlRelationalTbaleModel не имя таблицы задавать, а какойнибудь произвольный запрос, что если мне нужны данные из нескольких таблиц объединенных например inner join ом в запросе я тогда использую QSqlQueryModel и его метод setQuery(запрос). А как мне это реализовать в QSqlRelationalTbaleModel. А и ещё... Я могу закрыть для редактирования какие то поля и сделать свое собственное редактирование данных переопределив методы setData и flags,  могу ли я делать это в QSqlRelationalTbaleModel. Я думаю чем законченнее класс тем он дает меньше возможностей, а чем абстрактнее тем возможностей больше, но в меру конечно)) И я считаю что QSqlQueryModel дает больше возможностей или я нне права.


Название: Re: QComboBox+QDataWidgetMapper
Отправлено: MoPDoBoPoT от Май 31, 2010, 13:21
а можно если я использую QSqlRelationalTbaleModel не имя таблицы задавать, а какойнибудь произвольный запрос, что если мне нужны данные из нескольких таблиц объединенных например inner join ом в запросе я тогда использую QSqlQueryModel и его метод setQuery(запрос). А как мне это реализовать в QSqlRelationalTbaleModel.
Можно в БД создать представление (CREATE VIEW ...) и задавать его имя в QSqlRelationalTableModel как обычную таблицу, иначе, как ты и делал, использовать QSqlQueryModel.
...переопределив методы setData и flags,  могу ли я делать это в QSqlRelationalTbaleModel
Эти методы расположены в public секции, поэтому ты можешь их переопределить в наследнике QSqlRelationalTableModel.


Название: Re: QComboBox+QDataWidgetMapper
Отправлено: crossly от Май 31, 2010, 14:00
setQuery так же можно использовать в  наследнике... и кстати я не советовал использовать relatinaltablemodel.... и лишь предлагал подсмотреть реализацию нужного вам функционала...


Название: Re: QComboBox+QDataWidgetMapper
Отправлено: nata267 от Май 31, 2010, 14:24
...переопределив методы setData и flags,  могу ли я делать это в QSqlRelationalTbaleModel
Эти методы расположены в public секции, поэтому ты можешь их переопределить в наследнике QSqlRelationalTableModel.

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


Название: Re: QComboBox+QDataWidgetMapper
Отправлено: nata267 от Май 31, 2010, 14:27
а можно если я использую QSqlRelationalTbaleModel не имя таблицы задавать, а какойнибудь произвольный запрос, что если мне нужны данные из нескольких таблиц объединенных например inner join ом в запросе я тогда использую QSqlQueryModel и его метод setQuery(запрос). А как мне это реализовать в QSqlRelationalTbaleModel.
Можно в БД создать представление (CREATE VIEW ...) и задавать его имя в QSqlRelationalTableModel как обычную таблицу, иначе, как ты и делал, использовать QSqlQueryModel.

спасибо, попробую!!


Название: Re: QComboBox+QDataWidgetMapper
Отправлено: nata267 от Июль 28, 2010, 08:58
нашла другую реализацию делегата - http://doc.trolltech.com/qq/qq21-datawidgetmapper.html

Код:
class Delegate : public QItemDelegate
    {
        Q_OBJECT
    public:
        Delegate(QObject *parent = 0);


        void setEditorData(QWidget *editor,
                           const QModelIndex &index) const
        {
        if (!editor->metaObject()->userProperty().isValid()) {
         if (editor->property("currentIndex").isValid()) {
          editor->setProperty("currentIndex", index.data());
          return;
        }
       }
       QItemDelegate::setEditorData(editor, index);

        }


        void setModelData(QWidget *editor,
                          QAbstractItemModel *model,
                          const QModelIndex &index) const

       {

       if (!editor->metaObject()->userProperty().isValid()) {
        QVariant value = editor->property("currentIndex");
        if (value.isValid()) {
          model->setData(index, value);
          return;
        }
      }
      QItemDelegate::setModelData(editor, model, index);

        }
    };