display mulitple image thumbnails in qt - c++

I am trying to list image thumbnails on listwidget . Now I can display a thumbnail . I want to display multiple image thumbnails from a directory.
Here is the code I tried so far.
ui->listWidget->setViewMode(QListWidget::IconMode);
ui->listWidget->setIconSize(QSize(320,240));
ui->listWidget->setResizeMode(QListWidget::Adjust);
ui->listWidget->addItem(new QListWidgetItem(QIcon("image path"),"name"));

You must use QDir, set appropriate filters like *.png, *.jpg and in the end use entryInfoList() returns a QFileInfo list that has the information of the fileName and absoluteFilePath.
ui->listWidget->setViewMode(QListWidget::IconMode);
ui->listWidget->setIconSize(QSize(320,240));
ui->listWidget->setResizeMode(QListWidget::Adjust);
QDir directory("/path/of/directory");
directory.setNameFilters({"*.png", "*.jpg"});
for(const QFileInfo & finfo: directory.entryInfoList()){
QListWidgetItem *item = new QListWidgetItem(QIcon(finfo.absoluteFilePath()), finfo.fileName());
ui->listWidget->addItem(item);
}

Related

Display a subdirectory (path retrieved from a string) inside a treeView

I have a QString fileName which stores in it a path to a subdirectory (eg. C:/Qt). I also have a treeView inside a dialog box.
Upon starting the application, we browse a file and once the file/folder is selected, I save the path of the file/folder in fileName string. Upon clicking "OK" (QPushButton), I intend to open a new Dialog Box divided into a treeView displaying the subdirectory with the selected folder as the root node of the tree, and a listView displaying all the files/folders within that folder and nothing if empty.
I used the following QFileSystemModel functions to display the C:/ directory (only drive on my pc) :
QString path;
//QFileSystemModel *dirModel;
//QFileSystemModel *fileModel;
//TreeView
dirModel = new QFileSystemModel;
dirModel->setFilter(QDir::NoDotAndDotDot | QDir::AllDirs);
dirModel->setRootPath(path);
ui->treeView->setModel(dirModel);
//ListView
fileModel = new QFileSystemModel;
fileModel->setFilter(QDir::NoDotAndDotDot | QDir::Files);
fileModel->setRootPath(path);
ui->listView->setModel(fileModel);
If I set the path to fileName (QString path = fileName;), nothing changes. I'm assuming QDir::AllDirs is the reason for this.
I looked for other QDir filters (like QDir::Dirs or setFilter) but nothing seems to work.
I even tried QDesktopServices::openUrl, but it just opens the file path in a new window instead of the treeView.

display a lot of images with Qt

I want to display a lot of images in my Qt application, for that I have created a button that when clicked will access to the computer's user and add images. My issue is that I don't know how to display these images in the application.
Here is my Code:
void Mainwindow::on_pushButton_pressed()
{
QStringList fileName = QFileDialog::getOpenFileNames(this,tr("Open Image"),
"C:/qt-win-opensource-src-4.5.0/bin/",
tr("Image Files(*.png *.jpg *.bmp *.avi *.gif)"));
iterator = new QStringListIterator(fileName);
label = new QLabel;
if(iterator->hasNext())
{
label->clear();
label->setPixmap(QPixmap(iterator->next()));
label->show();
}
}
You should use a scroll area for all those images you want to be displayed. You can set a layout depending on how you want those images to be arranged and display them using instances of QLabel.
iterator = new QStringListIterator(fileName);
label = new QLabel;
if(iterator->hasNext())
{
label->clear();
label->setPixmap(QPixmap(iterator->next()));
ui->scrollArea->layout()->addWidget(label); // need to add a scroll area widget in your ui file
// and set layout to it (horizontal, vertical, grid etc.)
}
This way, should be no problem and your labels should be displayed properly.

How can I display the image as a thumbnail

