It's a demonstration only image viewer made with Qt6. The binaries are available.
- Opens an image in a time independent of the count of images in a directory where it is located.
- Handles the images of the directory in a separated thread with
QtConcurrent::run. - The directory parsing is fast. It does not use
QFileInfoinstd::sort, but a custom struct. - Handles the directory only once, until it is changed. (For example, drag'n'dropping a file from the same directory does not trigger the directory parsing, since it's not needed to do, just find the file by name in the list structure.)
- Decodes 8.3 file names to long file names with Win API (
GetLongPathNameW). An 8.3 can be faced on a user input of a file with long path (260+ chars) from disc C from Windows Explorer: on Drag'n'Drop and when a user opens an image with a double click (the image path is passed as a command line argument to the program.) - Opens images with a long path starts with
\\?\(\\?\UNC\). - Preloades the adjacent images in a separate thread.
- Sorts by mtime, btime, size.
- Updates the image position (in the title) on the sorting change.
- Lists hidden files (
QDir::Hidden). - All long time taking operations log the execution time in the console with
qDebug().
Here is the example of the console log, after the program is started (~70 ms):
The speed results for 350 KB image with a directory with 30000+ files (Run it with Qt Creator to look at the qDebug() logs):
- [timer][displayImage]: 84 ms — time to display the image.
At this moment the image is visible.
That is performed in a background thread:
- [timer][entryInfoList]: 143 ms — time to get the list with QFileInfo of all files (31973) in the directory
- [timer][filterBySupportedExts]: 6 ms — time filter that list to exclude the unsupported files
- [filterBySupportedExts] fileInfoList.size: 31973
- [filterBySupportedExts] fileInfoListFiltered.size: 30006
- [timer][initFileEntryList]: 200 ms — time to create a list of data structure with all necessary information for all filtered files (30006)
- [timer][initFileList]: 352 ms — the total time of the work with directory files ~(143 + 6 + 200)
- [timer][sortByMtime]: 6 ms — to sort all files by mtime
Note: Do NOT use code that calls methods of QFileInfo in std::sort. It's incredibly slow.
That is up to 600 times slower
std::sort(fileEntryList.begin(), fileEntryList.end(),
[](const FileEntry& a, const FileEntry& b) {
return a.fileInfo.lastModified() < b.fileInfo.lastModified();
}
);than that
std::sort(fileEntryList.begin(), fileEntryList.end(),
[](const FileEntry& a, const FileEntry& b) {
return a.mtime < b.mtime;
}
);3200-3600 ms vs 6 ms.
So, store all required fields of QFileInfo in your own data struct.
Try by yourself (uncomment the line 307 and comment lines 298-304): https://github.com/AlttiRi/demo-image-viewer/blob/ad9ac9b1c9d78244462064983e676542700e96d9/core.h#L296-L311
-
Click on the green triangle button in Qt Creator to create
demo-imgv.exefile. Use release build. -
Open the build folder (
./build/Desktop_Qt_6_10_0_MinGW_64_bit-Release/release) -
Delete all files (
*.o,*.cpp,*.h) exceptdemo-imgv.exefile. -
Drag and drop
demo-imgv.exefile from the File Explorer onwindeployqt6(C:\Qt\6.10.0\mingw_64\bin\windeployqt6.exe) to create all reuired files (DLLs and others) for thedemo-imgv.exefile. -
Optionally, remove unneeded files to make the "lite" build. You only needed:
demo-imgv.exeQt6Core.dllQt6Gui.dllQt6Widgets.dlllibgcc_s_seh-1.dlllibstdc++-6.dlllibwinpthread-1.dllimageformats/*(qgif.dll,qico.dll,qjpeg.dll,qsvg.dll)platforms/qwindows.dllstyles/qmodernwindowsstyle.dll(optionally)
(So, remove:
D3Dcompiler_47.dll,Qt6Network.dll,Qt6Svg.dll,opengl32sw.dll,generic/,iconengines/,networkinformation/,tls/,translations/)
