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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: QListView и модель на основе QAbstractListModel - как правильно?  (Прочитано 5897 раз)
EyeOnNet
Гость
« : Август 10, 2011, 12:54 »

До недавнего времени успешно обходился классом QListWidget для отображения списков (из базы данных). Но вот появилась задача отобразить список с большим (от нескольких десятков тысяч до миллионов строк). Решил попробовать QListView. Сделал простую модель на основе класса QAbstractListModel - переопределил функции "rowCount()" и "data()", пробую, работает, только гораздо медленней, чем на QListWidget! Анализ показал, что список грузит из модели все строчки, а так как каждая из них формируется моделью из результата отдельного запроса к удаленной БД, неудивительно, что быстродействие оказалось плачевным. Но главное, это противоречит моему понимаю работы схемы модель/представление - я предполагал, что из модели никогда не будет грузиться намного больше, чем представление может одновременно отобразить на экране. Тем не менее, список грузит  подряд все строки, количество которых ему выдает rowCount(), и только загрузив последнюю, наконец-то отображает содержимое. После этого он уже работает примерно как положено, загружая в небольшом количестве строки только при листании списка. Рытье в google ответа не дало, возможно я упускаю какую-то мелочь и QListView должен и в момент инициализации работать как положено.

PS манипуляции с режимами вроде "setLayoutMode(QListView::Batched)" не помогли, в "Batched" режиме хотя приложение и не виснет до конца загрузки списка, но на экране он все равно пуст до окончания загрузки всех строк таблицы.
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #1 : Август 10, 2011, 13:09 »

Это неверное поведение. Сортировку устанавливал? Какие-нибудь настройки QListView менял?
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Kolobok
Гость
« Ответ #2 : Август 10, 2011, 13:09 »

и долго миллион запросов выполняется?
setUniformItemSizes ( bool enable ) поможет.
Записан
EyeOnNet
Гость
« Ответ #3 : Август 10, 2011, 13:39 »

Это неверное поведение. Сортировку устанавливал? Какие-нибудь настройки QListView менял?

Думал что может действительно что-то нахимичил, создал новый QListView, результат такой же. Сортировку не ставил, кроме изменений layoutMode и batchSize остальные параметры оставались по-умолчанию.
Записан
EyeOnNet
Гость
« Ответ #4 : Август 10, 2011, 13:48 »

и долго миллион запросов выполняется?
setUniformItemSizes ( bool enable ) поможет.
Терпения не хватило! Думаю очень долго. Снимал задачу на нескольких сотнях.  Веселый

Хм. После выполнения setUniformItemSizes(true); поведение изменилось - теперь QListView  выполняет только один запрос к модели, data(const QModelIndex &index, Qt::DisplayRole), и все. Список в окне пуст, программа работает, хотя подвисает.
Похоже для анализа прийдется сделать новое пустое приложение и там гонять списки.  

Собственно вот практически весь исходник пробного приложения:
Код
C++ (Qt)
 
#include "mainwindow.h"
#include "ui_mainwindow.h"
 
MainWindow::MainWindow(QWidget *parent) :
   QMainWindow(parent),
   ui(new Ui::MainWindow)
{
   ui->setupUi(this);
   Listt = new QListView(this);
   connect(ui->pushButton,SIGNAL(pressed()),this,SLOT(PushAction()));
 
}
 
MainWindow::~MainWindow()
{
   delete Listt;
   delete ui;
}
 
void MainWindow::PushAction(){
 
   model = new Mmodel();
   model->L1=ui->label;model->L2=ui->label_2;
   Listt->resize(200,50);
   Listt->setLayoutMode(QListView::Batched);
   Listt->setModel(model);
 
}
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
#include "mmodel.h"
 
Mmodel::Mmodel(QObject *parent) :
   QAbstractListModel(parent)
{
}
/* ------------------------------------------------ */
int Mmodel::rowCount(const QModelIndex &parent) const
{
static int Ccounter=0;
   Ccounter++;if(L1!=NULL)L1->setText(tr("Count rows gives=[%1]").arg(Ccounter));  
return 1000000;
}
// ====================
QVariant Mmodel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid())
        return QVariant();
static int Ccounter=0;
 
    if (role == Qt::DisplayRole){
 
        Ccounter++;if(L2!=NULL)L2->setText(tr("Count data gives=[%1]").arg(Ccounter));
 
        return tr("N=%1").arg(index.row());
           }
    else
        if (role == Qt::UserRole){
 
            return "---";
        }
    else
        return QVariant();
}
 


QListView по-прежнему грузит через "data()" с Qt::DisplayRole столько строк, сколько возвращает функция "rowCount()". Может надо обработать ещё какую-то роль, кроме "DisplayRole"? Или утановить какой-то флаг у QListView???
« Последнее редактирование: Август 10, 2011, 19:00 от EyeOnNet » Записан
EyeOnNet
Гость
« Ответ #5 : Август 17, 2011, 09:11 »

Вот тестовый проект. Проще некуда, но что неправильно так и не нашёл, хотя уже десятый раз перечитал описание класса QListView. Приходится думать, что первичная загрузка всех строк модели это нормальный режим для объекта этого класса. Может попробовать QTableView, может этот класс работает как положено? А может проблема в том, что я наследую класс модели от "QAbstractListModel" ?  Может представление при работе с потомками этого класса так и должно загружать данные полностью?
« Последнее редактирование: Август 17, 2011, 13:09 от EyeOnNet » Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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