Icons Example▲
These pixmaps are generated from the set of pixmaps made available to the icon, and are used by Qt widgets to show an icon representing a particular action.
Contents:
QIcon Overview▲
The QIcon class provides scalable icons in different modes and states. An icon's state and mode are depending on the intended use of the icon. Qt currently defines four modes:
Mode |
Description |
---|---|
QIcon::Normal |
Display the pixmap when the user is not interacting with the icon, but the functionality represented by the icon is available. |
QIcon::Active |
Display the pixmap when the functionality represented by the icon is available and the user is interacting with the icon, for example, moving the mouse over it or clicking it. |
QIcon::Disabled |
Display the pixmap when the functionality represented by the icon is not available. |
QIcon::Selected |
Display the pixmap when the icon is selected. |
QIcon's states are QIcon::On and QIcon::Off, which will display the pixmap when the widget is in the respective state. The most common usage of QIcon's states are when displaying checkable tool buttons or menu entries (see QAbstractButton::setCheckable() and QAction::setCheckable()). When a tool button or menu entry is checked, the QIcon's state is On, otherwise it's Off. You can, for example, use the QIcon's states to display differing pixmaps depending on whether the tool button or menu entry is checked or not.
A QIcon can generate smaller, larger, active, disabled, and selected pixmaps from the set of pixmaps it is given. Such pixmaps are used by Qt widgets to show an icon representing a particular action.
Overview of the Icons Application▲
With the Icons application you get a preview of an icon's generated pixmaps reflecting its different states, modes and size.
When an image is loaded into the application, it is converted into a pixmap and becomes a part of the set of pixmaps available to the icon. An image can be excluded from this set by checking off the related checkbox. The application provides a sub directory containing sets of images explicitly designed to illustrate how Qt renders an icon in different modes and states.
The application allows you to manipulate the icon size with some predefined sizes and a spin box. The predefined sizes are style dependent, but most of the styles have the same values. Only the macOS style differs by using 32 pixels instead of 16 pixels for toolbar buttons. You can navigate between the available styles using the View menu.

