6.5.3 clean
54
tests/manual/examples/widgets/application/CMakeLists.txt
Normal file
@ -0,0 +1,54 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(application LANGUAGES CXX)
|
||||
|
||||
if(NOT DEFINED INSTALL_EXAMPLESDIR)
|
||||
set(INSTALL_EXAMPLESDIR "examples")
|
||||
endif()
|
||||
|
||||
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/widgets/mainwindows/application")
|
||||
|
||||
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
|
||||
|
||||
qt_standard_project_setup()
|
||||
|
||||
qt_add_executable(application
|
||||
main.cpp
|
||||
mainwindow.cpp mainwindow.h
|
||||
)
|
||||
|
||||
set_target_properties(application PROPERTIES
|
||||
WIN32_EXECUTABLE TRUE
|
||||
MACOSX_BUNDLE TRUE
|
||||
)
|
||||
|
||||
target_link_libraries(application PRIVATE
|
||||
Qt6::Core
|
||||
Qt6::Gui
|
||||
Qt6::Widgets
|
||||
)
|
||||
|
||||
# Resources:
|
||||
set(application_resource_files
|
||||
"images/copy.png"
|
||||
"images/cut.png"
|
||||
"images/new.png"
|
||||
"images/open.png"
|
||||
"images/paste.png"
|
||||
"images/save.png"
|
||||
)
|
||||
|
||||
qt_add_resources(application "application"
|
||||
PREFIX
|
||||
"/"
|
||||
FILES
|
||||
${application_resource_files}
|
||||
)
|
||||
|
||||
install(TARGETS application
|
||||
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
)
|
13
tests/manual/examples/widgets/application/application.pro
Normal file
@ -0,0 +1,13 @@
|
||||
QT += widgets
|
||||
requires(qtConfig(filedialog))
|
||||
|
||||
HEADERS = mainwindow.h
|
||||
SOURCES = main.cpp \
|
||||
mainwindow.cpp
|
||||
#! [0]
|
||||
RESOURCES = application.qrc
|
||||
#! [0]
|
||||
|
||||
# install
|
||||
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/mainwindows/application
|
||||
INSTALLS += target
|
10
tests/manual/examples/widgets/application/application.qrc
Normal file
@ -0,0 +1,10 @@
|
||||
<!DOCTYPE RCC><RCC version="1.0">
|
||||
<qresource>
|
||||
<file>images/copy.png</file>
|
||||
<file>images/cut.png</file>
|
||||
<file>images/new.png</file>
|
||||
<file>images/open.png</file>
|
||||
<file>images/paste.png</file>
|
||||
<file>images/save.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
BIN
tests/manual/examples/widgets/application/images/copy.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
tests/manual/examples/widgets/application/images/cut.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
tests/manual/examples/widgets/application/images/new.png
Normal file
After Width: | Height: | Size: 852 B |
BIN
tests/manual/examples/widgets/application/images/open.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
tests/manual/examples/widgets/application/images/paste.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
tests/manual/examples/widgets/application/images/save.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
28
tests/manual/examples/widgets/application/main.cpp
Normal file
@ -0,0 +1,28 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include <QApplication>
|
||||
#include <QCommandLineParser>
|
||||
#include <QCommandLineOption>
|
||||
|
||||
#include "mainwindow.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
QCoreApplication::setOrganizationName("QtProject");
|
||||
QCoreApplication::setApplicationName("Application Example");
|
||||
QCoreApplication::setApplicationVersion(QT_VERSION_STR);
|
||||
QCommandLineParser parser;
|
||||
parser.setApplicationDescription(QCoreApplication::applicationName());
|
||||
parser.addHelpOption();
|
||||
parser.addVersionOption();
|
||||
parser.addPositionalArgument("file", "The file to open.");
|
||||
parser.process(app);
|
||||
|
||||
MainWindow mainWin;
|
||||
if (!parser.positionalArguments().isEmpty())
|
||||
mainWin.loadFile(parser.positionalArguments().first());
|
||||
mainWin.show();
|
||||
return app.exec();
|
||||
}
|
306
tests/manual/examples/widgets/application/mainwindow.cpp
Normal file
@ -0,0 +1,306 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include <QtWidgets>
|
||||
|
||||
#include "mainwindow.h"
|
||||
|
||||
MainWindow::MainWindow()
|
||||
: textEdit(new QPlainTextEdit)
|
||||
{
|
||||
setCentralWidget(textEdit);
|
||||
|
||||
createActions();
|
||||
createStatusBar();
|
||||
|
||||
readSettings();
|
||||
|
||||
connect(textEdit->document(), &QTextDocument::contentsChanged,
|
||||
this, &MainWindow::documentWasModified);
|
||||
|
||||
#ifndef QT_NO_SESSIONMANAGER
|
||||
connect(qApp, &QGuiApplication::commitDataRequest,
|
||||
this, &MainWindow::commitData);
|
||||
#endif
|
||||
|
||||
setCurrentFile(QString());
|
||||
setUnifiedTitleAndToolBarOnMac(true);
|
||||
}
|
||||
|
||||
void MainWindow::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
if (maybeSave()) {
|
||||
writeSettings();
|
||||
event->accept();
|
||||
} else {
|
||||
event->ignore();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::newFile()
|
||||
{
|
||||
if (maybeSave()) {
|
||||
textEdit->clear();
|
||||
setCurrentFile(QString());
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::open()
|
||||
{
|
||||
if (maybeSave()) {
|
||||
QString fileName = QFileDialog::getOpenFileName(this);
|
||||
if (!fileName.isEmpty())
|
||||
loadFile(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
bool MainWindow::save()
|
||||
{
|
||||
if (curFile.isEmpty()) {
|
||||
return saveAs();
|
||||
} else {
|
||||
return saveFile(curFile);
|
||||
}
|
||||
}
|
||||
|
||||
bool MainWindow::saveAs()
|
||||
{
|
||||
QFileDialog dialog(this);
|
||||
dialog.setWindowModality(Qt::WindowModal);
|
||||
dialog.setAcceptMode(QFileDialog::AcceptSave);
|
||||
if (dialog.exec() != QDialog::Accepted)
|
||||
return false;
|
||||
return saveFile(dialog.selectedFiles().first());
|
||||
}
|
||||
|
||||
void MainWindow::about()
|
||||
{
|
||||
QMessageBox::about(this, tr("About Application"),
|
||||
tr("The <b>Application</b> example demonstrates how to "
|
||||
"write modern GUI applications using Qt, with a menu bar, "
|
||||
"toolbars, and a status bar."));
|
||||
}
|
||||
|
||||
void MainWindow::documentWasModified()
|
||||
{
|
||||
setWindowModified(textEdit->document()->isModified());
|
||||
}
|
||||
|
||||
void MainWindow::createActions()
|
||||
{
|
||||
|
||||
QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
|
||||
QToolBar *fileToolBar = addToolBar(tr("File"));
|
||||
const QIcon newIcon = QIcon::fromTheme("document-new", QIcon(":/images/new.png"));
|
||||
QAction *newAct = new QAction(newIcon, tr("&New"), this);
|
||||
newAct->setShortcuts(QKeySequence::New);
|
||||
newAct->setStatusTip(tr("Create a new file"));
|
||||
connect(newAct, &QAction::triggered, this, &MainWindow::newFile);
|
||||
fileMenu->addAction(newAct);
|
||||
fileToolBar->addAction(newAct);
|
||||
|
||||
const QIcon openIcon = QIcon::fromTheme("document-open", QIcon(":/images/open.png"));
|
||||
QAction *openAct = new QAction(openIcon, tr("&Open..."), this);
|
||||
openAct->setShortcuts(QKeySequence::Open);
|
||||
openAct->setStatusTip(tr("Open an existing file"));
|
||||
connect(openAct, &QAction::triggered, this, &MainWindow::open);
|
||||
fileMenu->addAction(openAct);
|
||||
fileToolBar->addAction(openAct);
|
||||
|
||||
const QIcon saveIcon = QIcon::fromTheme("document-save", QIcon(":/images/save.png"));
|
||||
QAction *saveAct = new QAction(saveIcon, tr("&Save"), this);
|
||||
saveAct->setShortcuts(QKeySequence::Save);
|
||||
saveAct->setStatusTip(tr("Save the document to disk"));
|
||||
connect(saveAct, &QAction::triggered, this, &MainWindow::save);
|
||||
fileMenu->addAction(saveAct);
|
||||
fileToolBar->addAction(saveAct);
|
||||
|
||||
const QIcon saveAsIcon = QIcon::fromTheme("document-save-as");
|
||||
QAction *saveAsAct = fileMenu->addAction(saveAsIcon, tr("Save &As..."), this, &MainWindow::saveAs);
|
||||
saveAsAct->setShortcuts(QKeySequence::SaveAs);
|
||||
saveAsAct->setStatusTip(tr("Save the document under a new name"));
|
||||
|
||||
fileMenu->addSeparator();
|
||||
|
||||
const QIcon exitIcon = QIcon::fromTheme("application-exit");
|
||||
QAction *exitAct = fileMenu->addAction(exitIcon, tr("E&xit"), this, &QWidget::close);
|
||||
exitAct->setShortcuts(QKeySequence::Quit);
|
||||
exitAct->setStatusTip(tr("Exit the application"));
|
||||
|
||||
QMenu *editMenu = menuBar()->addMenu(tr("&Edit"));
|
||||
QToolBar *editToolBar = addToolBar(tr("Edit"));
|
||||
|
||||
#ifndef QT_NO_CLIPBOARD
|
||||
const QIcon cutIcon = QIcon::fromTheme("edit-cut", QIcon(":/images/cut.png"));
|
||||
QAction *cutAct = new QAction(cutIcon, tr("Cu&t"), this);
|
||||
cutAct->setShortcuts(QKeySequence::Cut);
|
||||
cutAct->setStatusTip(tr("Cut the current selection's contents to the "
|
||||
"clipboard"));
|
||||
connect(cutAct, &QAction::triggered, textEdit, &QPlainTextEdit::cut);
|
||||
editMenu->addAction(cutAct);
|
||||
editToolBar->addAction(cutAct);
|
||||
|
||||
const QIcon copyIcon = QIcon::fromTheme("edit-copy", QIcon(":/images/copy.png"));
|
||||
QAction *copyAct = new QAction(copyIcon, tr("&Copy"), this);
|
||||
copyAct->setShortcuts(QKeySequence::Copy);
|
||||
copyAct->setStatusTip(tr("Copy the current selection's contents to the "
|
||||
"clipboard"));
|
||||
connect(copyAct, &QAction::triggered, textEdit, &QPlainTextEdit::copy);
|
||||
editMenu->addAction(copyAct);
|
||||
editToolBar->addAction(copyAct);
|
||||
|
||||
const QIcon pasteIcon = QIcon::fromTheme("edit-paste", QIcon(":/images/paste.png"));
|
||||
QAction *pasteAct = new QAction(pasteIcon, tr("&Paste"), this);
|
||||
pasteAct->setShortcuts(QKeySequence::Paste);
|
||||
pasteAct->setStatusTip(tr("Paste the clipboard's contents into the current "
|
||||
"selection"));
|
||||
connect(pasteAct, &QAction::triggered, textEdit, &QPlainTextEdit::paste);
|
||||
editMenu->addAction(pasteAct);
|
||||
editToolBar->addAction(pasteAct);
|
||||
|
||||
menuBar()->addSeparator();
|
||||
|
||||
#endif // !QT_NO_CLIPBOARD
|
||||
|
||||
QMenu *helpMenu = menuBar()->addMenu(tr("&Help"));
|
||||
QAction *aboutAct = helpMenu->addAction(tr("&About"), this, &MainWindow::about);
|
||||
aboutAct->setStatusTip(tr("Show the application's About box"));
|
||||
|
||||
QAction *aboutQtAct = helpMenu->addAction(tr("About &Qt"), qApp, &QApplication::aboutQt);
|
||||
aboutQtAct->setStatusTip(tr("Show the Qt library's About box"));
|
||||
|
||||
#ifndef QT_NO_CLIPBOARD
|
||||
cutAct->setEnabled(false);
|
||||
copyAct->setEnabled(false);
|
||||
connect(textEdit, &QPlainTextEdit::copyAvailable, cutAct, &QAction::setEnabled);
|
||||
connect(textEdit, &QPlainTextEdit::copyAvailable, copyAct, &QAction::setEnabled);
|
||||
#endif // !QT_NO_CLIPBOARD
|
||||
}
|
||||
|
||||
void MainWindow::createStatusBar()
|
||||
{
|
||||
statusBar()->showMessage(tr("Ready"));
|
||||
}
|
||||
|
||||
void MainWindow::readSettings()
|
||||
{
|
||||
QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName());
|
||||
const QByteArray geometry = settings.value("geometry", QByteArray()).toByteArray();
|
||||
if (geometry.isEmpty()) {
|
||||
const QRect availableGeometry = screen()->availableGeometry();
|
||||
resize(availableGeometry.width() / 3, availableGeometry.height() / 2);
|
||||
move((availableGeometry.width() - width()) / 2,
|
||||
(availableGeometry.height() - height()) / 2);
|
||||
} else {
|
||||
restoreGeometry(geometry);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::writeSettings()
|
||||
{
|
||||
QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName());
|
||||
settings.setValue("geometry", saveGeometry());
|
||||
}
|
||||
|
||||
bool MainWindow::maybeSave()
|
||||
{
|
||||
if (!textEdit->document()->isModified())
|
||||
return true;
|
||||
const QMessageBox::StandardButton ret
|
||||
= QMessageBox::warning(this, tr("Application"),
|
||||
tr("The document has been modified.\n"
|
||||
"Do you want to save your changes?"),
|
||||
QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
|
||||
switch (ret) {
|
||||
case QMessageBox::Save:
|
||||
return save();
|
||||
case QMessageBox::Cancel:
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void MainWindow::loadFile(const QString &fileName)
|
||||
{
|
||||
QFile file(fileName);
|
||||
if (!file.open(QFile::ReadOnly | QFile::Text)) {
|
||||
QMessageBox::warning(this, tr("Application"),
|
||||
tr("Cannot read file %1:\n%2.")
|
||||
.arg(QDir::toNativeSeparators(fileName), file.errorString()));
|
||||
return;
|
||||
}
|
||||
|
||||
QTextStream in(&file);
|
||||
#ifndef QT_NO_CURSOR
|
||||
QGuiApplication::setOverrideCursor(Qt::WaitCursor);
|
||||
#endif
|
||||
textEdit->setPlainText(in.readAll());
|
||||
#ifndef QT_NO_CURSOR
|
||||
QGuiApplication::restoreOverrideCursor();
|
||||
#endif
|
||||
|
||||
setCurrentFile(fileName);
|
||||
statusBar()->showMessage(tr("File loaded"), 2000);
|
||||
}
|
||||
|
||||
bool MainWindow::saveFile(const QString &fileName)
|
||||
{
|
||||
QString errorMessage;
|
||||
|
||||
QGuiApplication::setOverrideCursor(Qt::WaitCursor);
|
||||
QSaveFile file(fileName);
|
||||
if (file.open(QFile::WriteOnly | QFile::Text)) {
|
||||
QTextStream out(&file);
|
||||
out << textEdit->toPlainText();
|
||||
if (!file.commit()) {
|
||||
errorMessage = tr("Cannot write file %1:\n%2.")
|
||||
.arg(QDir::toNativeSeparators(fileName), file.errorString());
|
||||
}
|
||||
} else {
|
||||
errorMessage = tr("Cannot open file %1 for writing:\n%2.")
|
||||
.arg(QDir::toNativeSeparators(fileName), file.errorString());
|
||||
}
|
||||
QGuiApplication::restoreOverrideCursor();
|
||||
|
||||
if (!errorMessage.isEmpty()) {
|
||||
QMessageBox::warning(this, tr("Application"), errorMessage);
|
||||
return false;
|
||||
}
|
||||
|
||||
setCurrentFile(fileName);
|
||||
statusBar()->showMessage(tr("File saved"), 2000);
|
||||
return true;
|
||||
}
|
||||
|
||||
void MainWindow::setCurrentFile(const QString &fileName)
|
||||
{
|
||||
curFile = fileName;
|
||||
textEdit->document()->setModified(false);
|
||||
setWindowModified(false);
|
||||
|
||||
QString shownName = curFile;
|
||||
if (curFile.isEmpty())
|
||||
shownName = "untitled.txt";
|
||||
setWindowFilePath(shownName);
|
||||
}
|
||||
|
||||
QString MainWindow::strippedName(const QString &fullFileName)
|
||||
{
|
||||
return QFileInfo(fullFileName).fileName();
|
||||
}
|
||||
|
||||
#ifndef QT_NO_SESSIONMANAGER
|
||||
void MainWindow::commitData(QSessionManager &manager)
|
||||
{
|
||||
if (manager.allowsInteraction()) {
|
||||
if (!maybeSave())
|
||||
manager.cancel();
|
||||
} else {
|
||||
// Non-interactive: save without asking
|
||||
if (textEdit->document()->isModified())
|
||||
save();
|
||||
}
|
||||
}
|
||||
#endif
|
53
tests/manual/examples/widgets/application/mainwindow.h
Normal file
@ -0,0 +1,53 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#ifndef MAINWINDOW_H
|
||||
#define MAINWINDOW_H
|
||||
|
||||
#include <QMainWindow>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QAction;
|
||||
class QMenu;
|
||||
class QPlainTextEdit;
|
||||
class QSessionManager;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MainWindow();
|
||||
|
||||
void loadFile(const QString &fileName);
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *event) override;
|
||||
|
||||
private slots:
|
||||
void newFile();
|
||||
void open();
|
||||
bool save();
|
||||
bool saveAs();
|
||||
void about();
|
||||
void documentWasModified();
|
||||
#ifndef QT_NO_SESSIONMANAGER
|
||||
void commitData(QSessionManager &);
|
||||
#endif
|
||||
|
||||
private:
|
||||
void createActions();
|
||||
void createStatusBar();
|
||||
void readSettings();
|
||||
void writeSettings();
|
||||
bool maybeSave();
|
||||
bool saveFile(const QString &fileName);
|
||||
void setCurrentFile(const QString &fileName);
|
||||
QString strippedName(const QString &fullFileName);
|
||||
|
||||
QPlainTextEdit *textEdit;
|
||||
QString curFile;
|
||||
};
|
||||
|
||||
#endif
|
@ -0,0 +1,55 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(classwizard LANGUAGES CXX)
|
||||
|
||||
if(NOT DEFINED INSTALL_EXAMPLESDIR)
|
||||
set(INSTALL_EXAMPLESDIR "examples")
|
||||
endif()
|
||||
|
||||
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/widgets/dialogs/classwizard")
|
||||
|
||||
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
|
||||
|
||||
qt_standard_project_setup()
|
||||
|
||||
qt_add_executable(classwizard
|
||||
classwizard.cpp classwizard.h
|
||||
main.cpp
|
||||
)
|
||||
|
||||
set_target_properties(classwizard PROPERTIES
|
||||
WIN32_EXECUTABLE TRUE
|
||||
MACOSX_BUNDLE TRUE
|
||||
)
|
||||
|
||||
target_link_libraries(classwizard PRIVATE
|
||||
Qt6::Core
|
||||
Qt6::Gui
|
||||
Qt6::Widgets
|
||||
)
|
||||
|
||||
# Resources:
|
||||
set(classwizard_resource_files
|
||||
"images/background.png"
|
||||
"images/banner.png"
|
||||
"images/logo1.png"
|
||||
"images/logo2.png"
|
||||
"images/logo3.png"
|
||||
"images/watermark1.png"
|
||||
"images/watermark2.png"
|
||||
)
|
||||
|
||||
qt_add_resources(classwizard "classwizard"
|
||||
PREFIX
|
||||
"/"
|
||||
FILES
|
||||
${classwizard_resource_files}
|
||||
)
|
||||
|
||||
install(TARGETS classwizard
|
||||
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
)
|
@ -0,0 +1,394 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include <QtWidgets>
|
||||
|
||||
#include "classwizard.h"
|
||||
|
||||
//! [0] //! [1]
|
||||
ClassWizard::ClassWizard(QWidget *parent)
|
||||
: QWizard(parent)
|
||||
{
|
||||
addPage(new IntroPage);
|
||||
addPage(new ClassInfoPage);
|
||||
addPage(new CodeStylePage);
|
||||
addPage(new OutputFilesPage);
|
||||
addPage(new ConclusionPage);
|
||||
//! [0]
|
||||
|
||||
setPixmap(QWizard::BannerPixmap, QPixmap(":/images/banner.png"));
|
||||
setPixmap(QWizard::BackgroundPixmap, QPixmap(":/images/background.png"));
|
||||
|
||||
setWindowTitle(tr("Class Wizard"));
|
||||
//! [2]
|
||||
}
|
||||
//! [1] //! [2]
|
||||
|
||||
//! [3]
|
||||
void ClassWizard::accept()
|
||||
//! [3] //! [4]
|
||||
{
|
||||
QByteArray className = field("className").toByteArray();
|
||||
QByteArray baseClass = field("baseClass").toByteArray();
|
||||
QByteArray macroName = field("macroName").toByteArray();
|
||||
QByteArray baseInclude = field("baseInclude").toByteArray();
|
||||
|
||||
QString outputDir = field("outputDir").toString();
|
||||
QString header = field("header").toString();
|
||||
QString implementation = field("implementation").toString();
|
||||
//! [4]
|
||||
|
||||
QByteArray block;
|
||||
|
||||
if (field("comment").toBool()) {
|
||||
block += "/*\n";
|
||||
block += " " + header.toLatin1() + '\n';
|
||||
block += "*/\n";
|
||||
block += '\n';
|
||||
}
|
||||
if (field("protect").toBool()) {
|
||||
block += "#ifndef " + macroName + '\n';
|
||||
block += "#define " + macroName + '\n';
|
||||
block += '\n';
|
||||
}
|
||||
if (field("includeBase").toBool()) {
|
||||
block += "#include " + baseInclude + '\n';
|
||||
block += '\n';
|
||||
}
|
||||
|
||||
block += "class " + className;
|
||||
if (!baseClass.isEmpty())
|
||||
block += " : public " + baseClass;
|
||||
block += '\n';
|
||||
block += "{\n";
|
||||
|
||||
/* qmake ignore Q_OBJECT */
|
||||
|
||||
if (field("qobjectMacro").toBool()) {
|
||||
block += " Q_OBJECT\n";
|
||||
block += '\n';
|
||||
}
|
||||
block += "public:\n";
|
||||
|
||||
if (field("qobjectCtor").toBool()) {
|
||||
block += " " + className + "(QObject *parent = nullptr);\n";
|
||||
} else if (field("qwidgetCtor").toBool()) {
|
||||
block += " " + className + "(QWidget *parent = nullptr);\n";
|
||||
} else if (field("defaultCtor").toBool()) {
|
||||
block += " " + className + "();\n";
|
||||
if (field("copyCtor").toBool()) {
|
||||
block += " " + className + "(const " + className + " &other);\n";
|
||||
block += '\n';
|
||||
block += " " + className + " &operator=" + "(const " + className
|
||||
+ " &other);\n";
|
||||
}
|
||||
}
|
||||
block += "};\n";
|
||||
|
||||
if (field("protect").toBool()) {
|
||||
block += '\n';
|
||||
block += "#endif\n";
|
||||
}
|
||||
|
||||
QFile headerFile(outputDir + '/' + header);
|
||||
if (!headerFile.open(QFile::WriteOnly | QFile::Text)) {
|
||||
QMessageBox::warning(nullptr, QObject::tr("Simple Wizard"),
|
||||
QObject::tr("Cannot write file %1:\n%2")
|
||||
.arg(headerFile.fileName())
|
||||
.arg(headerFile.errorString()));
|
||||
return;
|
||||
}
|
||||
headerFile.write(block);
|
||||
|
||||
block.clear();
|
||||
|
||||
if (field("comment").toBool()) {
|
||||
block += "/*\n";
|
||||
block += " " + implementation.toLatin1() + '\n';
|
||||
block += "*/\n";
|
||||
block += '\n';
|
||||
}
|
||||
block += "#include \"" + header.toLatin1() + "\"\n";
|
||||
block += '\n';
|
||||
|
||||
if (field("qobjectCtor").toBool()) {
|
||||
block += className + "::" + className + "(QObject *parent)\n";
|
||||
block += " : " + baseClass + "(parent)\n";
|
||||
block += "{\n";
|
||||
block += "}\n";
|
||||
} else if (field("qwidgetCtor").toBool()) {
|
||||
block += className + "::" + className + "(QWidget *parent)\n";
|
||||
block += " : " + baseClass + "(parent)\n";
|
||||
block += "{\n";
|
||||
block += "}\n";
|
||||
} else if (field("defaultCtor").toBool()) {
|
||||
block += className + "::" + className + "()\n";
|
||||
block += "{\n";
|
||||
block += " // missing code\n";
|
||||
block += "}\n";
|
||||
|
||||
if (field("copyCtor").toBool()) {
|
||||
block += "\n";
|
||||
block += className + "::" + className + "(const " + className
|
||||
+ " &other)\n";
|
||||
block += "{\n";
|
||||
block += " *this = other;\n";
|
||||
block += "}\n";
|
||||
block += '\n';
|
||||
block += className + " &" + className + "::operator=(const "
|
||||
+ className + " &other)\n";
|
||||
block += "{\n";
|
||||
if (!baseClass.isEmpty())
|
||||
block += " " + baseClass + "::operator=(other);\n";
|
||||
block += " // missing code\n";
|
||||
block += " return *this;\n";
|
||||
block += "}\n";
|
||||
}
|
||||
}
|
||||
|
||||
QFile implementationFile(outputDir + '/' + implementation);
|
||||
if (!implementationFile.open(QFile::WriteOnly | QFile::Text)) {
|
||||
QMessageBox::warning(nullptr, QObject::tr("Simple Wizard"),
|
||||
QObject::tr("Cannot write file %1:\n%2")
|
||||
.arg(implementationFile.fileName())
|
||||
.arg(implementationFile.errorString()));
|
||||
return;
|
||||
}
|
||||
implementationFile.write(block);
|
||||
|
||||
//! [5]
|
||||
QDialog::accept();
|
||||
//! [5] //! [6]
|
||||
}
|
||||
//! [6]
|
||||
|
||||
//! [7]
|
||||
IntroPage::IntroPage(QWidget *parent)
|
||||
: QWizardPage(parent)
|
||||
{
|
||||
setTitle(tr("Introduction"));
|
||||
setPixmap(QWizard::WatermarkPixmap, QPixmap(":/images/watermark1.png"));
|
||||
|
||||
label = new QLabel(tr("This wizard will generate a skeleton C++ class "
|
||||
"definition, including a few functions. You simply "
|
||||
"need to specify the class name and set a few "
|
||||
"options to produce a header file and an "
|
||||
"implementation file for your new C++ class."));
|
||||
label->setWordWrap(true);
|
||||
|
||||
QVBoxLayout *layout = new QVBoxLayout;
|
||||
layout->addWidget(label);
|
||||
setLayout(layout);
|
||||
}
|
||||
//! [7]
|
||||
|
||||
//! [8] //! [9]
|
||||
ClassInfoPage::ClassInfoPage(QWidget *parent)
|
||||
: QWizardPage(parent)
|
||||
{
|
||||
//! [8]
|
||||
setTitle(tr("Class Information"));
|
||||
setSubTitle(tr("Specify basic information about the class for which you "
|
||||
"want to generate skeleton source code files."));
|
||||
setPixmap(QWizard::LogoPixmap, QPixmap(":/images/logo1.png"));
|
||||
|
||||
//! [10]
|
||||
classNameLabel = new QLabel(tr("&Class name:"));
|
||||
classNameLineEdit = new QLineEdit;
|
||||
classNameLabel->setBuddy(classNameLineEdit);
|
||||
|
||||
baseClassLabel = new QLabel(tr("B&ase class:"));
|
||||
baseClassLineEdit = new QLineEdit;
|
||||
baseClassLabel->setBuddy(baseClassLineEdit);
|
||||
|
||||
qobjectMacroCheckBox = new QCheckBox(tr("Generate Q_OBJECT ¯o"));
|
||||
|
||||
//! [10]
|
||||
groupBox = new QGroupBox(tr("C&onstructor"));
|
||||
//! [9]
|
||||
|
||||
qobjectCtorRadioButton = new QRadioButton(tr("&QObject-style constructor"));
|
||||
qwidgetCtorRadioButton = new QRadioButton(tr("Q&Widget-style constructor"));
|
||||
defaultCtorRadioButton = new QRadioButton(tr("&Default constructor"));
|
||||
copyCtorCheckBox = new QCheckBox(tr("&Generate copy constructor and "
|
||||
"operator="));
|
||||
|
||||
defaultCtorRadioButton->setChecked(true);
|
||||
|
||||
connect(defaultCtorRadioButton, &QAbstractButton::toggled,
|
||||
copyCtorCheckBox, &QWidget::setEnabled);
|
||||
|
||||
//! [11] //! [12]
|
||||
registerField("className*", classNameLineEdit);
|
||||
registerField("baseClass", baseClassLineEdit);
|
||||
registerField("qobjectMacro", qobjectMacroCheckBox);
|
||||
//! [11]
|
||||
registerField("qobjectCtor", qobjectCtorRadioButton);
|
||||
registerField("qwidgetCtor", qwidgetCtorRadioButton);
|
||||
registerField("defaultCtor", defaultCtorRadioButton);
|
||||
registerField("copyCtor", copyCtorCheckBox);
|
||||
|
||||
QVBoxLayout *groupBoxLayout = new QVBoxLayout;
|
||||
//! [12]
|
||||
groupBoxLayout->addWidget(qobjectCtorRadioButton);
|
||||
groupBoxLayout->addWidget(qwidgetCtorRadioButton);
|
||||
groupBoxLayout->addWidget(defaultCtorRadioButton);
|
||||
groupBoxLayout->addWidget(copyCtorCheckBox);
|
||||
groupBox->setLayout(groupBoxLayout);
|
||||
|
||||
QGridLayout *layout = new QGridLayout;
|
||||
layout->addWidget(classNameLabel, 0, 0);
|
||||
layout->addWidget(classNameLineEdit, 0, 1);
|
||||
layout->addWidget(baseClassLabel, 1, 0);
|
||||
layout->addWidget(baseClassLineEdit, 1, 1);
|
||||
layout->addWidget(qobjectMacroCheckBox, 2, 0, 1, 2);
|
||||
layout->addWidget(groupBox, 3, 0, 1, 2);
|
||||
setLayout(layout);
|
||||
//! [13]
|
||||
}
|
||||
//! [13]
|
||||
|
||||
//! [14]
|
||||
CodeStylePage::CodeStylePage(QWidget *parent)
|
||||
: QWizardPage(parent)
|
||||
{
|
||||
setTitle(tr("Code Style Options"));
|
||||
setSubTitle(tr("Choose the formatting of the generated code."));
|
||||
setPixmap(QWizard::LogoPixmap, QPixmap(":/images/logo2.png"));
|
||||
|
||||
commentCheckBox = new QCheckBox(tr("&Start generated files with a "
|
||||
//! [14]
|
||||
"comment"));
|
||||
commentCheckBox->setChecked(true);
|
||||
|
||||
protectCheckBox = new QCheckBox(tr("&Protect header file against multiple "
|
||||
"inclusions"));
|
||||
protectCheckBox->setChecked(true);
|
||||
|
||||
macroNameLabel = new QLabel(tr("&Macro name:"));
|
||||
macroNameLineEdit = new QLineEdit;
|
||||
macroNameLabel->setBuddy(macroNameLineEdit);
|
||||
|
||||
includeBaseCheckBox = new QCheckBox(tr("&Include base class definition"));
|
||||
baseIncludeLabel = new QLabel(tr("Base class include:"));
|
||||
baseIncludeLineEdit = new QLineEdit;
|
||||
baseIncludeLabel->setBuddy(baseIncludeLineEdit);
|
||||
|
||||
connect(protectCheckBox, &QAbstractButton::toggled,
|
||||
macroNameLabel, &QWidget::setEnabled);
|
||||
connect(protectCheckBox, &QAbstractButton::toggled,
|
||||
macroNameLineEdit, &QWidget::setEnabled);
|
||||
connect(includeBaseCheckBox, &QAbstractButton::toggled,
|
||||
baseIncludeLabel, &QWidget::setEnabled);
|
||||
connect(includeBaseCheckBox, &QAbstractButton::toggled,
|
||||
baseIncludeLineEdit, &QWidget::setEnabled);
|
||||
|
||||
registerField("comment", commentCheckBox);
|
||||
registerField("protect", protectCheckBox);
|
||||
registerField("macroName", macroNameLineEdit);
|
||||
registerField("includeBase", includeBaseCheckBox);
|
||||
registerField("baseInclude", baseIncludeLineEdit);
|
||||
|
||||
QGridLayout *layout = new QGridLayout;
|
||||
layout->setColumnMinimumWidth(0, 20);
|
||||
layout->addWidget(commentCheckBox, 0, 0, 1, 3);
|
||||
layout->addWidget(protectCheckBox, 1, 0, 1, 3);
|
||||
layout->addWidget(macroNameLabel, 2, 1);
|
||||
layout->addWidget(macroNameLineEdit, 2, 2);
|
||||
layout->addWidget(includeBaseCheckBox, 3, 0, 1, 3);
|
||||
layout->addWidget(baseIncludeLabel, 4, 1);
|
||||
layout->addWidget(baseIncludeLineEdit, 4, 2);
|
||||
//! [15]
|
||||
setLayout(layout);
|
||||
}
|
||||
//! [15]
|
||||
|
||||
//! [16]
|
||||
void CodeStylePage::initializePage()
|
||||
{
|
||||
QString className = field("className").toString();
|
||||
macroNameLineEdit->setText(className.toUpper() + "_H");
|
||||
|
||||
QString baseClass = field("baseClass").toString();
|
||||
|
||||
includeBaseCheckBox->setChecked(!baseClass.isEmpty());
|
||||
includeBaseCheckBox->setEnabled(!baseClass.isEmpty());
|
||||
baseIncludeLabel->setEnabled(!baseClass.isEmpty());
|
||||
baseIncludeLineEdit->setEnabled(!baseClass.isEmpty());
|
||||
|
||||
QRegularExpression rx("Q[A-Z].*");
|
||||
if (baseClass.isEmpty()) {
|
||||
baseIncludeLineEdit->clear();
|
||||
} else if (rx.match(baseClass).hasMatch()) {
|
||||
baseIncludeLineEdit->setText('<' + baseClass + '>');
|
||||
} else {
|
||||
baseIncludeLineEdit->setText('"' + baseClass.toLower() + ".h\"");
|
||||
}
|
||||
}
|
||||
//! [16]
|
||||
|
||||
OutputFilesPage::OutputFilesPage(QWidget *parent)
|
||||
: QWizardPage(parent)
|
||||
{
|
||||
setTitle(tr("Output Files"));
|
||||
setSubTitle(tr("Specify where you want the wizard to put the generated "
|
||||
"skeleton code."));
|
||||
setPixmap(QWizard::LogoPixmap, QPixmap(":/images/logo3.png"));
|
||||
|
||||
outputDirLabel = new QLabel(tr("&Output directory:"));
|
||||
outputDirLineEdit = new QLineEdit;
|
||||
outputDirLabel->setBuddy(outputDirLineEdit);
|
||||
|
||||
headerLabel = new QLabel(tr("&Header file name:"));
|
||||
headerLineEdit = new QLineEdit;
|
||||
headerLabel->setBuddy(headerLineEdit);
|
||||
|
||||
implementationLabel = new QLabel(tr("&Implementation file name:"));
|
||||
implementationLineEdit = new QLineEdit;
|
||||
implementationLabel->setBuddy(implementationLineEdit);
|
||||
|
||||
registerField("outputDir*", outputDirLineEdit);
|
||||
registerField("header*", headerLineEdit);
|
||||
registerField("implementation*", implementationLineEdit);
|
||||
|
||||
QGridLayout *layout = new QGridLayout;
|
||||
layout->addWidget(outputDirLabel, 0, 0);
|
||||
layout->addWidget(outputDirLineEdit, 0, 1);
|
||||
layout->addWidget(headerLabel, 1, 0);
|
||||
layout->addWidget(headerLineEdit, 1, 1);
|
||||
layout->addWidget(implementationLabel, 2, 0);
|
||||
layout->addWidget(implementationLineEdit, 2, 1);
|
||||
setLayout(layout);
|
||||
}
|
||||
|
||||
//! [17]
|
||||
void OutputFilesPage::initializePage()
|
||||
{
|
||||
QString className = field("className").toString();
|
||||
headerLineEdit->setText(className.toLower() + ".h");
|
||||
implementationLineEdit->setText(className.toLower() + ".cpp");
|
||||
outputDirLineEdit->setText(QDir::toNativeSeparators(QDir::tempPath()));
|
||||
}
|
||||
//! [17]
|
||||
|
||||
ConclusionPage::ConclusionPage(QWidget *parent)
|
||||
: QWizardPage(parent)
|
||||
{
|
||||
setTitle(tr("Conclusion"));
|
||||
setPixmap(QWizard::WatermarkPixmap, QPixmap(":/images/watermark2.png"));
|
||||
|
||||
label = new QLabel;
|
||||
label->setWordWrap(true);
|
||||
|
||||
QVBoxLayout *layout = new QVBoxLayout;
|
||||
layout->addWidget(label);
|
||||
setLayout(layout);
|
||||
}
|
||||
|
||||
void ConclusionPage::initializePage()
|
||||
{
|
||||
QString finishText = wizard()->buttonText(QWizard::FinishButton);
|
||||
finishText.remove('&');
|
||||
label->setText(tr("Click %1 to generate the class skeleton.")
|
||||
.arg(finishText));
|
||||
}
|
119
tests/manual/examples/widgets/dialogs/classwizard/classwizard.h
Normal file
@ -0,0 +1,119 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#ifndef CLASSWIZARD_H
|
||||
#define CLASSWIZARD_H
|
||||
|
||||
#include <QWizard>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QCheckBox;
|
||||
class QGroupBox;
|
||||
class QLabel;
|
||||
class QLineEdit;
|
||||
class QRadioButton;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
//! [0]
|
||||
class ClassWizard : public QWizard
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ClassWizard(QWidget *parent = nullptr);
|
||||
|
||||
void accept() override;
|
||||
};
|
||||
//! [0]
|
||||
|
||||
//! [1]
|
||||
class IntroPage : public QWizardPage
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
IntroPage(QWidget *parent = nullptr);
|
||||
|
||||
private:
|
||||
QLabel *label;
|
||||
};
|
||||
//! [1]
|
||||
|
||||
//! [2]
|
||||
class ClassInfoPage : public QWizardPage
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ClassInfoPage(QWidget *parent = nullptr);
|
||||
|
||||
private:
|
||||
QLabel *classNameLabel;
|
||||
QLabel *baseClassLabel;
|
||||
QLineEdit *classNameLineEdit;
|
||||
QLineEdit *baseClassLineEdit;
|
||||
QCheckBox *qobjectMacroCheckBox;
|
||||
QGroupBox *groupBox;
|
||||
QRadioButton *qobjectCtorRadioButton;
|
||||
QRadioButton *qwidgetCtorRadioButton;
|
||||
QRadioButton *defaultCtorRadioButton;
|
||||
QCheckBox *copyCtorCheckBox;
|
||||
};
|
||||
//! [2]
|
||||
|
||||
//! [3]
|
||||
class CodeStylePage : public QWizardPage
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CodeStylePage(QWidget *parent = nullptr);
|
||||
|
||||
protected:
|
||||
void initializePage() override;
|
||||
|
||||
private:
|
||||
QCheckBox *commentCheckBox;
|
||||
QCheckBox *protectCheckBox;
|
||||
QCheckBox *includeBaseCheckBox;
|
||||
QLabel *macroNameLabel;
|
||||
QLabel *baseIncludeLabel;
|
||||
QLineEdit *macroNameLineEdit;
|
||||
QLineEdit *baseIncludeLineEdit;
|
||||
};
|
||||
//! [3]
|
||||
|
||||
class OutputFilesPage : public QWizardPage
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
OutputFilesPage(QWidget *parent = nullptr);
|
||||
|
||||
protected:
|
||||
void initializePage() override;
|
||||
|
||||
private:
|
||||
QLabel *outputDirLabel;
|
||||
QLabel *headerLabel;
|
||||
QLabel *implementationLabel;
|
||||
QLineEdit *outputDirLineEdit;
|
||||
QLineEdit *headerLineEdit;
|
||||
QLineEdit *implementationLineEdit;
|
||||
};
|
||||
|
||||
class ConclusionPage : public QWizardPage
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ConclusionPage(QWidget *parent = nullptr);
|
||||
|
||||
protected:
|
||||
void initializePage() override;
|
||||
|
||||
private:
|
||||
QLabel *label;
|
||||
};
|
||||
|
||||
#endif
|
@ -0,0 +1,10 @@
|
||||
QT += widgets
|
||||
|
||||
HEADERS = classwizard.h
|
||||
SOURCES = classwizard.cpp \
|
||||
main.cpp
|
||||
RESOURCES = classwizard.qrc
|
||||
|
||||
# install
|
||||
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/dialogs/classwizard
|
||||
INSTALLS += target
|
@ -0,0 +1,11 @@
|
||||
<!DOCTYPE RCC><RCC version="1.0">
|
||||
<qresource>
|
||||
<file>images/background.png</file>
|
||||
<file>images/banner.png</file>
|
||||
<file>images/logo1.png</file>
|
||||
<file>images/logo2.png</file>
|
||||
<file>images/logo3.png</file>
|
||||
<file>images/watermark1.png</file>
|
||||
<file>images/watermark2.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 3.9 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 15 KiB |
26
tests/manual/examples/widgets/dialogs/classwizard/main.cpp
Normal file
@ -0,0 +1,26 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include <QApplication>
|
||||
#include <QTranslator>
|
||||
#include <QLocale>
|
||||
#include <QLibraryInfo>
|
||||
|
||||
#include "classwizard.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
|
||||
#ifndef QT_NO_TRANSLATION
|
||||
QString translatorFileName = QLatin1String("qtbase_");
|
||||
translatorFileName += QLocale::system().name();
|
||||
QTranslator *translator = new QTranslator(&app);
|
||||
if (translator->load(translatorFileName, QLibraryInfo::path(QLibraryInfo::TranslationsPath)))
|
||||
app.installTranslator(translator);
|
||||
#endif
|
||||
|
||||
ClassWizard wizard;
|
||||
wizard.show();
|
||||
return app.exec();
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(extension LANGUAGES CXX)
|
||||
|
||||
if(NOT DEFINED INSTALL_EXAMPLESDIR)
|
||||
set(INSTALL_EXAMPLESDIR "examples")
|
||||
endif()
|
||||
|
||||
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/widgets/dialogs/extension")
|
||||
|
||||
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
|
||||
|
||||
qt_standard_project_setup()
|
||||
|
||||
qt_add_executable(extension
|
||||
finddialog.cpp finddialog.h
|
||||
main.cpp
|
||||
)
|
||||
|
||||
set_target_properties(extension PROPERTIES
|
||||
WIN32_EXECUTABLE TRUE
|
||||
MACOSX_BUNDLE TRUE
|
||||
)
|
||||
|
||||
target_link_libraries(extension PRIVATE
|
||||
Qt6::Core
|
||||
Qt6::Gui
|
||||
Qt6::Widgets
|
||||
)
|
||||
|
||||
install(TARGETS extension
|
||||
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
)
|
@ -0,0 +1,9 @@
|
||||
QT += widgets
|
||||
|
||||
HEADERS = finddialog.h
|
||||
SOURCES = finddialog.cpp \
|
||||
main.cpp
|
||||
|
||||
# install
|
||||
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/dialogs/extension
|
||||
INSTALLS += target
|
@ -0,0 +1,77 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include <QtWidgets>
|
||||
|
||||
#include "finddialog.h"
|
||||
|
||||
//! [0]
|
||||
FindDialog::FindDialog(QWidget *parent)
|
||||
: QDialog(parent)
|
||||
{
|
||||
label = new QLabel(tr("Find &what:"));
|
||||
lineEdit = new QLineEdit;
|
||||
label->setBuddy(lineEdit);
|
||||
|
||||
caseCheckBox = new QCheckBox(tr("Match &case"));
|
||||
fromStartCheckBox = new QCheckBox(tr("Search from &start"));
|
||||
fromStartCheckBox->setChecked(true);
|
||||
|
||||
//! [1]
|
||||
findButton = new QPushButton(tr("&Find"));
|
||||
findButton->setDefault(true);
|
||||
|
||||
moreButton = new QPushButton(tr("&More"));
|
||||
moreButton->setCheckable(true);
|
||||
//! [0]
|
||||
moreButton->setAutoDefault(false);
|
||||
|
||||
//! [1]
|
||||
|
||||
//! [2]
|
||||
extension = new QWidget;
|
||||
|
||||
wholeWordsCheckBox = new QCheckBox(tr("&Whole words"));
|
||||
backwardCheckBox = new QCheckBox(tr("Search &backward"));
|
||||
searchSelectionCheckBox = new QCheckBox(tr("Search se&lection"));
|
||||
//! [2]
|
||||
|
||||
//! [3]
|
||||
buttonBox = new QDialogButtonBox(Qt::Vertical);
|
||||
buttonBox->addButton(findButton, QDialogButtonBox::ActionRole);
|
||||
buttonBox->addButton(moreButton, QDialogButtonBox::ActionRole);
|
||||
|
||||
connect(moreButton, &QAbstractButton::toggled, extension, &QWidget::setVisible);
|
||||
|
||||
QVBoxLayout *extensionLayout = new QVBoxLayout;
|
||||
extensionLayout->setContentsMargins(QMargins());
|
||||
extensionLayout->addWidget(wholeWordsCheckBox);
|
||||
extensionLayout->addWidget(backwardCheckBox);
|
||||
extensionLayout->addWidget(searchSelectionCheckBox);
|
||||
extension->setLayout(extensionLayout);
|
||||
//! [3]
|
||||
|
||||
//! [4]
|
||||
QHBoxLayout *topLeftLayout = new QHBoxLayout;
|
||||
topLeftLayout->addWidget(label);
|
||||
topLeftLayout->addWidget(lineEdit);
|
||||
|
||||
QVBoxLayout *leftLayout = new QVBoxLayout;
|
||||
leftLayout->addLayout(topLeftLayout);
|
||||
leftLayout->addWidget(caseCheckBox);
|
||||
leftLayout->addWidget(fromStartCheckBox);
|
||||
|
||||
QGridLayout *mainLayout = new QGridLayout;
|
||||
mainLayout->setSizeConstraint(QLayout::SetFixedSize);
|
||||
mainLayout->addLayout(leftLayout, 0, 0);
|
||||
mainLayout->addWidget(buttonBox, 0, 1);
|
||||
mainLayout->addWidget(extension, 1, 0, 1, 2);
|
||||
mainLayout->setRowStretch(2, 1);
|
||||
|
||||
setLayout(mainLayout);
|
||||
|
||||
setWindowTitle(tr("Extension"));
|
||||
//! [4] //! [5]
|
||||
extension->hide();
|
||||
}
|
||||
//! [5]
|
41
tests/manual/examples/widgets/dialogs/extension/finddialog.h
Normal file
@ -0,0 +1,41 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#ifndef FINDDIALOG_H
|
||||
#define FINDDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QCheckBox;
|
||||
class QDialogButtonBox;
|
||||
class QGroupBox;
|
||||
class QLabel;
|
||||
class QLineEdit;
|
||||
class QPushButton;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
//! [0]
|
||||
class FindDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
FindDialog(QWidget *parent = nullptr);
|
||||
|
||||
private:
|
||||
QLabel *label;
|
||||
QLineEdit *lineEdit;
|
||||
QCheckBox *caseCheckBox;
|
||||
QCheckBox *fromStartCheckBox;
|
||||
QCheckBox *wholeWordsCheckBox;
|
||||
QCheckBox *searchSelectionCheckBox;
|
||||
QCheckBox *backwardCheckBox;
|
||||
QDialogButtonBox *buttonBox;
|
||||
QPushButton *findButton;
|
||||
QPushButton *moreButton;
|
||||
QWidget *extension;
|
||||
};
|
||||
//! [0]
|
||||
|
||||
#endif
|
16
tests/manual/examples/widgets/dialogs/extension/main.cpp
Normal file
@ -0,0 +1,16 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
#include "finddialog.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
FindDialog dialog;
|
||||
|
||||
dialog.show();
|
||||
|
||||
return app.exec();
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(fridgemagnets LANGUAGES CXX)
|
||||
|
||||
if(NOT DEFINED INSTALL_EXAMPLESDIR)
|
||||
set(INSTALL_EXAMPLESDIR "examples")
|
||||
endif()
|
||||
|
||||
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/widgets/draganddrop/fridgemagnets")
|
||||
|
||||
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
|
||||
|
||||
qt_standard_project_setup()
|
||||
|
||||
qt_add_executable(fridgemagnets
|
||||
draglabel.cpp draglabel.h
|
||||
dragwidget.cpp dragwidget.h
|
||||
main.cpp
|
||||
)
|
||||
|
||||
set_target_properties(fridgemagnets PROPERTIES
|
||||
WIN32_EXECUTABLE TRUE
|
||||
MACOSX_BUNDLE TRUE
|
||||
)
|
||||
|
||||
target_link_libraries(fridgemagnets PRIVATE
|
||||
Qt6::Core
|
||||
Qt6::Gui
|
||||
Qt6::Widgets
|
||||
)
|
||||
|
||||
# Resources:
|
||||
set(fridgemagnets_resource_files
|
||||
"words.txt"
|
||||
)
|
||||
|
||||
qt_add_resources(fridgemagnets "fridgemagnets"
|
||||
PREFIX
|
||||
"/dictionary"
|
||||
FILES
|
||||
${fridgemagnets_resource_files}
|
||||
)
|
||||
|
||||
install(TARGETS fridgemagnets
|
||||
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
)
|
@ -0,0 +1,51 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include "draglabel.h"
|
||||
|
||||
#include <QtWidgets>
|
||||
|
||||
//! [0]
|
||||
DragLabel::DragLabel(const QString &text, QWidget *parent)
|
||||
: QLabel(parent)
|
||||
{
|
||||
QFontMetrics metric(font());
|
||||
QSize size = metric.size(Qt::TextSingleLine, text);
|
||||
|
||||
QImage image(size.width() + 12, size.height() + 12, QImage::Format_ARGB32_Premultiplied);
|
||||
image.fill(qRgba(0, 0, 0, 0));
|
||||
|
||||
QFont font;
|
||||
font.setStyleStrategy(QFont::ForceOutline);
|
||||
//! [0]
|
||||
|
||||
//! [1]
|
||||
QLinearGradient gradient(0, 0, 0, image.height()-1);
|
||||
gradient.setColorAt(0.0, Qt::white);
|
||||
gradient.setColorAt(0.2, QColor(200, 200, 255));
|
||||
gradient.setColorAt(0.8, QColor(200, 200, 255));
|
||||
gradient.setColorAt(1.0, QColor(127, 127, 200));
|
||||
|
||||
QPainter painter;
|
||||
painter.begin(&image);
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
painter.setBrush(gradient);
|
||||
painter.drawRoundedRect(QRectF(0.5, 0.5, image.width()-1, image.height()-1),
|
||||
25, 25, Qt::RelativeSize);
|
||||
|
||||
painter.setFont(font);
|
||||
painter.setBrush(Qt::black);
|
||||
painter.drawText(QRect(QPoint(6, 6), size), Qt::AlignCenter, text);
|
||||
painter.end();
|
||||
//! [1]
|
||||
|
||||
//! [2]
|
||||
setPixmap(QPixmap::fromImage(image));
|
||||
m_labelText = text;
|
||||
}
|
||||
//! [2]
|
||||
|
||||
QString DragLabel::labelText() const
|
||||
{
|
||||
return m_labelText;
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#ifndef DRAGLABEL_H
|
||||
#define DRAGLABEL_H
|
||||
|
||||
#include <QLabel>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QDragEnterEvent;
|
||||
class QDragMoveEvent;
|
||||
class QFrame;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
//! [0]
|
||||
class DragLabel : public QLabel
|
||||
{
|
||||
public:
|
||||
DragLabel(const QString &text, QWidget *parent);
|
||||
QString labelText() const;
|
||||
|
||||
private:
|
||||
QString m_labelText;
|
||||
};
|
||||
//! [0]
|
||||
|
||||
#endif // DRAGLABEL_H
|
@ -0,0 +1,176 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include "draglabel.h"
|
||||
#include "dragwidget.h"
|
||||
|
||||
#include <QtWidgets>
|
||||
|
||||
static inline QString fridgetMagnetsMimeType() { return QStringLiteral("application/x-fridgemagnet"); }
|
||||
|
||||
//! [0]
|
||||
DragWidget::DragWidget(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
QFile dictionaryFile(QStringLiteral(":/dictionary/words.txt"));
|
||||
dictionaryFile.open(QFile::ReadOnly);
|
||||
QTextStream inputStream(&dictionaryFile);
|
||||
//! [0]
|
||||
|
||||
//! [1]
|
||||
int x = 5;
|
||||
int y = 5;
|
||||
|
||||
while (!inputStream.atEnd()) {
|
||||
QString word;
|
||||
inputStream >> word;
|
||||
if (!word.isEmpty()) {
|
||||
DragLabel *wordLabel = new DragLabel(word, this);
|
||||
wordLabel->move(x, y);
|
||||
wordLabel->show();
|
||||
wordLabel->setAttribute(Qt::WA_DeleteOnClose);
|
||||
x += wordLabel->width() + 2;
|
||||
if (x >= 245) {
|
||||
x = 5;
|
||||
y += wordLabel->height() + 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
//! [1]
|
||||
|
||||
//! [2]
|
||||
QPalette newPalette = palette();
|
||||
newPalette.setColor(QPalette::Window, Qt::white);
|
||||
setPalette(newPalette);
|
||||
|
||||
setMinimumSize(400, qMax(200, y));
|
||||
setWindowTitle(tr("Fridge Magnets"));
|
||||
//! [2] //! [3]
|
||||
setAcceptDrops(true);
|
||||
}
|
||||
//! [3]
|
||||
|
||||
//! [4]
|
||||
void DragWidget::dragEnterEvent(QDragEnterEvent *event)
|
||||
{
|
||||
//! [4] //! [5]
|
||||
if (event->mimeData()->hasFormat(fridgetMagnetsMimeType())) {
|
||||
if (children().contains(event->source())) {
|
||||
event->setDropAction(Qt::MoveAction);
|
||||
event->accept();
|
||||
} else {
|
||||
event->acceptProposedAction();
|
||||
//! [5] //! [6]
|
||||
}
|
||||
//! [6] //! [7]
|
||||
} else if (event->mimeData()->hasText()) {
|
||||
event->acceptProposedAction();
|
||||
} else {
|
||||
event->ignore();
|
||||
}
|
||||
}
|
||||
//! [7]
|
||||
|
||||
//! [8]
|
||||
void DragWidget::dragMoveEvent(QDragMoveEvent *event)
|
||||
{
|
||||
if (event->mimeData()->hasFormat(fridgetMagnetsMimeType())) {
|
||||
if (children().contains(event->source())) {
|
||||
event->setDropAction(Qt::MoveAction);
|
||||
event->accept();
|
||||
} else {
|
||||
event->acceptProposedAction();
|
||||
}
|
||||
} else if (event->mimeData()->hasText()) {
|
||||
event->acceptProposedAction();
|
||||
} else {
|
||||
event->ignore();
|
||||
}
|
||||
}
|
||||
//! [8]
|
||||
|
||||
//! [9]
|
||||
void DragWidget::dropEvent(QDropEvent *event)
|
||||
{
|
||||
if (event->mimeData()->hasFormat(fridgetMagnetsMimeType())) {
|
||||
const QMimeData *mime = event->mimeData();
|
||||
//! [9] //! [10]
|
||||
QByteArray itemData = mime->data(fridgetMagnetsMimeType());
|
||||
QDataStream dataStream(&itemData, QIODevice::ReadOnly);
|
||||
|
||||
QString text;
|
||||
QPoint offset;
|
||||
dataStream >> text >> offset;
|
||||
//! [10]
|
||||
//! [11]
|
||||
DragLabel *newLabel = new DragLabel(text, this);
|
||||
newLabel->move(event->position().toPoint() - offset);
|
||||
newLabel->show();
|
||||
newLabel->setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
if (event->source() == this) {
|
||||
event->setDropAction(Qt::MoveAction);
|
||||
event->accept();
|
||||
} else {
|
||||
event->acceptProposedAction();
|
||||
}
|
||||
//! [11] //! [12]
|
||||
} else if (event->mimeData()->hasText()) {
|
||||
QStringList pieces = event->mimeData()->text().split(
|
||||
QRegularExpression(QStringLiteral("\\s+")), Qt::SkipEmptyParts);
|
||||
QPoint position = event->position().toPoint();
|
||||
|
||||
for (const QString &piece : pieces) {
|
||||
DragLabel *newLabel = new DragLabel(piece, this);
|
||||
newLabel->move(position);
|
||||
newLabel->show();
|
||||
newLabel->setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
position += QPoint(newLabel->width(), 0);
|
||||
}
|
||||
|
||||
event->acceptProposedAction();
|
||||
} else {
|
||||
event->ignore();
|
||||
}
|
||||
}
|
||||
//! [12]
|
||||
|
||||
//! [13]
|
||||
void DragWidget::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
//! [13]
|
||||
//! [14]
|
||||
DragLabel *child = static_cast<DragLabel*>(childAt(event->position().toPoint()));
|
||||
if (!child)
|
||||
return;
|
||||
|
||||
QPoint hotSpot = event->position().toPoint() - child->pos();
|
||||
|
||||
QByteArray itemData;
|
||||
QDataStream dataStream(&itemData, QIODevice::WriteOnly);
|
||||
dataStream << child->labelText() << QPoint(hotSpot);
|
||||
//! [14]
|
||||
|
||||
//! [15]
|
||||
QMimeData *mimeData = new QMimeData;
|
||||
mimeData->setData(fridgetMagnetsMimeType(), itemData);
|
||||
mimeData->setText(child->labelText());
|
||||
//! [15]
|
||||
|
||||
//! [16]
|
||||
QDrag *drag = new QDrag(this);
|
||||
drag->setMimeData(mimeData);
|
||||
drag->setPixmap(child->pixmap());
|
||||
drag->setHotSpot(hotSpot);
|
||||
|
||||
child->hide();
|
||||
//! [16]
|
||||
|
||||
//! [17]
|
||||
if (drag->exec(Qt::MoveAction | Qt::CopyAction, Qt::CopyAction) == Qt::MoveAction)
|
||||
child->close();
|
||||
else
|
||||
child->show();
|
||||
}
|
||||
//! [17]
|
@ -0,0 +1,28 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#ifndef DRAGWIDGET_H
|
||||
#define DRAGWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QDragEnterEvent;
|
||||
class QDropEvent;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
//! [0]
|
||||
class DragWidget : public QWidget
|
||||
{
|
||||
public:
|
||||
explicit DragWidget(QWidget *parent = nullptr);
|
||||
|
||||
protected:
|
||||
void dragEnterEvent(QDragEnterEvent *event) override;
|
||||
void dragMoveEvent(QDragMoveEvent *event) override;
|
||||
void dropEvent(QDropEvent *event) override;
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
};
|
||||
//! [0]
|
||||
|
||||
#endif // DRAGWIDGET_H
|
@ -0,0 +1,12 @@
|
||||
QT += widgets
|
||||
|
||||
HEADERS = draglabel.h \
|
||||
dragwidget.h
|
||||
RESOURCES = fridgemagnets.qrc
|
||||
SOURCES = draglabel.cpp \
|
||||
dragwidget.cpp \
|
||||
main.cpp
|
||||
|
||||
# install
|
||||
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/draganddrop/fridgemagnets
|
||||
INSTALLS += target
|
@ -0,0 +1,5 @@
|
||||
<!DOCTYPE RCC><RCC version="1.0">
|
||||
<qresource prefix="/dictionary">
|
||||
<file>words.txt</file>
|
||||
</qresource>
|
||||
</RCC>
|
@ -0,0 +1,23 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
#include "dragwidget.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
#ifdef QT_KEYPAD_NAVIGATION
|
||||
QApplication::setNavigationMode(Qt::NavigationModeCursorAuto);
|
||||
#endif
|
||||
DragWidget window;
|
||||
|
||||
bool smallScreen = QApplication::arguments().contains(QStringLiteral("-small-screen"));
|
||||
if (smallScreen)
|
||||
window.showFullScreen();
|
||||
else
|
||||
window.show();
|
||||
|
||||
return app.exec();
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
Colorless
|
||||
green
|
||||
ideas
|
||||
sleep
|
||||
furiously
|
||||
A
|
||||
colorless
|
||||
green
|
||||
idea
|
||||
is
|
||||
a
|
||||
new
|
||||
untried
|
||||
idea
|
||||
that
|
||||
is
|
||||
without
|
||||
vividness
|
||||
dull
|
||||
and
|
||||
unexciting
|
||||
To
|
||||
sleep
|
||||
furiously
|
||||
may
|
||||
seem
|
||||
a
|
||||
puzzling
|
||||
turn
|
||||
of
|
||||
phrase
|
||||
but
|
||||
the
|
||||
mind
|
||||
in
|
||||
sleep
|
||||
often
|
||||
indeed
|
||||
moves
|
||||
furiously
|
||||
with
|
||||
ideas
|
||||
and
|
||||
images
|
||||
flickering
|
||||
in
|
||||
and
|
||||
out
|
@ -0,0 +1,51 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(puzzle LANGUAGES CXX)
|
||||
|
||||
if(NOT DEFINED INSTALL_EXAMPLESDIR)
|
||||
set(INSTALL_EXAMPLESDIR "examples")
|
||||
endif()
|
||||
|
||||
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/widgets/draganddrop_puzzle")
|
||||
|
||||
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
|
||||
|
||||
qt_standard_project_setup()
|
||||
|
||||
qt_add_executable(draganddrop_puzzle
|
||||
main.cpp
|
||||
mainwindow.cpp mainwindow.h
|
||||
pieceslist.cpp pieceslist.h
|
||||
puzzlewidget.cpp puzzlewidget.h
|
||||
)
|
||||
|
||||
set_target_properties(draganddrop_puzzle PROPERTIES
|
||||
WIN32_EXECUTABLE TRUE
|
||||
MACOSX_BUNDLE TRUE
|
||||
)
|
||||
|
||||
target_link_libraries(draganddrop_puzzle PRIVATE
|
||||
Qt6::Core
|
||||
Qt6::Gui
|
||||
Qt6::Widgets
|
||||
)
|
||||
|
||||
# Resources:
|
||||
set(puzzle_resource_files
|
||||
"example.jpg"
|
||||
)
|
||||
|
||||
qt_add_resources(draganddrop_puzzle "puzzle"
|
||||
PREFIX
|
||||
"/images"
|
||||
FILES
|
||||
${puzzle_resource_files}
|
||||
)
|
||||
|
||||
install(TARGETS draganddrop_puzzle
|
||||
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
)
|
BIN
tests/manual/examples/widgets/draganddrop/puzzle/example.jpg
Normal file
After Width: | Height: | Size: 42 KiB |
15
tests/manual/examples/widgets/draganddrop/puzzle/main.cpp
Normal file
@ -0,0 +1,15 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include "mainwindow.h"
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
MainWindow window;
|
||||
window.loadImage(QStringLiteral(":/images/example.jpg"));
|
||||
window.show();
|
||||
return app.exec();
|
||||
}
|
118
tests/manual/examples/widgets/draganddrop/puzzle/mainwindow.cpp
Normal file
@ -0,0 +1,118 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include "mainwindow.h"
|
||||
#include "pieceslist.h"
|
||||
#include "puzzlewidget.h"
|
||||
|
||||
#include <QtWidgets>
|
||||
#include <stdlib.h>
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent)
|
||||
: QMainWindow(parent)
|
||||
{
|
||||
setupMenus();
|
||||
setupWidgets();
|
||||
|
||||
setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
|
||||
setWindowTitle(tr("Puzzle"));
|
||||
}
|
||||
|
||||
void MainWindow::openImage()
|
||||
{
|
||||
const QString directory =
|
||||
QStandardPaths::standardLocations(QStandardPaths::PicturesLocation).value(0, QDir::homePath());
|
||||
QFileDialog dialog(this, tr("Open Image"), directory);
|
||||
dialog.setAcceptMode(QFileDialog::AcceptOpen);
|
||||
dialog.setFileMode(QFileDialog::ExistingFile);
|
||||
QStringList mimeTypeFilters;
|
||||
for (const QByteArray &mimeTypeName : QImageReader::supportedMimeTypes())
|
||||
mimeTypeFilters.append(mimeTypeName);
|
||||
mimeTypeFilters.sort();
|
||||
dialog.setMimeTypeFilters(mimeTypeFilters);
|
||||
dialog.selectMimeTypeFilter("image/jpeg");
|
||||
if (dialog.exec() == QDialog::Accepted)
|
||||
loadImage(dialog.selectedFiles().constFirst());
|
||||
}
|
||||
|
||||
void MainWindow::loadImage(const QString &fileName)
|
||||
{
|
||||
QPixmap newImage;
|
||||
if (!newImage.load(fileName)) {
|
||||
QMessageBox::warning(this, tr("Open Image"),
|
||||
tr("The image file could not be loaded."),
|
||||
QMessageBox::Close);
|
||||
return;
|
||||
}
|
||||
puzzleImage = newImage;
|
||||
setupPuzzle();
|
||||
}
|
||||
|
||||
void MainWindow::setCompleted()
|
||||
{
|
||||
QMessageBox::information(this, tr("Puzzle Completed"),
|
||||
tr("Congratulations! You have completed the puzzle!\n"
|
||||
"Click OK to start again."),
|
||||
QMessageBox::Ok);
|
||||
|
||||
setupPuzzle();
|
||||
}
|
||||
|
||||
void MainWindow::setupPuzzle()
|
||||
{
|
||||
int size = qMin(puzzleImage.width(), puzzleImage.height());
|
||||
puzzleImage = puzzleImage.copy((puzzleImage.width() - size) / 2,
|
||||
(puzzleImage.height() - size) / 2, size, size).scaled(puzzleWidget->width(),
|
||||
puzzleWidget->height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
||||
|
||||
piecesList->clear();
|
||||
|
||||
for (int y = 0; y < 5; ++y) {
|
||||
for (int x = 0; x < 5; ++x) {
|
||||
int pieceSize = puzzleWidget->pieceSize();
|
||||
QPixmap pieceImage = puzzleImage.copy(x * pieceSize, y * pieceSize, pieceSize, pieceSize);
|
||||
piecesList->addPiece(pieceImage, QPoint(x, y));
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < piecesList->count(); ++i) {
|
||||
if (QRandomGenerator::global()->bounded(2) == 1) {
|
||||
QListWidgetItem *item = piecesList->takeItem(i);
|
||||
piecesList->insertItem(0, item);
|
||||
}
|
||||
}
|
||||
|
||||
puzzleWidget->clear();
|
||||
}
|
||||
|
||||
void MainWindow::setupMenus()
|
||||
{
|
||||
QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
|
||||
|
||||
QAction *openAction = fileMenu->addAction(tr("&Open..."), this, &MainWindow::openImage);
|
||||
openAction->setShortcuts(QKeySequence::Open);
|
||||
|
||||
QAction *exitAction = fileMenu->addAction(tr("E&xit"), qApp, &QCoreApplication::quit);
|
||||
exitAction->setShortcuts(QKeySequence::Quit);
|
||||
|
||||
QMenu *gameMenu = menuBar()->addMenu(tr("&Game"));
|
||||
|
||||
gameMenu->addAction(tr("&Restart"), this, &MainWindow::setupPuzzle);
|
||||
}
|
||||
|
||||
void MainWindow::setupWidgets()
|
||||
{
|
||||
QFrame *frame = new QFrame;
|
||||
QHBoxLayout *frameLayout = new QHBoxLayout(frame);
|
||||
puzzleWidget = new PuzzleWidget(400);
|
||||
|
||||
piecesList = new PiecesList(puzzleWidget->pieceSize(), this);
|
||||
|
||||
|
||||
connect(puzzleWidget, &PuzzleWidget::puzzleCompleted,
|
||||
this, &MainWindow::setCompleted, Qt::QueuedConnection);
|
||||
|
||||
frameLayout->addWidget(piecesList);
|
||||
frameLayout->addWidget(puzzleWidget);
|
||||
setCentralWidget(frame);
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#ifndef MAINWINDOW_H
|
||||
#define MAINWINDOW_H
|
||||
|
||||
#include <QMainWindow>
|
||||
#include <QPixmap>
|
||||
|
||||
class PiecesList;
|
||||
class PuzzleWidget;
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QListWidgetItem;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MainWindow(QWidget *parent = nullptr);
|
||||
void loadImage(const QString &path);
|
||||
|
||||
public slots:
|
||||
void openImage();
|
||||
void setupPuzzle();
|
||||
|
||||
private slots:
|
||||
void setCompleted();
|
||||
|
||||
private:
|
||||
void setupMenus();
|
||||
void setupWidgets();
|
||||
|
||||
QPixmap puzzleImage;
|
||||
PiecesList *piecesList;
|
||||
PuzzleWidget *puzzleWidget;
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
@ -0,0 +1,87 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include "pieceslist.h"
|
||||
|
||||
#include <QDrag>
|
||||
#include <QDragEnterEvent>
|
||||
#include <QMimeData>
|
||||
|
||||
PiecesList::PiecesList(int pieceSize, QWidget *parent)
|
||||
: QListWidget(parent), m_PieceSize(pieceSize)
|
||||
{
|
||||
setDragEnabled(true);
|
||||
setViewMode(QListView::IconMode);
|
||||
setIconSize(QSize(m_PieceSize, m_PieceSize));
|
||||
setSpacing(10);
|
||||
setAcceptDrops(true);
|
||||
setDropIndicatorShown(true);
|
||||
}
|
||||
|
||||
void PiecesList::dragEnterEvent(QDragEnterEvent *event)
|
||||
{
|
||||
if (event->mimeData()->hasFormat(PiecesList::puzzleMimeType()))
|
||||
event->accept();
|
||||
else
|
||||
event->ignore();
|
||||
}
|
||||
|
||||
void PiecesList::dragMoveEvent(QDragMoveEvent *event)
|
||||
{
|
||||
if (event->mimeData()->hasFormat(PiecesList::puzzleMimeType())) {
|
||||
event->setDropAction(Qt::MoveAction);
|
||||
event->accept();
|
||||
} else {
|
||||
event->ignore();
|
||||
}
|
||||
}
|
||||
|
||||
void PiecesList::dropEvent(QDropEvent *event)
|
||||
{
|
||||
if (event->mimeData()->hasFormat(PiecesList::puzzleMimeType())) {
|
||||
QByteArray pieceData = event->mimeData()->data(PiecesList::puzzleMimeType());
|
||||
QDataStream dataStream(&pieceData, QIODevice::ReadOnly);
|
||||
QPixmap pixmap;
|
||||
QPoint location;
|
||||
dataStream >> pixmap >> location;
|
||||
|
||||
addPiece(pixmap, location);
|
||||
|
||||
event->setDropAction(Qt::MoveAction);
|
||||
event->accept();
|
||||
} else {
|
||||
event->ignore();
|
||||
}
|
||||
}
|
||||
|
||||
void PiecesList::addPiece(const QPixmap &pixmap, const QPoint &location)
|
||||
{
|
||||
QListWidgetItem *pieceItem = new QListWidgetItem(this);
|
||||
pieceItem->setIcon(QIcon(pixmap));
|
||||
pieceItem->setData(Qt::UserRole, QVariant(pixmap));
|
||||
pieceItem->setData(Qt::UserRole+1, location);
|
||||
pieceItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled);
|
||||
}
|
||||
|
||||
void PiecesList::startDrag(Qt::DropActions /*supportedActions*/)
|
||||
{
|
||||
QListWidgetItem *item = currentItem();
|
||||
|
||||
QByteArray itemData;
|
||||
QDataStream dataStream(&itemData, QIODevice::WriteOnly);
|
||||
QPixmap pixmap = qvariant_cast<QPixmap>(item->data(Qt::UserRole));
|
||||
QPoint location = item->data(Qt::UserRole+1).toPoint();
|
||||
|
||||
dataStream << pixmap << location;
|
||||
|
||||
QMimeData *mimeData = new QMimeData;
|
||||
mimeData->setData(PiecesList::puzzleMimeType(), itemData);
|
||||
|
||||
QDrag *drag = new QDrag(this);
|
||||
drag->setMimeData(mimeData);
|
||||
drag->setHotSpot(QPoint(pixmap.width()/2, pixmap.height()/2));
|
||||
drag->setPixmap(pixmap);
|
||||
|
||||
if (drag->exec(Qt::MoveAction) == Qt::MoveAction)
|
||||
delete takeItem(row(item));
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#ifndef PIECESLIST_H
|
||||
#define PIECESLIST_H
|
||||
|
||||
#include <QListWidget>
|
||||
|
||||
class PiecesList : public QListWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit PiecesList(int pieceSize, QWidget *parent = nullptr);
|
||||
void addPiece(const QPixmap &pixmap, const QPoint &location);
|
||||
|
||||
static QString puzzleMimeType() { return QStringLiteral("image/x-puzzle-piece"); }
|
||||
|
||||
protected:
|
||||
void dragEnterEvent(QDragEnterEvent *event) override;
|
||||
void dragMoveEvent(QDragMoveEvent *event) override;
|
||||
void dropEvent(QDropEvent *event) override;
|
||||
void startDrag(Qt::DropActions supportedActions) override;
|
||||
|
||||
int m_PieceSize;
|
||||
};
|
||||
|
||||
#endif // PIECESLIST_H
|
17
tests/manual/examples/widgets/draganddrop/puzzle/puzzle.pro
Normal file
@ -0,0 +1,17 @@
|
||||
QT += widgets
|
||||
requires(qtConfig(filedialog))
|
||||
|
||||
HEADERS = mainwindow.h \
|
||||
pieceslist.h \
|
||||
puzzlewidget.h
|
||||
RESOURCES = puzzle.qrc
|
||||
SOURCES = main.cpp \
|
||||
mainwindow.cpp \
|
||||
pieceslist.cpp \
|
||||
puzzlewidget.cpp
|
||||
|
||||
QMAKE_PROJECT_NAME = dndpuzzle
|
||||
|
||||
# install
|
||||
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/draganddrop/puzzle
|
||||
INSTALLS += target
|
@ -0,0 +1,5 @@
|
||||
<!DOCTYPE RCC><RCC version="1.0">
|
||||
<qresource prefix="/images">
|
||||
<file>example.jpg</file>
|
||||
</qresource>
|
||||
</RCC>
|
@ -0,0 +1,167 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include "puzzlewidget.h"
|
||||
#include "pieceslist.h"
|
||||
|
||||
#include <QDrag>
|
||||
#include <QDragEnterEvent>
|
||||
#include <QMimeData>
|
||||
#include <QPainter>
|
||||
|
||||
PuzzleWidget::PuzzleWidget(int imageSize, QWidget *parent)
|
||||
: QWidget(parent), m_ImageSize(imageSize)
|
||||
{
|
||||
setAcceptDrops(true);
|
||||
setMinimumSize(m_ImageSize, m_ImageSize);
|
||||
setMaximumSize(m_ImageSize, m_ImageSize);
|
||||
}
|
||||
|
||||
void PuzzleWidget::clear()
|
||||
{
|
||||
pieces.clear();
|
||||
highlightedRect = QRect();
|
||||
inPlace = 0;
|
||||
update();
|
||||
}
|
||||
|
||||
void PuzzleWidget::dragEnterEvent(QDragEnterEvent *event)
|
||||
{
|
||||
if (event->mimeData()->hasFormat(PiecesList::puzzleMimeType()))
|
||||
event->accept();
|
||||
else
|
||||
event->ignore();
|
||||
}
|
||||
|
||||
void PuzzleWidget::dragLeaveEvent(QDragLeaveEvent *event)
|
||||
{
|
||||
QRect updateRect = highlightedRect;
|
||||
highlightedRect = QRect();
|
||||
update(updateRect);
|
||||
event->accept();
|
||||
}
|
||||
|
||||
void PuzzleWidget::dragMoveEvent(QDragMoveEvent *event)
|
||||
{
|
||||
QRect updateRect = highlightedRect.united(targetSquare(event->position().toPoint()));
|
||||
|
||||
if (event->mimeData()->hasFormat(PiecesList::puzzleMimeType())
|
||||
&& findPiece(targetSquare(event->position().toPoint())) == -1) {
|
||||
|
||||
highlightedRect = targetSquare(event->position().toPoint());
|
||||
event->setDropAction(Qt::MoveAction);
|
||||
event->accept();
|
||||
} else {
|
||||
highlightedRect = QRect();
|
||||
event->ignore();
|
||||
}
|
||||
|
||||
update(updateRect);
|
||||
}
|
||||
|
||||
void PuzzleWidget::dropEvent(QDropEvent *event)
|
||||
{
|
||||
if (event->mimeData()->hasFormat(PiecesList::puzzleMimeType())
|
||||
&& findPiece(targetSquare(event->position().toPoint())) == -1) {
|
||||
|
||||
QByteArray pieceData = event->mimeData()->data(PiecesList::puzzleMimeType());
|
||||
QDataStream dataStream(&pieceData, QIODevice::ReadOnly);
|
||||
Piece piece;
|
||||
piece.rect = targetSquare(event->position().toPoint());
|
||||
dataStream >> piece.pixmap >> piece.location;
|
||||
|
||||
pieces.append(piece);
|
||||
|
||||
highlightedRect = QRect();
|
||||
update(piece.rect);
|
||||
|
||||
event->setDropAction(Qt::MoveAction);
|
||||
event->accept();
|
||||
|
||||
if (piece.location == piece.rect.topLeft() / pieceSize()) {
|
||||
inPlace++;
|
||||
if (inPlace == 25)
|
||||
emit puzzleCompleted();
|
||||
}
|
||||
} else {
|
||||
highlightedRect = QRect();
|
||||
event->ignore();
|
||||
}
|
||||
}
|
||||
|
||||
int PuzzleWidget::findPiece(const QRect &pieceRect) const
|
||||
{
|
||||
for (int i = 0, size = pieces.size(); i < size; ++i) {
|
||||
if (pieces.at(i).rect == pieceRect)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void PuzzleWidget::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
QRect square = targetSquare(event->position().toPoint());
|
||||
const int found = findPiece(square);
|
||||
|
||||
if (found == -1)
|
||||
return;
|
||||
|
||||
Piece piece = pieces.takeAt(found);
|
||||
|
||||
if (piece.location == square.topLeft() / pieceSize())
|
||||
inPlace--;
|
||||
|
||||
update(square);
|
||||
|
||||
QByteArray itemData;
|
||||
QDataStream dataStream(&itemData, QIODevice::WriteOnly);
|
||||
|
||||
dataStream << piece.pixmap << piece.location;
|
||||
|
||||
QMimeData *mimeData = new QMimeData;
|
||||
mimeData->setData(PiecesList::puzzleMimeType(), itemData);
|
||||
|
||||
QDrag *drag = new QDrag(this);
|
||||
drag->setMimeData(mimeData);
|
||||
drag->setHotSpot(event->position().toPoint() - square.topLeft());
|
||||
drag->setPixmap(piece.pixmap);
|
||||
|
||||
if (drag->exec(Qt::MoveAction) != Qt::MoveAction) {
|
||||
pieces.insert(found, piece);
|
||||
update(targetSquare(event->position().toPoint()));
|
||||
|
||||
if (piece.location == square.topLeft() / pieceSize())
|
||||
inPlace++;
|
||||
}
|
||||
}
|
||||
|
||||
void PuzzleWidget::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
QPainter painter(this);
|
||||
painter.fillRect(event->rect(), Qt::white);
|
||||
|
||||
if (highlightedRect.isValid()) {
|
||||
painter.setBrush(QColor("#ffcccc"));
|
||||
painter.setPen(Qt::NoPen);
|
||||
painter.drawRect(highlightedRect.adjusted(0, 0, -1, -1));
|
||||
}
|
||||
|
||||
for (const Piece &piece : pieces)
|
||||
painter.drawPixmap(piece.rect, piece.pixmap);
|
||||
}
|
||||
|
||||
const QRect PuzzleWidget::targetSquare(const QPoint &position) const
|
||||
{
|
||||
QPoint topLeft = QPoint(position.x() / pieceSize(), position.y() / pieceSize()) * pieceSize();
|
||||
return QRect(topLeft, QSize(pieceSize(), pieceSize()));
|
||||
}
|
||||
|
||||
int PuzzleWidget::pieceSize() const
|
||||
{
|
||||
return m_ImageSize / 5;
|
||||
}
|
||||
|
||||
int PuzzleWidget::imageSize() const
|
||||
{
|
||||
return m_ImageSize;
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#ifndef PUZZLEWIDGET_H
|
||||
#define PUZZLEWIDGET_H
|
||||
|
||||
#include <QPoint>
|
||||
#include <QPixmap>
|
||||
#include <QList>
|
||||
#include <QWidget>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QDragEnterEvent;
|
||||
class QDropEvent;
|
||||
class QMouseEvent;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class PuzzleWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit PuzzleWidget(int imageSize, QWidget *parent = nullptr);
|
||||
void clear();
|
||||
|
||||
int pieceSize() const;
|
||||
int imageSize() const;
|
||||
|
||||
signals:
|
||||
void puzzleCompleted();
|
||||
|
||||
protected:
|
||||
void dragEnterEvent(QDragEnterEvent *event) override;
|
||||
void dragLeaveEvent(QDragLeaveEvent *event) override;
|
||||
void dragMoveEvent(QDragMoveEvent *event) override;
|
||||
void dropEvent(QDropEvent *event) override;
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
|
||||
private:
|
||||
struct Piece {
|
||||
QPixmap pixmap;
|
||||
QRect rect;
|
||||
QPoint location;
|
||||
};
|
||||
|
||||
int findPiece(const QRect &pieceRect) const;
|
||||
const QRect targetSquare(const QPoint &position) const;
|
||||
|
||||
QList<Piece> pieces;
|
||||
QRect highlightedRect;
|
||||
int inPlace;
|
||||
int m_ImageSize;
|
||||
};
|
||||
|
||||
#endif // PUZZLEWIDGET_H
|
@ -0,0 +1,49 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(fademessage LANGUAGES CXX)
|
||||
|
||||
if(NOT DEFINED INSTALL_EXAMPLESDIR)
|
||||
set(INSTALL_EXAMPLESDIR "examples")
|
||||
endif()
|
||||
|
||||
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/widgets/effects/fademessage")
|
||||
|
||||
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
|
||||
|
||||
qt_standard_project_setup()
|
||||
|
||||
qt_add_executable(fademessage
|
||||
fademessage.cpp fademessage.h
|
||||
main.cpp
|
||||
)
|
||||
|
||||
set_target_properties(fademessage PROPERTIES
|
||||
WIN32_EXECUTABLE TRUE
|
||||
MACOSX_BUNDLE TRUE
|
||||
)
|
||||
|
||||
target_link_libraries(fademessage PRIVATE
|
||||
Qt6::Core
|
||||
Qt6::Gui
|
||||
Qt6::Widgets
|
||||
)
|
||||
|
||||
# Resources:
|
||||
set(fademessage_resource_files
|
||||
"background.jpg"
|
||||
)
|
||||
|
||||
qt_add_resources(fademessage "fademessage"
|
||||
PREFIX
|
||||
"/"
|
||||
FILES
|
||||
${fademessage_resource_files}
|
||||
)
|
||||
|
||||
install(TARGETS fademessage
|
||||
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
)
|
2
tests/manual/examples/widgets/effects/fademessage/README
Normal file
@ -0,0 +1,2 @@
|
||||
The background is taken from a public domain photo at:
|
||||
http://www.photos8.com/view/windows_problem_blue-800x600.html
|
BIN
tests/manual/examples/widgets/effects/fademessage/background.jpg
Normal file
After Width: | Height: | Size: 155 KiB |
@ -0,0 +1,91 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include "fademessage.h"
|
||||
|
||||
#include <QtWidgets>
|
||||
|
||||
FadeMessage::FadeMessage(QWidget *parent): QGraphicsView(parent)
|
||||
{
|
||||
setScene(&m_scene);
|
||||
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
|
||||
setupScene();
|
||||
|
||||
m_animation = new QPropertyAnimation(m_effect, "strength", this);
|
||||
m_animation->setDuration(500);
|
||||
m_animation->setEasingCurve(QEasingCurve::InOutSine);
|
||||
m_animation->setStartValue(0);
|
||||
m_animation->setEndValue(1);
|
||||
|
||||
setRenderHint(QPainter::Antialiasing, true);
|
||||
setFrameStyle(QFrame::NoFrame);
|
||||
}
|
||||
|
||||
void FadeMessage::togglePopup()
|
||||
{
|
||||
if (m_message->isVisible()) {
|
||||
m_message->setVisible(false);
|
||||
m_animation->setDirection(QAbstractAnimation::Backward);
|
||||
} else {
|
||||
m_message->setVisible(true);
|
||||
m_animation->setDirection(QAbstractAnimation::Forward);
|
||||
}
|
||||
m_animation->start();
|
||||
}
|
||||
|
||||
void FadeMessage::setupScene()
|
||||
{
|
||||
QGraphicsRectItem *parent = m_scene.addRect(0, 0, 800, 600);
|
||||
parent->setPen(Qt::NoPen);
|
||||
parent->setZValue(0);
|
||||
|
||||
QGraphicsPixmapItem *bg = m_scene.addPixmap(QPixmap(":/background.jpg"));
|
||||
bg->setParentItem(parent);
|
||||
bg->setZValue(-1);
|
||||
|
||||
for (int i = 1; i < 5; ++i)
|
||||
for (int j = 2; j < 5; ++j) {
|
||||
QGraphicsRectItem *item = m_scene.addRect(i * 50, (j - 1) * 50, 38, 38);
|
||||
item->setParentItem(parent);
|
||||
item->setZValue(1);
|
||||
int hue = 12 * (i * 5 + j);
|
||||
item->setBrush(QColor::fromHsv(hue, 128, 128));
|
||||
}
|
||||
|
||||
QFont font;
|
||||
font.setPointSize(font.pointSize() * 2);
|
||||
font.setBold(true);
|
||||
QFontMetrics fontMetrics(font);
|
||||
int fh = fontMetrics.height();
|
||||
|
||||
QString sceneText = "Qt Everywhere!";
|
||||
int sceneTextWidth = fontMetrics.horizontalAdvance(sceneText);
|
||||
|
||||
QGraphicsRectItem *block = m_scene.addRect(50, 300, sceneTextWidth, fh + 3);
|
||||
block->setPen(Qt::NoPen);
|
||||
block->setBrush(QColor(102, 153, 51));
|
||||
|
||||
QGraphicsTextItem *text = m_scene.addText(sceneText, font);
|
||||
text->setDefaultTextColor(Qt::white);
|
||||
text->setPos(50, 300);
|
||||
block->setZValue(2);
|
||||
block->hide();
|
||||
|
||||
text->setParentItem(block);
|
||||
m_message = block;
|
||||
|
||||
m_effect = new QGraphicsColorizeEffect;
|
||||
m_effect->setColor(QColor(122, 193, 66));
|
||||
m_effect->setStrength(0);
|
||||
m_effect->setEnabled(true);
|
||||
parent->setGraphicsEffect(m_effect);
|
||||
|
||||
QPushButton *press = new QPushButton;
|
||||
press->setText(tr("Press me"));
|
||||
connect(press, &QAbstractButton::clicked, this, &FadeMessage::togglePopup);
|
||||
m_scene.addWidget(press);
|
||||
|
||||
press->move(300, 500);
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#ifndef FADEMESSAGE_H
|
||||
#define FADEMESSAGE_H
|
||||
|
||||
#include <QGraphicsEffect>
|
||||
#include <QGraphicsView>
|
||||
#include <QPropertyAnimation>
|
||||
|
||||
#include "fademessage.h"
|
||||
|
||||
class FadeMessage: public QGraphicsView
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
FadeMessage(QWidget *parent = nullptr);
|
||||
|
||||
private:
|
||||
void setupScene();
|
||||
|
||||
private slots:
|
||||
void togglePopup();
|
||||
|
||||
private:
|
||||
QGraphicsScene m_scene;
|
||||
QGraphicsColorizeEffect *m_effect;
|
||||
QGraphicsItem *m_message;
|
||||
QPropertyAnimation *m_animation;
|
||||
};
|
||||
|
||||
#endif // FADEMESSAGE_H
|
@ -0,0 +1,9 @@
|
||||
QT += widgets
|
||||
|
||||
SOURCES += main.cpp fademessage.cpp
|
||||
HEADERS += fademessage.h
|
||||
RESOURCES += fademessage.qrc
|
||||
|
||||
# install
|
||||
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/effects/fademessage
|
||||
INSTALLS += target
|
@ -0,0 +1,5 @@
|
||||
<RCC>
|
||||
<qresource prefix="/" >
|
||||
<file>background.jpg</file>
|
||||
</qresource>
|
||||
</RCC>
|
18
tests/manual/examples/widgets/effects/fademessage/main.cpp
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
#include "fademessage.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
|
||||
FadeMessage widget;
|
||||
widget.setWindowTitle(QT_TRANSLATE_NOOP(QGraphicsView, "Popup Message with Effect"));
|
||||
widget.setFixedSize(400, 600);
|
||||
widget.show();
|
||||
|
||||
return app.exec();
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(embeddeddialogs LANGUAGES CXX)
|
||||
|
||||
if(NOT DEFINED INSTALL_EXAMPLESDIR)
|
||||
set(INSTALL_EXAMPLESDIR "examples")
|
||||
endif()
|
||||
|
||||
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/widgets/graphicsview/embeddeddialogs")
|
||||
|
||||
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
|
||||
|
||||
qt_standard_project_setup()
|
||||
|
||||
qt_add_executable(embeddeddialogs
|
||||
customproxy.cpp customproxy.h
|
||||
embeddeddialog.cpp embeddeddialog.h embeddeddialog.ui
|
||||
main.cpp
|
||||
)
|
||||
|
||||
set_target_properties(embeddeddialogs PROPERTIES
|
||||
WIN32_EXECUTABLE TRUE
|
||||
MACOSX_BUNDLE TRUE
|
||||
)
|
||||
|
||||
target_link_libraries(embeddeddialogs PRIVATE
|
||||
Qt6::Core
|
||||
Qt6::Gui
|
||||
Qt6::Widgets
|
||||
)
|
||||
|
||||
# Resources:
|
||||
set(embeddeddialogs_resource_files
|
||||
"No-Ones-Laughing-3.jpg"
|
||||
)
|
||||
|
||||
qt_add_resources(embeddeddialogs "embeddeddialogs"
|
||||
PREFIX
|
||||
"/"
|
||||
FILES
|
||||
${embeddeddialogs_resource_files}
|
||||
)
|
||||
|
||||
install(TARGETS embeddeddialogs
|
||||
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
)
|
After Width: | Height: | Size: 30 KiB |
@ -0,0 +1,133 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include "customproxy.h"
|
||||
|
||||
#include <QGraphicsScene>
|
||||
#include <QPainter>
|
||||
#include <QStyleOptionGraphicsItem>
|
||||
|
||||
CustomProxy::CustomProxy(QGraphicsItem *parent, Qt::WindowFlags wFlags)
|
||||
: QGraphicsProxyWidget(parent, wFlags), timeLine(new QTimeLine(250, this))
|
||||
{
|
||||
connect(timeLine, &QTimeLine::valueChanged,
|
||||
this, &CustomProxy::updateStep);
|
||||
connect(timeLine, &QTimeLine::stateChanged,
|
||||
this, &CustomProxy::stateChanged);
|
||||
}
|
||||
|
||||
QRectF CustomProxy::boundingRect() const
|
||||
{
|
||||
return QGraphicsProxyWidget::boundingRect().adjusted(0, 0, 10, 10);
|
||||
}
|
||||
|
||||
void CustomProxy::paintWindowFrame(QPainter *painter, const QStyleOptionGraphicsItem *option,
|
||||
QWidget *widget)
|
||||
{
|
||||
const QColor color(0, 0, 0, 64);
|
||||
|
||||
QRectF r = windowFrameRect();
|
||||
QRectF right(r.right(), r.top() + 10, 10, r.height() - 10);
|
||||
QRectF bottom(r.left() + 10, r.bottom(), r.width(), 10);
|
||||
bool intersectsRight = right.intersects(option->exposedRect);
|
||||
bool intersectsBottom = bottom.intersects(option->exposedRect);
|
||||
if (intersectsRight && intersectsBottom) {
|
||||
QPainterPath path;
|
||||
path.addRect(right);
|
||||
path.addRect(bottom);
|
||||
painter->setPen(Qt::NoPen);
|
||||
painter->setBrush(color);
|
||||
painter->drawPath(path);
|
||||
} else if (intersectsBottom) {
|
||||
painter->fillRect(bottom, color);
|
||||
} else if (intersectsRight) {
|
||||
painter->fillRect(right, color);
|
||||
}
|
||||
|
||||
QGraphicsProxyWidget::paintWindowFrame(painter, option, widget);
|
||||
}
|
||||
|
||||
void CustomProxy::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
|
||||
{
|
||||
QGraphicsProxyWidget::hoverEnterEvent(event);
|
||||
scene()->setActiveWindow(this);
|
||||
if (qFuzzyCompare(timeLine->currentValue(), 1))
|
||||
zoomIn();
|
||||
}
|
||||
|
||||
void CustomProxy::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
|
||||
{
|
||||
QGraphicsProxyWidget::hoverLeaveEvent(event);
|
||||
if (!popupShown
|
||||
&& (timeLine->direction() != QTimeLine::Backward || qFuzzyIsNull(timeLine->currentValue()))) {
|
||||
zoomOut();
|
||||
}
|
||||
}
|
||||
|
||||
bool CustomProxy::sceneEventFilter(QGraphicsItem *watched, QEvent *event)
|
||||
{
|
||||
if (watched->isWindow()
|
||||
&& (event->type() == QEvent::UngrabMouse || event->type() == QEvent::GrabMouse)) {
|
||||
popupShown = watched->isVisible();
|
||||
if (!popupShown && !isUnderMouse())
|
||||
zoomOut();
|
||||
}
|
||||
return QGraphicsProxyWidget::sceneEventFilter(watched, event);
|
||||
}
|
||||
|
||||
QVariant CustomProxy::itemChange(GraphicsItemChange change, const QVariant &value)
|
||||
{
|
||||
if (change == ItemChildAddedChange || change == ItemChildRemovedChange) {
|
||||
if (change == ItemChildAddedChange) {
|
||||
currentPopup = qvariant_cast<QGraphicsItem *>(value);
|
||||
currentPopup->setCacheMode(ItemCoordinateCache);
|
||||
if (scene())
|
||||
currentPopup->installSceneEventFilter(this);
|
||||
} else if (scene()) {
|
||||
currentPopup->removeSceneEventFilter(this);
|
||||
currentPopup = nullptr;
|
||||
}
|
||||
} else if (currentPopup && change == ItemSceneHasChanged) {
|
||||
currentPopup->installSceneEventFilter(this);
|
||||
}
|
||||
return QGraphicsProxyWidget::itemChange(change, value);
|
||||
}
|
||||
|
||||
void CustomProxy::updateStep(qreal step)
|
||||
{
|
||||
QRectF r = boundingRect();
|
||||
setTransform(QTransform()
|
||||
.translate(r.width() / 2, r.height() / 2)
|
||||
.rotate(step * 30, Qt::XAxis)
|
||||
.rotate(step * 10, Qt::YAxis)
|
||||
.rotate(step * 5, Qt::ZAxis)
|
||||
.scale(1 + 1.5 * step, 1 + 1.5 * step)
|
||||
.translate(-r.width() / 2, -r.height() / 2));
|
||||
}
|
||||
|
||||
void CustomProxy::stateChanged(QTimeLine::State state)
|
||||
{
|
||||
if (state == QTimeLine::Running) {
|
||||
if (timeLine->direction() == QTimeLine::Forward)
|
||||
setCacheMode(ItemCoordinateCache);
|
||||
} else if (state == QTimeLine::NotRunning) {
|
||||
if (timeLine->direction() == QTimeLine::Backward)
|
||||
setCacheMode(DeviceCoordinateCache);
|
||||
}
|
||||
}
|
||||
|
||||
void CustomProxy::zoomIn()
|
||||
{
|
||||
if (timeLine->direction() != QTimeLine::Forward)
|
||||
timeLine->setDirection(QTimeLine::Forward);
|
||||
if (timeLine->state() == QTimeLine::NotRunning)
|
||||
timeLine->start();
|
||||
}
|
||||
|
||||
void CustomProxy::zoomOut()
|
||||
{
|
||||
if (timeLine->direction() != QTimeLine::Backward)
|
||||
timeLine->setDirection(QTimeLine::Backward);
|
||||
if (timeLine->state() == QTimeLine::NotRunning)
|
||||
timeLine->start();
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#ifndef CUSTOMPROXY_H
|
||||
#define CUSTOMPROXY_H
|
||||
|
||||
#include <QTimeLine>
|
||||
#include <QGraphicsProxyWidget>
|
||||
|
||||
class CustomProxy : public QGraphicsProxyWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit CustomProxy(QGraphicsItem *parent = nullptr, Qt::WindowFlags wFlags = { });
|
||||
|
||||
QRectF boundingRect() const override;
|
||||
void paintWindowFrame(QPainter *painter, const QStyleOptionGraphicsItem *option,
|
||||
QWidget *widget) override;
|
||||
|
||||
protected:
|
||||
void hoverEnterEvent(QGraphicsSceneHoverEvent *event) override;
|
||||
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) override;
|
||||
bool sceneEventFilter(QGraphicsItem *watched, QEvent *event) override;
|
||||
QVariant itemChange(GraphicsItemChange change, const QVariant &value) override;
|
||||
|
||||
private slots:
|
||||
void updateStep(qreal step);
|
||||
void stateChanged(QTimeLine::State);
|
||||
void zoomIn();
|
||||
void zoomOut();
|
||||
|
||||
private:
|
||||
QTimeLine *timeLine;
|
||||
QGraphicsItem *currentPopup = nullptr;
|
||||
bool popupShown = false;
|
||||
};
|
||||
|
||||
#endif // CUSTOMPROXY_H
|
@ -0,0 +1,70 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include "embeddeddialog.h"
|
||||
#include "ui_embeddeddialog.h"
|
||||
|
||||
#include <QStyleFactory>
|
||||
|
||||
EmbeddedDialog::EmbeddedDialog(QWidget *parent)
|
||||
: QDialog(parent)
|
||||
, ui(new Ui::EmbeddedDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->layoutDirection->setCurrentIndex(layoutDirection() != Qt::LeftToRight);
|
||||
|
||||
const QStringList styleKeys = QStyleFactory::keys();
|
||||
for (const QString &styleName : styleKeys) {
|
||||
ui->style->addItem(styleName);
|
||||
if (style()->objectName().toLower() == styleName.toLower())
|
||||
ui->style->setCurrentIndex(ui->style->count() - 1);
|
||||
}
|
||||
|
||||
connect(ui->layoutDirection, &QComboBox::activated,
|
||||
this, &EmbeddedDialog::layoutDirectionChanged);
|
||||
connect(ui->spacing, &QSlider::valueChanged,
|
||||
this, &EmbeddedDialog::spacingChanged);
|
||||
connect(ui->fontComboBox, &QFontComboBox::currentFontChanged,
|
||||
this, &EmbeddedDialog::fontChanged);
|
||||
connect(ui->style, &QComboBox::textActivated,
|
||||
this, &EmbeddedDialog::styleChanged);
|
||||
}
|
||||
|
||||
EmbeddedDialog::~EmbeddedDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void EmbeddedDialog::layoutDirectionChanged(int index)
|
||||
{
|
||||
setLayoutDirection(index == 0 ? Qt::LeftToRight : Qt::RightToLeft);
|
||||
}
|
||||
|
||||
void EmbeddedDialog::spacingChanged(int spacing)
|
||||
{
|
||||
layout()->setSpacing(spacing);
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
void EmbeddedDialog::fontChanged(const QFont &font)
|
||||
{
|
||||
setFont(font);
|
||||
}
|
||||
|
||||
static void setStyleHelper(QWidget *widget, QStyle *style)
|
||||
{
|
||||
widget->setStyle(style);
|
||||
widget->setPalette(style->standardPalette());
|
||||
const QObjectList children = widget->children();
|
||||
for (QObject *child : children) {
|
||||
if (QWidget *childWidget = qobject_cast<QWidget *>(child))
|
||||
setStyleHelper(childWidget, style);
|
||||
}
|
||||
}
|
||||
|
||||
void EmbeddedDialog::styleChanged(const QString &styleName)
|
||||
{
|
||||
QStyle *style = QStyleFactory::create(styleName);
|
||||
if (style)
|
||||
setStyleHelper(this, style);
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#ifndef EMBEDDEDDIALOG_H
|
||||
#define EMBEDDEDDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
namespace Ui {
|
||||
class EmbeddedDialog;
|
||||
}
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class EmbeddedDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
EmbeddedDialog(QWidget *parent = nullptr);
|
||||
~EmbeddedDialog();
|
||||
|
||||
private slots:
|
||||
void layoutDirectionChanged(int index);
|
||||
void spacingChanged(int spacing);
|
||||
void fontChanged(const QFont &font);
|
||||
void styleChanged(const QString &styleName);
|
||||
|
||||
private:
|
||||
Ui::EmbeddedDialog *ui;
|
||||
};
|
||||
|
||||
#endif // EMBEDDEDDIALOG_H
|
@ -0,0 +1,88 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>EmbeddedDialog</class>
|
||||
<widget class="QDialog" name="EmbeddedDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>407</width>
|
||||
<height>134</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Embedded Dialog</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Layout Direction:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>layoutDirection</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="layoutDirection">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Left to Right</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Right to Left</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Select Font:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>fontComboBox</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QFontComboBox" name="fontComboBox"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Style:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>style</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="style"/>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Layout spacing:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>spacing</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QSlider" name="spacing">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
@ -0,0 +1,18 @@
|
||||
QT += widgets
|
||||
requires(qtConfig(fontcombobox))
|
||||
|
||||
SOURCES += main.cpp
|
||||
SOURCES += customproxy.cpp embeddeddialog.cpp
|
||||
HEADERS += customproxy.h embeddeddialog.h
|
||||
|
||||
FORMS += embeddeddialog.ui
|
||||
RESOURCES += embeddeddialogs.qrc
|
||||
|
||||
build_all:!build_pass {
|
||||
CONFIG -= build_all
|
||||
CONFIG += release
|
||||
}
|
||||
|
||||
# install
|
||||
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/graphicsview/embeddeddialogs
|
||||
INSTALLS += target
|
@ -0,0 +1,5 @@
|
||||
<RCC>
|
||||
<qresource>
|
||||
<file>No-Ones-Laughing-3.jpg</file>
|
||||
</qresource>
|
||||
</RCC>
|
@ -0,0 +1,42 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include "customproxy.h"
|
||||
#include "embeddeddialog.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QGraphicsScene>
|
||||
#include <QGraphicsView>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
|
||||
QGraphicsScene scene;
|
||||
scene.setStickyFocus(true);
|
||||
const int gridSize = 10;
|
||||
|
||||
for (int y = 0; y < gridSize; ++y) {
|
||||
for (int x = 0; x < gridSize; ++x) {
|
||||
CustomProxy *proxy = new CustomProxy(nullptr, Qt::Window);
|
||||
proxy->setWidget(new EmbeddedDialog);
|
||||
|
||||
QRectF rect = proxy->boundingRect();
|
||||
|
||||
proxy->setPos(x * rect.width() * 1.05, y * rect.height() * 1.05);
|
||||
proxy->setCacheMode(QGraphicsItem::DeviceCoordinateCache);
|
||||
|
||||
scene.addItem(proxy);
|
||||
}
|
||||
}
|
||||
scene.setSceneRect(scene.itemsBoundingRect());
|
||||
|
||||
QGraphicsView view(&scene);
|
||||
view.scale(0.5, 0.5);
|
||||
view.setRenderHints(view.renderHints() | QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
|
||||
view.setBackgroundBrush(QPixmap(":/No-Ones-Laughing-3.jpg"));
|
||||
view.setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);
|
||||
view.show();
|
||||
view.setWindowTitle("Embedded Dialogs Example");
|
||||
return app.exec();
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(flowlayout LANGUAGES CXX)
|
||||
|
||||
if(NOT DEFINED INSTALL_EXAMPLESDIR)
|
||||
set(INSTALL_EXAMPLESDIR "examples")
|
||||
endif()
|
||||
|
||||
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/widgets/graphicsview_flowlayout")
|
||||
|
||||
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
|
||||
|
||||
qt_standard_project_setup()
|
||||
|
||||
qt_add_executable(graphicsview_flowlayout
|
||||
flowlayout.cpp flowlayout.h
|
||||
main.cpp
|
||||
window.cpp window.h
|
||||
)
|
||||
|
||||
set_target_properties(graphicsview_flowlayout PROPERTIES
|
||||
WIN32_EXECUTABLE TRUE
|
||||
MACOSX_BUNDLE TRUE
|
||||
)
|
||||
|
||||
target_link_libraries(graphicsview_flowlayout PRIVATE
|
||||
Qt6::Core
|
||||
Qt6::Gui
|
||||
Qt6::Widgets
|
||||
)
|
||||
|
||||
install(TARGETS graphicsview_flowlayout
|
||||
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
)
|
@ -0,0 +1,170 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include "flowlayout.h"
|
||||
|
||||
#include <QtMath>
|
||||
|
||||
FlowLayout::FlowLayout(QGraphicsLayoutItem *parent) : QGraphicsLayout(parent)
|
||||
{
|
||||
QSizePolicy sp = sizePolicy();
|
||||
sp.setHeightForWidth(true);
|
||||
setSizePolicy(sp);
|
||||
}
|
||||
|
||||
void FlowLayout::insertItem(int index, QGraphicsLayoutItem *item)
|
||||
{
|
||||
item->setParentLayoutItem(this);
|
||||
if (index > m_items.count() || index < 0)
|
||||
index = m_items.count();
|
||||
m_items.insert(index, item);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
int FlowLayout::count() const
|
||||
{
|
||||
return m_items.count();
|
||||
}
|
||||
|
||||
QGraphicsLayoutItem *FlowLayout::itemAt(int index) const
|
||||
{
|
||||
return m_items.value(index);
|
||||
}
|
||||
|
||||
void FlowLayout::removeAt(int index)
|
||||
{
|
||||
m_items.removeAt(index);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
qreal FlowLayout::spacing(Qt::Orientation o) const
|
||||
{
|
||||
return m_spacing[int(o) - 1];
|
||||
}
|
||||
|
||||
void FlowLayout::setSpacing(Qt::Orientations o, qreal spacing)
|
||||
{
|
||||
if (o & Qt::Horizontal)
|
||||
m_spacing[0] = spacing;
|
||||
if (o & Qt::Vertical)
|
||||
m_spacing[1] = spacing;
|
||||
}
|
||||
|
||||
void FlowLayout::setGeometry(const QRectF &geom)
|
||||
{
|
||||
QGraphicsLayout::setGeometry(geom);
|
||||
doLayout(geom, true);
|
||||
}
|
||||
|
||||
qreal FlowLayout::doLayout(const QRectF &geom, bool applyNewGeometry) const
|
||||
{
|
||||
qreal left, top, right, bottom;
|
||||
getContentsMargins(&left, &top, &right, &bottom);
|
||||
const qreal maxw = geom.width() - left - right;
|
||||
|
||||
qreal x = 0;
|
||||
qreal y = 0;
|
||||
qreal maxRowHeight = 0;
|
||||
QSizeF pref;
|
||||
for (QGraphicsLayoutItem *item : m_items) {
|
||||
pref = item->effectiveSizeHint(Qt::PreferredSize);
|
||||
maxRowHeight = qMax(maxRowHeight, pref.height());
|
||||
|
||||
qreal next_x;
|
||||
next_x = x + pref.width();
|
||||
if (next_x > maxw) {
|
||||
if (qFuzzyIsNull(x)) {
|
||||
pref.setWidth(maxw);
|
||||
} else {
|
||||
x = 0;
|
||||
next_x = pref.width();
|
||||
}
|
||||
y += maxRowHeight + spacing(Qt::Vertical);
|
||||
maxRowHeight = 0;
|
||||
}
|
||||
|
||||
if (applyNewGeometry)
|
||||
item->setGeometry(QRectF(QPointF(left + x, top + y), pref));
|
||||
x = next_x + spacing(Qt::Horizontal);
|
||||
}
|
||||
maxRowHeight = qMax(maxRowHeight, pref.height());
|
||||
return top + y + maxRowHeight + bottom;
|
||||
}
|
||||
|
||||
QSizeF FlowLayout::minSize(const QSizeF &constraint) const
|
||||
{
|
||||
QSizeF size(0, 0);
|
||||
qreal left, top, right, bottom;
|
||||
getContentsMargins(&left, &top, &right, &bottom);
|
||||
if (constraint.width() >= 0) { // height for width
|
||||
const qreal height = doLayout(QRectF(QPointF(0,0), constraint), false);
|
||||
size = QSizeF(constraint.width(), height);
|
||||
} else if (constraint.height() >= 0) { // width for height?
|
||||
// not supported
|
||||
} else {
|
||||
for (const QGraphicsLayoutItem *item : std::as_const(m_items))
|
||||
size = size.expandedTo(item->effectiveSizeHint(Qt::MinimumSize));
|
||||
size += QSizeF(left + right, top + bottom);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
QSizeF FlowLayout::prefSize() const
|
||||
{
|
||||
qreal left, right;
|
||||
getContentsMargins(&left, nullptr, &right, nullptr);
|
||||
|
||||
qreal maxh = 0;
|
||||
qreal totalWidth = 0;
|
||||
for (const QGraphicsLayoutItem *item : std::as_const(m_items)) {
|
||||
if (totalWidth > 0)
|
||||
totalWidth += spacing(Qt::Horizontal);
|
||||
QSizeF pref = item->effectiveSizeHint(Qt::PreferredSize);
|
||||
totalWidth += pref.width();
|
||||
maxh = qMax(maxh, pref.height());
|
||||
}
|
||||
maxh += spacing(Qt::Vertical);
|
||||
|
||||
const qreal goldenAspectRatio = 1.61803399;
|
||||
qreal w = qSqrt(totalWidth * maxh * goldenAspectRatio) + left + right;
|
||||
|
||||
return minSize(QSizeF(w, -1));
|
||||
}
|
||||
|
||||
QSizeF FlowLayout::maxSize() const
|
||||
{
|
||||
qreal totalWidth = 0;
|
||||
qreal totalHeight = 0;
|
||||
for (const QGraphicsLayoutItem *item : std::as_const(m_items)) {
|
||||
if (totalWidth > 0)
|
||||
totalWidth += spacing(Qt::Horizontal);
|
||||
if (totalHeight > 0)
|
||||
totalHeight += spacing(Qt::Vertical);
|
||||
QSizeF pref = item->effectiveSizeHint(Qt::PreferredSize);
|
||||
totalWidth += pref.width();
|
||||
totalHeight += pref.height();
|
||||
}
|
||||
|
||||
qreal left, top, right, bottom;
|
||||
getContentsMargins(&left, &top, &right, &bottom);
|
||||
return QSizeF(left + totalWidth + right, top + totalHeight + bottom);
|
||||
}
|
||||
|
||||
QSizeF FlowLayout::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
|
||||
{
|
||||
QSizeF sh = constraint;
|
||||
switch (which) {
|
||||
case Qt::PreferredSize:
|
||||
sh = prefSize();
|
||||
break;
|
||||
case Qt::MinimumSize:
|
||||
sh = minSize(constraint);
|
||||
break;
|
||||
case Qt::MaximumSize:
|
||||
sh = maxSize();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return sh;
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#ifndef FLOWLAYOUT_H
|
||||
#define FLOWLAYOUT_H
|
||||
|
||||
#include <QGraphicsLayout>
|
||||
|
||||
class FlowLayout : public QGraphicsLayout
|
||||
{
|
||||
public:
|
||||
FlowLayout(QGraphicsLayoutItem *parent = nullptr);
|
||||
inline void addItem(QGraphicsLayoutItem *item);
|
||||
void insertItem(int index, QGraphicsLayoutItem *item);
|
||||
void setSpacing(Qt::Orientations o, qreal spacing);
|
||||
qreal spacing(Qt::Orientation o) const;
|
||||
|
||||
// inherited functions
|
||||
void setGeometry(const QRectF &geom) override;
|
||||
|
||||
int count() const override;
|
||||
QGraphicsLayoutItem *itemAt(int index) const override;
|
||||
void removeAt(int index) override;
|
||||
|
||||
protected:
|
||||
QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const override;
|
||||
|
||||
private:
|
||||
qreal doLayout(const QRectF &geom, bool applyNewGeometry) const;
|
||||
QSizeF minSize(const QSizeF &constraint) const;
|
||||
QSizeF prefSize() const;
|
||||
QSizeF maxSize() const;
|
||||
|
||||
QList<QGraphicsLayoutItem *> m_items;
|
||||
qreal m_spacing[2] = {6, 6};
|
||||
};
|
||||
|
||||
|
||||
inline void FlowLayout::addItem(QGraphicsLayoutItem *item)
|
||||
{
|
||||
insertItem(-1, item);
|
||||
}
|
||||
|
||||
#endif // FLOWLAYOUT_H
|
@ -0,0 +1,10 @@
|
||||
QT += widgets
|
||||
|
||||
QMAKE_PROJECT_NAME = flowlayout_graphicsview
|
||||
|
||||
HEADERS += flowlayout.h window.h
|
||||
SOURCES += flowlayout.cpp main.cpp window.cpp
|
||||
|
||||
# install
|
||||
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/graphicsview/flowlayout
|
||||
INSTALLS += target
|
@ -0,0 +1,24 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
//! [1]
|
||||
#include "window.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QGraphicsView>
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
|
||||
QGraphicsScene scene;
|
||||
QGraphicsView view(&scene);
|
||||
Window *w = new Window;
|
||||
scene.addItem(w);
|
||||
|
||||
view.resize(400, 300);
|
||||
view.show();
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
//! [1]
|
@ -0,0 +1,24 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include "window.h"
|
||||
#include "flowlayout.h"
|
||||
|
||||
#include <QGraphicsProxyWidget>
|
||||
#include <QLabel>
|
||||
|
||||
Window::Window(QGraphicsItem *parent) : QGraphicsWidget(parent, Qt::Window)
|
||||
{
|
||||
FlowLayout *lay = new FlowLayout;
|
||||
const QString sentence(QLatin1String("I am not bothered by the fact that I am unknown."
|
||||
" I am bothered when I do not know others. (Confucius)"));
|
||||
const QList<QStringView> words = QStringView{ sentence }.split(QLatin1Char(' '), Qt::SkipEmptyParts);
|
||||
for (const QStringView &word : words) {
|
||||
QGraphicsProxyWidget *proxy = new QGraphicsProxyWidget(this);
|
||||
QLabel *label = new QLabel(word.toString());
|
||||
label->setFrameStyle(QFrame::Box | QFrame::Plain);
|
||||
proxy->setWidget(label);
|
||||
lay->addItem(proxy);
|
||||
}
|
||||
setLayout(lay);
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#ifndef WINDOW_H
|
||||
#define WINDOW_H
|
||||
|
||||
#include <QGraphicsWidget>
|
||||
|
||||
class Window : public QGraphicsWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
Window(QGraphicsItem *parent = nullptr);
|
||||
};
|
||||
|
||||
#endif // WINDOW_H
|
56
tests/manual/examples/widgets/itemviews/chart/CMakeLists.txt
Normal file
@ -0,0 +1,56 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(chart LANGUAGES CXX)
|
||||
|
||||
if(NOT DEFINED INSTALL_EXAMPLESDIR)
|
||||
set(INSTALL_EXAMPLESDIR "examples")
|
||||
endif()
|
||||
|
||||
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/widgets/itemviews/chart")
|
||||
|
||||
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
|
||||
|
||||
qt_standard_project_setup()
|
||||
|
||||
qt_add_executable(chart
|
||||
main.cpp
|
||||
mainwindow.cpp mainwindow.h
|
||||
pieview.cpp pieview.h
|
||||
)
|
||||
|
||||
set_target_properties(chart PROPERTIES
|
||||
WIN32_EXECUTABLE TRUE
|
||||
MACOSX_BUNDLE TRUE
|
||||
)
|
||||
|
||||
target_link_libraries(chart PRIVATE
|
||||
Qt6::Core
|
||||
Qt6::Gui
|
||||
Qt6::Widgets
|
||||
)
|
||||
|
||||
# Resources:
|
||||
set(chart_resource_files
|
||||
"qtdata.cht"
|
||||
)
|
||||
|
||||
qt_add_resources(chart "chart"
|
||||
PREFIX
|
||||
"/Charts"
|
||||
FILES
|
||||
${chart_resource_files}
|
||||
)
|
||||
|
||||
if(UNIX AND NOT APPLE AND NOT HAIKU AND NOT INTEGRITY AND NOT VXWORKS)
|
||||
target_link_libraries(chart PRIVATE
|
||||
m
|
||||
)
|
||||
endif()
|
||||
|
||||
install(TARGETS chart
|
||||
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
)
|
14
tests/manual/examples/widgets/itemviews/chart/chart.pro
Normal file
@ -0,0 +1,14 @@
|
||||
QT += widgets
|
||||
requires(qtConfig(filedialog))
|
||||
|
||||
HEADERS = mainwindow.h \
|
||||
pieview.h
|
||||
RESOURCES = chart.qrc
|
||||
SOURCES = main.cpp \
|
||||
mainwindow.cpp \
|
||||
pieview.cpp
|
||||
unix:!mac:!vxworks:!integrity:!haiku:LIBS += -lm
|
||||
|
||||
# install
|
||||
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/itemviews/chart
|
||||
INSTALLS += target
|
5
tests/manual/examples/widgets/itemviews/chart/chart.qrc
Normal file
@ -0,0 +1,5 @@
|
||||
<!DOCTYPE RCC><RCC version="1.0">
|
||||
<qresource prefix="/Charts" >
|
||||
<file>qtdata.cht</file>
|
||||
</qresource>
|
||||
</RCC>
|
14
tests/manual/examples/widgets/itemviews/chart/main.cpp
Normal file
@ -0,0 +1,14 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
#include "mainwindow.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
MainWindow window;
|
||||
window.show();
|
||||
return app.exec();
|
||||
}
|
136
tests/manual/examples/widgets/itemviews/chart/mainwindow.cpp
Normal file
@ -0,0 +1,136 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include "pieview.h"
|
||||
#include "mainwindow.h"
|
||||
|
||||
#include <QtWidgets>
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent)
|
||||
: QMainWindow(parent)
|
||||
{
|
||||
QMenu *fileMenu = new QMenu(tr("&File"), this);
|
||||
QAction *openAction = fileMenu->addAction(tr("&Open..."));
|
||||
openAction->setShortcuts(QKeySequence::Open);
|
||||
QAction *saveAction = fileMenu->addAction(tr("&Save As..."));
|
||||
saveAction->setShortcuts(QKeySequence::SaveAs);
|
||||
QAction *quitAction = fileMenu->addAction(tr("E&xit"));
|
||||
quitAction->setShortcuts(QKeySequence::Quit);
|
||||
|
||||
setupModel();
|
||||
setupViews();
|
||||
|
||||
connect(openAction, &QAction::triggered, this, &MainWindow::openFile);
|
||||
connect(saveAction, &QAction::triggered, this, &MainWindow::saveFile);
|
||||
connect(quitAction, &QAction::triggered, qApp, &QCoreApplication::quit);
|
||||
|
||||
menuBar()->addMenu(fileMenu);
|
||||
statusBar();
|
||||
|
||||
loadFile(":/Charts/qtdata.cht");
|
||||
|
||||
setWindowTitle(tr("Chart"));
|
||||
resize(870, 550);
|
||||
}
|
||||
|
||||
void MainWindow::setupModel()
|
||||
{
|
||||
model = new QStandardItemModel(8, 2, this);
|
||||
model->setHeaderData(0, Qt::Horizontal, tr("Label"));
|
||||
model->setHeaderData(1, Qt::Horizontal, tr("Quantity"));
|
||||
}
|
||||
|
||||
void MainWindow::setupViews()
|
||||
{
|
||||
QSplitter *splitter = new QSplitter;
|
||||
QTableView *table = new QTableView;
|
||||
pieChart = new PieView;
|
||||
splitter->addWidget(table);
|
||||
splitter->addWidget(pieChart);
|
||||
splitter->setStretchFactor(0, 0);
|
||||
splitter->setStretchFactor(1, 1);
|
||||
|
||||
table->setModel(model);
|
||||
pieChart->setModel(model);
|
||||
|
||||
QItemSelectionModel *selectionModel = new QItemSelectionModel(model);
|
||||
table->setSelectionModel(selectionModel);
|
||||
pieChart->setSelectionModel(selectionModel);
|
||||
|
||||
QHeaderView *headerView = table->horizontalHeader();
|
||||
headerView->setStretchLastSection(true);
|
||||
|
||||
setCentralWidget(splitter);
|
||||
}
|
||||
|
||||
void MainWindow::openFile()
|
||||
{
|
||||
const QString fileName =
|
||||
QFileDialog::getOpenFileName(this, tr("Choose a data file"), "", "*.cht");
|
||||
if (!fileName.isEmpty())
|
||||
loadFile(fileName);
|
||||
}
|
||||
|
||||
void MainWindow::loadFile(const QString &fileName)
|
||||
{
|
||||
QFile file(fileName);
|
||||
if (!file.open(QFile::ReadOnly | QFile::Text))
|
||||
return;
|
||||
|
||||
QTextStream stream(&file);
|
||||
|
||||
model->removeRows(0, model->rowCount(QModelIndex()), QModelIndex());
|
||||
|
||||
int row = 0;
|
||||
while (!stream.atEnd()) {
|
||||
const QString line = stream.readLine();
|
||||
if (!line.isEmpty()) {
|
||||
model->insertRows(row, 1, QModelIndex());
|
||||
|
||||
const QStringList pieces = line.split(QLatin1Char(','), Qt::SkipEmptyParts);
|
||||
if (pieces.size() < 3)
|
||||
continue;
|
||||
model->setData(model->index(row, 0, QModelIndex()),
|
||||
pieces.value(0));
|
||||
model->setData(model->index(row, 1, QModelIndex()),
|
||||
pieces.value(1));
|
||||
model->setData(model->index(row, 0, QModelIndex()),
|
||||
QColor(pieces.value(2)), Qt::DecorationRole);
|
||||
row++;
|
||||
}
|
||||
};
|
||||
|
||||
file.close();
|
||||
statusBar()->showMessage(tr("Loaded %1").arg(fileName), 2000);
|
||||
}
|
||||
|
||||
void MainWindow::saveFile()
|
||||
{
|
||||
QString fileName = QFileDialog::getSaveFileName(this,
|
||||
tr("Save file as"), "", "*.cht");
|
||||
|
||||
if (fileName.isEmpty())
|
||||
return;
|
||||
|
||||
QFile file(fileName);
|
||||
if (!file.open(QFile::WriteOnly | QFile::Text))
|
||||
return;
|
||||
|
||||
QTextStream stream(&file);
|
||||
for (int row = 0; row < model->rowCount(QModelIndex()); ++row) {
|
||||
|
||||
QStringList pieces;
|
||||
|
||||
pieces.append(model->data(model->index(row, 0, QModelIndex()),
|
||||
Qt::DisplayRole).toString());
|
||||
pieces.append(model->data(model->index(row, 1, QModelIndex()),
|
||||
Qt::DisplayRole).toString());
|
||||
pieces.append(model->data(model->index(row, 0, QModelIndex()),
|
||||
Qt::DecorationRole).toString());
|
||||
|
||||
stream << pieces.join(',') << "\n";
|
||||
}
|
||||
|
||||
file.close();
|
||||
statusBar()->showMessage(tr("Saved %1").arg(fileName), 2000);
|
||||
}
|
34
tests/manual/examples/widgets/itemviews/chart/mainwindow.h
Normal file
@ -0,0 +1,34 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#ifndef MAINWINDOW_H
|
||||
#define MAINWINDOW_H
|
||||
|
||||
#include <QMainWindow>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QAbstractItemModel;
|
||||
class QAbstractItemView;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MainWindow(QWidget *parent = nullptr);
|
||||
|
||||
private slots:
|
||||
void openFile();
|
||||
void saveFile();
|
||||
|
||||
private:
|
||||
void setupModel();
|
||||
void setupViews();
|
||||
void loadFile(const QString &path);
|
||||
|
||||
QAbstractItemModel *model = nullptr;
|
||||
QAbstractItemView *pieChart = nullptr;
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
506
tests/manual/examples/widgets/itemviews/chart/pieview.cpp
Normal file
@ -0,0 +1,506 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include "pieview.h"
|
||||
|
||||
#include <QtWidgets>
|
||||
|
||||
PieView::PieView(QWidget *parent)
|
||||
: QAbstractItemView(parent)
|
||||
{
|
||||
horizontalScrollBar()->setRange(0, 0);
|
||||
verticalScrollBar()->setRange(0, 0);
|
||||
}
|
||||
|
||||
void PieView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight,
|
||||
const QList<int> &roles)
|
||||
{
|
||||
QAbstractItemView::dataChanged(topLeft, bottomRight, roles);
|
||||
|
||||
if (!roles.contains(Qt::DisplayRole))
|
||||
return;
|
||||
|
||||
validItems = 0;
|
||||
totalValue = 0.0;
|
||||
|
||||
for (int row = 0; row < model()->rowCount(rootIndex()); ++row) {
|
||||
|
||||
QModelIndex index = model()->index(row, 1, rootIndex());
|
||||
double value = model()->data(index, Qt::DisplayRole).toDouble();
|
||||
|
||||
if (value > 0.0) {
|
||||
totalValue += value;
|
||||
validItems++;
|
||||
}
|
||||
}
|
||||
viewport()->update();
|
||||
}
|
||||
|
||||
bool PieView::edit(const QModelIndex &index, EditTrigger trigger, QEvent *event)
|
||||
{
|
||||
if (index.column() == 0)
|
||||
return QAbstractItemView::edit(index, trigger, event);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
Returns the item that covers the coordinate given in the view.
|
||||
*/
|
||||
|
||||
QModelIndex PieView::indexAt(const QPoint &point) const
|
||||
{
|
||||
if (validItems == 0)
|
||||
return QModelIndex();
|
||||
|
||||
// Transform the view coordinates into contents widget coordinates.
|
||||
int wx = point.x() + horizontalScrollBar()->value();
|
||||
int wy = point.y() + verticalScrollBar()->value();
|
||||
|
||||
if (wx < totalSize) {
|
||||
double cx = wx - totalSize / 2;
|
||||
double cy = totalSize / 2 - wy; // positive cy for items above the center
|
||||
|
||||
// Determine the distance from the center point of the pie chart.
|
||||
double d = std::sqrt(std::pow(cx, 2) + std::pow(cy, 2));
|
||||
|
||||
if (d == 0 || d > pieSize / 2)
|
||||
return QModelIndex();
|
||||
|
||||
// Determine the angle of the point.
|
||||
double angle = qRadiansToDegrees(std::atan2(cy, cx));
|
||||
if (angle < 0)
|
||||
angle = 360 + angle;
|
||||
|
||||
// Find the relevant slice of the pie.
|
||||
double startAngle = 0.0;
|
||||
|
||||
for (int row = 0; row < model()->rowCount(rootIndex()); ++row) {
|
||||
|
||||
QModelIndex index = model()->index(row, 1, rootIndex());
|
||||
double value = model()->data(index).toDouble();
|
||||
|
||||
if (value > 0.0) {
|
||||
double sliceAngle = 360 * value / totalValue;
|
||||
|
||||
if (angle >= startAngle && angle < (startAngle + sliceAngle))
|
||||
return model()->index(row, 1, rootIndex());
|
||||
|
||||
startAngle += sliceAngle;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
QStyleOptionViewItem option;
|
||||
initViewItemOption(&option);
|
||||
double itemHeight = QFontMetrics(option.font).height();
|
||||
int listItem = int((wy - margin) / itemHeight);
|
||||
int validRow = 0;
|
||||
|
||||
for (int row = 0; row < model()->rowCount(rootIndex()); ++row) {
|
||||
|
||||
QModelIndex index = model()->index(row, 1, rootIndex());
|
||||
if (model()->data(index).toDouble() > 0.0) {
|
||||
|
||||
if (listItem == validRow)
|
||||
return model()->index(row, 0, rootIndex());
|
||||
|
||||
// Update the list index that corresponds to the next valid row.
|
||||
++validRow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
bool PieView::isIndexHidden(const QModelIndex & /*index*/) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
Returns the rectangle of the item at position \a index in the
|
||||
model. The rectangle is in contents coordinates.
|
||||
*/
|
||||
|
||||
QRect PieView::itemRect(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QRect();
|
||||
|
||||
// Check whether the index's row is in the list of rows represented
|
||||
// by slices.
|
||||
QModelIndex valueIndex;
|
||||
|
||||
if (index.column() != 1)
|
||||
valueIndex = model()->index(index.row(), 1, rootIndex());
|
||||
else
|
||||
valueIndex = index;
|
||||
|
||||
if (model()->data(valueIndex).toDouble() <= 0.0)
|
||||
return QRect();
|
||||
|
||||
int listItem = 0;
|
||||
for (int row = index.row()-1; row >= 0; --row) {
|
||||
if (model()->data(model()->index(row, 1, rootIndex())).toDouble() > 0.0)
|
||||
listItem++;
|
||||
}
|
||||
|
||||
switch (index.column()) {
|
||||
case 0: {
|
||||
QStyleOptionViewItem option;
|
||||
initViewItemOption(&option);
|
||||
const qreal itemHeight = QFontMetricsF(option.font).height();
|
||||
return QRect(totalSize,
|
||||
qRound(margin + listItem * itemHeight),
|
||||
totalSize - margin, qRound(itemHeight));
|
||||
}
|
||||
case 1:
|
||||
return viewport()->rect();
|
||||
}
|
||||
return QRect();
|
||||
}
|
||||
|
||||
QRegion PieView::itemRegion(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QRegion();
|
||||
|
||||
if (index.column() != 1)
|
||||
return itemRect(index);
|
||||
|
||||
if (model()->data(index).toDouble() <= 0.0)
|
||||
return QRegion();
|
||||
|
||||
double startAngle = 0.0;
|
||||
for (int row = 0; row < model()->rowCount(rootIndex()); ++row) {
|
||||
|
||||
QModelIndex sliceIndex = model()->index(row, 1, rootIndex());
|
||||
double value = model()->data(sliceIndex).toDouble();
|
||||
|
||||
if (value > 0.0) {
|
||||
double angle = 360 * value / totalValue;
|
||||
|
||||
if (sliceIndex == index) {
|
||||
QPainterPath slicePath;
|
||||
slicePath.moveTo(totalSize / 2, totalSize / 2);
|
||||
slicePath.arcTo(margin, margin, margin + pieSize, margin + pieSize,
|
||||
startAngle, angle);
|
||||
slicePath.closeSubpath();
|
||||
|
||||
return QRegion(slicePath.toFillPolygon().toPolygon());
|
||||
}
|
||||
|
||||
startAngle += angle;
|
||||
}
|
||||
}
|
||||
|
||||
return QRegion();
|
||||
}
|
||||
|
||||
int PieView::horizontalOffset() const
|
||||
{
|
||||
return horizontalScrollBar()->value();
|
||||
}
|
||||
|
||||
void PieView::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
QAbstractItemView::mousePressEvent(event);
|
||||
origin = event->position().toPoint();
|
||||
if (!rubberBand)
|
||||
rubberBand = new QRubberBand(QRubberBand::Rectangle, viewport());
|
||||
rubberBand->setGeometry(QRect(origin, QSize()));
|
||||
rubberBand->show();
|
||||
}
|
||||
|
||||
void PieView::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
if (rubberBand)
|
||||
rubberBand->setGeometry(QRect(origin, event->position().toPoint()).normalized());
|
||||
QAbstractItemView::mouseMoveEvent(event);
|
||||
}
|
||||
|
||||
void PieView::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
QAbstractItemView::mouseReleaseEvent(event);
|
||||
if (rubberBand)
|
||||
rubberBand->hide();
|
||||
viewport()->update();
|
||||
}
|
||||
|
||||
QModelIndex PieView::moveCursor(QAbstractItemView::CursorAction cursorAction,
|
||||
Qt::KeyboardModifiers /*modifiers*/)
|
||||
{
|
||||
QModelIndex current = currentIndex();
|
||||
|
||||
switch (cursorAction) {
|
||||
case MoveLeft:
|
||||
case MoveUp:
|
||||
if (current.row() > 0)
|
||||
current = model()->index(current.row() - 1, current.column(),
|
||||
rootIndex());
|
||||
else
|
||||
current = model()->index(0, current.column(), rootIndex());
|
||||
break;
|
||||
case MoveRight:
|
||||
case MoveDown:
|
||||
if (current.row() < rows(current) - 1)
|
||||
current = model()->index(current.row() + 1, current.column(),
|
||||
rootIndex());
|
||||
else
|
||||
current = model()->index(rows(current) - 1, current.column(),
|
||||
rootIndex());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
viewport()->update();
|
||||
return current;
|
||||
}
|
||||
|
||||
void PieView::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
QItemSelectionModel *selections = selectionModel();
|
||||
QStyleOptionViewItem option;
|
||||
initViewItemOption(&option);
|
||||
|
||||
QBrush background = option.palette.base();
|
||||
QPen foreground(option.palette.color(QPalette::WindowText));
|
||||
|
||||
QPainter painter(viewport());
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
|
||||
painter.fillRect(event->rect(), background);
|
||||
painter.setPen(foreground);
|
||||
|
||||
// Viewport rectangles
|
||||
QRect pieRect = QRect(margin, margin, pieSize, pieSize);
|
||||
|
||||
if (validItems <= 0)
|
||||
return;
|
||||
|
||||
painter.save();
|
||||
painter.translate(pieRect.x() - horizontalScrollBar()->value(),
|
||||
pieRect.y() - verticalScrollBar()->value());
|
||||
painter.drawEllipse(0, 0, pieSize, pieSize);
|
||||
double startAngle = 0.0;
|
||||
int row;
|
||||
|
||||
for (row = 0; row < model()->rowCount(rootIndex()); ++row) {
|
||||
QModelIndex index = model()->index(row, 1, rootIndex());
|
||||
double value = model()->data(index).toDouble();
|
||||
|
||||
if (value > 0.0) {
|
||||
double angle = 360 * value / totalValue;
|
||||
|
||||
QModelIndex colorIndex = model()->index(row, 0, rootIndex());
|
||||
QColor color = QColor(model()->data(colorIndex, Qt::DecorationRole).toString());
|
||||
|
||||
if (currentIndex() == index)
|
||||
painter.setBrush(QBrush(color, Qt::Dense4Pattern));
|
||||
else if (selections->isSelected(index))
|
||||
painter.setBrush(QBrush(color, Qt::Dense3Pattern));
|
||||
else
|
||||
painter.setBrush(QBrush(color));
|
||||
|
||||
painter.drawPie(0, 0, pieSize, pieSize, int(startAngle*16), int(angle*16));
|
||||
|
||||
startAngle += angle;
|
||||
}
|
||||
}
|
||||
painter.restore();
|
||||
|
||||
for (row = 0; row < model()->rowCount(rootIndex()); ++row) {
|
||||
QModelIndex index = model()->index(row, 1, rootIndex());
|
||||
double value = model()->data(index).toDouble();
|
||||
|
||||
if (value > 0.0) {
|
||||
QModelIndex labelIndex = model()->index(row, 0, rootIndex());
|
||||
|
||||
QStyleOptionViewItem option;
|
||||
initViewItemOption(&option);
|
||||
|
||||
option.rect = visualRect(labelIndex);
|
||||
if (selections->isSelected(labelIndex))
|
||||
option.state |= QStyle::State_Selected;
|
||||
if (currentIndex() == labelIndex)
|
||||
option.state |= QStyle::State_HasFocus;
|
||||
itemDelegate()->paint(&painter, option, labelIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PieView::resizeEvent(QResizeEvent * /* event */)
|
||||
{
|
||||
updateGeometries();
|
||||
}
|
||||
|
||||
int PieView::rows(const QModelIndex &index) const
|
||||
{
|
||||
return model()->rowCount(model()->parent(index));
|
||||
}
|
||||
|
||||
void PieView::rowsInserted(const QModelIndex &parent, int start, int end)
|
||||
{
|
||||
for (int row = start; row <= end; ++row) {
|
||||
QModelIndex index = model()->index(row, 1, rootIndex());
|
||||
double value = model()->data(index).toDouble();
|
||||
|
||||
if (value > 0.0) {
|
||||
totalValue += value;
|
||||
++validItems;
|
||||
}
|
||||
}
|
||||
|
||||
QAbstractItemView::rowsInserted(parent, start, end);
|
||||
}
|
||||
|
||||
void PieView::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
|
||||
{
|
||||
for (int row = start; row <= end; ++row) {
|
||||
QModelIndex index = model()->index(row, 1, rootIndex());
|
||||
double value = model()->data(index).toDouble();
|
||||
if (value > 0.0) {
|
||||
totalValue -= value;
|
||||
--validItems;
|
||||
}
|
||||
}
|
||||
|
||||
QAbstractItemView::rowsAboutToBeRemoved(parent, start, end);
|
||||
}
|
||||
|
||||
void PieView::scrollContentsBy(int dx, int dy)
|
||||
{
|
||||
viewport()->scroll(dx, dy);
|
||||
}
|
||||
|
||||
void PieView::scrollTo(const QModelIndex &index, ScrollHint)
|
||||
{
|
||||
QRect area = viewport()->rect();
|
||||
QRect rect = visualRect(index);
|
||||
|
||||
if (rect.left() < area.left()) {
|
||||
horizontalScrollBar()->setValue(
|
||||
horizontalScrollBar()->value() + rect.left() - area.left());
|
||||
} else if (rect.right() > area.right()) {
|
||||
horizontalScrollBar()->setValue(
|
||||
horizontalScrollBar()->value() + qMin(
|
||||
rect.right() - area.right(), rect.left() - area.left()));
|
||||
}
|
||||
|
||||
if (rect.top() < area.top()) {
|
||||
verticalScrollBar()->setValue(
|
||||
verticalScrollBar()->value() + rect.top() - area.top());
|
||||
} else if (rect.bottom() > area.bottom()) {
|
||||
verticalScrollBar()->setValue(
|
||||
verticalScrollBar()->value() + qMin(
|
||||
rect.bottom() - area.bottom(), rect.top() - area.top()));
|
||||
}
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
/*
|
||||
Find the indices corresponding to the extent of the selection.
|
||||
*/
|
||||
|
||||
void PieView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags command)
|
||||
{
|
||||
// Use content widget coordinates because we will use the itemRegion()
|
||||
// function to check for intersections.
|
||||
|
||||
QRect contentsRect = rect.translated(
|
||||
horizontalScrollBar()->value(),
|
||||
verticalScrollBar()->value()).normalized();
|
||||
|
||||
int rows = model()->rowCount(rootIndex());
|
||||
int columns = model()->columnCount(rootIndex());
|
||||
QModelIndexList indexes;
|
||||
|
||||
for (int row = 0; row < rows; ++row) {
|
||||
for (int column = 0; column < columns; ++column) {
|
||||
QModelIndex index = model()->index(row, column, rootIndex());
|
||||
QRegion region = itemRegion(index);
|
||||
if (region.intersects(contentsRect))
|
||||
indexes.append(index);
|
||||
}
|
||||
}
|
||||
|
||||
if (indexes.size() > 0) {
|
||||
int firstRow = indexes.at(0).row();
|
||||
int lastRow = firstRow;
|
||||
int firstColumn = indexes.at(0).column();
|
||||
int lastColumn = firstColumn;
|
||||
|
||||
for (int i = 1; i < indexes.size(); ++i) {
|
||||
firstRow = qMin(firstRow, indexes.at(i).row());
|
||||
lastRow = qMax(lastRow, indexes.at(i).row());
|
||||
firstColumn = qMin(firstColumn, indexes.at(i).column());
|
||||
lastColumn = qMax(lastColumn, indexes.at(i).column());
|
||||
}
|
||||
|
||||
QItemSelection selection(
|
||||
model()->index(firstRow, firstColumn, rootIndex()),
|
||||
model()->index(lastRow, lastColumn, rootIndex()));
|
||||
selectionModel()->select(selection, command);
|
||||
} else {
|
||||
QModelIndex noIndex;
|
||||
QItemSelection selection(noIndex, noIndex);
|
||||
selectionModel()->select(selection, command);
|
||||
}
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
void PieView::updateGeometries()
|
||||
{
|
||||
horizontalScrollBar()->setPageStep(viewport()->width());
|
||||
horizontalScrollBar()->setRange(0, qMax(0, 2 * totalSize - viewport()->width()));
|
||||
verticalScrollBar()->setPageStep(viewport()->height());
|
||||
verticalScrollBar()->setRange(0, qMax(0, totalSize - viewport()->height()));
|
||||
}
|
||||
|
||||
int PieView::verticalOffset() const
|
||||
{
|
||||
return verticalScrollBar()->value();
|
||||
}
|
||||
|
||||
/*
|
||||
Returns the position of the item in viewport coordinates.
|
||||
*/
|
||||
|
||||
QRect PieView::visualRect(const QModelIndex &index) const
|
||||
{
|
||||
QRect rect = itemRect(index);
|
||||
if (!rect.isValid())
|
||||
return rect;
|
||||
|
||||
return QRect(rect.left() - horizontalScrollBar()->value(),
|
||||
rect.top() - verticalScrollBar()->value(),
|
||||
rect.width(), rect.height());
|
||||
}
|
||||
|
||||
/*
|
||||
Returns a region corresponding to the selection in viewport coordinates.
|
||||
*/
|
||||
|
||||
QRegion PieView::visualRegionForSelection(const QItemSelection &selection) const
|
||||
{
|
||||
int ranges = selection.count();
|
||||
|
||||
if (ranges == 0)
|
||||
return QRect();
|
||||
|
||||
QRegion region;
|
||||
for (int i = 0; i < ranges; ++i) {
|
||||
const QItemSelectionRange &range = selection.at(i);
|
||||
for (int row = range.top(); row <= range.bottom(); ++row) {
|
||||
for (int col = range.left(); col <= range.right(); ++col) {
|
||||
QModelIndex index = model()->index(row, col, rootIndex());
|
||||
region += visualRect(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
return region;
|
||||
}
|
66
tests/manual/examples/widgets/itemviews/chart/pieview.h
Normal file
@ -0,0 +1,66 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#ifndef PIEVIEW_H
|
||||
#define PIEVIEW_H
|
||||
|
||||
#include <QAbstractItemView>
|
||||
|
||||
//! [0]
|
||||
class PieView : public QAbstractItemView
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
PieView(QWidget *parent = nullptr);
|
||||
|
||||
QRect visualRect(const QModelIndex &index) const override;
|
||||
void scrollTo(const QModelIndex &index, ScrollHint hint = EnsureVisible) override;
|
||||
QModelIndex indexAt(const QPoint &point) const override;
|
||||
|
||||
protected slots:
|
||||
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight,
|
||||
const QList<int> &roles = QList<int>()) override;
|
||||
void rowsInserted(const QModelIndex &parent, int start, int end) override;
|
||||
void rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) override;
|
||||
|
||||
protected:
|
||||
bool edit(const QModelIndex &index, EditTrigger trigger, QEvent *event) override;
|
||||
QModelIndex moveCursor(QAbstractItemView::CursorAction cursorAction,
|
||||
Qt::KeyboardModifiers modifiers) override;
|
||||
|
||||
int horizontalOffset() const override;
|
||||
int verticalOffset() const override;
|
||||
|
||||
bool isIndexHidden(const QModelIndex &index) const override;
|
||||
|
||||
void setSelection(const QRect&, QItemSelectionModel::SelectionFlags command) override;
|
||||
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
|
||||
void mouseMoveEvent(QMouseEvent *event) override;
|
||||
void mouseReleaseEvent(QMouseEvent *event) override;
|
||||
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
void scrollContentsBy(int dx, int dy) override;
|
||||
|
||||
QRegion visualRegionForSelection(const QItemSelection &selection) const override;
|
||||
|
||||
private:
|
||||
QRect itemRect(const QModelIndex &item) const;
|
||||
QRegion itemRegion(const QModelIndex &index) const;
|
||||
int rows(const QModelIndex &index = QModelIndex()) const;
|
||||
void updateGeometries() override;
|
||||
|
||||
int margin = 0;
|
||||
int totalSize = 300;
|
||||
int pieSize = totalSize - 2 * margin;
|
||||
int validItems = 0;
|
||||
double totalValue = 0.0;
|
||||
QRubberBand *rubberBand = nullptr;
|
||||
QPoint origin;
|
||||
};
|
||||
//! [0]
|
||||
|
||||
#endif // PIEVIEW_H
|
14
tests/manual/examples/widgets/itemviews/chart/qtdata.cht
Normal file
@ -0,0 +1,14 @@
|
||||
Scientific Research,21,#99e600
|
||||
Engineering & Design,18,#99cc00
|
||||
Automotive,14,#99b300
|
||||
Aerospace,13,#9f991a
|
||||
Automation & Machine Tools,13,#a48033
|
||||
Medical & Bioinformatics,13,#a9664d
|
||||
Imaging & Special Effects,12,#ae4d66
|
||||
Defense,11,#b33380
|
||||
Test & Measurement Systems,9,#a64086
|
||||
Oil & Gas,9,#994d8d
|
||||
Entertainment & Broadcasting,7,#8d5a93
|
||||
Financial,6,#806699
|
||||
Consumer Electronics,4,#8073a6
|
||||
Other,38,#8080b3
|
@ -0,0 +1,36 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(dirview LANGUAGES CXX)
|
||||
|
||||
if(NOT DEFINED INSTALL_EXAMPLESDIR)
|
||||
set(INSTALL_EXAMPLESDIR "examples")
|
||||
endif()
|
||||
|
||||
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/widgets/itemviews/dirview")
|
||||
|
||||
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
|
||||
|
||||
qt_standard_project_setup()
|
||||
|
||||
qt_add_executable(dirview
|
||||
main.cpp
|
||||
)
|
||||
|
||||
set_target_properties(dirview PROPERTIES
|
||||
WIN32_EXECUTABLE TRUE
|
||||
MACOSX_BUNDLE TRUE
|
||||
)
|
||||
|
||||
target_link_libraries(dirview PRIVATE
|
||||
Qt6::Core
|
||||
Qt6::Gui
|
||||
Qt6::Widgets
|
||||
)
|
||||
|
||||
install(TARGETS dirview
|
||||
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
)
|
@ -0,0 +1,8 @@
|
||||
QT += widgets
|
||||
requires(qtConfig(treeview))
|
||||
|
||||
SOURCES = main.cpp
|
||||
|
||||
# install
|
||||
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/itemviews/dirview
|
||||
INSTALLS += target
|
62
tests/manual/examples/widgets/itemviews/dirview/main.cpp
Normal file
@ -0,0 +1,62 @@
|
||||
// Copyright (C) 2020 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include <QApplication>
|
||||
#include <QFileSystemModel>
|
||||
#include <QFileIconProvider>
|
||||
#include <QScreen>
|
||||
#include <QScroller>
|
||||
#include <QTreeView>
|
||||
#include <QCommandLineParser>
|
||||
#include <QCommandLineOption>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
|
||||
QCoreApplication::setApplicationVersion(QT_VERSION_STR);
|
||||
QCommandLineParser parser;
|
||||
parser.setApplicationDescription("Qt Dir View Example");
|
||||
parser.addHelpOption();
|
||||
parser.addVersionOption();
|
||||
QCommandLineOption dontUseCustomDirectoryIconsOption("c", "Set QFileSystemModel::DontUseCustomDirectoryIcons");
|
||||
parser.addOption(dontUseCustomDirectoryIconsOption);
|
||||
QCommandLineOption dontWatchOption("w", "Set QFileSystemModel::DontWatch");
|
||||
parser.addOption(dontWatchOption);
|
||||
parser.addPositionalArgument("directory", "The directory to start in.");
|
||||
parser.process(app);
|
||||
const QString rootPath = parser.positionalArguments().isEmpty()
|
||||
? QString() : parser.positionalArguments().first();
|
||||
|
||||
QFileSystemModel model;
|
||||
QFileIconProvider iconProvider;
|
||||
model.setIconProvider(&iconProvider);
|
||||
model.setRootPath("");
|
||||
if (parser.isSet(dontUseCustomDirectoryIconsOption))
|
||||
model.setOption(QFileSystemModel::DontUseCustomDirectoryIcons);
|
||||
if (parser.isSet(dontWatchOption))
|
||||
model.setOption(QFileSystemModel::DontWatchForChanges);
|
||||
QTreeView tree;
|
||||
tree.setModel(&model);
|
||||
if (!rootPath.isEmpty()) {
|
||||
const QModelIndex rootIndex = model.index(QDir::cleanPath(rootPath));
|
||||
if (rootIndex.isValid())
|
||||
tree.setRootIndex(rootIndex);
|
||||
}
|
||||
|
||||
// Demonstrating look and feel features
|
||||
tree.setAnimated(false);
|
||||
tree.setIndentation(20);
|
||||
tree.setSortingEnabled(true);
|
||||
const QSize availableSize = tree.screen()->availableGeometry().size();
|
||||
tree.resize(availableSize / 2);
|
||||
tree.setColumnWidth(0, tree.width() / 3);
|
||||
|
||||
// Make it flickable on touchscreens
|
||||
QScroller::grabGesture(&tree, QScroller::TouchGesture);
|
||||
|
||||
tree.setWindowTitle(QObject::tr("Dir View"));
|
||||
tree.show();
|
||||
|
||||
return app.exec();
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(interview LANGUAGES CXX)
|
||||
|
||||
if(NOT DEFINED INSTALL_EXAMPLESDIR)
|
||||
set(INSTALL_EXAMPLESDIR "examples")
|
||||
endif()
|
||||
|
||||
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/widgets/itemviews/interview")
|
||||
|
||||
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
|
||||
|
||||
qt_standard_project_setup()
|
||||
|
||||
qt_add_executable(interview
|
||||
main.cpp
|
||||
model.cpp model.h
|
||||
)
|
||||
|
||||
set_target_properties(interview PROPERTIES
|
||||
WIN32_EXECUTABLE TRUE
|
||||
MACOSX_BUNDLE TRUE
|
||||
)
|
||||
|
||||
target_link_libraries(interview PRIVATE
|
||||
Qt6::Core
|
||||
Qt6::Gui
|
||||
Qt6::Widgets
|
||||
)
|
||||
|
||||
# Resources:
|
||||
set(interview_resource_files
|
||||
"images/folder.png"
|
||||
"images/interview.png"
|
||||
"images/services.png"
|
||||
)
|
||||
|
||||
qt_add_resources(interview "interview"
|
||||
PREFIX
|
||||
"/"
|
||||
FILES
|
||||
${interview_resource_files}
|
||||
)
|
||||
|
||||
install(TARGETS interview
|
||||
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
)
|
2
tests/manual/examples/widgets/itemviews/interview/README
Normal file
@ -0,0 +1,2 @@
|
||||
The interview example shows the same model and selection being shared
|
||||
between three different views.
|
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 174 B |
After Width: | Height: | Size: 3.7 KiB |
@ -0,0 +1,16 @@
|
||||
TEMPLATE = app
|
||||
QT += widgets
|
||||
requires(qtConfig(treeview))
|
||||
|
||||
HEADERS += model.h
|
||||
SOURCES += model.cpp main.cpp
|
||||
RESOURCES += interview.qrc
|
||||
|
||||
build_all:!build_pass {
|
||||
CONFIG -= build_all
|
||||
CONFIG += release
|
||||
}
|
||||
|
||||
# install
|
||||
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/itemviews/interview
|
||||
INSTALLS += target
|
@ -0,0 +1,7 @@
|
||||
<!DOCTYPE RCC><RCC version="1.0">
|
||||
<qresource prefix="/">
|
||||
<file>images/folder.png</file>
|
||||
<file>images/services.png</file>
|
||||
<file>images/interview.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
55
tests/manual/examples/widgets/itemviews/interview/main.cpp
Normal file
@ -0,0 +1,55 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include "model.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QHeaderView>
|
||||
#include <QListView>
|
||||
#include <QSplitter>
|
||||
#include <QTableView>
|
||||
#include <QTreeView>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
QSplitter page;
|
||||
|
||||
QAbstractItemModel *data = new Model(1000, 10, &page);
|
||||
QItemSelectionModel *selections = new QItemSelectionModel(data);
|
||||
|
||||
QTableView *table = new QTableView;
|
||||
table->setModel(data);
|
||||
table->setSelectionModel(selections);
|
||||
table->horizontalHeader()->setSectionsMovable(true);
|
||||
table->verticalHeader()->setSectionsMovable(true);
|
||||
// Set StaticContents to enable minimal repaints on resizes.
|
||||
table->viewport()->setAttribute(Qt::WA_StaticContents);
|
||||
page.addWidget(table);
|
||||
|
||||
QTreeView *tree = new QTreeView;
|
||||
tree->setModel(data);
|
||||
tree->setSelectionModel(selections);
|
||||
tree->setUniformRowHeights(true);
|
||||
tree->header()->setStretchLastSection(false);
|
||||
tree->viewport()->setAttribute(Qt::WA_StaticContents);
|
||||
// Disable the focus rect to get minimal repaints when scrolling on Mac.
|
||||
tree->setAttribute(Qt::WA_MacShowFocusRect, false);
|
||||
page.addWidget(tree);
|
||||
|
||||
QListView *list = new QListView;
|
||||
list->setModel(data);
|
||||
list->setSelectionModel(selections);
|
||||
list->setViewMode(QListView::IconMode);
|
||||
list->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||
list->setAlternatingRowColors(false);
|
||||
list->viewport()->setAttribute(Qt::WA_StaticContents);
|
||||
list->setAttribute(Qt::WA_MacShowFocusRect, false);
|
||||
page.addWidget(list);
|
||||
|
||||
page.setWindowIcon(QPixmap(":/images/interview.png"));
|
||||
page.setWindowTitle("Interview");
|
||||
page.show();
|
||||
|
||||
return app.exec();
|
||||
}
|
110
tests/manual/examples/widgets/itemviews/interview/model.cpp
Normal file
@ -0,0 +1,110 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include "model.h"
|
||||
|
||||
#include <QPixmap>
|
||||
|
||||
Model::Model(int rows, int columns, QObject *parent)
|
||||
: QAbstractItemModel(parent),
|
||||
services(QPixmap(":/images/services.png")),
|
||||
rc(rows),
|
||||
cc(columns),
|
||||
tree(new QList<Node>(rows, Node()))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Model::~Model()
|
||||
{
|
||||
delete tree;
|
||||
}
|
||||
|
||||
QModelIndex Model::index(int row, int column, const QModelIndex &parent) const
|
||||
{
|
||||
if (row < rc && row >= 0 && column < cc && column >= 0) {
|
||||
Node *parentNode = static_cast<Node*>(parent.internalPointer());
|
||||
Node *childNode = node(row, parentNode);
|
||||
if (childNode)
|
||||
return createIndex(row, column, childNode);
|
||||
}
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
QModelIndex Model::parent(const QModelIndex &child) const
|
||||
{
|
||||
if (child.isValid()) {
|
||||
Node *childNode = static_cast<Node*>(child.internalPointer());
|
||||
Node *parentNode = parent(childNode);
|
||||
if (parentNode)
|
||||
return createIndex(row(parentNode), 0, parentNode);
|
||||
}
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
int Model::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
return (parent.isValid() && parent.column() != 0) ? 0 : rc;
|
||||
}
|
||||
|
||||
int Model::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
return cc;
|
||||
}
|
||||
|
||||
QVariant Model::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
if (role == Qt::DisplayRole)
|
||||
return QVariant("Item " + QString::number(index.row()) + ':' + QString::number(index.column()));
|
||||
if (role == Qt::DecorationRole) {
|
||||
if (index.column() == 0)
|
||||
return iconProvider.icon(QFileIconProvider::Folder);
|
||||
return iconProvider.icon(QFileIconProvider::File);
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QVariant Model::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (role == Qt::DisplayRole)
|
||||
return QString::number(section);
|
||||
if (role == Qt::DecorationRole)
|
||||
return QVariant::fromValue(services);
|
||||
return QAbstractItemModel::headerData(section, orientation, role);
|
||||
}
|
||||
|
||||
bool Model::hasChildren(const QModelIndex &parent) const
|
||||
{
|
||||
if (parent.isValid() && parent.column() != 0)
|
||||
return false;
|
||||
return rc > 0 && cc > 0;
|
||||
}
|
||||
|
||||
Qt::ItemFlags Model::flags(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return {};
|
||||
return Qt::ItemIsDragEnabled|QAbstractItemModel::flags(index);
|
||||
}
|
||||
|
||||
Model::Node *Model::node(int row, Node *parent) const
|
||||
{
|
||||
if (parent && !parent->children)
|
||||
parent->children = new QList<Node>(rc, Node(parent));
|
||||
QList<Node> *v = parent ? parent->children : tree;
|
||||
return const_cast<Node*>(&(v->at(row)));
|
||||
}
|
||||
|
||||
Model::Node *Model::parent(Node *child) const
|
||||
{
|
||||
return child ? child->parent : nullptr;
|
||||
}
|
||||
|
||||
int Model::row(Node *node) const
|
||||
{
|
||||
const Node *first = node->parent ? &(node->parent->children->at(0)) : &(tree->at(0));
|
||||
return node - first;
|
||||
}
|
53
tests/manual/examples/widgets/itemviews/interview/model.h
Normal file
@ -0,0 +1,53 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#ifndef MODEL_H
|
||||
#define MODEL_H
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
#include <QFileIconProvider>
|
||||
#include <QIcon>
|
||||
#include <QList>
|
||||
|
||||
class Model : public QAbstractItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Model(int rows, int columns, QObject *parent = nullptr);
|
||||
~Model();
|
||||
|
||||
QModelIndex index(int row, int column, const QModelIndex &parent) const override;
|
||||
QModelIndex parent(const QModelIndex &child) const override;
|
||||
|
||||
int rowCount(const QModelIndex &parent) const override;
|
||||
int columnCount(const QModelIndex &parent) const override;
|
||||
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
||||
|
||||
bool hasChildren(const QModelIndex &parent) const override;
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||
|
||||
private:
|
||||
|
||||
struct Node
|
||||
{
|
||||
Node(Node *parent = nullptr) : parent(parent), children(nullptr) {}
|
||||
~Node() { delete children; }
|
||||
Node *parent;
|
||||
QList<Node> *children;
|
||||
};
|
||||
|
||||
Node *node(int row, Node *parent) const;
|
||||
Node *parent(Node *child) const;
|
||||
int row(Node *node) const;
|
||||
|
||||
QIcon services;
|
||||
int rc;
|
||||
int cc;
|
||||
QList<Node> *tree;
|
||||
QFileIconProvider iconProvider;
|
||||
};
|
||||
|
||||
#endif // MODEL_H
|
@ -0,0 +1,58 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(pixelator LANGUAGES CXX)
|
||||
|
||||
if(NOT DEFINED INSTALL_EXAMPLESDIR)
|
||||
set(INSTALL_EXAMPLESDIR "examples")
|
||||
endif()
|
||||
|
||||
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/widgets/itemviews/pixelator")
|
||||
|
||||
find_package(Qt6
|
||||
REQUIRED COMPONENTS Core Gui Widgets
|
||||
OPTIONAL_COMPONENTS PrintSupport
|
||||
)
|
||||
|
||||
qt_standard_project_setup()
|
||||
|
||||
qt_add_executable(pixelator
|
||||
imagemodel.cpp imagemodel.h
|
||||
main.cpp
|
||||
mainwindow.cpp mainwindow.h
|
||||
pixeldelegate.cpp pixeldelegate.h
|
||||
)
|
||||
|
||||
set_target_properties(pixelator PROPERTIES
|
||||
WIN32_EXECUTABLE TRUE
|
||||
MACOSX_BUNDLE TRUE
|
||||
)
|
||||
|
||||
target_link_libraries(pixelator PRIVATE
|
||||
Qt6::Core
|
||||
Qt6::Gui
|
||||
Qt6::Widgets
|
||||
)
|
||||
|
||||
if(TARGET Qt6::PrintSupport)
|
||||
target_link_libraries(pixelator PRIVATE Qt6::PrintSupport)
|
||||
endif()
|
||||
|
||||
# Resources:
|
||||
set(images_resource_files
|
||||
"images/qt.png"
|
||||
)
|
||||
|
||||
qt_add_resources(pixelator "images"
|
||||
PREFIX
|
||||
"/"
|
||||
FILES
|
||||
${images_resource_files}
|
||||
)
|
||||
|
||||
install(TARGETS pixelator
|
||||
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
)
|
@ -0,0 +1,53 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include "imagemodel.h"
|
||||
|
||||
//! [0]
|
||||
ImageModel::ImageModel(QObject *parent)
|
||||
: QAbstractTableModel(parent)
|
||||
{
|
||||
}
|
||||
//! [0]
|
||||
|
||||
//! [1]
|
||||
void ImageModel::setImage(const QImage &image)
|
||||
{
|
||||
beginResetModel();
|
||||
modelImage = image;
|
||||
endResetModel();
|
||||
}
|
||||
//! [1]
|
||||
|
||||
//! [2]
|
||||
int ImageModel::rowCount(const QModelIndex & /* parent */) const
|
||||
{
|
||||
return modelImage.height();
|
||||
}
|
||||
|
||||
int ImageModel::columnCount(const QModelIndex & /* parent */) const
|
||||
//! [2] //! [3]
|
||||
{
|
||||
return modelImage.width();
|
||||
}
|
||||
//! [3]
|
||||
|
||||
//! [4]
|
||||
QVariant ImageModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid() || role != Qt::DisplayRole)
|
||||
return QVariant();
|
||||
return qGray(modelImage.pixel(index.column(), index.row()));
|
||||
}
|
||||
//! [4]
|
||||
|
||||
//! [5]
|
||||
QVariant ImageModel::headerData(int /* section */,
|
||||
Qt::Orientation /* orientation */,
|
||||
int role) const
|
||||
{
|
||||
if (role == Qt::SizeHintRole)
|
||||
return QSize(1, 1);
|
||||
return QVariant();
|
||||
}
|
||||
//! [5]
|
@ -0,0 +1,31 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#ifndef IMAGEMODEL_H
|
||||
#define IMAGEMODEL_H
|
||||
|
||||
#include <QAbstractTableModel>
|
||||
#include <QImage>
|
||||
|
||||
//! [0]
|
||||
class ImageModel : public QAbstractTableModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ImageModel(QObject *parent = nullptr);
|
||||
|
||||
void setImage(const QImage &image);
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
||||
|
||||
private:
|
||||
QImage modelImage;
|
||||
};
|
||||
//! [0]
|
||||
|
||||
#endif // IMAGEMODEL_H
|