Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: radislav72 от Ноября 16, 2010, 16:04



Название: Произвольная строка в QTableView
Отправлено: radislav72 от Ноября 16, 2010, 16:04
Здравствуйте!
Есть QTableView, подсоединненный к QSqlQueryModel. Можно ли в нем программно добавить в конце списка, полученного из БД, итоговую строку, заполнив ее произвольными данными, а также задать этой строке свой формат (например, цвет, жирный шрифт)?

Если да, то как?


Название: Re: Произвольная строка в QTableView
Отправлено: aliks-os от Ноября 16, 2010, 16:24
В твоем случае лучше добавлять строку в модель, а что ее разукрасить, надо определить свой делегат. Чтобы иметь больше свободы при работе с таблицами, лучше использовать QTableWidget


Название: Re: Произвольная строка в QTableView
Отправлено: Kolobok от Ноября 16, 2010, 17:47
Интересно, какие свободы появляются при использовании QTableWidget? И как к нему прикрутить базу данных?

Разукрасить можно из модели. Посмотри Qt::ItemDataRole.


Название: Re: Произвольная строка в QTableView
Отправлено: crashsp от Ноября 17, 2010, 06:59
Цитировать
Можно ли в нем программно добавить в конце списка, полученного из БД, итоговую строку, заполнив ее произвольными данными

Есть вариант ,но не знаю на сколько он правелен

И так  связка QTableView и QSqlQueryModel
insertRow( int row, const QModelIndex & parent = QModelIndex()) не прокатывает не стал вникать почему, торопился
выкрутился так :в QSqlQueryModel есть функция int rowCount(const QModelIndex &parent = QModelIndex())
переопределил ее сделал ее вот так :

int Model::rowCount(const QModelIndex &parent) const{
    return rowCountInModel;
}

соответственно в конструкторе переменую rowCountInModel иницилизировал  нулем,при выполнение запроса в модель узнаешь количество вернувшихся строк прибавляешь 1 ,делаешь rowCountInModel равным этому числу, вызываешь  функцию model->reset() и так появилась пустая строка в конец твоего списка.

Дальше тебе нужен QHash<QModelIndex,QVariant>m_hash делай свои вычисление,вставляй их в m_hash (думаю как
выяснить QModelIndex который тебе надо догадаешься)

Дальше смотри в model функцию QVariant data(const QModelIndex &index, int role) const
этот кусок примерно выглядит так:


Код:
QVariant model::data(const QModelIndex &index, int role) const{

    QVariant value = QSqlQueryModel::data(index,role);

     switch(role){
        case Qt::DisplayRole:
        case Qt::EditRole:
             if(index.row() == this->rowCount()-1)   //Если последняя строка отображаем данные из хэш
                 return m_hash.value(index);
             else
                 return value;                                //В остальном отображаются данные из твоего запроса
       
        case ....
            ...       
        case.....
            ...

       
     }
return value;


Про цвет и шрифт тебе написал Kolobok в функцию data аналогично добавляешь роль следишь для какой строки тебе нужен цвет и возвращаешь его....

Кто знает как все упростить был бы очень признателен....




Название: Re: Произвольная строка в QTableView
Отправлено: radislav72 от Ноября 17, 2010, 08:44
Спасибо всем за ответы.

А можно ли вставить в модель строку без создания нового унаследованного класса?
Хотелось бы поменьше своих производных классов делать, проект большой, и так уже много накодировано.

Непосредственно использовать insertRow как-то не получается. Может, у кого-то есть идеи по этому поводу?


Название: Re: Произвольная строка в QTableView
Отправлено: crashsp от Ноября 17, 2010, 11:18
Цитировать
А можно ли вставить в модель строку без создания нового унаследованного класса?
Если в QTableView будет установленна QSqlTableModel то можно точно без проблемм
имеет возможно смысл посмотреть в исходниках QSqlTableModel как она это делает и повторить )


Название: Re: Произвольная строка в QTableView
Отправлено: radislav72 от Ноября 17, 2010, 11:20
Пробую делать так:
Код:
    int row = modFileDeposites->rowCount()-1;
    if (!modFileDeposites->insertRows(row, 1))
    {
        QMessageBox::critical(this, tr("ERR"),
            tr("Вставка строки вызвала ошибку:\r\n %1").arg(modFileDeposites->lastError().databaseText()));
        return;
    }

