Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: PavelVX от Июль 20, 2011, 09:44



Название: Вопросы по QTableView
Отправлено: PavelVX от Июль 20, 2011, 09:44
Добрый день всем!
1. В QTableView можно показать, скрыть колонки. А как мне просто поменять местами колонки? У меня с базы приходит все в определенном порядке, а в разных формах показывать надо по разному. :(
2. Сортировки: tableView->setSortingEnabled(true); (QSqlQueryModel)
2а. появились треугольнички, но если на них нажимать, то порядок сортировки не меняется.
2б. Можно ли как-то самому для конкретных колонок указывать по какому столбцу их сортировать?


Название: Re: Вопросы по QTableView
Отправлено: Пантер от Июль 20, 2011, 09:47
Тебе нужна QSortFilterProxyModel.


Название: Re: Вопросы по QTableView
Отправлено: Kolobok от Июль 20, 2011, 09:56
1.  QTableView::horizontalHeader()::moveSection ( int from, int to )


Название: Re: Вопросы по QTableView
Отправлено: Странник от Июль 20, 2011, 13:05
2б. QTableView::sortByColumn(int column, Qt::SortOrder order).

Тебе нужна QSortFilterProxyModel.
на небольших объемах работает неплохо, на выборках побольше тормозит нещадно. возможно, придется реализовывать sort() для модели самостоятельно.

меня еще интересует, как разрешить пользователю менять порядок столбцов drag-n-drop'ом. установка tableView->horizontalHeader()->setMovable(true) не помогает, есть еще что-то?


Название: Re: Вопросы по QTableView
Отправлено: Авварон от Июль 20, 2011, 13:52
Почему у меня прокся с 19000 строк не тормозила?


Название: Re: Вопросы по QTableView
Отправлено: Странник от Июль 20, 2011, 14:02
Почему у меня прокся с 19000 строк не тормозила?
интересно. у меня бобик дох на сортировке по строковому столбцу уже при ~5000 записей, даже на шустрой машинке. пойду эксперементировать.


Название: Re: Вопросы по QTableView
Отправлено: Авварон от Июль 20, 2011, 18:49
ну я 1 колонку фильтровал через startsWith. Покажите, как фильтруете.


Название: Re: Вопросы по QTableView
Отправлено: Странник от Июль 21, 2011, 10:40
ну я 1 колонку фильтровал через startsWith. Покажите, как фильтруете.
фильтры по StartsWith работают нормально, тормоза замечены только на FixedString. но я про сортировку говорил, там вроде негде накосячить:
Код:
QSqlQueryModel *model = new QSqlQueryModel;

QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel;
proxyModel->setDynamicSortFilter(true);
proxyModel->setSourceModel(model);

QTableView *tableView = new QTableView;
tableView->setSortingEnabled(true);
tableView->setModel(proxyModel);

увы и ах, уже при ~150 записях заметная задержка, сделал сортировку на сервере.


Название: Re: Вопросы по QTableView
Отправлено: PavelVX от Июль 22, 2011, 05:24
а можно как-то перехватывать нажатия на значек сортировок?
если модель QSqlQueryModel, tableView->setSortingEnabled(true);
то при нажатии на треугольнички сортировка не происходит. Вот это бы нажатие и перехватывать. Тогда можно было бы как угодно извращать сортировки. Типа раз нажали на 5 колонку, то и сортируем по нужному столбцу.
Кстати, возвращаясь к сортировкам: типы сортировок можно как-то указывать? Или сортировка всегда отдается на сервер, если вы данные берете с сервера? Просто с сортировкам на сервере есть и минус: на постгре серваках линуксовых сортировка не учитывает пробелы и прочие спецсимволы, что очень неудобно.


Название: Re: Вопросы по QTableView
Отправлено: Странник от Июль 22, 2011, 09:12
после нажатия на треугольничек вызывается функция sort(int column, Qt::SortOrder order) модели. переопределяйте и сортируйте - хотите белочку, хотите зайчика.


Название: Re: Вопросы по QTableView
Отправлено: PavelVX от Июль 22, 2011, 10:27
оффтоп: нас тут вином угостили, у человека праздник. И тут я читаю про белочку ... в начале даже не понял про какую идет речь, вроде по чуть-чуть совсем выпили. :)
По существу: ламерский вопрос, поисковик не помогает, разбирать sql строку запроса считаю неправильным.
А как мне по номеру колонки из QSqlQueryModel вытащить имя самой колонки?
void TestModel::sort(int column, Qt::SortOrder order) //наследник от QSqlQueryModel
{
//тут как-то надо по номеру вытащить название, что бы в refresh правильно прописать order by
}
Или это как-то по другому делается


Название: Re: Вопросы по QTableView
Отправлено: kambala от Июль 22, 2011, 10:52
headerData() ?


