/examples/widgets/gallery/widgetgallery.cpp
C++ | 474 lines | 359 code | 65 blank | 50 comment | 11 complexity | 79c6a863e5920be196a1b60be4754681 MD5 | raw file
- /****************************************************************************
- **
- ** Copyright (C) 2020 The Qt Company Ltd.
- ** Contact: https://www.qt.io/licensing/
- **
- ** This file is part of the examples of the Qt Toolkit.
- **
- ** $QT_BEGIN_LICENSE:BSD$
- ** Commercial License Usage
- ** Licensees holding valid commercial Qt licenses may use this file in
- ** accordance with the commercial license agreement provided with the
- ** Software or, alternatively, in accordance with the terms contained in
- ** a written agreement between you and The Qt Company. For licensing terms
- ** and conditions see https://www.qt.io/terms-conditions. For further
- ** information use the contact form at https://www.qt.io/contact-us.
- **
- ** BSD License Usage
- ** Alternatively, you may use this file under the terms of the BSD license
- ** as follows:
- **
- ** "Redistribution and use in source and binary forms, with or without
- ** modification, are permitted provided that the following conditions are
- ** met:
- ** * Redistributions of source code must retain the above copyright
- ** notice, this list of conditions and the following disclaimer.
- ** * Redistributions in binary form must reproduce the above copyright
- ** notice, this list of conditions and the following disclaimer in
- ** the documentation and/or other materials provided with the
- ** distribution.
- ** * Neither the name of The Qt Company Ltd nor the names of its
- ** contributors may be used to endorse or promote products derived
- ** from this software without specific prior written permission.
- **
- **
- ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
- **
- ** $QT_END_LICENSE$
- **
- ****************************************************************************/
- #include "widgetgallery.h"
- #include <QApplication>
- #include <QCheckBox>
- #include <QComboBox>
- #include <QCommandLinkButton>
- #include <QDateTimeEdit>
- #include <QDial>
- #include <QDialogButtonBox>
- #include <QFileSystemModel>
- #include <QGridLayout>
- #include <QGroupBox>
- #include <QMenu>
- #include <QLabel>
- #include <QLineEdit>
- #include <QListWidget>
- #include <QPlainTextEdit>
- #include <QProgressBar>
- #include <QPushButton>
- #include <QRadioButton>
- #include <QScrollBar>
- #include <QShortcut>
- #include <QSpinBox>
- #include <QStandardItemModel>
- #include <QStyle>
- #include <QStyleFactory>
- #include <QTextBrowser>
- #include <QTreeView>
- #include <QTableWidget>
- #include <QTextEdit>
- #include <QToolBox>
- #include <QToolButton>
- #include <QIcon>
- #include <QDesktopServices>
- #include <QScreen>
- #include <QWindow>
- #include <QDebug>
- #include <QLibraryInfo>
- #include <QSysInfo>
- #include <QTextStream>
- #include <QTimer>
- static inline QString className(const QObject *o)
- {
- return QString::fromUtf8(o->metaObject()->className());
- }
- static inline void setClassNameToolTip(QWidget *w)
- {
- w->setToolTip(className(w));
- }
- static QString helpUrl(const QString &page)
- {
- QString result;
- QTextStream(&result) << "https://doc.qt.io/qt-" << QT_VERSION_MAJOR
- << '/' << page << ".html";
- return result;
- }
- static inline QString helpUrl(const QWidget *w)
- {
- return helpUrl(className(w).toLower());
- }
- static void launchHelp(const QWidget *w)
- {
- QDesktopServices::openUrl(helpUrl(w));
- }
- static void launchModuleHelp()
- {
- QDesktopServices::openUrl(helpUrl(QLatin1String("qtwidgets-index")));
- }
- template <class Widget>
- Widget *createWidget(const char *name, QWidget *parent = nullptr)
- {
- auto result = new Widget(parent);
- result->setObjectName(QLatin1String(name));
- setClassNameToolTip(result);
- return result;
- }
- template <class Widget, class Parameter>
- Widget *createWidget1(const Parameter &p1, const char *name, QWidget *parent = nullptr)
- {
- auto result = new Widget(p1, parent);
- result->setObjectName(QLatin1String(name));
- setClassNameToolTip(result);
- return result;
- }
- QTextStream &operator<<(QTextStream &str, const QRect &r)
- {
- str << r.width() << 'x' << r.height() << Qt::forcesign << r.x() << r.y()
- << Qt::noforcesign;
- return str;
- }
- static QString highDpiScaleFactorRoundingPolicy()
- {
- QString result;
- QDebug(&result) << QGuiApplication::highDpiScaleFactorRoundingPolicy();
- if (result.endsWith(QLatin1Char(')')))
- result.chop(1);
- const int lastSep = result.lastIndexOf(QLatin1String("::"));
- if (lastSep != -1)
- result.remove(0, lastSep + 2);
- return result;
- }
- WidgetGallery::WidgetGallery(QWidget *parent)
- : QDialog(parent)
- , progressBar(createProgressBar())
- {
- setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
- auto styleComboBox = createWidget<QComboBox>("styleComboBox");
- const QString defaultStyleName = QApplication::style()->objectName();
- QStringList styleNames = QStyleFactory::keys();
- for (int i = 1, size = styleNames.size(); i < size; ++i) {
- if (defaultStyleName.compare(styleNames.at(i), Qt::CaseInsensitive) == 0) {
- styleNames.swapItemsAt(0, i);
- break;
- }
- }
- styleComboBox->addItems(styleNames);
- auto styleLabel = createWidget1<QLabel>(tr("&Style:"), "styleLabel");
- styleLabel->setBuddy(styleComboBox);
- auto helpLabel = createWidget1<QLabel>(tr("Press F1 over a widget to see Documentation"), "helpLabel");
- auto disableWidgetsCheckBox = createWidget1<QCheckBox>(tr("&Disable widgets"), "disableWidgetsCheckBox");
- auto buttonsGroupBox = createButtonsGroupBox();
- auto itemViewTabWidget = createItemViewTabWidget();
- auto simpleInputWidgetsGroupBox = createSimpleInputWidgetsGroupBox();
- auto textToolBox = createTextToolBox();
- connect(styleComboBox, &QComboBox::textActivated,
- this, &WidgetGallery::changeStyle);
- connect(disableWidgetsCheckBox, &QCheckBox::toggled,
- buttonsGroupBox, &QWidget::setDisabled);
- connect(disableWidgetsCheckBox, &QCheckBox::toggled,
- textToolBox, &QWidget::setDisabled);
- connect(disableWidgetsCheckBox, &QCheckBox::toggled,
- itemViewTabWidget, &QWidget::setDisabled);
- connect(disableWidgetsCheckBox, &QCheckBox::toggled,
- simpleInputWidgetsGroupBox, &QWidget::setDisabled);
- auto topLayout = new QHBoxLayout;
- topLayout->addWidget(styleLabel);
- topLayout->addWidget(styleComboBox);
- topLayout->addStretch(1);
- topLayout->addWidget(helpLabel);
- topLayout->addStretch(1);
- topLayout->addWidget(disableWidgetsCheckBox);
- auto dialogButtonBox = createWidget1<QDialogButtonBox>(QDialogButtonBox::Help | QDialogButtonBox::Close,
- "dialogButtonBox");
- connect(dialogButtonBox, &QDialogButtonBox::helpRequested, this, launchModuleHelp);
- connect(dialogButtonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
- auto mainLayout = new QGridLayout(this);
- mainLayout->addLayout(topLayout, 0, 0, 1, 2);
- mainLayout->addWidget(buttonsGroupBox, 1, 0);
- mainLayout->addWidget(simpleInputWidgetsGroupBox, 1, 1);
- mainLayout->addWidget(itemViewTabWidget, 2, 0);
- mainLayout->addWidget(textToolBox, 2, 1);
- mainLayout->addWidget(progressBar, 3, 0, 1, 2);
- mainLayout->addWidget(dialogButtonBox, 4, 0, 1, 2);
- setWindowTitle(tr("Widget Gallery Qt %1").arg(QT_VERSION_STR));
- new QShortcut(QKeySequence::HelpContents, this, this, &WidgetGallery::helpOnCurrentWidget);
- }
- void WidgetGallery::setVisible(bool visible)
- {
- QDialog::setVisible(visible);
- if (visible) {
- connect(windowHandle(), &QWindow::screenChanged, this, &WidgetGallery::updateSystemInfo);
- updateSystemInfo();
- }
- }
- void WidgetGallery::changeStyle(const QString &styleName)
- {
- QApplication::setStyle(QStyleFactory::create(styleName));
- }
- void WidgetGallery::advanceProgressBar()
- {
- int curVal = progressBar->value();
- int maxVal = progressBar->maximum();
- progressBar->setValue(curVal + (maxVal - curVal) / 100);
- }
- QGroupBox *WidgetGallery::createButtonsGroupBox()
- {
- auto result = createWidget1<QGroupBox>(tr("Buttons"), "buttonsGroupBox");
- auto defaultPushButton = createWidget1<QPushButton>(tr("Default Push Button"), "defaultPushButton");
- defaultPushButton->setDefault(true);
- auto togglePushButton = createWidget1<QPushButton>(tr("Toggle Push Button"), "togglePushButton");
- togglePushButton->setCheckable(true);
- togglePushButton->setChecked(true);
- auto flatPushButton = createWidget1<QPushButton>(tr("Flat Push Button"), "flatPushButton");
- flatPushButton->setFlat(true);
- auto toolButton = createWidget<QToolButton>("toolButton");
- toolButton->setText(tr("Tool Button"));
- auto menuToolButton = createWidget<QToolButton>("menuButton");
- menuToolButton->setText(tr("Menu Button"));
- auto toolMenu = new QMenu(menuToolButton);
- menuToolButton->setPopupMode(QToolButton::InstantPopup);
- toolMenu->addAction("Option");
- toolMenu->addSeparator();
- auto action = toolMenu->addAction("Checkable Option");
- action->setCheckable(true);
- menuToolButton->setMenu(toolMenu);
- auto toolLayout = new QHBoxLayout;
- toolLayout->addWidget(toolButton);
- toolLayout->addWidget(menuToolButton);
- auto commandLinkButton = createWidget1<QCommandLinkButton>(tr("Command Link Button"), "commandLinkButton");
- commandLinkButton->setDescription(tr("Description"));
- auto buttonLayout = new QVBoxLayout;
- buttonLayout->addWidget(defaultPushButton);
- buttonLayout->addWidget(togglePushButton);
- buttonLayout->addWidget(flatPushButton);
- buttonLayout->addLayout(toolLayout);
- buttonLayout->addWidget(commandLinkButton);
- buttonLayout->addStretch(1);
- auto radioButton1 = createWidget1<QRadioButton>(tr("Radio button 1"), "radioButton1");
- auto radioButton2 = createWidget1<QRadioButton>(tr("Radio button 2"), "radioButton2");
- auto radioButton3 = createWidget1<QRadioButton>(tr("Radio button 3"), "radioButton3");
- radioButton1->setChecked(true);
- auto checkBox = createWidget1<QCheckBox>(tr("Tri-state check box"), "checkBox");
- checkBox->setTristate(true);
- checkBox->setCheckState(Qt::PartiallyChecked);
- auto checkableLayout = new QVBoxLayout;
- checkableLayout->addWidget(radioButton1);
- checkableLayout->addWidget(radioButton2);
- checkableLayout->addWidget(radioButton3);
- checkableLayout->addWidget(checkBox);
- checkableLayout->addStretch(1);
- auto mainLayout = new QHBoxLayout(result);
- mainLayout->addLayout(buttonLayout);
- mainLayout->addLayout(checkableLayout);
- mainLayout->addStretch();
- return result;
- }
- static QWidget *embedIntoHBoxLayout(QWidget *w, int margin = 5)
- {
- auto result = new QWidget;
- auto layout = new QHBoxLayout(result);
- layout->setContentsMargins(margin, margin, margin, margin);
- layout->addWidget(w);
- return result;
- }
- QToolBox *WidgetGallery::createTextToolBox()
- {
- auto result = createWidget<QToolBox>("toolBox");
- const QString plainText = tr("Twinkle, twinkle, little star,\n"
- "How I wonder what you are.\n"
- "Up above the world so high,\n"
- "Like a diamond in the sky.\n"
- "Twinkle, twinkle, little star,\n"
- "How I wonder what you are!\n");
- // Create centered/italic HTML rich text
- QString richText = QLatin1String("<html><head/><body><i>");
- for (const auto &line : QStringView{ plainText }.split(QLatin1Char('\n')))
- richText += QString::fromLatin1("<center>%1</center>").arg(line);
- richText += QLatin1String("</i></body></html>");
- auto textEdit = createWidget1<QTextEdit>(richText, "textEdit");
- auto plainTextEdit = createWidget1<QPlainTextEdit>(plainText, "plainTextEdit");
- systemInfoTextBrowser = createWidget<QTextBrowser>("systemInfoTextBrowser");
- result->addItem(embedIntoHBoxLayout(textEdit), tr("Text Edit"));
- result->addItem(embedIntoHBoxLayout(plainTextEdit), tr("Plain Text Edit"));
- result->addItem(embedIntoHBoxLayout(systemInfoTextBrowser), tr("Text Browser"));
- return result;
- }
- QTabWidget *WidgetGallery::createItemViewTabWidget()
- {
- auto result = createWidget<QTabWidget>("bottomLeftTabWidget");
- result->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Ignored);
- auto treeView = createWidget<QTreeView>("treeView");
- auto fileSystemModel = new QFileSystemModel(treeView);
- fileSystemModel->setRootPath(QDir::rootPath());
- treeView->setModel(fileSystemModel);
- auto tableWidget = createWidget<QTableWidget>("tableWidget");
- tableWidget->setRowCount(10);
- tableWidget->setColumnCount(10);
- auto listModel = new QStandardItemModel(0, 1, result);
- listModel->appendRow(new QStandardItem(QIcon(QLatin1String(":/qt-project.org/styles/commonstyle/images/diropen-128.png")),
- tr("Directory")));
- listModel->appendRow(new QStandardItem(QIcon(QLatin1String(":/qt-project.org/styles/commonstyle/images/computer-32.png")),
- tr("Computer")));
- auto listView = createWidget<QListView>("listView");
- listView->setModel(listModel);
- auto iconModeListView = createWidget<QListView>("iconModeListView");
- iconModeListView->setViewMode(QListView::IconMode);
- iconModeListView->setModel(listModel);
- result->addTab(embedIntoHBoxLayout(treeView), tr("&Tree View"));
- result->addTab(embedIntoHBoxLayout(tableWidget), tr("T&able"));
- result->addTab(embedIntoHBoxLayout(listView), tr("&List"));
- result->addTab(embedIntoHBoxLayout(iconModeListView), tr("&Icon Mode List"));
- return result;
- }
- QGroupBox *WidgetGallery::createSimpleInputWidgetsGroupBox()
- {
- auto result = createWidget1<QGroupBox>(tr("Simple Input Widgets"), "bottomRightGroupBox");
- result->setCheckable(true);
- result->setChecked(true);
- auto lineEdit = createWidget1<QLineEdit>("s3cRe7", "lineEdit");
- lineEdit->setClearButtonEnabled(true);
- lineEdit->setEchoMode(QLineEdit::Password);
- auto spinBox = createWidget<QSpinBox>("spinBox", result);
- spinBox->setValue(50);
- auto dateTimeEdit = createWidget<QDateTimeEdit>("dateTimeEdit", result);
- dateTimeEdit->setDateTime(QDateTime::currentDateTime());
- auto slider = createWidget<QSlider>("slider", result);
- slider->setOrientation(Qt::Horizontal);
- slider->setValue(40);
- auto scrollBar = createWidget<QScrollBar>("scrollBar", result);
- scrollBar->setOrientation(Qt::Horizontal);
- setClassNameToolTip(scrollBar);
- scrollBar->setValue(60);
- auto dial = createWidget<QDial>("dial", result);
- dial->setValue(30);
- dial->setNotchesVisible(true);
- auto layout = new QGridLayout(result);
- layout->addWidget(lineEdit, 0, 0, 1, 2);
- layout->addWidget(spinBox, 1, 0, 1, 2);
- layout->addWidget(dateTimeEdit, 2, 0, 1, 2);
- layout->addWidget(slider, 3, 0);
- layout->addWidget(scrollBar, 4, 0);
- layout->addWidget(dial, 3, 1, 2, 1);
- layout->setRowStretch(5, 1);
- return result;
- }
- QProgressBar *WidgetGallery::createProgressBar()
- {
- auto result = createWidget<QProgressBar>("progressBar");
- result->setRange(0, 10000);
- result->setValue(0);
- auto timer = new QTimer(this);
- connect(timer, &QTimer::timeout, this, &WidgetGallery::advanceProgressBar);
- timer->start(1000);
- return result;
- }
- void WidgetGallery::updateSystemInfo()
- {
- QString systemInfo;
- QTextStream str(&systemInfo);
- str << "<html><head/><body><h3>Build</h3><p>" << QLibraryInfo::build() << "</p>"
- << "<h3>Operating System</h3><p>" << QSysInfo::prettyProductName() << "</p>"
- << "<h3>Screens</h3><p>High DPI scale factor rounding policy: "
- << highDpiScaleFactorRoundingPolicy() << "</p><ol>";
- const auto screens = QGuiApplication::screens();
- for (auto screen : screens) {
- const bool current = screen == this->screen();
- str << "<li>";
- if (current)
- str << "<i>";
- str << '"' << screen->name() << "\" " << screen->geometry() << ", "
- << screen->logicalDotsPerInchX() << "DPI, DPR="
- << screen->devicePixelRatio();
- if (current)
- str << "</i>";
- str << "</li>";
- }
- str << "</ol></body></html>";
- systemInfoTextBrowser->setHtml(systemInfo);
- }
- void WidgetGallery::helpOnCurrentWidget()
- {
- // Skip over internal widgets
- for (auto w = QApplication::widgetAt(QCursor::pos(screen())); w; w = w->parentWidget()) {
- const QString name = w->objectName();
- if (!name.isEmpty() && !name.startsWith(QLatin1String("qt_"))) {
- launchHelp(w);
- break;
- }
- }
- }