Russian Qt Forum
Ноябрь 01, 2024, 03:36 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: [Решено] sql запрос в делегате  (Прочитано 9941 раз)
chu
Гость
« : Апрель 23, 2012, 16:39 »

Есть две таблицы:
1) список элементов с описанием их свойств  items (id,  property1, property2, ...);
2) список операций с элементами  actions (id, item_id, info1, info2, ... ).
В actions.item_id записывается один из items.id.
Хотел написать делегат для второй таблицы, который бы изменял цвет ячейки в зависимости от одного из свойств соответствующего элемента. Для этого переопределил в делегате функцию paint и попытался из неё вызвать sql-запрос, но упустил что функция paint имеет квалификатор const.
Подскажите какой-нибудь другой подход Улыбающийся
« Последнее редактирование: Апрель 26, 2012, 10:50 от chu » Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #1 : Апрель 23, 2012, 17:12 »

Делать селект надо хотя бы при создании элемента, а ни как при его отрисовке.
Записан

Qt 5.11/4.8.7 (X11/Win)
chu
Гость
« Ответ #2 : Апрель 23, 2012, 23:23 »

В голову пришло только такое решение:
Код:
    model = new QSqlQueryModel();
    model->setQuery("SELECT a.id, a.item_id, i.item_type AS item_type FROM actions a "
                    "INNER JOIN items i ON i.id = a.item_id ");

    MyDelegate *delegate = new MyDelegate(ui->actionsTV);
    ui->actionsTV->setModel(model);
    ui->actionsTV->setItemDelegateForColumn(2,delegate);
    ui->actionsTV->resizeColumnsToContents();
Сменил QSqlTableModel на QSqlQueryModel, во вью таким образом появился отдельный столбец для отображения цвета
В делегате:
Код:
void AnswerDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    int id = index.data(Qt::DisplayRole).toInt();
    if (option.state & QStyle::State_Selected)
             painter->fillRect(option.rect, option.palette.highlight());
    if (option.state & QStyle::State_Selected)
             painter->setBrush(option.palette.highlightedText());
         else
             painter->setBrush(QBrush(colors.at(id)));
    painter->fillRect(option.rect, painter->brush());
}
Но мне этот метод не нравится: отдельная колонка для цвета, уход от QSqlTableModel. В данном случае для меня это не критично, но  на будущее хотелось бы знать, можно ли реализовать по другому...
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #3 : Апрель 24, 2012, 07:24 »

А кто мешает установить Qt::BackgroundRole и не городить огород?
Записан

Qt 5.11/4.8.7 (X11/Win)
chu
Гость
« Ответ #4 : Апрель 24, 2012, 11:57 »

А кто мешает установить Qt::BackgroundRole и не городить огород?
Мешает недостаток знаний. Мне модель свою писать и там переопределять роль в методе QVariant MyModel::data(const QModelIndex &index, int role) const?  Но он тоже константный.
Записан
chu
Гость
« Ответ #5 : Апрель 24, 2012, 12:08 »

Не смотря на то что метод data константный, запрос из него высылать можно, и это отлично Улыбающийся
GreatSnake, спасибо!
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #6 : Апрель 24, 2012, 12:23 »

Мешает недостаток знаний. Мне модель свою писать и там переопределять роль в методе QVariant MyModel::data(const QModelIndex &index, int role) const?  Но он тоже константный.
Зачем нужна своя модель для изменения цвета ячейки Непонимающий
На этапе создания элементов рассчитывай цвет и выставляй его через QAbstractItemModel::setData() с Qt::BackgroundRole.

Не смотря на то что метод data константный, запрос из него высылать можно, и это отлично Улыбающийся
Делать селект из data() тоже неразумно, т.к. этот метод вызывается при отрисовке и не только, т.е. очень часто.
« Последнее редактирование: Апрель 24, 2012, 12:28 от GreatSnake » Записан