Получается перманентная ошибка без каког-либо описания...

Что не так?


Название: Re: Произвольная строка в QTableView
Отправлено: radislav72 от Ноября 17, 2010, 11:47
Да... QSqlQueryModel попросту ничего этого не делает... Нужно самому писать соответствующий метод.
Не внимательно читал доку. У QSqlQueryModel метод insertRow:
The base class implementation of this function does nothing and returns false.

Посему, похоже, вечная ошибка без описания :). Ведь метод ничего не делает и возвращает false :)


Название: Re: Произвольная строка в QTableView
Отправлено: radislav72 от Ноября 17, 2010, 12:12
Есть вариант ,но не знаю на сколько он правелен

И так  связка QTableView и QSqlQueryModel
insertRow( int row, const QModelIndex & parent = QModelIndex()) не прокатывает не стал вникать почему, торопился
выкрутился так :в QSqlQueryModel есть функция int rowCount(const QModelIndex &parent = QModelIndex())
переопределил ее сделал ее вот так...

По этому способу у меня вопрос, не совсем понял:
- rowCountInModel - это новое поле, которое мы добавляем в класс, так? Т.е. она никак не влияет на действительное количество строк модели
- как тогда добавляется новая строка? model->reset() вроде бы не должен добавлять новую строку, не так ли? Дока по этому методу пишет: "Resets the model to its original state in any attached views."


Название: Re: Произвольная строка в QTableView
Отправлено: crossly от Ноября 17, 2010, 12:41
а может стоит попробовать прилепить эту строку в запросе.... например с помощью union


Название: Re: Произвольная строка в QTableView
Отправлено: crashsp от Ноября 17, 2010, 12:57
Цитировать
По этому способу у меня вопрос, не совсем понял:
- rowCountInModel - это новое поле, которое мы добавляем в класс, так? Т.е. она никак не влияет на действительное количество строк модели
Нет это переменая типа int если оно у тебя будет ноль а запрос вернет скажем 20 записей все равно в модели будет ноль
поэтому как толко сделал запрос тебе надо узнать сколько строк вернул он, типо того model->query().numRowsAffected() прибавить 1 цу
и сделать переменую rowCountInModel равную этому числу в итоге у тебя появиться в конце твоей выборки пустая строка
не заню истенное предназначение reset() но если ее не вызвать пустая строка не появиться


Название: Re: Произвольная строка в QTableView
Отправлено: crashsp от Ноября 17, 2010, 12:58
Цитировать
а может стоит попробовать прилепить эту строку в запросе.... например с помощью union
можно чуток поподробнее?


Название: Re: Произвольная строка в QTableView
Отправлено: radislav72 от Ноября 17, 2010, 13:51
Цитировать
Нет это переменая типа int...
У меня вопрос только в том, что на член класса QAbstractTableModel или QSqlQueryModel это не похоже (в доках не нашел), то есть мы ее должны сами определить. Тогда как она влияет на кол. строк?

Цитировать
а может стоит попробовать прилепить эту строку в запросе.... например с помощью union
Я к этому тоже начинаю склоняться... вроде проще всего :)

Цитировать
можно чуток поподробнее?
Ну, пишем запрос типа
Код:
SELECT id, tname, price, .... FROM tableA 
UNION
SELECT 0 AS id, 'Всего:' AS tname, 12345.67 AS price, ...

И тогда последняя строка автоматом оказывается в модели, нужно ее только после этого отформатировать

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


Название: Re: Произвольная строка в QTableView
Отправлено: Kolobok от Ноября 17, 2010, 14:07
а может стоит попробовать прилепить эту строку в запросе.... например с помощью union

Прилепить то можно, а отформатировать нет. Все равно нужно будет data(...) переписывать.


Название: Re: Произвольная строка в QTableView
Отправлено: radislav72 от Ноября 17, 2010, 14:53
Прилепить то можно, а отформатировать нет. Все равно нужно будет data(...) переписывать.

Да, но это возможное решение первой части задачи: добавить в модель строку.
А то как лучше/ проще сделать эту первую часть мне тоже не совсем очевидно.


