Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: setRelation оказался лишним?
Форум на CrossPlatform.RU > Библиотеки > Qt > Qt Модель/Представление
Steklova Olga
Здравствуйте :) Есть у меня три таблицы в БД:
TD_OBJ_SRC_NAME (словарь) с полями F_OBJ_SRC_CODE, F_OBJ_SRC_NAME
F_OBJ_SRC_CODE - PK
T_OBJ (главная) с полями F_OBJ_ID, TO_F_OBJ_SRC_CODE, ...
F_OBJ_ID, TO_F_OBJ_SRC_CODE - PK
TO_F_OBJ_SRC_CODE - FK, указывающий на F_OBJ_SRC_CODE словаря
T_OBJ_DET_NMBS (дочерняя) с полями F_RECORD_NMB, TO_F_OBJ_ID, TO_TO_F_OBJ_SRC_CODE, ...
F_RECORD_NMB - PK
TO_F_OBJ_ID, TO_TO_F_OBJ_SRC_CODE - FK, указывающий на F_OBJ_ID, TO_F_OBJ_SRC_CODE главной таблицы
Отношение главной и дочерней таблиц: 1-N.
Задача в том, что, с одной стороны, при отображении главной таблицы надо вместо OBJ_SRC_CODE отображать OBJ_SRC_NAME из словаря, а, с другой стороны, при изменении текущей записи в главной таблице (OBJ_ID, OBJ_SRC_CODE) надо отображать соотв. записи из дочерней.
Раскрывающийся текст
//создание модели главной таблицы
void MainWindow::create_model_obj()
{
    model_obj = new MyModel_obj(this);
    model_obj->setTable("T_OBJ");
    view_obj->setModel(model_obj);    
    ...
}

//создание модели дочерней таблицы
void MainWindow::create_model_NN_det_for_obj_query()
{
    model_NN_det_for_obj_query = new MyModel_NN_det_for_obj_query(this);
    model_NN_det_for_obj_query_StrSelect =
            "SELECT"
            " T_OBJ_DET_NMBS.F_RECORD_NMB,"
            " T_OBJ_DET_NMBS.TO_F_OBJ_ID,"
            " T_OBJ_DET_NMBS.TO_TO_F_OBJ_SRC_CODE,"
            ...
            "FROM"
            " T_OBJ_DET_NMBS";
    model_NN_det_for_obj_query_StrFilter =
            "WHERE T_OBJ_DET_NMBS.TO_F_OBJ_ID = -1"
            " AND T_OBJ_DET_NMBS.TO_TO_F_OBJ_SRC_CODE = -1";
    model_NN_det_for_obj_query_Str =
            model_NN_det_for_obj_query_StrSelect + " " +
            model_NN_det_for_obj_query_StrFilter;
    model_NN_det_for_obj_query->setQuery(
            model_NN_det_for_obj_query_Str
            );
    view_NN_det_for_obj->setModel(model_NN_det_for_obj_query);
    connect(view_obj->selectionModel(),
            SIGNAL(currentRowChanged(const QModelIndex &, const QModelIndex &)),
            this, SLOT(update_view_NN_det_for_obj_query()));
}

//обновление дочерней таблицы при изменении текущей записи в главной таблице
void MainWindow::update_view_NN_det_for_obj_query()
{
    QModelIndex index = view_obj->currentIndex();
    if (index.isValid()) {
        QSqlRecord record = model_obj->record(index.row());
        int id = record.value("F_OBJ_ID").toInt(); //поле в model_obj
        int src_code = record.value("TO_F_OBJ_SRC_CODE").toInt(); //поле в model_obj
        model_NN_det_for_obj_query_StrFilter =
                QString("WHERE T_OBJ_DET_NMBS.TO_F_OBJ_ID = %1"
                        " AND T_OBJ_DET_NMBS.TO_TO_F_OBJ_SRC_CODE = %2")
              .arg(id).arg(src_code); //поля в model_NN_det_for_obj_query
    } else {
        model_NN_det_for_obj_query_StrFilter =
                "WHERE T_OBJ_DET_NMBS.TO_F_OBJ_ID = -1"
                " AND T_OBJ_DET_NMBS.TO_TO_F_OBJ_SRC_CODE = -1"; //поля в model_NN_det_for_obj_query
    }
    model_NN_det_for_obj_query_Str =
            model_NN_det_for_obj_query_StrSelect + " " +
            model_NN_det_for_obj_query_StrFilter;
    model_NN_det_for_obj_query->setQuery(
            model_NN_det_for_obj_query_Str
            );
}
Если бы в create_model_obj() я указала
    model_obj->setRelation(T_OBJ_ColNmb_OBJ_SRC_CODE,
        QSqlRelation("TD_OBJ_SRC_NAME", "F_OBJ_SRC_CODE", "F_OBJ_SRC_NAME"));