Qt 5.11/4.8.7 (X11/Win)
chu
Гость
« Ответ #7 : Апрель 24, 2012, 13:31 »

Если я правильно понял, нужно реализовать что-то такое:
Код:
    model = new QSqlTableModel();
    model->setTable("actions");
    model->setSort(model->fieldIndex("id"),Qt::AscendingOrder);
    model->select();
    int row(0);
    QSqlQuery q;
    q.exec(QString("SELECT i.item_type FROM items i "
                   "INNER JOIN actions a ON i.id = a.item_id ORDER BY a.id"));
    while(q.next()) {
        int item_type = q.value(0).toInt();
        qDebug() << model->setData(model->index(row++,1),QBrush(colors.at(item_type)), Qt::BackgroundRole);
        qDebug() << model->lastError() << row << colors.at(item_type);
    }
Но setData возвращает false, model->lastError() ошибки не выдает. Что не так?
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #8 : Апрель 24, 2012, 13:45 »

Но setData возвращает false, model->lastError() ошибки не выдает. Что не так?
Обычно "setData возвращает false", если её подсовывают левый index.
Сколько колонок в model? Случайно не 1?
Записан

Qt 5.11/4.8.7 (X11/Win)
chu
Гость
« Ответ #9 : Апрель 24, 2012, 13:53 »

Но setData возвращает false, model->lastError() ошибки не выдает. Что не так?
Обычно "setData возвращает false", если её подсовывают левый index.
Сколько колонок в model? Случайно не 1?
нет. колонок 6
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #10 : Апрель 24, 2012, 14:02 »

см. что возвращает model->index(row++,1).
И непонятно почему у тебя row, который применяется к таблице "actions" рассчитывается от размерности "items".
Чего-то с логикой не то.

PS. хотя судя по "INNER JOIN actions" количество строк вроде как должно быть одинаковым.
Распечатай размерность модели после model->select():
Код
C++ (Qt)
qDebug() << model->rowCount() << model->columnCount()
« Последнее редактирование: Апрель 24, 2012, 14:12 от GreatSnake » Записан

Qt 5.11/4.8.7 (X11/Win)
chu
Гость
« Ответ #11 : Апрель 24, 2012, 14:22 »

Код:
26 6 
QModelIndex(0,4,0x0,QSqlTableModel(0x11798d0) )
QModelIndex(1,4,0x0,QSqlTableModel(0x11798d0) )
QModelIndex(2,4,0x0,QSqlTableModel(0x11798d0) )
...
Записан
chu
Гость
« Ответ #12 : Апрель 25, 2012, 00:59 »

С индексами все в порядке, потому что когда я применяю setData с Qt::EditRole все корректно срабатывает
Код:
    qDebug() << model->setData(model->index(0,1), 123, Qt::EditRole);

 а вот с Qt::BackgroundRole setData возвращает false
Код:
    qDebug() << model->setData(model->index(0,1),QBrush(Qt::green, Qt::SolidPattern), Qt::BackgroundRole);
Пробовал еще вызывать setData c FontRole и DisplayRole - так же возвращает false.
С чем это может быть связано?
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #13 : Апрель 25, 2012, 10:26 »

QModelIndex(2,4,0x0,QSqlTableModel(0x11798d0) )
Цитировать
model->index(row++,1)
Что-то странное... Как при запросе индекса для колонки 1 модель тебе отдаёт индекс с колонкой 4 Непонимающий
Записан

Qt 5.11/4.8.7 (X11/Win)
chu
Гость
« Ответ #14 : Апрель 25, 2012, 11:17 »

QModelIndex(2,4,0x0,QSqlTableModel(0x11798d0) )
Цитировать
model->index(row++,1)
Что-то странное... Как при запросе индекса для колонки 1 модель тебе отдаёт индекс с колонкой 4 Непонимающий

запрос для 4ой колонки делал
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.078 секунд. Запросов: 22.