QPixmap in a QtableView cell
-
Hi
I wonder if somebody of You loaded jpeg or png picture to a tableView cells. I want to do it in my soft but I have some doubts what is the best way to do it.
Hence my hereunder questions:-
What size (in KB) of the picture is resonable taking into account that the soft has to load pictures without any noticeable delays.
-
What will be more efficent: write pictures to binary file and load it from the file to the tableView cells or to have some
pictures resource(png, jpeg files) on a hard drive and load it by
setting the path to just created QPixmap or QImage object?
3.To set a picture to a TableView cell is not so hard but what about how it looks in the cell. I mean that the cell can be strech
to its content but it looks not nice, see hereunder picture:- Is it a good idea to have a very small size picture like icon in the cell and when the mouse cursor is above the "icon", then the picture whould became bigger. But is it posssible without
streching the tableview cell?
Maybe it would be better to click "icon" in the cell and the picture would be open by another software(which is a part of windows or another operating system.
So if somebody of you did it before please give me some indicators, clues
-
-
Hi,
- It depends on what you want to show exactly, if it's a small version of your picture then you should generate thumbnails. This will avoid loading big images.
- Where would these pictures come from ?
- How are you doing it currently ?
- Do you mean you want to show a bigger preview when hovering the cells containing images ?
-
Answer 2 and 3:
Pictures are taken by me using a smartphone. Then I use Photoshop to make its size smaller. Then place them in some directory of my soft. By clicking a PushButton on GUI I call QFileDialog and chose a file(picture). This way I get the path of the file(picture) which is used to set one of the Model variable
"photoPath". In the data function of the Model I placed the part of code which load picture to the model and finally to the TableView :QVariant MagazynModel::data(const QModelIndex &index, int role) const
{
........
else if(index.column() == 19)
{
QString filePath = magazyn.GetTowar().GetPhotoPath();
if(role == Qt::DisplayRole)
return filePath;QPixmap pixmap(filePath); if(role == Qt::DecorationRole) { return pixmap; } if (role == Qt::SizeHintRole) return pixmap.size(); }
}
Answer 4:
Yes. I ment something like you can see on some webside when
you place mouse arrow on a picture it gets bigger.So if somebody of you did it before please give me some indicators, clues
-
You should considering a QPixmapCache otherwise you are going to trigger lots of file operation for not much reasons.
-
QPixmapCache looks promissing. I will try to implement it.
-
I tried to implement QPixelMapCache but with no success.
The hereunder piece of code(an exemple of use the QPixmapCache) seems to be not difficult:void Lights::paintEvent(QPaintEvent *)
{
QString key = QString("lights:%1:%2")
.arg(m_color.name())
.arg(m_diameter);//creation pixmapscache keys
QPixmap pixmap;//creation pixmap object//if pixmap not exists in pixmapCache
if (!QPixmapCache::find(key, pixmap))
{
pixmap = generatePixmap();
QPixmapCache::insert(key, pixmap);//insert pixmap to cache
}
bitBlt(this, 0, 0, &pixmap);
}
... but the paint event is involved and I am not sure if the QPixmapCache is proper to my soft?So in a menwhile I decided to resize images from 1.6MB to 42KB
using Photoshop:
Picture 42KB:
Looks quite well.I set into tableView cell the path to an image and used tooltip
for showing the image:
else if(index.column() == 19)
{
QString filePath = magazyn.GetTowar().GetPhotoPath();// QPixmap pixmap;
// pixmap.load(filePath);// if(role == Qt::DecorationRole )
// {
// return pixmap;
// }if (role == Qt::ToolTipRole) { // find path for specified index return QString("<img src='%1'>").arg(filePath); } }
The result is good. When mouse arrow is abowe the tableView cell with the image path the picture appears:
I inserted 1000 records in the tableView and the soft works quite
quick. -
What is Lights ?
-
I took the piece of code from en exemple - it is not my code.
I wanted only to show how it is used.
I am still wonder if QPixmapCache would do the trick in my soft. -
Another alternative can be subclassing QAbstractItemView and customize it to your needs.
We only need to override a fiew pure virtual methods in our derived class:#ifndef ITEMVIEW_H
#define ITEMVIEW_H#include <QAbstractItemView>
#include <QScrollBar>
#include <QGridLayout>
#include <QLabel>
#include <QVector>
#include <memory>class ItemView : public QAbstractItemView
{
Q_OBJECTpublic:
ItemView(QWidget *parent = nullptr); virtual QModelIndex indexAt( const QPoint &point ) const override; virtual void scrollTo( const QModelIndex &index, ScrollHint hint = EnsureVisible ) override; virtual QRect visualRect( const QModelIndex &index ) const override;
protected:
virtual int horizontalOffset() const override; virtual bool isIndexHidden(const QModelIndex &index ) const override; virtual QModelIndex moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers) override; virtual void setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags flags) override; virtual int verticalOffset() const override; virtual QRegion visualRegionForSelection( const QItemSelection &selection) const override;
protected slots:
virtual void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles = QVector<int> ()) override; virtual void selectionChanged( const QItemSelection &selected, const QItemSelection &deselected) override;
private:
QGridLayout *gridLayout = nullptr; QLabel *label = nullptr; void UpdateItemView(); std::unique_ptr<QPixmap> pixmapPtr = nullptr; int labelWidth; int labelHeight;
};
How it works?
Now on one layout we add TableView , ItemView and splitter which
separats the Tableview and the ItemView. See hereunder picture:So now it is possible to see the photos by moving from one cell (containing photos) to another one using arrow keys which is I think better then using tooltip.
...but I do not need to see the photo all the time when operating on other data in a tableView(simply the TableView is then wider).
So in constructor of the ItemView I set:
this->setFixedWidth(0);
So TableView looks like this:When we select a photo we set this->setFixedWidth(here we set ItemView width for the width of the photo);the TableView and the ItemView looks like hereabove:
When we again select other data than photos the tableView makes itself wider and photo(the itemView) disappeard as showed in the gif animation.
I will be appreciated if somebody have any ideas how it can be more improved. Any ideas are wellcommed.