display a lot of images with Qt - c++

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.

Related

Why does scene not being displayed when widget is set as central

I have a problem displaying two labels, the label "label" is displayed with no problem ( it has some buttons adjusted Horizontally ) and the second label "label1" is not being displayed ( it contains a scene which has a view , in the scene i have a title and a picture ). This is the code i am trying to use.
widget1 = new QWidget;
setCentralWidget(widget1);
label1 = new QLabel(widget1);
scene = new QGraphicsScene(label1);
vue = new QGraphicsView(scene);
label1->move(100,100);
label = new QLabel(widget1);
layout = new QHBoxLayout(label);
label->resize(500,100);
It's my first time using QGraphicsScene/View and it is confusing me a little bit.
Thanks for the answers
You're definitly not using all those widgets the right way.
you don't need a label to display a QGraphcisView, neither the QGraphicsScene to be the child of the label.
If you want to display, let's say, a label and a view in the center widget you could write this :
//==== Central widget part
QWidget* widget = new QWidget(this);
setCentralWidget(widget);
//==== Graphics part
QGraphicsScene* scene = new QGraphcisScene(this);
QGraphicsView* view = new QGraphicsView(widget);
view->setScene(scene);
//==== Label part
QLabel* label = new QLabel(widget);
//==== Layout part
QHBoxLayout* layout = new QHBoxLayout(widget);
layout.addWidget(label);
layout.addWidget(view);
widget.setLatout(layout);
This should show a label and a graphics view in row.
If you allow me a piece of advice : you should understand the parenting system before trying to use the QGraphics module. It's one of the cornerstones of Qt and that what you did wrong here. Starts here for the parenting system : https://doc.qt.io/qt-5/objecttrees.html
and here for the graphics : https://doc.qt.io/qt-5/graphicsview.html
Hope that helps you.

QT Making a Dropdown Menu Widget Programmatically

I am using QT 5.5 with Mac OSX. I want to make several dropdown menu widgets programmatically that will have various options that can change the values of certain variables.
So for example, I would have dropdown menu 1 represent variable "command" have:
- Q
- W
- E
- R
And by selecting whichever one, then it would make command = Q, or command = W. So that way, I can send command to another program knowing that I sent Q, or W.
My current mainwindow looks something like this:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
//******* Set up
ui->setupUi(this);
ui->centralWidget->setLayout(new QVBoxLayout);
// 01: Creation of Console
console = new Console;
console->setEnabled(false);
/************** Adding Widgets *********************/
//creation and attribution of slider
slider = new QSlider();
slider->resize(255, 20);
slider->setOrientation(Qt::Horizontal);
slider->setRange(0, 255); //0-255 is range we can read
//creation and attribution of the lcd
lcd = new QLCDNumber();
lcd->setSegmentStyle(QLCDNumber::Flat);
lcd->resize(255, 50);
//03: Adding widgets to layout
//add console as a widget to the main widget
//layout with slider and lcd underneath console
ui->centralWidget->layout()->addWidget(console);
ui->centralWidget->layout()->addWidget(slider);
ui->centralWidget->layout()->addWidget(lcd);
////////I WANT TO ADD VARIOUS DROPDOWN MENUS HERE NEXT TO EACH OTHER////////
/************** Connection Events ***********************/
....
}
Assuming you want a ComboBox, Here is how you can do it:
QStringList commands = { "Q", "W", "E", "R" };
QComboBox* combo = new QComboBox(this);
combo->addItems(commands);
connect( combo, &QComboBox::currentTextChanged, this, &MainWindow::commandChanged);
Now you will get the command text when user changes the combo box item. and you can write your code based on that.
MainWindow::commandChanged(const QString& command_text)
{
//Do the logic based on command_text
}
Another option if you want to choose combobox item texts differently is that you set itemData for combobox items. and get them in your slot by currentData property of the ComboBox.

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);

Qt: save entire QScrollArea contents as an image

I am trying to save the contents of a QScrollArea as an image.
Currently, I am doing it this way...
QPixmap pixmap(ui->overview->rect().size());
ui->overview->render(&pixmap, QPoint(),QRegion(ui->overview->rect()));
QString saveFilename = QFileDialog::getSaveFileName(this, "Save as", "Choose a filename","PNG(*.png);; TIFF(*.tiff *.tif);; JPEG(*.jpg *.jpeg)");
if(!pixmap.save(saveFilename))
{
QMessageBox::warning(this, "Error","File could not be saved", QMessageBox::Ok);
}
But if the contents exceed one screen (and you need to scroll to see the entire image) and I save that,
the image only shows the part of the screen it's currently on.
How can I save the full contents of the scrollArea so that the image shows the entire thing, and not just a part of it?
QImage img(ui->scrollAreaWidgetContents->size(),QImage::Format::Format_ARGB32);
QPainter painter(&img);
ui->scrollAreaWidgetContents->render(&painter);
bool istrue = img.save("/file.jpg");

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