Скроллинг ListView с изображениями

89
18 декабря 2020, 17:00

Я использую Qt 5.9.4, QtCreator for Windows, MinGW compiler.

Я использую QML компонент - ListView для вывода сообщений чата через делегат. Задача в проскролливании ListView в самый конец (в моем случае вниз). В обычном случае, когда сообщение содержит только текст без ссылок, используется listView.positionViewAtEnd() и работает хорошо, но при наличии в делегате изображений этот вариант работает плохо.

Описание проблемы:

Для вывода изображений в делегате используется XMLHttpRequest. Так как изображения приходят в виде ссылок, требуется проверка - изображение это или файл:

function ifUrlFile(url, callback)
{
    var xhr = new XMLHttpRequest();
    xhr.open('HEAD', url, true);
    xhr.send();
    xhr.onreadystatechange = function()
    {
        if(xhr.readyState === 4)
        {
            if(xhr.status === 200)
            {
                var myHeader = xhr.getResponseHeader("content-type");
                var isWeb = myHeader.startsWith("text/html");
                callback(isWeb === false); //!isWeb
            }
            else
                callback(false);
        }
    }
}

В итоге ссылка на изображение вставляется в свойство source у блока Image делегата.

 Image {
            id: messageImage
            visible: (mainBlock.isUrlFile ? true : false)
            source:{
                if(mainBlock.isUrlFile)
                {
                    if(mainBlock.isImage())
                    {
                        return model.text;
                    }
                    else
                    {
                        return mainBlock.getFileIcon();
                    }
                }
                else
                {
                    return "";
                }
            }
        }
  • Мое предположение:

Теперь при вызове listView.positionViewAtEnd() позиция устанавливается верно. Затем происходит работа скрипта и обработчика xhr.onreadystatechange, картинки подгружаются, а позиция меняется куда-то в середину экрана или загрузившегося изображения. Если сделать xhr запрос синхронным, то изображения вообще не появляются. Пример ошибки. Позиция на середине изображения после нажатия кнопки scrollButton:

  • А требуется установить положение ровно вниз до конца последнего элемента по нажатию кнопки

    Button {
    id: scrollButton
    function scrollToBottom() {
          var newIndex = listView.count - 1;// last index
          listView.positionViewAtEnd();
          listView.currentIndex = newIndex;
        }
    onClicked: {
        scrollToBottom();
    }
    

    }