Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: i_rik_mik от Март 25, 2014, 10:57



Название: мигание QListView
Отправлено: 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) при добавлении данных которые не видно на экране и довольствоваться этим ?





Название: Re: мигание QListView
Отправлено: i_rik_mik от Март 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)


Название: Re: мигание QListView
Отправлено: _OLEGator_ от Март 25, 2014, 21:45
Код
C++ (Qt)
QApplication::processEvents()
Это может помочь.


Название: Re: мигание QListView
Отправлено: GreatSnake от Март 26, 2014, 07:25
запрет на обновление перерисовки не помогает
Запрещай вьюпорт.


Название: Re: мигание QListView
Отправлено: i_rik_mik от Март 27, 2014, 15:02
Запрещай вьюпорт.

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

читал тему Тема: Ускорить отрисовку qtextedit там ваш ответ по поводу Re: Ускорить отрисовку qtextedit
сделал так ни помогло (( все равно мигает, в теме правдо вы писали что вся проблема не в отрисовке, а в форматировании.


Название: Re: мигание QListView
Отправлено: GreatSnake от Март 27, 2014, 15:06
подскажите как это сделать запрещать viewport какой нибудь примерчик
Код
C++ (Qt)
ui->listView->viewport()->setUpdatesEnabled(true);


Название: Re: мигание QListView
Отправлено: i_rik_mik от Март 28, 2014, 10:01
Код
C++ (Qt)
ui->listView->viewport()->setUpdatesEnabled(true);

помогло, стало меньше моргать + ввел задержку в 200 мили секунд в поток после сигнала + поставил ui->listView->setUniformItemSizes(true), стало более менее приемлемо.


Название: Re: мигание QListView
Отправлено: GreatSnake от Март 28, 2014, 10:19
Только в любом случае это не более чем костыль.
Мерцаний, да, не будет, но нагрузка будет очень большая.
Нужно накапливать строки и добавлять уже пачку.
В слоте накапливаешь строки и перезаряжаешь таймер на те же 200мс, в котором уже добавляешь в модель строки.


Название: Re: мигание QListView
Отправлено: i_rik_mik от Март 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();



Название: Re: мигание QListView
Отправлено: GreatSnake от Март 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();
}
}
 


Название: Re: мигание QListView
Отправлено: i_rik_mik от Март 28, 2014, 13:05
Сделал в gui-потоке
как Вы указали выше
результат с таймером на 150 мс отрисуется 1 раз в самом конце
результат с таймером на 70 мс отрусуется также в 2 ступени

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


когда останавливаю поток путем семафора отрисовку на теже 90000 можно наблюдать. Предыдущий вариант лучше