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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: мигание QListView  (Прочитано 5255 раз)
i_rik_mik
Гость
« : Март 25, 2014, 10:57 »

Доброго времени суток.
проблема в мигании QListView
из потока (поиск файлов) выдается по сигналу результат (QString), результат забивается в модель QStringListModel (model_result_files) ниже представлен слот к сигналу
Код:
void MyFindFiles::view_result(const QString &res)
{
    int col = model_result_files->rowCount();
    model_result_files->insertRows(col, 1);
    model_result_files->setData(model_result_files->index(col-1), res);
}
если файлов мало то отрисовывается все мгновенно, если файлов много то происходит перерисовка QListView и все мигает, останавливается когда поток завершен.

Есть ли способы убрать мигание?

Или придется устанавливать setupdatesEnabled(false) при добавлении данных которые не видно на экране и довольствоваться этим ?



Записан
i_rik_mik
Гость
« Ответ #1 : Март 25, 2014, 14:12 »

запрет на обновление перерисовки не помогает
Код:
void MyFindFiles::view_result(const QString &res)
{
    int col = model_result_files->rowCount();
    if(col)
    {
        QModelIndex lastIndex = model_result_files->index(col-1);
        //строка с результатом не в зоне видимости
        if(ui->listView->viewport()->rect().contains(QPoint(0, ui->listView->visualRect(lastIndex).y() + ui->listView->visualRect(lastIndex).height() + 1)))
        {
            if(!ui->listView->updatesEnabled())
                ui->listView->setUpdatesEnabled(true);
        }
        else
        {
            if(ui->listView->updatesEnabled())
                ui->listView->setUpdatesEnabled(false);
        }
    }


    model_result_files->insertRows(col, 1);
    model_result_files->setData(model_result_files->index(col-1), res);
}


thread finished =  ui->listView->setUpdatesEnabled(true);

неприятно наблюдать такой поиск (может зависнуть на пол секунды белым фоном)и в конце увидеть как все моргнет и перерисуется
хочу сделать поиск как в тотале ползет спокойно scroll, нет подмигиваний (тотал при этом работает под wine)
Записан
_OLEGator_
Гость
« Ответ #2 : Март 25, 2014, 21:45 »

Код
C++ (Qt)
QApplication::processEvents()
Это может помочь.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #3 : Март 26, 2014, 07:25 »

запрет на обновление перерисовки не помогает
Запрещай вьюпорт.
Записан

Qt 5.11/4.8.7 (X11/Win)
i_rik_mik
Гость
« Ответ #4 : Март 27, 2014, 15:02 »

Запрещай вьюпорт.

подскажите как это сделать запрещать viewport какой нибудь примерчик

читал тему Тема: Ускорить отрисовку qtextedit там ваш ответ по поводу Re: Ускорить отрисовку qtextedit
сделал так ни помогло (( все равно мигает, в теме правдо вы писали что вся проблема не в отрисовке, а в форматировании.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #5 : Март 27, 2014, 15:06 »

подскажите как это сделать запрещать viewport какой нибудь примерчик
Код
C++ (Qt)
ui->listView->viewport()->setUpdatesEnabled(true);
Записан

Qt 5.11/4.8.7 (X11/Win)
i_rik_mik
Гость
« Ответ #6 : Март 28, 2014, 10:01 »

Код
C++ (Qt)
ui->listView->viewport()->setUpdatesEnabled(true);

помогло, стало меньше моргать + ввел задержку в 200 мили секунд в поток после сигнала + поставил ui->listView->setUniformItemSizes(true), стало более менее приемлемо.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #7 : Март 28, 2014, 10:19 »

Только в любом случае это не более чем костыль.
Мерцаний, да, не будет, но нагрузка будет очень большая.
Нужно накапливать строки и добавлять уже пачку.
В слоте накапливаешь строки и перезаряжаешь таймер на те же 200мс, в котором уже добавляешь в модель строки.
Записан

Qt 5.11/4.8.7 (X11/Win)
i_rik_mik
Гость
« Ответ #8 : Март 28, 2014, 12:09 »

Только в любом случае это не более чем костыль.
Мерцаний, да, не будет, но нагрузка будет очень большая.
Нужно накапливать строки и добавлять уже пачку.
В слоте накапливаешь строки и перезаряжаешь таймер на те же 200мс, в котором уже добавляешь в модель строки.
Попробовал
накапливаю в QStringList - переменная получается разделяемый ресурс
в начале таймера ставлю паузу с помощью QSemaphore на поток чтобы он не накидывал больше
в конце таймера очищаю QStringList снимаю паузу
Результат нет миганий, но нет и ощущения реального процесса поиска
таймер на 200 мс сработает 2 раза, т.е. картинка такая
нажали старт половина прилетела сразу и потом прилитела вторая половина результата
таймер на 70 мс на также 2 раза сработает но 1 часть результат будет меньше

Думаю оставить вариант с таймером и еще думаю можно сделать свою модель данных чтобы добавлять не по 1 а сразу добавлять списком
сейчас вывод выглядит следующим образом
Код:
if(str_list.isEmpty())
        return;

    if(thread_search)
        thread_search->pause();
    int col = model_result_files->rowCount();
    model_result_files->insertRows(col, str_list.size());
    for(int i = 0; i < str_list.size(); i++)
    {
        model_result_files->setData(model_result_files->index(col-1+i), str_list.at(i));
    }

    str_list.clear();
    if(thread_search)
        thread_search->wake();

« Последнее редактирование: Март 28, 2014, 12:11 от i_rik_mik » Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #9 : Март 28, 2014, 12:23 »

Ну зачем же так всё усложнять Непонимающий
Внимательно читай мое предложение.
Всё это легко делается в gui-потоке:
Код
C++ (Qt)
MyFindFiles::view_result( const QString &res )
{
str_list << res;
if( timer_id )
killTimer( timer_id );
timer_id = startTimer( 200 );
}
 
void MyFindFiles::::timerEvent( QTimerEvent* e )
{
if( e->timerId() == timer_id )
{
killTimer( timer_id );
timer_id = 0;
int col = model_result_files->rowCount();
model_result_files->insertRows(col, str_list.size());
for(int i = 0; i < str_list.size(); i++)
{
model_result_files->setData(model_result_files->index(col-1+i), str_list.at(i));
}
str_list.clear();
}
}
 
Записан

Qt 5.11/4.8.7 (X11/Win)
i_rik_mik
Гость
« Ответ #10 : Март 28, 2014, 13:05 »

Сделал в gui-потоке
как Вы указали выше
результат с таймером на 150 мс отрисуется 1 раз в самом конце
результат с таймером на 70 мс отрусуется также в 2 ступени

результат на 90000 файлов можно будет увидеть только после окончании потока 3 сек будет белый экран с любым значением таймера


когда останавливаю поток путем семафора отрисовку на теже 90000 можно наблюдать. Предыдущий вариант лучше
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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