Qt: threaded grid image loading

This commit is contained in:
Brad Parker 2018-05-03 00:49:43 -04:00
parent 5f7abb068b
commit f79ba4885a
4 changed files with 54 additions and 7 deletions

View File

@ -338,9 +338,9 @@ OBJ += ui/drivers/ui_qt.o \
MOC_HEADERS += ui/drivers/ui_qt.h \
ui/drivers/qt/ui_qt_load_core_window.h
DEFINES += $(QT5CORE_CFLAGS) $(QT5GUI_CFLAGS) $(QT5WIDGETS_CFLAGS) -DHAVE_MAIN
DEFINES += $(QT5CORE_CFLAGS) $(QT5GUI_CFLAGS) $(QT5WIDGETS_CFLAGS) $(QT5CONCURRENT_CFLAGS) -DHAVE_MAIN
#DEFINES += $(QT5WEBENGINE_CFLAGS)
LIBS += $(QT5CORE_LIBS) $(QT5GUI_LIBS) $(QT5WIDGETS_LIBS)
LIBS += $(QT5CORE_LIBS) $(QT5GUI_LIBS) $(QT5WIDGETS_LIBS) $(QT5CONCURRENT_LIBS)
#LIBS += $(QT5WEBENGINE_LIBS)
NEED_CXX_LINKER = 1

View File

@ -276,14 +276,16 @@ if [ "$HAVE_QT" != 'no' ] && [ "$MOC_PATH" != 'none' ]; then
check_pkgconf QT5CORE Qt5Core 5.2
check_pkgconf QT5GUI Qt5Gui 5.2
check_pkgconf QT5WIDGETS Qt5Widgets 5.2
check_pkgconf QT5CONCURRENT Qt5Concurrent 5.2
#check_pkgconf QT5WEBENGINE Qt5WebEngine 5.4
check_val '' QT5CORE -lQt5Core QT5CORE
check_val '' QT5GUI -lQt5Gui QT5GUI
check_val '' QT5WIDGETS -lQt5Widgets QT5WIDGETS
check_val '' QT5CONCURRENT -lQt5Widgets QT5CONCURRENT
#check_val '' QT5WEBENGINE -lQt5WebEngine QT5WEBENGINE
if [ "$HAVE_QT5CORE" = "no" ] || [ "$HAVE_QT5GUI" = "no" ] || [ "$HAVE_QT5WIDGETS" = "no" ]; then
if [ "$HAVE_QT5CORE" = "no" ] || [ "$HAVE_QT5GUI" = "no" ] || [ "$HAVE_QT5WIDGETS" = "no" ] || [ "$HAVE_QT5CONCURRENT" = "no" ]; then
die : 'Notice: Not building Qt support, required libraries were not found.'
HAVE_QT=no
else

View File

@ -29,6 +29,7 @@
#include <QMenu>
#include <QDockWidget>
#include <QList>
#include <QtConcurrentRun>
#include "../ui_qt.h"
#include "ui_qt_load_core_window.h"
@ -101,6 +102,16 @@ static void scan_finished_handler(void *task_data, void *user_data, const char *
}
#endif
GridItem::GridItem() :
widget(NULL)
,label(NULL)
,hash()
,image()
,pixmap()
,imageWatcher()
{
}
TreeView::TreeView(QWidget *parent) :
QTreeView(parent)
{
@ -2753,6 +2764,29 @@ void MainWindow::removeGridItems()
}
}
void MainWindow::onDeferredImageLoaded()
{
const QFutureWatcher<GridItem*> *watcher = static_cast<QFutureWatcher<GridItem*>*>(sender());
GridItem *item = watcher->result();
if (!item->image.isNull())
item->label->setPixmap(QPixmap::fromImage(item->image));
}
void MainWindow::loadImageDeferred(GridItem *item, QString path)
{
connect(&item->imageWatcher, SIGNAL(finished()), this, SLOT(onDeferredImageLoaded()), Qt::QueuedConnection);
item->imageWatcher.setFuture(QtConcurrent::run<GridItem*>(this, &MainWindow::doDeferredImageLoad, item, path));
}
GridItem* MainWindow::doDeferredImageLoad(GridItem *item, QString path)
{
/* this runs in another thread */
item->image = QImage(path);
return item;
}
void MainWindow::addPlaylistItemsToGrid(QString pathString)
{
QList<QHash<QString, QString> > items = getPlaylistItems(pathString);
@ -2764,7 +2798,6 @@ void MainWindow::addPlaylistItemsToGrid(QString pathString)
const QHash<QString, QString> &hash = items.at(i);
GridItem *item = new GridItem();
ThumbnailLabel *label = NULL;
QPixmap pixmap;
QString thumbnailFileNameNoExt;
QLabel *newLabel = NULL;
@ -2779,9 +2812,7 @@ void MainWindow::addPlaylistItemsToGrid(QString pathString)
label = new ThumbnailLabel(item->widget);
pixmap = QPixmap(QString(settings->paths.directory_thumbnails) + "/" + hash.value("db_name") + "/" + THUMBNAIL_BOXART + "/" + thumbnailFileNameNoExt + ".png");
label->setPixmap(pixmap);
item->label = label;
item->widget->layout()->addWidget(label);
@ -2793,6 +2824,8 @@ void MainWindow::addPlaylistItemsToGrid(QString pathString)
m_gridLayout->addWidget(item->widget);
m_gridItems.append(item);
loadImageDeferred(item, QString(settings->paths.directory_thumbnails) + "/" + hash.value("db_name") + "/" + THUMBNAIL_BOXART + "/" + thumbnailFileNameNoExt + ".png");
}
}

View File

@ -28,6 +28,8 @@
#include <QRegularExpression>
#include <QPalette>
#include <QPlainTextEdit>
#include <QFutureWatcher>
#include <QImage>
extern "C" {
#include <retro_common_api.h>
@ -58,12 +60,19 @@ class QScrollArea;
class LoadCoreWindow;
class MainWindow;
class ThumbnailWidget;
class ThumbnailLabel;
class FlowLayout;
struct GridItem
{
GridItem();
ThumbnailWidget *widget;
ThumbnailLabel *label;
QHash<QString, QString> hash;
QImage image;
QPixmap pixmap;
QFutureWatcher<GridItem*> imageWatcher;
};
class ThumbnailWidget : public QWidget
@ -255,6 +264,7 @@ public:
bool setCustomThemeFile(QString filePath);
void setCustomThemeString(QString qss);
const QString& customThemeString() const;
GridItem* doDeferredImageLoad(GridItem *item, QString path);
signals:
void thumbnailChanged(const QPixmap &pixmap);
@ -309,6 +319,7 @@ private slots:
void onFileBrowserTreeContextMenuRequested(const QPoint &pos);
void onPlaylistWidgetContextMenuRequested(const QPoint &pos);
void onStopClicked();
void onDeferredImageLoaded();
private:
void setCurrentCoreLabel();
@ -316,6 +327,7 @@ private:
bool isCoreLoaded();
bool isContentLessCore();
void removeGridItems();
void loadImageDeferred(GridItem *item, QString path);
QList<QHash<QString, QString> > getPlaylistItems(QString pathString);
LoadCoreWindow *m_loadCoreWindow;