Название: Re: Вопросы по QTableView
Отправлено: Странник от Июль 22, 2011, 11:03
в headerData() может храниться произвольный текст. имя колонки можно узнать в QSqlQueryModel::record().fieldName(int index).


Название: Re: Вопросы по QTableView
Отправлено: PavelVX от Июль 22, 2011, 11:05
в headerData() указывается ваше название, которое может не совпадать с основным!
Хмм, пока писал, Странник уже ответил :)
Странник СПАСИБО!
Похоже создав несколько форм и поднакопив опыт удобнее будет написать свою модель и основывать на ней свои формы.


Название: Re: Вопросы по QTableView
Отправлено: Danila_Bagrofff от Декабрь 22, 2011, 20:20
Снова хочу поднять эту тему. Встал вопрос сортировок более глобально.
Если работа с базами данных ведется активно, есть много пользователей, читающих данные из больших таблиц, то запросы с условием order by начинают грузить сервер, создавать блокировки на изменение данных в таблицах и т.д.
Условие order by заставляет всегда прочитать всю таблицу для данной сессии в память. Если у вас используются joinы плюсуйте и эти таблицы. Каждый клиент при работе с бд заставляет заново перечитывать таблицу и держать в кэше все эти данные, загружая сервак. А если данные еще и пишутся в эти таблицу - то тут поднимаются еще и опросы блокировок или актуальности данных на момент чтения. Операция сортировки зачастую может составлять до 90% всего времени запроса. Чем больше эта таблица - тем дольше проходит сортировка.
В общем получается так, что иногда проще выполнять сортировку на клиенте, чтобы меньше загружать сервер БД.

Весь вопрос упирается в то, где все-таки лучше делать сортировку.
С одной стороны лучше на клиенте:
-если вы уверены, что данные не изменились, или они в БД доступны только для чтения
- что загружать сервер БД - критично, существует много обращений на запись
- если таблицы относительно невелики, гонять по сети большие таблицы - тоже не есть гут.

Лучше делать на сервере order by.
- если мало постоянных изменений, и больше чтения, и чтения не так уж и много.
- если таблица очень большая и сортировка на клиенте явно менее производительнее.

Теперь вопрос, как действительно бы лучше делать сортировку данных именно на клиенте?
- строковых
- данных
- целых

Какие механизмы самые оптимальные? Может, есть коды?


Название: Re: Вопросы по QTableView
Отправлено: antipart от Январь 05, 2012, 12:45
меня еще интересует, как разрешить пользователю менять порядок столбцов drag-n-drop'ом. установка tableView->horizontalHeader()->setMovable(true) не помогает, есть еще что-то?

Не знаю ... у меня все работает
Код:
    proxyModel = new QSortFilterProxyModel(this);
    proxyModel->setDynamicSortFilter(true);
    proxyModel->setSourceModel(userModel);

    userView->setModel(proxyModel);
    userView->setSortingEnabled(true);

   userView->verticalHeader()->hide();
    userView->horizontalHeader()->setMovable(true);


Название: Re: Вопросы по QTableView
Отправлено: eJinn от Май 28, 2013, 23:11
Добрый день!

после нажатия на треугольничек вызывается функция sort(int column, Qt::SortOrder order) модели. переопределяйте и сортируйте.
Спасибо за подсказку. Переопределил. Надо всего-лишь не сортировать пару столбцов. Как можно убрать треугольнички, которые появляются при нажатии на эти столбцы?


Название: Re: Вопросы по QTableView
Отправлено: eJinn от Май 29, 2013, 00:35
Добрый день!

после нажатия на треугольничек вызывается функция sort(int column, Qt::SortOrder order) модели. переопределяйте и сортируйте.
Спасибо за подсказку. Переопределил. Надо всего-лишь не сортировать пару столбцов. Как можно убрать треугольнички, которые появляются при нажатии на эти столбцы?
Вопрос решен:
Код:
...
QMainWindow View;
QTableView table;

connect( View->table->horizontalHeader(), SIGNAL(sectionClicked(int)), this, SLOT( deactivate_column_sort(int) ) );
...

void mainWindow::deactivate_column_sort(int column )
{
    if( column != MODE_TABLE_COLUMN && column != DESCRIPTION_COLUMN )
        View->table->horizontalHeader()->setSortIndicatorShown( true );
    else
        View->table->horizontalHeader()->setSortIndicatorShown( false );
}
А сортировка модели model, подключеной в table: View->table->setModel( model );
переопределена подобным образом:
Код:
void mySqlTableModel::sort(int column, Qt::SortOrder order)
{
    if( column != MODE_TABLE_COLUMN && column != DESCRIPTION_COLUMN )
    {
        QSqlTableModel::sort( column, order );  // вызываем стандартную сортировку
    }
}

В результате столбцы с номерами MODE_TABLE_COLUMN и DESCRIPTION_COLUMN не сортируются, и треугольнички при нажатии на них не появляются.
Остальные столбцы работают по стандартной сортировке.