то после этого я не смогла бы в update_view_NN_det_for_obj_query() выполнить
    int src_code = record.value("TO_F_OBJ_SRC_CODE").toInt(); //поле в model_obj_short
так как в update_view_NN_det_for_obj_query()
    int indexOf_TO_F_OBJ_SRC_CODE = record.indexOf("TO_F_OBJ_SRC_CODE");
выдает -1, если в таблице T_OBJ установлен setRelation для поля TO_F_OBJ_SRC_CODE
а
    QString fieldName_1 = record.fieldName(1);
выдает "F_OBJ_SRC_NAME", если в таблице T_OBJ установлен setRelation для поля TO_F_OBJ_SRC_CODE
выдает "TO_F_OBJ_SRC_CODE", если в таблице T_OBJ не установлен setRelation для поля TO_F_OBJ_SRC_CODE

Решение пока такое: вместо использования setRelation
наследую модель MyModel_obj от QSqlRelationalTableModel и переопределяю DisplayRole.
Можно, конечно, предварительно сделать один раз запрос к словарю, чтобы взять там все значения поля OBJ_SRC_NAME, а не прописывать их прямо в коде...
Раскрывающийся текст
QVariant MyModel_obj::data(const QModelIndex &index, int role) const {
    QVariant value = QSqlRelationalTableModel::data(index, role);
    switch (role) {
    case Qt::DisplayRole:
        //для того, чтобы в view_obj вместо
        //Кода источника информации об объекте отображалось
        //соотв Наименование источника информации об объекте
        if (index.column() == T_OBJ_ColNmb_OBJ_SRC_CODE)
            return value.toInt() == 0 ? "SRC_0" : "SRC_1";
        //ВНИМАНИЕ! Должно быть соответствие между
        //кодами и наименованиями источников информации об объекте,
        //- хранящимися в БД в таблице TD_OBJ_SRC_NAME
        //- указанными в MyModel_obj::data
        return value;
    }
    return value;
}
Или я ничего не понимаю, и это делают совсем не так? :rolleyes:
Litkevich Yuriy
Цитата(Steklova Olga @ 27.1.2012, 20:17) *
Задача в том, что, с одной стороны, при отображении главной таблицы надо вместо OBJ_SRC_CODE отображать OBJ_SRC_NAME из словаря, а, с другой стороны, при изменении текущей записи в главной таблице (OBJ_ID, OBJ_SRC_CODE) надо отображать соотв. записи из дочерней.

не смог представить, как я (пользователь) этим пользуюсь
Steklova Olga
Цитата
не смог представить, как я (пользователь) этим пользуюсь
Пользуюсь так:
- отображаю на экране одновременно два QTableView
(сверху - view_obj для главной таблицы, снизу - view_NN_det_for_obj для дочерней таблицы),
- в главной таблице отображаю поля "N объекта", "Источник инф. об объекте" (наименование, а не код),
- в главной таблице выделяю одну из строк (текущую),
- при изменении текущей строки в главной таблице обновляю отображение дочерней таблицы, выводя в дочернюю таблицу параметры деталей объекта, имеющего "N объекта" и "Код источника инф. об объекте" из текущей строки главной таблицы.
Steklova Olga
Извините, ни у кого, что-ли, такой ситуации не было? :rolleyes:
wiz29
не совсем понятна суть вопроса.
Steklova Olga
Я имела в виду, что кроме переопределения Qt::DisplayRole здесь ничего не поможет, что-ли? :)
И если написать setRelation, то после этого до замененного поля уже нельзя будет добраться?

А для того, чтобы пользоваться setRelation, надо было по-другому делать связь между главной и дочерней таблицами, создав для этого в главной таблице дополнительно поле ID и ссылаться на него из дочерней таблицы, в которой создать соответственно поле TO_ID?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2024 IPS, Inc.