I have a QTreeView to display the hard drives and Directories. also I have a QListView to display the images files as the following:
But I want to display the images as thumbnails, like the following:
My code:
mainWidget::mainWidget(QWidget *parent) : QWidget(parent), ui(new Ui::mainWidget){
ui->setupUi(this);
dirsModel = new QFileSystemModel;
filesModel = new QFileSystemModel;
dirsModel->setRootPath("");
ui->treeView->setModel(dirsModel);
ui->listView->setModel(filesModel);
dirsModel->setFilter(QDir::AllDirs | QDir::NoDotAndDotDot);
filesModel->setFilter(QDir::Files);
ui->treeView->hideColumn(1);
ui->treeView->hideColumn(2);
ui->treeView->hideColumn(3);
ui->treeView->header()->hide();
}
void mainWidget::on_treeView_clicked(const QModelIndex &index){
ui->listView->setRootIndex(filesModel->setRootPath(dirsModel->filePath(index)));
}
Unfortunately, I don't know what is the way of changing the image view from icon to thumbnail.
Depending on what you are after there are better ways to go about it I think, but here is an example based on a project of mine in python:
What you can do is subclass the QFileIconProvider:
ICON_SIZE = QSize(64,64)
accepted_types = (".jpg",".tiff",".png",".exr",".psd")
# this depends on the plugins you have installed,
# PSD and EXR requires external ones).
class IconProvider(QFileIconProvider):
def __init__(self) -> None:
super().__init__()
def icon(self, type: 'QFileIconProvider.IconType'):
fn = type.filePath()
if fn.endswith(accepted_types):
a = QPixmap(ICON_SIZE)
a.load(fn)
return QIcon(a)
else:
return super().icon(type)
Then on the Model you use:
self.fileSystemModel.setIconProvider(IconProvider)
Example on TreeView:
You should use special ViewMode:
ui->listView->setViewMode(QListView::IconMode);
But it will show you only icons(not whole images), so I think you should create for example QStandardItemModel (because QFileSystemModel is not very suitable) and set pixmap to this model with Qt::DecorationRole, but scale this images to smaller size. As you understand if there are many images in the dir, this process can be long.
As you can see, you should every time (every on_treeView_clicked) get new list of images in the directory, You can do this with:
QStringList QDir::entryList(const QStringList & nameFilters, Filters filters = NoFilter, SortFlags sort = NoSort) const
with special filters. When you have list of files, in the loop you can create pixmaps, scale it and set to model.
By default QListView::IconMode provide Free movement. If you want avoid this you should use:
ui->listView->setMovement(QListView::Static);

Generate checkbox on the fly

I've got a dynamically created list of image extensions that I want to display checkboxes for.
I have a QStringList that contains .png, .jpg, .bmp. This list can be altered by the user so I need to generate a checkbox on the UI for each possibility.
QStringList filters;
filters << "*.jpg" << "*.png" << "*.jpeg";
I was thinking about a foreach or for loop to achieve this.
foreach(QString filt, filters){
QCheckBox *checkbox = new QCheckBox(filt, this);
}
This puts 3 checkboxes on the UI but they are all on top of one another.
How can I space them and also, how can I work with the change in state from check to unchecked on the fly?
Absolutely lost about how to do this when it's generating checkboxes from a stringlist.
Thanks.
The checkboxes are stacking on top of one another because you are not adding them to the widget's layout. Here's an example that will put each checkbox into a vertical layout.
QWidget *w = new QWidget;
QVBoxLayout *vbox = new QVBoxLayout;
foreach(QString filt, filters){
QCheckBox *checkbox = new QCheckBox(filt, this);
checkbox->setChecked(true);
vbox->addWidget(checkbox);
}
w->setLayout(vbox);
w->show()
Read up on QVBoxLayout at http://qt-project.org/doc/qt-5.0/qtwidgets/qvboxlayout.html

Can I store some user data in every item of a QListWidget?

I want to store some filenames in a QListWidget. I need to have the full file paths, but I only want to show the base filename. I probably could store the full filename in the tooltip for each item, but I'd rather not have tooltips for the list items.
You can set data for and get data from each QListWidgetItem. See QListWidgetItem::setData() and QListWidgetItem::data(). Data can be set for different roles. Use Qt::UserRole, which is "The first role that can be used for application-specific purposes."
Try something like this:
QListWidgetItem *newItem = new QListWidgetItem;
QString fullFilePath("/home/username/file");
QVariant fullFilePathData(fullFilePath);
newItem->setData(Qt::UserRole, fullFilePathData);
newItem->setText(itemText);
listWidget->insertItem(row, newItem);
and:
QListWidgeItem* currentItem = listWidget->currentItem();
if (currentItem != 0) {
QVariant data = currentItem->data(Qt::UserRole);
QString fullFilePath = data.toString();
}
Here is how it looks like in Python (PyQt5):
from PyQt5 import QtCore, QtWidgets
# Creates a QListWidgetItem
item_to_add = QtWidgets.QListWidgetItem()
# Setting your QListWidgetItem Text
item_to_add.setText('String to Display')
# Setting your QListWidgetItem Data
item_to_add.setData(QtCore.Qt.UserRole, YOUR_DATA)
# Add the new rule to the QListWidget
YOUR_QListWidget.addItem(item_to_add)
Retrieving the data:
# Looping through items
for item_index in range(YOUR_QListWidget.count()):
# Getting the data embedded in each item from the listWidget
item_data = YOUR_QListWidget.item(item_index).data(QtCore.Qt.UserRole)
# Getting the datatext of each item from the listWidget
item_text = YOUR_QListWidget.item(item_index).text()