Polish the Icons example.
- Remove unneeded member variables. - Use new connection syntax in createActions() to assemble the menu there, removing the createMenus() function. - Use a QButtonGroup for the sizes with the style metrics as id. - Streamline code, rename variables for clarity. - Introduce static functions returning the list of states/modes and their names in display order to IconPreviewArea, removing the duplicates. - Split actions to open sample icons provided from source directory or standard pictures location to make sample icons more prominently visible. - Check and display @2x images and add tooltips showing device pixel ratio and actual size. - HighDPI: Add groupbox displaying screen name and device pixel ratio, connect to screen changed signal and update icons panel accordingly. Add check box for toggling Qt::AA_UseHighDpiPixmaps. - Adjust documentation Task-number: QTBUG-18680 Task-number: QTBUG-46615 Change-Id: Ice96e9898f168ef2a30e9f46cb260ed57ae015f0 Reviewed-by: Topi Reiniö <topi.reinio@digia.com>
This commit is contained in:
parent
f3fd7b3d96
commit
8132cb655a
@ -254,6 +254,21 @@
|
||||
generated pixmaps corresponding to an icon's possible states and
|
||||
modes at a given size.
|
||||
|
||||
\snippet widgets/icons/iconpreviewarea.cpp 42
|
||||
|
||||
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
|
||||
|
||||
\snippet widgets/icons/iconpreviewarea.cpp 43
|
||||
|
||||
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 \c createHeaderLabel() and \c createPixmapLabel()
|
||||
@ -326,7 +341,12 @@
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
\section2 MainWindow Class Definition
|
||||
|
||||
@ -347,8 +367,14 @@
|
||||
\li The \c changeSize() slot changes the size of the preview area's icon.
|
||||
\li The \c changeIcon() slot updates the set of pixmaps available to the
|
||||
icon displayed in the preview area.
|
||||
\li The \c addImage() slot allows the user to load a new image into the
|
||||
application.
|
||||
\li The \c addSampleImages() slot allows the user to load a new image
|
||||
from the samples provided into the application.
|
||||
\li The \c addOtherImages() slot allows the user to load a new image from
|
||||
the directory obtained by calling
|
||||
QStandardPaths::standardLocations(QStandardPaths::PicturesLocation).
|
||||
\li The \c screenChanged() updates the display in the \uicontrol{High DPI}
|
||||
group box to correctly display the parameters of the current screen
|
||||
the window is located on.
|
||||
\endlist
|
||||
|
||||
In addition we declare several private functions to simplify the
|
||||
@ -362,8 +388,7 @@
|
||||
widget and its child widgets, and put them in a grid layout. Then
|
||||
we create the menus with their associated entries and actions.
|
||||
|
||||
Before we resize the application window to a suitable size, we set
|
||||
the window title and determine the current style for the
|
||||
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.
|
||||
@ -421,21 +446,27 @@
|
||||
The \c changeSize() slot sets the size for the preview area's
|
||||
icon.
|
||||
|
||||
To determine the new size we first check if the spin box is
|
||||
It is invoked by the QButtonGroup whose members are radio buttons for
|
||||
controlling the icon size. In \c createIconSizeGroupBox(), each button is
|
||||
assigned a QStyle::PixelMetric value as an id, which is passed as a
|
||||
parameter to the slot.
|
||||
|
||||
The special value \c 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 search through the predefined size options,
|
||||
extract the QStyle::PixelMetric and use the QStyle::pixelMetric()
|
||||
function to determine the extent. Then we create a QSize object
|
||||
based on the extent, and use that object to set the size of the
|
||||
preview area's icon.
|
||||
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.
|
||||
|
||||
\snippet widgets/icons/mainwindow.cpp 12
|
||||
|
||||
The first thing we do when the \c addImage() slot is called, is to
|
||||
show a file dialog to the user. The easiest way to create a file
|
||||
dialog is to use QFileDialog's static functions. Here we use the
|
||||
\l {QFileDialog::getOpenFileNames()}{getOpenFileNames()} function
|
||||
that will return one or more existing files selected by the user.
|
||||
The function \c 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
|
||||
@ -446,9 +477,13 @@
|
||||
|
||||
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. Then 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
|
||||
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 \c @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.
|
||||
|
||||
@ -465,7 +500,7 @@
|
||||
contains "_act", "_dis", or "_sel", the modes are changed to
|
||||
Active, Disabled, or Selected. And if the file name contains
|
||||
"_on", the state is changed to On. The sample files in the
|
||||
example's \c images subdirectory respect this naming convension.
|
||||
example's \c images subdirectory respect this naming convention.
|
||||
|
||||
\snippet widgets/icons/mainwindow.cpp 18
|
||||
\snippet widgets/icons/mainwindow.cpp 19
|
||||
@ -482,7 +517,6 @@
|
||||
make sure that the new image's check box is enabled.
|
||||
|
||||
\snippet widgets/icons/mainwindow.cpp 6
|
||||
\snippet widgets/icons/mainwindow.cpp 7
|
||||
|
||||
The \c changeIcon() slot is called when the user alters the set
|
||||
of images listed in the QTableWidget, to update the QIcon object
|
||||
@ -562,7 +596,7 @@
|
||||
\snippet widgets/icons/mainwindow.cpp 25
|
||||
|
||||
At the end, we connect the QTableWidget::itemChanged() signal to
|
||||
the \c changeIcon() slot to ensuret that the preview area is in
|
||||
the \c changeIcon() slot to ensure that the preview area is in
|
||||
sync with the image table.
|
||||
|
||||
\image icons_size_groupbox.png Screenshot of the icon size group box
|
||||
@ -574,7 +608,14 @@
|
||||
\snippet widgets/icons/mainwindow.cpp 26
|
||||
|
||||
First we create a group box that will contain all the widgets;
|
||||
then we create the radio buttons and the spin box.
|
||||
then we create the radio buttons and the spin box. We add the
|
||||
radio buttons to an instance of QButtonGroup, using the value
|
||||
of the QStyle::PixelMetric they represent as an integer id.
|
||||
|
||||
\snippet widgets/icons/mainwindow.cpp 40
|
||||
|
||||
We introduce an enumeration constant \c OtherSize to represent
|
||||
a custom size.
|
||||
|
||||
The spin box is not a regular QSpinBox but an \c IconSizeSpinBox.
|
||||
The \c IconSizeSpinBox class inherits QSpinBox and reimplements
|
||||
@ -602,19 +643,16 @@
|
||||
In particular we create the \c styleActionGroup based on the
|
||||
currently available GUI styles using
|
||||
QStyleFactory. QStyleFactory::keys() returns a list of valid keys,
|
||||
typically including "windows", "cleanlooks" and
|
||||
"plastique". Depending on the platform, "windowsxp", "windowsvista", "gtk" and
|
||||
"macintosh" may be available.
|
||||
typically including "windows" and "fusion". Depending on the platform,
|
||||
"windowsvista" and "macintosh" may be available.
|
||||
|
||||
We create one action for each key, and adds the action to the
|
||||
action group. Also, for each action, we call QAction::setData()
|
||||
with the style name. We will retrieve it later using
|
||||
QAction::data().
|
||||
|
||||
\snippet widgets/icons/mainwindow.cpp 29
|
||||
|
||||
In the \c createMenu() function, we add the previously created
|
||||
actions to the \uicontrol File, \uicontrol View and \uicontrol Help menus.
|
||||
As we go along, we create the \uicontrol File, \uicontrol View and
|
||||
\uicontrol Help menus and add the actions to them.
|
||||
|
||||
The QMenu class provides a menu widget for use in menu bars,
|
||||
context menus, and other popup menus. We put each menu in the
|
||||
@ -656,6 +694,13 @@
|
||||
Q_ASSERT() macro to make sure that QStyleFactory::create()
|
||||
returned a valid pointer.
|
||||
|
||||
\snippet widgets/icons/mainwindow.cpp 44
|
||||
|
||||
We overload the show() function to set up the updating of the
|
||||
current screen in \c screenChanged(). After calling QWidget::show(),
|
||||
the QWindow associated with the QWidget is created and we can
|
||||
connect to its QWindow::screenChanged() signal.
|
||||
|
||||
\section2 IconSizeSpinBox Class Definition
|
||||
|
||||
\snippet widgets/icons/iconsizespinbox.h 0
|
||||
@ -690,7 +735,7 @@
|
||||
reimplement the \c valueFromText() function to interpret the
|
||||
parameter text and return the associated int value.
|
||||
|
||||
We parse the text using a regular expression (a QRegExp). We
|
||||
We parse the text using a regular expression (a QRegularExpression). We
|
||||
define an expression that matches one or several digits,
|
||||
optionally followed by whitespace, an "x" or the times symbol,
|
||||
whitespace and one or several digits again.
|
||||
@ -748,7 +793,7 @@
|
||||
index for editing. The parent widget and style option are used to
|
||||
control the appearance of the editor widget.
|
||||
|
||||
Our reimplementation create and populate a combobox instead of
|
||||
Our reimplementation creates and populates a combobox instead of
|
||||
the default line edit. The contents of the combobox depends on
|
||||
the column in the table for which the editor is requested. Column
|
||||
1 contains the QIcon modes, whereas column 2 contains the QIcon
|
||||
@ -786,4 +831,12 @@
|
||||
triggered the slot. This signal must be emitted when the editor
|
||||
widget has completed editing the data, and wants to write it back
|
||||
into the model.
|
||||
|
||||
\section2 The Implementation of the Function main()
|
||||
|
||||
\snippet widgets/icons/main.cpp 45
|
||||
|
||||
We use QCommandLineParser to handle any command line options or parameters
|
||||
passed to the application. Then, we resize the main window according
|
||||
to the available screen geometry and show it.
|
||||
*/
|
||||
|
@ -46,33 +46,95 @@
|
||||
IconPreviewArea::IconPreviewArea(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
QGridLayout *mainLayout = new QGridLayout;
|
||||
setLayout(mainLayout);
|
||||
QGridLayout *mainLayout = new QGridLayout(this);
|
||||
|
||||
stateLabels[0] = createHeaderLabel(tr("Off"));
|
||||
stateLabels[1] = createHeaderLabel(tr("On"));
|
||||
for (int row = 0; row < NumStates; ++row) {
|
||||
stateLabels[row] = createHeaderLabel(IconPreviewArea::iconStateNames().at(row));
|
||||
mainLayout->addWidget(stateLabels[row], row + 1, 0);
|
||||
}
|
||||
Q_ASSERT(NumStates == 2);
|
||||
|
||||
modeLabels[0] = createHeaderLabel(tr("Normal"));
|
||||
modeLabels[1] = createHeaderLabel(tr("Active"));
|
||||
modeLabels[2] = createHeaderLabel(tr("Disabled"));
|
||||
modeLabels[3] = createHeaderLabel(tr("Selected"));
|
||||
for (int column = 0; column < NumModes; ++column) {
|
||||
modeLabels[column] = createHeaderLabel(IconPreviewArea::iconModeNames().at(column));
|
||||
mainLayout->addWidget(modeLabels[column], 0, column + 1);
|
||||
}
|
||||
Q_ASSERT(NumModes == 4);
|
||||
|
||||
for (int j = 0; j < NumStates; ++j)
|
||||
mainLayout->addWidget(stateLabels[j], j + 1, 0);
|
||||
|
||||
for (int i = 0; i < NumModes; ++i) {
|
||||
mainLayout->addWidget(modeLabels[i], 0, i + 1);
|
||||
|
||||
for (int j = 0; j < NumStates; ++j) {
|
||||
pixmapLabels[i][j] = createPixmapLabel();
|
||||
mainLayout->addWidget(pixmapLabels[i][j], j + 1, i + 1);
|
||||
for (int column = 0; column < NumModes; ++column) {
|
||||
for (int row = 0; row < NumStates; ++row) {
|
||||
pixmapLabels[column][row] = createPixmapLabel();
|
||||
mainLayout->addWidget(pixmapLabels[column][row], row + 1, column + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
//! [0]
|
||||
|
||||
#ifdef Q_COMPILER_INITIALIZER_LISTS
|
||||
|
||||
//! [42]
|
||||
QVector<QIcon::Mode> IconPreviewArea::iconModes()
|
||||
{
|
||||
static const QVector<QIcon::Mode> result = {QIcon::Normal, QIcon::Active, QIcon::Disabled, QIcon::Selected};
|
||||
return result;
|
||||
}
|
||||
|
||||
QVector<QIcon::State> IconPreviewArea::iconStates()
|
||||
{
|
||||
static const QVector<QIcon::State> 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;
|
||||
}
|
||||
//! [42]
|
||||
|
||||
#else // Q_COMPILER_INITIALIZER_LISTS
|
||||
|
||||
//! [43]
|
||||
QVector<QIcon::Mode> IconPreviewArea::iconModes()
|
||||
{
|
||||
static QVector<QIcon::Mode> result;
|
||||
if (result.isEmpty())
|
||||
result << QIcon::Normal << QIcon::Active << QIcon::Disabled << QIcon::Selected;
|
||||
return result;
|
||||
}
|
||||
//! [43]
|
||||
|
||||
QVector<QIcon::State> IconPreviewArea::iconStates()
|
||||
{
|
||||
static QVector<QIcon::State> result;
|
||||
if (result.isEmpty())
|
||||
result << QIcon::Off << QIcon::On;
|
||||
return result;
|
||||
}
|
||||
|
||||
QStringList IconPreviewArea::iconModeNames()
|
||||
{
|
||||
static QStringList result;
|
||||
if (result.isEmpty())
|
||||
result << tr("Normal") << tr("Active") << tr("Disabled") << tr("Selected");
|
||||
return result;
|
||||
}
|
||||
|
||||
QStringList IconPreviewArea::iconStateNames()
|
||||
{
|
||||
static QStringList result;
|
||||
if (result.isEmpty())
|
||||
result << tr("Off") << tr("On");
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif // !Q_COMPILER_INITIALIZER_LISTS
|
||||
|
||||
//! [1]
|
||||
void IconPreviewArea::setIcon(const QIcon &icon)
|
||||
{
|
||||
@ -118,23 +180,27 @@ QLabel *IconPreviewArea::createPixmapLabel()
|
||||
//! [5]
|
||||
void IconPreviewArea::updatePixmapLabels()
|
||||
{
|
||||
for (int i = 0; i < NumModes; ++i) {
|
||||
QIcon::Mode mode;
|
||||
if (i == 0) {
|
||||
mode = QIcon::Normal;
|
||||
} else if (i == 1) {
|
||||
mode = QIcon::Active;
|
||||
} else if (i == 2) {
|
||||
mode = QIcon::Disabled;
|
||||
} else {
|
||||
mode = QIcon::Selected;
|
||||
}
|
||||
|
||||
for (int j = 0; j < NumStates; ++j) {
|
||||
QIcon::State state = (j == 0) ? QIcon::Off : QIcon::On;
|
||||
QPixmap pixmap = icon.pixmap(size, mode, state);
|
||||
pixmapLabels[i][j]->setPixmap(pixmap);
|
||||
pixmapLabels[i][j]->setEnabled(!pixmap.isNull());
|
||||
QWindow *window = Q_NULLPTR;
|
||||
if (const QWidget *nativeParent = nativeParentWidget())
|
||||
window = nativeParent->windowHandle();
|
||||
for (int column = 0; column < NumModes; ++column) {
|
||||
for (int row = 0; row < NumStates; ++row) {
|
||||
const QPixmap pixmap =
|
||||
icon.pixmap(window, size, IconPreviewArea::iconModes().at(column),
|
||||
IconPreviewArea::iconStates().at(row));
|
||||
QLabel *pixmapLabel = pixmapLabels[column][row];
|
||||
pixmapLabel->setPixmap(pixmap);
|
||||
pixmapLabel->setEnabled(!pixmap.isNull());
|
||||
QString toolTip;
|
||||
if (!pixmap.isNull()) {
|
||||
const QSize actualSize = icon.actualSize(size);
|
||||
toolTip =
|
||||
tr("Size: %1x%2\nActual size: %3x%4\nDevice pixel ratio: %5")
|
||||
.arg(size.width()).arg(size.height())
|
||||
.arg(actualSize.width()).arg(actualSize.height())
|
||||
.arg(pixmap.devicePixelRatioF());
|
||||
}
|
||||
pixmapLabel->setToolTip(toolTip);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -43,6 +43,8 @@
|
||||
|
||||
#include <QIcon>
|
||||
#include <QWidget>
|
||||
#include <QStringList>
|
||||
#include <QVector>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QLabel;
|
||||
@ -54,11 +56,16 @@ class IconPreviewArea : public QWidget
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
IconPreviewArea(QWidget *parent = 0);
|
||||
explicit IconPreviewArea(QWidget *parent = Q_NULLPTR);
|
||||
|
||||
void setIcon(const QIcon &icon);
|
||||
void setSize(const QSize &size);
|
||||
|
||||
static QVector<QIcon::Mode> iconModes();
|
||||
static QVector<QIcon::State> iconStates();
|
||||
static QStringList iconModeNames();
|
||||
static QStringList iconStateNames();
|
||||
|
||||
private:
|
||||
QLabel *createHeaderLabel(const QString &text);
|
||||
QLabel *createPixmapLabel();
|
||||
|
@ -10,6 +10,8 @@ SOURCES = iconpreviewarea.cpp \
|
||||
main.cpp \
|
||||
mainwindow.cpp
|
||||
|
||||
DEFINES += SRCDIR=\\\"$$PWD/\\\"
|
||||
|
||||
EXAMPLE_FILES = images/*
|
||||
|
||||
# install
|
||||
|
@ -52,13 +52,13 @@ IconSizeSpinBox::IconSizeSpinBox(QWidget *parent)
|
||||
//! [1]
|
||||
int IconSizeSpinBox::valueFromText(const QString &text) const
|
||||
{
|
||||
QRegExp regExp(tr("(\\d+)(\\s*[xx]\\s*\\d+)?"));
|
||||
static const QRegularExpression regExp(tr("(\\d+)(\\s*[xx]\\s*\\d+)?"));
|
||||
Q_ASSERT(regExp.isValid());
|
||||
|
||||
if (regExp.exactMatch(text)) {
|
||||
return regExp.cap(1).toInt();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
const QRegularExpressionMatch match = regExp.match(text);
|
||||
if (match.isValid())
|
||||
return match.captured(1).toInt();
|
||||
return 0;
|
||||
}
|
||||
//! [1]
|
||||
|
||||
|
@ -49,7 +49,7 @@ class IconSizeSpinBox : public QSpinBox
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
IconSizeSpinBox(QWidget *parent = 0);
|
||||
explicit IconSizeSpinBox(QWidget *parent = Q_NULLPTR);
|
||||
|
||||
int valueFromText(const QString &text) const Q_DECL_OVERRIDE;
|
||||
QString textFromValue(int value) const Q_DECL_OVERRIDE;
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include <QtWidgets>
|
||||
|
||||
#include "imagedelegate.h"
|
||||
#include "iconpreviewarea.h"
|
||||
|
||||
//! [0]
|
||||
ImageDelegate::ImageDelegate(QObject *parent)
|
||||
@ -55,17 +56,14 @@ QWidget *ImageDelegate::createEditor(QWidget *parent,
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
QComboBox *comboBox = new QComboBox(parent);
|
||||
if (index.column() == 1) {
|
||||
comboBox->addItem(tr("Normal"));
|
||||
comboBox->addItem(tr("Active"));
|
||||
comboBox->addItem(tr("Disabled"));
|
||||
comboBox->addItem(tr("Selected"));
|
||||
} else if (index.column() == 2) {
|
||||
comboBox->addItem(tr("Off"));
|
||||
comboBox->addItem(tr("On"));
|
||||
}
|
||||
if (index.column() == 1)
|
||||
comboBox->addItems(IconPreviewArea::iconModeNames());
|
||||
else if (index.column() == 2)
|
||||
comboBox->addItems(IconPreviewArea::iconStateNames());
|
||||
|
||||
connect(comboBox, SIGNAL(activated(int)), this, SLOT(emitCommitData()));
|
||||
typedef void (QComboBox::*QComboBoxIntSignal)(int);
|
||||
connect(comboBox, static_cast<QComboBoxIntSignal>(&QComboBox::activated),
|
||||
this, &ImageDelegate::emitCommitData);
|
||||
|
||||
return comboBox;
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ class ImageDelegate : public QItemDelegate
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ImageDelegate(QObject *parent = 0);
|
||||
explicit ImageDelegate(QObject *parent = Q_NULLPTR);
|
||||
//! [0]
|
||||
|
||||
//! [1]
|
||||
|
@ -39,13 +39,39 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include <QApplication>
|
||||
#include <QCommandLineParser>
|
||||
#include <QDesktopWidget>
|
||||
|
||||
#include "mainwindow.h"
|
||||
|
||||
//! [45]
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
QCoreApplication::setApplicationName(MainWindow::tr("Icons"));
|
||||
QCoreApplication::setApplicationVersion(QT_VERSION_STR);
|
||||
QCommandLineParser commandLineParser;
|
||||
commandLineParser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions);
|
||||
commandLineParser.addHelpOption();
|
||||
commandLineParser.addVersionOption();
|
||||
QCommandLineOption noHighDpiPixmapOption("no-highdpi-pixmaps",
|
||||
"Disable High DPI image loading (Qt::AA_UseHighDpiPixmaps)");
|
||||
commandLineParser.addOption(noHighDpiPixmapOption);
|
||||
commandLineParser.addPositionalArgument(MainWindow::tr("[file]"), MainWindow::tr("Icon file(s) to open."));
|
||||
commandLineParser.process(QCoreApplication::arguments());
|
||||
|
||||
if (!commandLineParser.isSet(noHighDpiPixmapOption))
|
||||
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
|
||||
MainWindow mainWin;
|
||||
if (!commandLineParser.positionalArguments().isEmpty())
|
||||
mainWin.loadImages(commandLineParser.positionalArguments());
|
||||
|
||||
const QRect availableGeometry = QApplication::desktop()->availableGeometry(&mainWin);
|
||||
mainWin.resize(availableGeometry.width() / 2, availableGeometry.height() * 2 / 3);
|
||||
mainWin.move((availableGeometry.width() - mainWin.width()) / 2, (availableGeometry.height() - mainWin.height()) / 2);
|
||||
|
||||
mainWin.show();
|
||||
return app.exec();
|
||||
}
|
||||
//! [45]
|
||||
|
@ -45,34 +45,49 @@
|
||||
#include "imagedelegate.h"
|
||||
#include "mainwindow.h"
|
||||
|
||||
//! [40]
|
||||
enum { OtherSize = QStyle::PM_CustomBase };
|
||||
//! [40]
|
||||
|
||||
//! [0]
|
||||
MainWindow::MainWindow()
|
||||
{
|
||||
centralWidget = new QWidget;
|
||||
QWidget *centralWidget = new QWidget(this);
|
||||
setCentralWidget(centralWidget);
|
||||
|
||||
createPreviewGroupBox();
|
||||
createImagesGroupBox();
|
||||
createIconSizeGroupBox();
|
||||
|
||||
createActions();
|
||||
createMenus();
|
||||
createContextMenu();
|
||||
|
||||
QGridLayout *mainLayout = new QGridLayout;
|
||||
QGridLayout *mainLayout = new QGridLayout(centralWidget);
|
||||
|
||||
QGroupBox *previewGroupBox = new QGroupBox(tr("Preview"));
|
||||
previewArea = new IconPreviewArea(previewGroupBox);
|
||||
QVBoxLayout *previewLayout = new QVBoxLayout(previewGroupBox);
|
||||
previewLayout->addWidget(previewArea);
|
||||
|
||||
mainLayout->addWidget(previewGroupBox, 0, 0, 1, 2);
|
||||
mainLayout->addWidget(imagesGroupBox, 1, 0);
|
||||
mainLayout->addWidget(iconSizeGroupBox, 1, 1);
|
||||
centralWidget->setLayout(mainLayout);
|
||||
mainLayout->addWidget(createImagesGroupBox(), 1, 0);
|
||||
QVBoxLayout *vBox = new QVBoxLayout;
|
||||
vBox->addWidget(createIconSizeGroupBox());
|
||||
vBox->addWidget(createHighDpiIconSizeGroupBox());
|
||||
vBox->addItem(new QSpacerItem(0, 0, QSizePolicy::Ignored, QSizePolicy::MinimumExpanding));
|
||||
mainLayout->addLayout(vBox, 1, 1);
|
||||
createContextMenu();
|
||||
|
||||
setWindowTitle(tr("Icons"));
|
||||
checkCurrentStyle();
|
||||
otherRadioButton->click();
|
||||
|
||||
resize(minimumSizeHint());
|
||||
sizeButtonGroup->button(OtherSize)->click();
|
||||
}
|
||||
//! [0]
|
||||
|
||||
//! [44]
|
||||
void MainWindow::show()
|
||||
{
|
||||
QMainWindow::show();
|
||||
connect(windowHandle(), &QWindow::screenChanged, this, &MainWindow::screenChanged);
|
||||
screenChanged();
|
||||
}
|
||||
//! [44]
|
||||
|
||||
//! [1]
|
||||
void MainWindow::about()
|
||||
{
|
||||
@ -89,60 +104,62 @@ void MainWindow::changeStyle(bool checked)
|
||||
if (!checked)
|
||||
return;
|
||||
|
||||
QAction *action = qobject_cast<QAction *>(sender());
|
||||
const QAction *action = qobject_cast<QAction *>(sender());
|
||||
//! [2] //! [3]
|
||||
QStyle *style = QStyleFactory::create(action->data().toString());
|
||||
//! [3] //! [4]
|
||||
Q_ASSERT(style);
|
||||
QApplication::setStyle(style);
|
||||
|
||||
smallRadioButton->setText(tr("Small (%1 x %1)")
|
||||
.arg(style->pixelMetric(QStyle::PM_SmallIconSize)));
|
||||
largeRadioButton->setText(tr("Large (%1 x %1)")
|
||||
.arg(style->pixelMetric(QStyle::PM_LargeIconSize)));
|
||||
toolBarRadioButton->setText(tr("Toolbars (%1 x %1)")
|
||||
.arg(style->pixelMetric(QStyle::PM_ToolBarIconSize)));
|
||||
listViewRadioButton->setText(tr("List views (%1 x %1)")
|
||||
.arg(style->pixelMetric(QStyle::PM_ListViewIconSize)));
|
||||
iconViewRadioButton->setText(tr("Icon views (%1 x %1)")
|
||||
.arg(style->pixelMetric(QStyle::PM_IconViewIconSize)));
|
||||
tabBarRadioButton->setText(tr("Tab bars (%1 x %1)")
|
||||
.arg(style->pixelMetric(QStyle::PM_TabBarIconSize)));
|
||||
foreach (QAbstractButton *button, sizeButtonGroup->buttons()) {
|
||||
const QStyle::PixelMetric metric = static_cast<QStyle::PixelMetric>(sizeButtonGroup->id(button));
|
||||
const int value = style->pixelMetric(metric);
|
||||
switch (metric) {
|
||||
case QStyle::PM_SmallIconSize:
|
||||
button->setText(tr("Small (%1 x %1)").arg(value));
|
||||
break;
|
||||
case QStyle::PM_LargeIconSize:
|
||||
button->setText(tr("Large (%1 x %1)").arg(value));
|
||||
break;
|
||||
case QStyle::PM_ToolBarIconSize:
|
||||
button->setText(tr("Toolbars (%1 x %1)").arg(value));
|
||||
break;
|
||||
case QStyle::PM_ListViewIconSize:
|
||||
button->setText(tr("List views (%1 x %1)").arg(value));
|
||||
break;
|
||||
case QStyle::PM_IconViewIconSize:
|
||||
button->setText(tr("Icon views (%1 x %1)").arg(value));
|
||||
break;
|
||||
case QStyle::PM_TabBarIconSize:
|
||||
button->setText(tr("Tab bars (%1 x %1)").arg(value));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
changeSize();
|
||||
triggerChangeSize();
|
||||
}
|
||||
//! [4]
|
||||
|
||||
//! [5]
|
||||
void MainWindow::changeSize(bool checked)
|
||||
void MainWindow::changeSize(int id, bool checked)
|
||||
{
|
||||
if (!checked)
|
||||
return;
|
||||
|
||||
int extent;
|
||||
const bool other = id == int(OtherSize);
|
||||
const int extent = other
|
||||
? otherSpinBox->value()
|
||||
: QApplication::style()->pixelMetric(static_cast<QStyle::PixelMetric>(id));
|
||||
|
||||
if (otherRadioButton->isChecked()) {
|
||||
extent = otherSpinBox->value();
|
||||
} else {
|
||||
QStyle::PixelMetric metric;
|
||||
|
||||
if (smallRadioButton->isChecked()) {
|
||||
metric = QStyle::PM_SmallIconSize;
|
||||
} else if (largeRadioButton->isChecked()) {
|
||||
metric = QStyle::PM_LargeIconSize;
|
||||
} else if (toolBarRadioButton->isChecked()) {
|
||||
metric = QStyle::PM_ToolBarIconSize;
|
||||
} else if (listViewRadioButton->isChecked()) {
|
||||
metric = QStyle::PM_ListViewIconSize;
|
||||
} else if (iconViewRadioButton->isChecked()) {
|
||||
metric = QStyle::PM_IconViewIconSize;
|
||||
} else {
|
||||
metric = QStyle::PM_TabBarIconSize;
|
||||
}
|
||||
extent = QApplication::style()->pixelMetric(metric);
|
||||
}
|
||||
previewArea->setSize(QSize(extent, extent));
|
||||
otherSpinBox->setEnabled(otherRadioButton->isChecked());
|
||||
otherSpinBox->setEnabled(other);
|
||||
}
|
||||
|
||||
void MainWindow::triggerChangeSize()
|
||||
{
|
||||
changeSize(sizeButtonGroup->checkedId(), true);
|
||||
}
|
||||
//! [5]
|
||||
|
||||
@ -152,33 +169,21 @@ void MainWindow::changeIcon()
|
||||
QIcon icon;
|
||||
|
||||
for (int row = 0; row < imagesTable->rowCount(); ++row) {
|
||||
QTableWidgetItem *item0 = imagesTable->item(row, 0);
|
||||
QTableWidgetItem *item1 = imagesTable->item(row, 1);
|
||||
QTableWidgetItem *item2 = imagesTable->item(row, 2);
|
||||
const QTableWidgetItem *fileItem = imagesTable->item(row, 0);
|
||||
const QTableWidgetItem *modeItem = imagesTable->item(row, 1);
|
||||
const QTableWidgetItem *stateItem = imagesTable->item(row, 2);
|
||||
|
||||
if (item0->checkState() == Qt::Checked) {
|
||||
QIcon::Mode mode;
|
||||
if (item1->text() == tr("Normal")) {
|
||||
mode = QIcon::Normal;
|
||||
} else if (item1->text() == tr("Active")) {
|
||||
mode = QIcon::Active;
|
||||
} else if (item1->text() == tr("Disabled")) {
|
||||
mode = QIcon::Disabled;
|
||||
} else {
|
||||
mode = QIcon::Selected;
|
||||
}
|
||||
|
||||
QIcon::State state;
|
||||
if (item2->text() == tr("On")) {
|
||||
state = QIcon::On;
|
||||
} else {
|
||||
state = QIcon::Off;
|
||||
//! [6] //! [7]
|
||||
}
|
||||
//! [7]
|
||||
if (fileItem->checkState() == Qt::Checked) {
|
||||
const int modeIndex = IconPreviewArea::iconModeNames().indexOf(modeItem->text());
|
||||
Q_ASSERT(modeIndex >= 0);
|
||||
const int stateIndex = IconPreviewArea::iconStateNames().indexOf(stateItem->text());
|
||||
Q_ASSERT(stateIndex >= 0);
|
||||
const QIcon::Mode mode = IconPreviewArea::iconModes().at(modeIndex);
|
||||
const QIcon::State state = IconPreviewArea::iconStates().at(stateIndex);
|
||||
//! [6]
|
||||
|
||||
//! [8]
|
||||
QString fileName = item0->data(Qt::UserRole).toString();
|
||||
const QString fileName = fileItem->data(Qt::UserRole).toString();
|
||||
QImage image(fileName);
|
||||
if (!image.isNull())
|
||||
icon.addPixmap(QPixmap::fromImage(image), mode, state);
|
||||
@ -193,61 +198,109 @@ void MainWindow::changeIcon()
|
||||
}
|
||||
//! [11]
|
||||
|
||||
//! [12]
|
||||
void MainWindow::addImages()
|
||||
void MainWindow::addSampleImages()
|
||||
{
|
||||
QStringList fileNames = QFileDialog::getOpenFileNames(this,
|
||||
tr("Open Images"), "",
|
||||
tr("Images (*.png *.xpm *.jpg);;"
|
||||
"All Files (*)"));
|
||||
if (!fileNames.isEmpty()) {
|
||||
foreach (QString fileName, fileNames) {
|
||||
int row = imagesTable->rowCount();
|
||||
imagesTable->setRowCount(row + 1);
|
||||
//! [12]
|
||||
addImages(QLatin1String(SRCDIR) + QLatin1String("/images"));
|
||||
}
|
||||
|
||||
void MainWindow::addOtherImages()
|
||||
{
|
||||
static bool firstInvocation = true;
|
||||
QString directory;
|
||||
if (firstInvocation) {
|
||||
firstInvocation = false;
|
||||
directory = QStandardPaths::standardLocations(QStandardPaths::PicturesLocation).value(0, QString());
|
||||
}
|
||||
addImages(directory);
|
||||
}
|
||||
|
||||
//! [12]
|
||||
void MainWindow::addImages(const QString &directory)
|
||||
{
|
||||
QFileDialog fileDialog(this, tr("Open Images"), directory);
|
||||
QStringList mimeTypeFilters;
|
||||
foreach (const QByteArray &mimeTypeName, QImageReader::supportedMimeTypes())
|
||||
mimeTypeFilters.append(mimeTypeName);
|
||||
mimeTypeFilters.sort();
|
||||
fileDialog.setMimeTypeFilters(mimeTypeFilters);
|
||||
fileDialog.selectMimeTypeFilter(QLatin1String("image/png"));
|
||||
fileDialog.setAcceptMode(QFileDialog::AcceptOpen);
|
||||
fileDialog.setFileMode(QFileDialog::ExistingFiles);
|
||||
if (!nativeFileDialogAct->isChecked())
|
||||
fileDialog.setOption(QFileDialog::DontUseNativeDialog);
|
||||
if (fileDialog.exec() == QDialog::Accepted)
|
||||
loadImages(fileDialog.selectedFiles());
|
||||
//! [12]
|
||||
}
|
||||
|
||||
void MainWindow::loadImages(const QStringList &fileNames)
|
||||
{
|
||||
foreach (const QString &fileName, fileNames) {
|
||||
const int row = imagesTable->rowCount();
|
||||
imagesTable->setRowCount(row + 1);
|
||||
//! [13]
|
||||
QString imageName = QFileInfo(fileName).baseName();
|
||||
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\nFile: %2\nFile@2x: %3\nSize: %4x%5")
|
||||
.arg(QDir::toNativeSeparators(fileInfo.absolutePath()), fileInfo.fileName())
|
||||
.arg(fileInfo2x.exists() ? fileInfo2x.fileName() : tr("<None>"))
|
||||
.arg(image.width()).arg(image.height());
|
||||
//! [13] //! [14]
|
||||
QTableWidgetItem *item0 = new QTableWidgetItem(imageName);
|
||||
item0->setData(Qt::UserRole, fileName);
|
||||
item0->setFlags(item0->flags() & ~Qt::ItemIsEditable);
|
||||
QTableWidgetItem *fileItem = new QTableWidgetItem(imageName);
|
||||
fileItem->setData(Qt::UserRole, fileName);
|
||||
fileItem->setIcon(QPixmap::fromImage(image));
|
||||
fileItem->setFlags((fileItem->flags() | Qt::ItemIsUserCheckable) & ~Qt::ItemIsEditable);
|
||||
fileItem->setToolTip(toolTip);
|
||||
//! [14]
|
||||
|
||||
//! [15]
|
||||
QTableWidgetItem *item1 = new QTableWidgetItem(tr("Normal"));
|
||||
QIcon::Mode mode = QIcon::Normal;
|
||||
//! [15] //! [16]
|
||||
QTableWidgetItem *item2 = new QTableWidgetItem(tr("Off"));
|
||||
QIcon::State state = QIcon::Off;
|
||||
if (guessModeStateAct->isChecked()) {
|
||||
if (imageName.contains(QLatin1String("_act"), Qt::CaseInsensitive))
|
||||
mode = QIcon::Active;
|
||||
else if (imageName.contains(QLatin1String("_dis"), Qt::CaseInsensitive))
|
||||
mode = QIcon::Disabled;
|
||||
else if (imageName.contains(QLatin1String("_sel"), Qt::CaseInsensitive))
|
||||
mode = QIcon::Selected;
|
||||
|
||||
if (guessModeStateAct->isChecked()) {
|
||||
if (fileName.contains("_act")) {
|
||||
item1->setText(tr("Active"));
|
||||
} else if (fileName.contains("_dis")) {
|
||||
item1->setText(tr("Disabled"));
|
||||
} else if (fileName.contains("_sel")) {
|
||||
item1->setText(tr("Selected"));
|
||||
}
|
||||
|
||||
if (fileName.contains("_on"))
|
||||
item2->setText(tr("On"));
|
||||
if (imageName.contains(QLatin1String("_on"), Qt::CaseInsensitive))
|
||||
state = QIcon::On;
|
||||
//! [16] //! [17]
|
||||
}
|
||||
}
|
||||
//! [17]
|
||||
|
||||
//! [18]
|
||||
imagesTable->setItem(row, 0, item0);
|
||||
imagesTable->setItem(row, 0, fileItem);
|
||||
//! [18] //! [19]
|
||||
imagesTable->setItem(row, 1, item1);
|
||||
imagesTable->setItem(row, 2, item2);
|
||||
imagesTable->openPersistentEditor(item1);
|
||||
imagesTable->openPersistentEditor(item2);
|
||||
QTableWidgetItem *modeItem =
|
||||
new QTableWidgetItem(IconPreviewArea::iconModeNames().at(IconPreviewArea::iconModes().indexOf(mode)));
|
||||
modeItem->setToolTip(toolTip);
|
||||
imagesTable->setItem(row, 1, modeItem);
|
||||
QTableWidgetItem *stateItem =
|
||||
new QTableWidgetItem(IconPreviewArea::iconStateNames().at(IconPreviewArea::iconStates().indexOf(state)));
|
||||
stateItem->setToolTip(toolTip);
|
||||
imagesTable->setItem(row, 2, stateItem);
|
||||
imagesTable->openPersistentEditor(modeItem);
|
||||
imagesTable->openPersistentEditor(stateItem);
|
||||
|
||||
item0->setCheckState(Qt::Checked);
|
||||
}
|
||||
fileItem->setCheckState(Qt::Checked);
|
||||
}
|
||||
}
|
||||
//! [19]
|
||||
|
||||
void MainWindow::useHighDpiPixmapsChanged(int checkState)
|
||||
{
|
||||
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps, checkState == Qt::Checked);
|
||||
changeIcon();
|
||||
}
|
||||
|
||||
//! [20]
|
||||
void MainWindow::removeAllImages()
|
||||
{
|
||||
@ -256,21 +309,10 @@ void MainWindow::removeAllImages()
|
||||
}
|
||||
//! [20]
|
||||
|
||||
void MainWindow::createPreviewGroupBox()
|
||||
{
|
||||
previewGroupBox = new QGroupBox(tr("Preview"));
|
||||
|
||||
previewArea = new IconPreviewArea;
|
||||
|
||||
QVBoxLayout *layout = new QVBoxLayout;
|
||||
layout->addWidget(previewArea);
|
||||
previewGroupBox->setLayout(layout);
|
||||
}
|
||||
|
||||
//! [21]
|
||||
void MainWindow::createImagesGroupBox()
|
||||
QWidget *MainWindow::createImagesGroupBox()
|
||||
{
|
||||
imagesGroupBox = new QGroupBox(tr("Images"));
|
||||
QGroupBox *imagesGroupBox = new QGroupBox(tr("Images"));
|
||||
|
||||
imagesTable = new QTableWidget;
|
||||
imagesTable->setSelectionMode(QAbstractItemView::NoSelection);
|
||||
@ -292,57 +334,63 @@ void MainWindow::createImagesGroupBox()
|
||||
//! [23]
|
||||
|
||||
//! [24]
|
||||
connect(imagesTable, SIGNAL(itemChanged(QTableWidgetItem*)),
|
||||
connect(imagesTable, &QTableWidget::itemChanged,
|
||||
//! [24] //! [25]
|
||||
this, SLOT(changeIcon()));
|
||||
this, &MainWindow::changeIcon);
|
||||
|
||||
QVBoxLayout *layout = new QVBoxLayout;
|
||||
QVBoxLayout *layout = new QVBoxLayout(imagesGroupBox);
|
||||
layout->addWidget(imagesTable);
|
||||
imagesGroupBox->setLayout(layout);
|
||||
return imagesGroupBox;
|
||||
}
|
||||
//! [25]
|
||||
|
||||
//! [26]
|
||||
void MainWindow::createIconSizeGroupBox()
|
||||
QWidget *MainWindow::createIconSizeGroupBox()
|
||||
{
|
||||
iconSizeGroupBox = new QGroupBox(tr("Icon Size"));
|
||||
QGroupBox *iconSizeGroupBox = new QGroupBox(tr("Icon Size"));
|
||||
|
||||
smallRadioButton = new QRadioButton;
|
||||
largeRadioButton = new QRadioButton;
|
||||
toolBarRadioButton = new QRadioButton;
|
||||
listViewRadioButton = new QRadioButton;
|
||||
iconViewRadioButton = new QRadioButton;
|
||||
tabBarRadioButton = new QRadioButton;
|
||||
otherRadioButton = new QRadioButton(tr("Other:"));
|
||||
sizeButtonGroup = new QButtonGroup(this);
|
||||
sizeButtonGroup->setExclusive(true);
|
||||
|
||||
typedef void (QButtonGroup::*QButtonGroupIntBoolSignal)(int, bool);
|
||||
connect(sizeButtonGroup, static_cast<QButtonGroupIntBoolSignal>(&QButtonGroup::buttonToggled),
|
||||
this, &MainWindow::changeSize);
|
||||
|
||||
QRadioButton *smallRadioButton = new QRadioButton;
|
||||
sizeButtonGroup->addButton(smallRadioButton, QStyle::PM_SmallIconSize);
|
||||
QRadioButton *largeRadioButton = new QRadioButton;
|
||||
sizeButtonGroup->addButton(largeRadioButton, QStyle::PM_LargeIconSize);
|
||||
QRadioButton *toolBarRadioButton = new QRadioButton;
|
||||
sizeButtonGroup->addButton(toolBarRadioButton, QStyle::PM_ToolBarIconSize);
|
||||
QRadioButton *listViewRadioButton = new QRadioButton;
|
||||
sizeButtonGroup->addButton(listViewRadioButton, QStyle::PM_ListViewIconSize);
|
||||
QRadioButton *iconViewRadioButton = new QRadioButton;
|
||||
sizeButtonGroup->addButton(iconViewRadioButton, QStyle::PM_IconViewIconSize);
|
||||
QRadioButton *tabBarRadioButton = new QRadioButton;
|
||||
sizeButtonGroup->addButton(tabBarRadioButton, QStyle::PM_TabBarIconSize);
|
||||
QRadioButton *otherRadioButton = new QRadioButton(tr("Other:"));
|
||||
sizeButtonGroup->addButton(otherRadioButton, OtherSize);
|
||||
otherSpinBox = new IconSizeSpinBox;
|
||||
otherSpinBox->setRange(8, 128);
|
||||
otherSpinBox->setRange(8, 256);
|
||||
const QString spinBoxToolTip =
|
||||
tr("Enter a custom size within %1..%2")
|
||||
.arg(otherSpinBox->minimum()).arg(otherSpinBox->maximum());
|
||||
otherSpinBox->setValue(64);
|
||||
otherSpinBox->setToolTip(spinBoxToolTip);
|
||||
otherRadioButton->setToolTip(spinBoxToolTip);
|
||||
//! [26]
|
||||
|
||||
//! [27]
|
||||
connect(smallRadioButton, SIGNAL(toggled(bool)),
|
||||
this, SLOT(changeSize(bool)));
|
||||
connect(largeRadioButton, SIGNAL(toggled(bool)),
|
||||
this, SLOT(changeSize(bool)));
|
||||
connect(toolBarRadioButton, SIGNAL(toggled(bool)),
|
||||
this, SLOT(changeSize(bool)));
|
||||
connect(listViewRadioButton, SIGNAL(toggled(bool)),
|
||||
this, SLOT(changeSize(bool)));
|
||||
connect(iconViewRadioButton, SIGNAL(toggled(bool)),
|
||||
this, SLOT(changeSize(bool)));
|
||||
connect(tabBarRadioButton, SIGNAL(toggled(bool)),
|
||||
this, SLOT(changeSize(bool)));
|
||||
connect(otherRadioButton, SIGNAL(toggled(bool)),
|
||||
this, SLOT(changeSize(bool)));
|
||||
connect(otherSpinBox, SIGNAL(valueChanged(int)), this, SLOT(changeSize()));
|
||||
typedef void (QSpinBox::*QSpinBoxIntSignal)(int);
|
||||
connect(otherSpinBox, static_cast<QSpinBoxIntSignal>(&QSpinBox::valueChanged),
|
||||
this, &MainWindow::triggerChangeSize);
|
||||
|
||||
QHBoxLayout *otherSizeLayout = new QHBoxLayout;
|
||||
otherSizeLayout->addWidget(otherRadioButton);
|
||||
otherSizeLayout->addWidget(otherSpinBox);
|
||||
otherSizeLayout->addStretch();
|
||||
|
||||
QGridLayout *layout = new QGridLayout;
|
||||
QGridLayout *layout = new QGridLayout(iconSizeGroupBox);
|
||||
layout->addWidget(smallRadioButton, 0, 0);
|
||||
layout->addWidget(largeRadioButton, 1, 0);
|
||||
layout->addWidget(toolBarRadioButton, 2, 0);
|
||||
@ -351,75 +399,99 @@ void MainWindow::createIconSizeGroupBox()
|
||||
layout->addWidget(tabBarRadioButton, 2, 1);
|
||||
layout->addLayout(otherSizeLayout, 3, 0, 1, 2);
|
||||
layout->setRowStretch(4, 1);
|
||||
iconSizeGroupBox->setLayout(layout);
|
||||
return iconSizeGroupBox;
|
||||
}
|
||||
//! [27]
|
||||
|
||||
void MainWindow::screenChanged()
|
||||
{
|
||||
devicePixelRatioLabel->setText(QString::number(devicePixelRatioF()));
|
||||
if (const QWindow *window = windowHandle()) {
|
||||
const QScreen *screen = window->screen();
|
||||
const QString screenDescription =
|
||||
tr("\"%1\" (%2x%3)").arg(screen->name())
|
||||
.arg(screen->geometry().width()).arg(screen->geometry().height());
|
||||
screenNameLabel->setText(screenDescription);
|
||||
}
|
||||
changeIcon();
|
||||
}
|
||||
|
||||
QWidget *MainWindow::createHighDpiIconSizeGroupBox()
|
||||
{
|
||||
QGroupBox *highDpiGroupBox = new QGroupBox(tr("High DPI Scaling"));
|
||||
QFormLayout *layout = new QFormLayout(highDpiGroupBox);
|
||||
devicePixelRatioLabel = new QLabel(highDpiGroupBox);
|
||||
screenNameLabel = new QLabel(highDpiGroupBox);
|
||||
layout->addRow(tr("Screen:"), screenNameLabel);
|
||||
layout->addRow(tr("Device pixel ratio:"), devicePixelRatioLabel);
|
||||
QCheckBox *highDpiPixmapsCheckBox = new QCheckBox(QLatin1String("Qt::AA_UseHighDpiPixmaps"));
|
||||
highDpiPixmapsCheckBox->setChecked(QCoreApplication::testAttribute(Qt::AA_UseHighDpiPixmaps));
|
||||
connect(highDpiPixmapsCheckBox, &QCheckBox::stateChanged, this, &MainWindow::useHighDpiPixmapsChanged);
|
||||
layout->addRow(highDpiPixmapsCheckBox);
|
||||
return highDpiGroupBox;
|
||||
}
|
||||
|
||||
//! [28]
|
||||
void MainWindow::createActions()
|
||||
{
|
||||
addImagesAct = new QAction(tr("&Add Images..."), this);
|
||||
addImagesAct->setShortcut(tr("Ctrl+A"));
|
||||
connect(addImagesAct, SIGNAL(triggered()), this, SLOT(addImages()));
|
||||
QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
|
||||
|
||||
addSampleImagesAct = new QAction(tr("Add &Sample Images..."), this);
|
||||
addSampleImagesAct->setShortcut(tr("Ctrl+A"));
|
||||
connect(addSampleImagesAct, &QAction::triggered, this, &MainWindow::addSampleImages);
|
||||
fileMenu->addAction(addSampleImagesAct);
|
||||
|
||||
addOtherImagesAct = new QAction(tr("&Add Images..."), this);
|
||||
addOtherImagesAct->setShortcut(QKeySequence::Open);
|
||||
connect(addOtherImagesAct, &QAction::triggered, this, &MainWindow::addOtherImages);
|
||||
fileMenu->addAction(addOtherImagesAct);
|
||||
|
||||
removeAllImagesAct = new QAction(tr("&Remove All Images"), this);
|
||||
removeAllImagesAct->setShortcut(tr("Ctrl+R"));
|
||||
connect(removeAllImagesAct, SIGNAL(triggered()),
|
||||
this, SLOT(removeAllImages()));
|
||||
connect(removeAllImagesAct, &QAction::triggered,
|
||||
this, &MainWindow::removeAllImages);
|
||||
fileMenu->addAction(removeAllImagesAct);
|
||||
|
||||
exitAct = new QAction(tr("&Quit"), this);
|
||||
fileMenu->addSeparator();
|
||||
|
||||
QAction *exitAct = fileMenu->addAction(tr("&Quit"), this, &QWidget::close);
|
||||
exitAct->setShortcuts(QKeySequence::Quit);
|
||||
connect(exitAct, SIGNAL(triggered()), this, SLOT(close()));
|
||||
|
||||
QMenu *viewMenu = menuBar()->addMenu(tr("&View"));
|
||||
|
||||
styleActionGroup = new QActionGroup(this);
|
||||
foreach (QString styleName, QStyleFactory::keys()) {
|
||||
QAction *action = new QAction(styleActionGroup);
|
||||
action->setText(tr("%1 Style").arg(styleName));
|
||||
foreach (const QString &styleName, QStyleFactory::keys()) {
|
||||
QAction *action = new QAction(tr("%1 Style").arg(styleName), styleActionGroup);
|
||||
action->setData(styleName);
|
||||
action->setCheckable(true);
|
||||
connect(action, SIGNAL(triggered(bool)), this, SLOT(changeStyle(bool)));
|
||||
connect(action, &QAction::triggered, this, &MainWindow::changeStyle);
|
||||
viewMenu->addAction(action);
|
||||
}
|
||||
|
||||
QMenu *settingsMenu = menuBar()->addMenu(tr("&Settings"));
|
||||
|
||||
guessModeStateAct = new QAction(tr("&Guess Image Mode/State"), this);
|
||||
guessModeStateAct->setCheckable(true);
|
||||
guessModeStateAct->setChecked(true);
|
||||
settingsMenu->addAction(guessModeStateAct);
|
||||
|
||||
aboutAct = new QAction(tr("&About"), this);
|
||||
connect(aboutAct, SIGNAL(triggered()), this, SLOT(about()));
|
||||
nativeFileDialogAct = new QAction(tr("&Use Native File Dialog"), this);
|
||||
nativeFileDialogAct->setCheckable(true);
|
||||
nativeFileDialogAct->setChecked(true);
|
||||
settingsMenu->addAction(nativeFileDialogAct);
|
||||
|
||||
aboutQtAct = new QAction(tr("About &Qt"), this);
|
||||
connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
|
||||
QMenu *helpMenu = menuBar()->addMenu(tr("&Help"));
|
||||
helpMenu->addAction(tr("&About"), this, &MainWindow::about);
|
||||
helpMenu->addAction(tr("About &Qt"), qApp, &QApplication::aboutQt);
|
||||
}
|
||||
//! [28]
|
||||
|
||||
//! [29]
|
||||
void MainWindow::createMenus()
|
||||
{
|
||||
fileMenu = menuBar()->addMenu(tr("&File"));
|
||||
fileMenu->addAction(addImagesAct);
|
||||
fileMenu->addAction(removeAllImagesAct);
|
||||
fileMenu->addSeparator();
|
||||
fileMenu->addAction(exitAct);
|
||||
|
||||
viewMenu = menuBar()->addMenu(tr("&View"));
|
||||
foreach (QAction *action, styleActionGroup->actions())
|
||||
viewMenu->addAction(action);
|
||||
viewMenu->addSeparator();
|
||||
viewMenu->addAction(guessModeStateAct);
|
||||
|
||||
menuBar()->addSeparator();
|
||||
|
||||
helpMenu = menuBar()->addMenu(tr("&Help"));
|
||||
helpMenu->addAction(aboutAct);
|
||||
helpMenu->addAction(aboutQtAct);
|
||||
}
|
||||
//! [29]
|
||||
|
||||
//! [30]
|
||||
void MainWindow::createContextMenu()
|
||||
{
|
||||
imagesTable->setContextMenuPolicy(Qt::ActionsContextMenu);
|
||||
imagesTable->addAction(addImagesAct);
|
||||
imagesTable->addAction(addSampleImagesAct);
|
||||
imagesTable->addAction(addOtherImagesAct);
|
||||
imagesTable->addAction(removeAllImagesAct);
|
||||
}
|
||||
//! [30]
|
||||
@ -429,14 +501,13 @@ void MainWindow::checkCurrentStyle()
|
||||
{
|
||||
foreach (QAction *action, styleActionGroup->actions()) {
|
||||
QString styleName = action->data().toString();
|
||||
QStyle *candidate = QStyleFactory::create(styleName);
|
||||
Q_ASSERT(candidate);
|
||||
QScopedPointer<QStyle> candidate(QStyleFactory::create(styleName));
|
||||
Q_ASSERT(!candidate.isNull());
|
||||
if (candidate->metaObject()->className()
|
||||
== QApplication::style()->metaObject()->className()) {
|
||||
action->trigger();
|
||||
return;
|
||||
}
|
||||
delete candidate;
|
||||
}
|
||||
}
|
||||
//! [31]
|
||||
|
@ -49,9 +49,10 @@
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QAction;
|
||||
class QActionGroup;
|
||||
class QGroupBox;
|
||||
class QLabel;
|
||||
class QMenu;
|
||||
class QRadioButton;
|
||||
class QButtonGroup;
|
||||
class QTableWidget;
|
||||
QT_END_NAMESPACE
|
||||
class IconPreviewArea;
|
||||
@ -65,51 +66,47 @@ class MainWindow : public QMainWindow
|
||||
public:
|
||||
MainWindow();
|
||||
|
||||
void loadImages(const QStringList &fileNames);
|
||||
|
||||
void show();
|
||||
|
||||
private slots:
|
||||
void about();
|
||||
void changeStyle(bool checked);
|
||||
void changeSize(bool checked = true);
|
||||
void changeSize(int, bool);
|
||||
void triggerChangeSize();
|
||||
void changeIcon();
|
||||
void addImages();
|
||||
void addSampleImages();
|
||||
void addOtherImages();
|
||||
void removeAllImages();
|
||||
void useHighDpiPixmapsChanged(int checkState);
|
||||
void screenChanged();
|
||||
|
||||
private:
|
||||
void createPreviewGroupBox();
|
||||
void createImagesGroupBox();
|
||||
void createIconSizeGroupBox();
|
||||
QWidget *createImagesGroupBox();
|
||||
QWidget *createIconSizeGroupBox();
|
||||
QWidget *createHighDpiIconSizeGroupBox();
|
||||
void createActions();
|
||||
void createMenus();
|
||||
void createContextMenu();
|
||||
void checkCurrentStyle();
|
||||
void addImages(const QString &directory);
|
||||
|
||||
QWidget *centralWidget;
|
||||
|
||||
QGroupBox *previewGroupBox;
|
||||
IconPreviewArea *previewArea;
|
||||
|
||||
QGroupBox *imagesGroupBox;
|
||||
QTableWidget *imagesTable;
|
||||
|
||||
QGroupBox *iconSizeGroupBox;
|
||||
QRadioButton *smallRadioButton;
|
||||
QRadioButton *largeRadioButton;
|
||||
QRadioButton *toolBarRadioButton;
|
||||
QRadioButton *listViewRadioButton;
|
||||
QRadioButton *iconViewRadioButton;
|
||||
QRadioButton *tabBarRadioButton;
|
||||
QRadioButton *otherRadioButton;
|
||||
QButtonGroup *sizeButtonGroup;
|
||||
IconSizeSpinBox *otherSpinBox;
|
||||
|
||||
QMenu *fileMenu;
|
||||
QMenu *viewMenu;
|
||||
QMenu *helpMenu;
|
||||
QAction *addImagesAct;
|
||||
QLabel *devicePixelRatioLabel;
|
||||
QLabel *screenNameLabel;
|
||||
|
||||
QAction *addOtherImagesAct;
|
||||
QAction *addSampleImagesAct;
|
||||
QAction *removeAllImagesAct;
|
||||
QAction *exitAct;
|
||||
QAction *guessModeStateAct;
|
||||
QAction *nativeFileDialogAct;
|
||||
QActionGroup *styleActionGroup;
|
||||
QAction *aboutAct;
|
||||
QAction *aboutQtAct;
|
||||
};
|
||||
//! [0]
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user