Название: Re: Произвольная строка в QTableView
Отправлено: radislav72 от Ноября 19, 2010, 12:44
Тут кое-что получилось. Если кому интересно.
От идеи с UNION в запросе отказался- логику запроса портит, не понравилось. Пришлось создавать производній класс. Оказывается, новая строка появляется при простом переопределении метода rowCount:
Код:
int FileDepositesModel::rowCount (const QModelIndex & parent) const
{
    if (parent.isValid()) return 0;
    return QSqlQueryModel::rowCount(parent) + 1;
}

После этого в таблице автоматом появляется пустая строка. Дальше, как уже укзывали раньше, в методе data форматируем последнюю строчку. Типа
Код:
QVariant FileDepositesModel::data(const QModelIndex &index, int role) const
{
    QVariant value = QSqlQueryModel::data(index, role);

    switch (role)
    {
    case Qt::DisplayRole:
        if (index.row() == this->rowCount()-1)
        {
            if (index.column() == fldTotal) return tr_::total; else
                if (index.column() == fldSumm)
                {
                QString s;
                s.setNum(summ, 'f', 2);
                return s;
            }
        }
        break;
    case Qt::BackgroundColorRole:
        {
            if (index.row() == rowCount() - 1) return qVariantFromValue(QColor(224, 255, 193));
            else return value;
        }
    case Qt::FontRole:
        if (index.row() == rowCount() - 1)
        {
            QFont fnt = QFont(qvariant_cast<QFont>(value));
            fnt.setBold(true);
            return qVariantFromValue(fnt);
        }
        else return value;
        break;
    }
    return value;
}

Общий вид такого TableView'а на рисунке:
(http://s11.radikal.ru/i183/1011/8d/6b75d5f502aft.jpg) (http://radikal.ru/F/s11.radikal.ru/i183/1011/8d/6b75d5f502af.png.html)

Только еще вопрос появился: как убрать номер строки (в заголовке) для этой последней итоговой строки? На рисунке этот номер выделен красным кругом.

Буду рад за замечания. (И спасибо всем за советы :))


Название: Re: Произвольная строка в QTableView
Отправлено: Пантер от Ноября 19, 2010, 13:03
Переопределить headerData


Название: Re: Произвольная строка в QTableView
Отправлено: radislav72 от Ноября 19, 2010, 14:40
Переопределить headerData

Спасибо. Но у меня ситуация: заголовки для колонок уже заданы вызовом setHeaderData. Если же потом переопределить headerData, то все заданные раньше заголовки колонок исчезают. Или я что-то неправильно делаю:
Код:
if (orientation == Qt::Vertical)
    {
        switch (role)
        {
        case Qt::DisplayRole:
            if (section == rowCount() - 1) return ""; else return section;
            break;
        }
    }
    return QVariant();
Можно ли, чтобы для колонок оставались ранее заданные значения? Если да, то как? Что нужно возвращать вместо QVariant(), чтобы остались старые названия?


Название: Re: Произвольная строка в QTableView
Отправлено: Пантер от Ноября 19, 2010, 14:51
Попробуй QAbstractTableModel::headerData (section, orientation, role).


Название: Re: Произвольная строка в QTableView
Отправлено: radislav72 от Ноября 19, 2010, 14:53
Попробуй QAbstractTableModel::headerData (section, orientation, role).
Пробовал, тогда вместо старых заголовков ставятся цифры: 0,1,2...


Название: Re: Произвольная строка в QTableView
Отправлено: Пантер от Ноября 19, 2010, 14:56
А setHeaderData ты не переопределял?


Название: Re: Произвольная строка в QTableView
Отправлено: radislav72 от Ноября 19, 2010, 15:39
А setHeaderData ты не переопределял?
Нет.


Название: Re: Произвольная строка в QTableView
Отправлено: Пантер от Ноября 19, 2010, 15:48
Ну переопредели и храни заголовки у себя в классе.


Название: Re: Произвольная строка в QTableView
Отправлено: radislav72 от Ноября 19, 2010, 15:51
Ясно, спасибо. С этим проблем конечно нет.

Короче, вопрос решился :)