The View menu also provide the option to make the application guess the icon state and mode from an image's file name. The File menu provide the options of adding an image and removing all images. These last options are also available through a context menu that appears if you press the right mouse button within the table of image files. In addition, the File menu provide an Exit option, and the Help menu provide information about the example and about Qt.
The screenshot above shows the application with one image file loaded. The Guess Image Mode/State is enabled and the style is Plastique.
When QIcon is provided with only one available pixmap, that pixmap is used for all the states and modes. In this case the pixmap's icon mode is set to normal, and the generated pixmaps for the normal and active modes will look the same. But in disabled and selected mode, Qt will generate a slightly different pixmap.
The next screenshot shows the application with an additional file loaded, providing QIcon with two available pixmaps. Note that the new image file's mode is set to disabled. When rendering the Disabled mode pixmaps, Qt will now use the new image. We can see the difference: The generated disabled pixmap in the first screenshot is slightly darker than the pixmap with the originally set disabled mode in the second screenshot.
When Qt renders the icon's pixmaps it searches through the set of available pixmaps following a particular algorithm. The algorithm is documented in QIcon, but we will describe some particular cases below.
In the screenshot above, we have set monkey_on_32x32 to be an Active/On pixmap and monkey_off_64x64 to be Normal/Off. To render the other six mode/state combinations, QIcon uses the search algorithm described in the table below:
Requested Pixmap |
Preferred Alternatives (mode/state) |
||||||||
---|---|---|---|---|---|---|---|---|---|
Mode |
State |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
Normal |
Off |
N0 |
A0 |
N1 |
A1 |
D0 |
S0 |
D1 |
S1 |
On |
N1 |
A1 |
N0 |
A0 |
D1 |
S1 |
D0 |
S0 |
|
Active |
Off |
A0 |
N0 |
A1 |
N1 |
D0 |
S0 |
D1 |
S1 |
On |
A1 |
N1 |
A0 |
N0 |
D1 |
S1 |
D0 |
S0 |
|
Disabled |
Off |
D0 |
N0' |
A0' |
D1 |
N1' |
A1' |
S0' |
S1' |
On |
D1 |
N1' |
A1' |
D0 |
N0' |
A0' |
S1' |
S0' |
|
Selected |
Off |
S0 |
N0'' |
A0'' |
S1 |
N1'' |
A1'' |
D0'' |
D1'' |
On |
S1 |
N1'' |
A1'' |
S0 |
N0'' |
A0'' |
D1'' |
D0'' |
In the table, "0" and "1" stand for Off" and "On", respectively. Single quotes indicates that QIcon generates a disabled ("grayed out") version of the pixmap; similarly, double quuote indicate that QIcon generates a selected ("blued out") version of the pixmap.
The alternatives used in the screenshot above are shown in bold. For example, the Disabled/Off pixmap is derived by graying out the Normal/Off pixmap (monkey_off_64x64).
In the next screenshots, we loaded the whole set of monkey images. By checking or unchecking file names from the image list, we get different results:
For any given mode/state combination, it is possible to specify several images at different resolutions. When rendering an icon, QIcon will automatically pick the most suitable image and scale it down if necessary. (QIcon never scales up images, because this rarely looks good.)
The screenshots below shows what happens when we provide QIcon with three images (qt_extended_16x16.png, qt_extended_32x32.png, qt_extended_48x48.png) and try to render the QIcon at various resolutions:
|
|
|
|
8 x 8 |
16 x 16 |
17 x 17 |
|
|
|
|
|
32 x 32 |
33 x 33 |
48 x 48 |
64 x 64 |
For sizes up to 16 x 16, QIcon uses qt_extended_16x16.png and scales it down if necessary. For sizes between 17 x 17 and 32 x 32, it uses qt_extended_32x32.png. For sizes above 32 x 32, it uses qt_extended_48x48.png.
Line-by-Line Walkthrough▲
The Icons example consists of four classes:
-
MainWindow inherits QMainWindow and is the main application window.
-
IconPreviewArea is a custom widget that displays all combinations of states and modes for a given icon.
-
IconSizeSpinBox is a subclass of QSpinBox that lets the user enter icon sizes (e.g., "48 x 48").
-
ImageDelegate is a subclass of QItemDelegate that provides comboboxes for letting the user set the mode and state associated with an image.
We will start by reviewing the IconPreviewArea class before we take a look at the MainWindow class. Finally, we will review the IconSizeSpinBox and ImageDelegate classes.
IconPreviewArea Class Definition▲
An IconPreviewArea widget consists of a group box containing a grid of QLabel widgets displaying headers and pixmaps.
class
IconPreviewArea : public
QWidget
{
Q_OBJECT
public
:
explicit
IconPreviewArea(QWidget *
parent =
nullptr
);
void
setIcon(const
QIcon &
amp;icon);
void
setSize(const
QSize &
amp;size);
static
QVector&
lt;QIcon::
Mode&
gt; iconModes();
static
QVector&
lt;QIcon::
State&
gt; iconStates();
static
QStringList iconModeNames();
static
QStringList iconStateNames();
private
:
QLabel *
createHeaderLabel(const
QString &
amp;text);
QLabel *
createPixmapLabel();
void
updatePixmapLabels();
enum
{
NumModes =
4
, NumStates =
2
}
;
QIcon icon;
QSize size;
QLabel *
stateLabels[NumStates];
QLabel *
modeLabels[NumModes];
QLabel *
pixmapLabels[NumModes][NumStates];
}
;
The IconPreviewArea class inherits QWidget. It displays the generated pixmaps corresponding to an icon's possible states and modes at a given size.
QVector&
lt;QIcon::
Mode&
gt; IconPreviewArea::
iconModes()
{
static
const
QVector&
lt;QIcon::
Mode&
gt; result =
{
QIcon::
Normal, QIcon::
Active, QIcon::
Disabled, QIcon::
Selected}
;
return
result;
}
QVector&
lt;QIcon::
State&
gt; IconPreviewArea::
iconStates()
{
static
const
QVector&
lt;QIcon::
State&
gt; result =
{
QIcon::
Off, QIcon::
On}
;
return
result;
}
QStringList IconPreviewArea::
iconModeNames()
{
static
const
QStringList result =
{
tr("Normal"
), tr("Active"
), tr("Disabled"
), tr("Selected"
)}
;
return
result;
}
QStringList IconPreviewArea::
iconStateNames()
{
static
const
QStringList result =
{
tr("Off"
), tr("On"
)}
;
return
result;
}
We would like the table columns to be in the order QIcon::Normal, QIcon::Active, QIcon::Disabled, QIcon::Selected and the rows in the order QIcon::Off, QIcon::On, which does not match the enumeration. The above code provides arrays allowing to map from enumeration value to row/column (by using QVector::indexOf()) and back by using the array index and lists of the matching strings. Qt's containers can be easily populated by using C++ 11 initializer lists. If the compiler does not provide that feature, a pattern like
QVector&
lt;QIcon::
Mode&
gt; IconPreviewArea::
iconModes()
{
static
QVector&
lt;QIcon::
Mode&
gt; result;
if
(result.isEmpty())
result &
lt;&
lt; QIcon::
Normal &
lt;&
lt; QIcon::
Active &
lt;&
lt; QIcon::
Disabled &
lt;&
lt; QIcon::
Selected;
return
result;
}
can be used.
We need two public functions to set the current icon and the icon's size. In addition the class has three private functions: We use the createHeaderLabel() and createPixmapLabel() functions when constructing the preview area, and we need the updatePixmapLabels() function to update the preview area when the icon or the icon's size has changed.
The NumModes and NumStates constants reflect QIcon's number of currently defined modes and states.
IconPreviewArea Class Implementation▲
IconPreviewArea::
IconPreviewArea(QWidget *
parent)
:
QWidget(parent)
{
QGridLayout *
mainLayout =
new
QGridLayout(this
);
for
(int
row =
0
; row &
lt; NumStates; ++
row) {
stateLabels[row] =
createHeaderLabel(IconPreviewArea::
iconStateNames().at(row));
mainLayout-&
gt;addWidget(stateLabels[row], row +
1
, 0
);
}
Q_ASSERT(NumStates ==
2
);
for
(int
column =
0
; column &
lt; NumModes; ++
column) {
modeLabels[column] =
createHeaderLabel(IconPreviewArea::
iconModeNames().at(column));
mainLayout-&
gt;addWidget(modeLabels[column], 0
, column +
1
);
}
Q_ASSERT(NumModes ==
4
);
for
(int
column =
0
; column &
lt; NumModes; ++
column) {
for
(int
row =
0
; row &
lt; NumStates; ++
row) {
pixmapLabels[column][row] =
createPixmapLabel();
mainLayout-&
gt;addWidget(pixmapLabels[column][row], row +
1
, column +
1
);
}
}
}
In the constructor we create the labels displaying the headers and the icon's generated pixmaps, and add them to a grid layout.
When creating the header labels, we make sure the enums NumModes and NumStates defined in the .h file, correspond with the number of labels that we create. Then if the enums at some point are changed, the Q_ASSERT() macro will alert that this part of the .cpp file needs to be updated as well.
If the application is built in debug mode, the Q_ASSERT() macro will expand to
if
(!
condition)
qFatal("ASSERT: "
condition" in file ..."
);
In release mode, the macro simply disappear. The mode can be set in the application's .pro file. One way to do so is to add an option to qmake when building the application:
qmake "CONFIG += debug"
icons.pro
or
qmake "CONFIG += release"
icons.pro
Another approach is to add this line directly to the .pro file.
void
IconPreviewArea::
setIcon(const
QIcon &
amp;icon)
{
this
-&
gt;icon =
icon;
updatePixmapLabels();
}
void
IconPreviewArea::
setSize(const
QSize &
amp;size)
{
if
(size !=
this
-&
gt;size) {
this
-&
gt;size =
size;
updatePixmapLabels();
}
}
The public setIcon() and setSize() functions change the icon or the icon size, and make sure that the generated pixmaps are updated.
QLabel *
IconPreviewArea::
createHeaderLabel(const
QString &
amp;text)
{
QLabel *
label =
new
QLabel(tr("<b>%1</b>"
).arg(text));
label-&
gt;setAlignment(Qt::
AlignCenter);
return
label;
}
QLabel *
IconPreviewArea::
createPixmapLabel()
{
QLabel *
label =
new
QLabel;
label-&
gt;setEnabled(false
);
label-&
gt;setAlignment(Qt::
AlignCenter);
label-&
gt;setFrameShape(QFrame::
Box);
label-&
gt;setSizePolicy(QSizePolicy::
Expanding, QSizePolicy::
Expanding);
label-&
gt;setBackgroundRole(QPalette::
Base);
label-&
gt;setAutoFillBackground(true
);
label-&
gt;setMinimumSize(132
, 132
);
return
label;
}
We use the createHeaderLabel() and createPixmapLabel() functions to create the preview area's labels displaying the headers and the icon's generated pixmaps. Both functions return the QLabel that is created.
void
IconPreviewArea::
updatePixmapLabels()
{
QWindow *
window =
nullptr
;
if
(const
QWidget *
nativeParent =
nativeParentWidget())
window =
nativeParent-&
gt;windowHandle();
for
(int
column =
0
; column &
lt; NumModes; ++
column) {
for
(int
row =
0
; row &
lt; NumStates; ++
row) {
const
QPixmap pixmap =
icon.pixmap(window, size, IconPreviewArea::
iconModes().at(column),
IconPreviewArea::
iconStates().at(row));
QLabel *
pixmapLabel =
pixmapLabels[column][row];
pixmapLabel-&
gt;setPixmap(pixmap);
pixmapLabel-&
gt;setEnabled(!
pixmap.isNull());
QString toolTip;
if
(!
pixmap.isNull()) {
const
QSize actualSize =
icon.actualSize(size);
toolTip =
tr("Size: %1x%2
\n
Actual size: %3x%4
\n
Device pixel ratio: %5"
)
.arg(size.width()).arg(size.height())
.arg(actualSize.width()).arg(actualSize.height())
.arg(pixmap.devicePixelRatioF());
}
pixmapLabel-&
gt;setToolTip(toolTip);
}
}
}
We use the private updatePixmapLabel() function to update the generated pixmaps displayed in the preview area.
For each mode, and for each state, we retrieve a pixmap using the QIcon::pixmap() function, which generates a pixmap corresponding to the given state, mode and size. We pass the QWindows instance obtained by calling QWidget::windowHandle() on the top level widget (QWidget::nativeParentWidget()) in order to retrieve the pixmap that matches best. We format a tooltip displaying size, actual size and device pixel ratio.
MainWindow Class Definition▲
The MainWindow widget consists of three main elements: an images group box, an icon size group box and a preview area.
class
MainWindow : public
QMainWindow
{
Q_OBJECT
public
:
MainWindow(QWidget *
parent =
nullptr
);
void
loadImages(const
QStringList &
amp;fileNames);
void
show();
private
slots:
void
about();
void
changeStyle(bool
checked);
void
changeSize(int
, bool
);
void
triggerChangeSize();
void
changeIcon();
void
addSampleImages();
void
addOtherImages();
void
removeAllImages();
void
useHighDpiPixmapsChanged(int
checkState);
void
screenChanged();
private
:
QWidget *
createImagesGroupBox();
QWidget *
createIconSizeGroupBox();
QWidget *
createHighDpiIconSizeGroupBox();
void
createActions();
void
createContextMenu();
void
checkCurrentStyle();
void
addImages(const
QString &
amp;directory);
IconPreviewArea *
previewArea;
QTableWidget *
imagesTable;
QButtonGroup *
sizeButtonGroup;
IconSizeSpinBox *
otherSpinBox;
QLabel *
devicePixelRatioLabel;
QLabel *
screenNameLabel;
QAction *
addOtherImagesAct;
QAction *
addSampleImagesAct;
QAction *
removeAllImagesAct;
QAction *
guessModeStateAct;
QAction *
nativeFileDialogAct;
QActionGroup *
styleActionGroup;
}
;
The MainWindow class inherits from QMainWindow. We reimplement the constructor, and declare several private slots:
-
The about() slot simply provides information about the example.
-
The changeStyle() slot changes the application's GUI style and adjust the style dependent size options.
-
The changeSize() slot changes the size of the preview area's icon.
-
The changeIcon() slot updates the set of pixmaps available to the icon displayed in the preview area.
-
The addSampleImages() slot allows the user to load a new image from the samples provided into the application.
-
The addOtherImages() slot allows the user to load a new image from the directory obtained by calling QStandardPaths::standardLocations(QStandardPaths::PicturesLocation).
-
The screenChanged() updates the display in the High DPI group box to correctly display the parameters of the current screen the window is located on.
In addition we declare several private functions to simplify the constructor.
MainWindow Class Implementation▲
MainWindow::
MainWindow(QWidget *
parent)
:
QMainWindow(parent)
{
QWidget *
centralWidget =
new
QWidget(this
);
setCentralWidget(centralWidget);
createActions();
QGridLayout *
mainLayout =
new
QGridLayout(centralWidget);
QGroupBox *
previewGroupBox =
new
QGroupBox(tr("Preview"
));
previewArea =
new
IconPreviewArea(previewGroupBox);
QVBoxLayout *
previewLayout =
new
QVBoxLayout(previewGroupBox);
previewLayout-&
gt;addWidget(previewArea);
mainLayout-&
gt;addWidget(previewGroupBox, 0
, 0
, 1
, 2
);
mainLayout-&
gt;addWidget(createImagesGroupBox(), 1
, 0
);
QVBoxLayout *
vBox =
new
QVBoxLayout;
vBox-&
gt;addWidget(createIconSizeGroupBox());
vBox-&
gt;addWidget(createHighDpiIconSizeGroupBox());
vBox-&
gt;addItem(new
QSpacerItem(0
, 0
, QSizePolicy::
Ignored, QSizePolicy::
MinimumExpanding));
mainLayout-&
gt;addLayout(vBox, 1
, 1
);
createContextMenu();
setWindowTitle(tr("Icons"
));
checkCurrentStyle();
sizeButtonGroup-&
gt;button(OtherSize)-&
gt;click();
}
In the constructor we first create the main window's central widget and its child widgets, and put them in a grid layout. Then we create the menus with their associated entries and actions.
We set the window title and determine the current style for the application. We also enable the icon size spin box by clicking the associated radio button, making the current value of the spin box the icon's initial size.
void
MainWindow::
about()
{
QMessageBox::
about(this
, tr("About Icons"
),
tr("The <b>Icons</b> example illustrates how Qt renders an icon in "
"different modes (active, normal, disabled, and selected) and "
"states (on and off) based on a set of images."
));
}
The about() slot displays a message box using the static QMessageBox::about() function. In this example it displays a simple box with information about the example.
The about() function looks for a suitable icon in four locations: It prefers its parent's icon if that exists. If it doesn't, the function tries the top-level widget containing parent, and if that fails, it tries the active window. As a last resort it uses the QMessageBox's Information icon.
void
MainWindow::
changeStyle(bool
checked)
{
if
(!
checked)
return
;
const
QAction *
action =
qobject_cast&
lt;QAction *&
gt;(sender());
In the changeStyle() slot we first check the slot's parameter. If it is false we immediately return, otherwise we find out which style to change to, i.e. which action that triggered the slot, using the QObject::sender() function.
This function returns the sender as a QObject pointer. Since we know that the sender is a QAction object, we can safely cast the QObject. We could have used a C-style cast or a C++ static_cast(), but as a defensive programming technique we use a qobject_cast(). The advantage is that if the object has the wrong type, a null pointer is returned. Crashes due to null pointers are much easier to diagnose than crashes due to unsafe casts.
QStyle *
style =
QStyleFactory::
create(action-&
gt;data().toString());
Q_ASSERT(style);
QApplication::
setStyle(style);
const
QList&
lt;QAbstractButton*&
gt; buttons =
sizeButtonGroup-&
gt;buttons();
for
(QAbstractButton *
button : buttons) {
const
QStyle::
PixelMetric metric =
static_cast
&
lt;QStyle::
PixelMetric&
gt;(sizeButtonGroup-&
gt;id(button));
const
int
value =
style-&
gt;pixelMetric(metric);
switch
(metric) {
case
QStyle::
PM_SmallIconSize:
button-&
gt;setText(tr("Small (%1 x %1)"
).arg(value));
break
;
case
QStyle::
PM_LargeIconSize:
button-&
gt;setText(tr("Large (%1 x %1)"
).arg(value));
break
;
case
QStyle::
PM_ToolBarIconSize:
button-&
gt;setText(tr("Toolbars (%1 x %1)"
).arg(value));
break
;
case
QStyle::
PM_ListViewIconSize:
button-&
gt;setText(tr("List views (%1 x %1)"
).arg(value));
break
;
case
QStyle::
PM_IconViewIconSize:
button-&
gt;setText(tr("Icon views (%1 x %1)"
).arg(value));
break
;
case
QStyle::
PM_TabBarIconSize:
button-&
gt;setText(tr("Tab bars (%1 x %1)"
).arg(value));
break
;
default
:
break
;
}
}
triggerChangeSize();
}
Once we have the action, we extract the style name using QAction::data(). Then we create a QStyle object using the static QStyleFactory::create() function.
Although we can assume that the style is supported by the QStyleFactory: To be on the safe side, we use the Q_ASSERT() macro to check if the created style is valid before we use the QApplication::setStyle() function to set the application's GUI style to the new style. QApplication will automatically delete the style object when a new style is set or when the application exits.
The predefined icon size options provided in the application are style dependent, so we need to update the labels in the icon size group box and in the end call the changeSize() slot to update the icon's size.
void
MainWindow::
changeSize(int
id, bool
checked)
{
if
(!
checked)
return
;
const
bool
other =
id ==
int
(OtherSize);
const
int
extent =
other
? otherSpinBox-&
gt;value()
:
QApplication::
style()-&
gt;pixelMetric(static_cast
&
lt;QStyle::
PixelMetric&
gt;(id));
previewArea-&
gt;setSize(QSize(extent, extent));
otherSpinBox-&
gt;setEnabled(other);
}
void
MainWindow::
triggerChangeSize()
{
changeSize(sizeButtonGroup-&
gt;checkedId(), true
);
}
The changeSize() slot sets the size for the preview area's icon.
It is invoked by the QButtonGroup whose members are radio buttons for controlling the icon size. In createIconSizeGroupBox(), each button is assigned a QStyle::PixelMetric value as an id, which is passed as a parameter to the slot.
The special value OtherSize indicates that the spin box is enabled. If it is, we extract the extent of the new size from the box. If it's not, we query the style for the metric. Then we create a QSize object based on the extent, and use that object to set the size of the preview area's icon.
void
MainWindow::
addImages(const
QString &
amp;directory)
{
QFileDialog fileDialog(this
, tr("Open Images"
), directory);
QStringList mimeTypeFilters;
const
QList&
lt;QByteArray&
gt; mimeTypes =
QImageReader::
supportedMimeTypes();
for
(const
QByteArray &
amp;mimeTypeName : mimeTypes)
mimeTypeFilters.append(mimeTypeName);
mimeTypeFilters.sort();
fileDialog.setMimeTypeFilters(mimeTypeFilters);
fileDialog.selectMimeTypeFilter(QLatin1String("image/png"
));
fileDialog.setAcceptMode(QFileDialog::
AcceptOpen);
fileDialog.setFileMode(QFileDialog::
ExistingFiles);
if
(!
nativeFileDialogAct-&
gt;isChecked())
fileDialog.setOption(QFileDialog::
DontUseNativeDialog);
if
(fileDialog.exec() ==
QDialog::
Accepted)
loadImages(fileDialog.selectedFiles());
The function addImages() is called by the slot addSampleImages() passing the samples directory, or by the slot addOtherImages() passing the directory obtained by querying QStandardPaths::standardLocations().
The first thing we do is to show a file dialog to the user. We initialize it to show the filters returned by QImageReader::supportedMimeTypes().
For each of the files the file dialog returns, we add a row to the table widget. The table widget is listing the images the user has loaded into the application.
const
QFileInfo fileInfo(fileName);
const
QString imageName =
fileInfo.baseName();
const
QString fileName2x =
fileInfo.absolutePath()
+
QLatin1Char('/'
) +
imageName +
QLatin1String("@2x."
) +
fileInfo.suffix();
const
QFileInfo fileInfo2x(fileName2x);
const
QImage image(fileName);
const
QString toolTip =
tr("Directory: %1
\n
File: %2
\n
File@2x: %3
\n
Size: %4x%5"
)
.arg(QDir::
toNativeSeparators(fileInfo.absolutePath()), fileInfo.fileName())
.arg(fileInfo2x.exists() ? fileInfo2x.fileName() : tr("<None>"
))
.arg(image.width()).arg(image.height());
QTableWidgetItem *
fileItem =
new
QTableWidgetItem(imageName);
fileItem-&
gt;setData(Qt::
UserRole, fileName);
fileItem-&
gt;setIcon(QPixmap::
fromImage(image));
fileItem-&
gt;setFlags((fileItem-&
gt;flags() |
Qt::
ItemIsUserCheckable) &
amp; ~
Qt::
ItemIsEditable);
fileItem-&
gt;setToolTip(toolTip);
We retrieve the image name using the QFileInfo::baseName() function that returns the base name of the file without the path, and create the first table widget item in the row. We check if a high resolution version of the image exists (identified by the suffix @2x on the base name) and display that along with the size in the tooltip.
We add the file's complete name to the item's data. Since an item can hold several information pieces, we need to assign the file name a role that will distinguish it from other data. This role can be Qt::UserRole or any value above it.
We also make sure that the item is not editable by removing the Qt::ItemIsEditable flag. Table items are editable by default.