qt 6.5.1 original

This commit is contained in:
kleuter
2023-10-29 23:33:08 +01:00
parent 71d22ab6b0
commit 85d238dfda
21202 changed files with 5499099 additions and 0 deletions

View File

@ -0,0 +1,28 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
qt_internal_add_example(addressbook)
qt_internal_add_example(basicsortfiltermodel)
qt_internal_add_example(chart)
qt_internal_add_example(coloreditorfactory)
qt_internal_add_example(combowidgetmapper)
qt_internal_add_example(customsortfiltermodel)
qt_internal_add_example(dirview)
qt_internal_add_example(editabletreemodel)
qt_internal_add_example(fetchmore)
qt_internal_add_example(flattreeview)
qt_internal_add_example(frozencolumn)
qt_internal_add_example(interview)
qt_internal_add_example(pixelator)
qt_internal_add_example(simpletreemodel)
qt_internal_add_example(simplewidgetmapper)
qt_internal_add_example(spinboxdelegate)
qt_internal_add_example(spreadsheet)
qt_internal_add_example(stardelegate)
qt_internal_add_example(storageview)
if(QT_FEATURE_draganddrop)
qt_internal_add_example(puzzle)
endif()
if(TARGET Qt6::Xml)
qt_internal_add_example(simpledommodel)
endif()

View File

@ -0,0 +1,8 @@
Item views are widgets that typically display data sets. Qt 4's model/view
framework lets you handle large data sets by separating the underlying data
from the way it is represented to the user, and provides support for
customized rendering through the use of delegates.
Documentation for these examples can be found via the Examples
link in the main Qt documentation.

View File

@ -0,0 +1,41 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
cmake_minimum_required(VERSION 3.16)
project(addressbook LANGUAGES CXX)
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/widgets/itemviews/addressbook")
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
qt_standard_project_setup()
qt_add_executable(addressbook
adddialog.cpp adddialog.h
addresswidget.cpp addresswidget.h
main.cpp
mainwindow.cpp mainwindow.h
newaddresstab.cpp newaddresstab.h
tablemodel.cpp tablemodel.h
)
set_target_properties(addressbook PROPERTIES
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
)
target_link_libraries(addressbook PRIVATE
Qt6::Core
Qt6::Gui
Qt6::Widgets
)
install(TARGETS addressbook
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
)

View File

@ -0,0 +1,59 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "adddialog.h"
#include <QtWidgets>
//! [0]
AddDialog::AddDialog(QWidget *parent)
: QDialog(parent),
nameText(new QLineEdit),
addressText(new QTextEdit)
{
auto nameLabel = new QLabel(tr("Name"));
auto addressLabel = new QLabel(tr("Address"));
auto okButton = new QPushButton(tr("OK"));
auto cancelButton = new QPushButton(tr("Cancel"));
auto gLayout = new QGridLayout;
gLayout->setColumnStretch(1, 2);
gLayout->addWidget(nameLabel, 0, 0);
gLayout->addWidget(nameText, 0, 1);
gLayout->addWidget(addressLabel, 1, 0, Qt::AlignLeft|Qt::AlignTop);
gLayout->addWidget(addressText, 1, 1, Qt::AlignLeft);
auto buttonLayout = new QHBoxLayout;
buttonLayout->addWidget(okButton);
buttonLayout->addWidget(cancelButton);
gLayout->addLayout(buttonLayout, 2, 1, Qt::AlignRight);
auto mainLayout = new QVBoxLayout;
mainLayout->addLayout(gLayout);
setLayout(mainLayout);
connect(okButton, &QAbstractButton::clicked, this, &QDialog::accept);
connect(cancelButton, &QAbstractButton::clicked, this, &QDialog::reject);
setWindowTitle(tr("Add a Contact"));
}
QString AddDialog::name() const
{
return nameText->text();
}
QString AddDialog::address() const
{
return addressText->toPlainText();
}
void AddDialog::editAddress(const QString &name, const QString &address)
{
nameText->setReadOnly(true);
nameText->setText(name);
addressText->setPlainText(address);
}
//! [0]

View File

@ -0,0 +1,34 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef ADDDIALOG_H
#define ADDDIALOG_H
#include <QDialog>
QT_BEGIN_NAMESPACE
class QLabel;
class QPushButton;
class QTextEdit;
class QLineEdit;
QT_END_NAMESPACE
//! [0]
class AddDialog : public QDialog
{
Q_OBJECT
public:
AddDialog(QWidget *parent = nullptr);
QString name() const;
QString address() const;
void editAddress(const QString &name, const QString &address);
private:
QLineEdit *nameText;
QTextEdit *addressText;
};
//! [0]
#endif // ADDDIALOG_H

View File

@ -0,0 +1,18 @@
QT += widgets
requires(qtConfig(listview))
SOURCES = adddialog.cpp \
addresswidget.cpp \
main.cpp \
mainwindow.cpp \
newaddresstab.cpp \
tablemodel.cpp
HEADERS = adddialog.h \
addresswidget.h \
mainwindow.h \
newaddresstab.h \
tablemodel.h
# install
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/itemviews/addressbook
INSTALLS += target

View File

@ -0,0 +1,186 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "addresswidget.h"
#include "adddialog.h"
#include <QtWidgets>
//! [0]
AddressWidget::AddressWidget(QWidget *parent)
: QTabWidget(parent),
table(new TableModel(this)),
newAddressTab(new NewAddressTab(this))
{
connect(newAddressTab, &NewAddressTab::sendDetails,
this, &AddressWidget::addEntry);
addTab(newAddressTab, tr("Address Book"));
setupTabs();
}
//! [0]
//! [2]
void AddressWidget::showAddEntryDialog()
{
AddDialog aDialog;
if (aDialog.exec())
addEntry(aDialog.name(), aDialog.address());
}
//! [2]
//! [3]
void AddressWidget::addEntry(const QString &name, const QString &address)
{
if (!table->getContacts().contains({ name, address })) {
table->insertRows(0, 1, QModelIndex());
QModelIndex index = table->index(0, 0, QModelIndex());
table->setData(index, name, Qt::EditRole);
index = table->index(0, 1, QModelIndex());
table->setData(index, address, Qt::EditRole);
removeTab(indexOf(newAddressTab));
} else {
QMessageBox::information(this, tr("Duplicate Name"),
tr("The name \"%1\" already exists.").arg(name));
}
}
//! [3]
//! [4a]
void AddressWidget::editEntry()
{
QTableView *temp = static_cast<QTableView*>(currentWidget());
QSortFilterProxyModel *proxy = static_cast<QSortFilterProxyModel*>(temp->model());
QItemSelectionModel *selectionModel = temp->selectionModel();
const QModelIndexList indexes = selectionModel->selectedRows();
QString name;
QString address;
int row = -1;
for (const QModelIndex &index : indexes) {
row = proxy->mapToSource(index).row();
QModelIndex nameIndex = table->index(row, 0, QModelIndex());
QVariant varName = table->data(nameIndex, Qt::DisplayRole);
name = varName.toString();
QModelIndex addressIndex = table->index(row, 1, QModelIndex());
QVariant varAddr = table->data(addressIndex, Qt::DisplayRole);
address = varAddr.toString();
}
//! [4a]
//! [4b]
AddDialog aDialog;
aDialog.setWindowTitle(tr("Edit a Contact"));
aDialog.editAddress(name, address);
if (aDialog.exec()) {
const QString newAddress = aDialog.address();
if (newAddress != address) {
const QModelIndex index = table->index(row, 1, QModelIndex());
table->setData(index, newAddress, Qt::EditRole);
}
}
}
//! [4b]
//! [5]
void AddressWidget::removeEntry()
{
QTableView *temp = static_cast<QTableView*>(currentWidget());
QSortFilterProxyModel *proxy = static_cast<QSortFilterProxyModel*>(temp->model());
QItemSelectionModel *selectionModel = temp->selectionModel();
const QModelIndexList indexes = selectionModel->selectedRows();
for (QModelIndex index : indexes) {
int row = proxy->mapToSource(index).row();
table->removeRows(row, 1, QModelIndex());
}
if (table->rowCount(QModelIndex()) == 0)
insertTab(0, newAddressTab, tr("Address Book"));
}
//! [5]
//! [1]
void AddressWidget::setupTabs()
{
using namespace Qt::StringLiterals;
const auto groups = { "ABC"_L1, "DEF"_L1, "GHI"_L1, "JKL"_L1, "MNO"_L1, "PQR"_L1,
"STU"_L1, "VW"_L1, "XYZ"_L1 };
for (QLatin1StringView str : groups) {
const auto regExp = QRegularExpression(QLatin1StringView("^[%1].*").arg(str),
QRegularExpression::CaseInsensitiveOption);
auto proxyModel = new QSortFilterProxyModel(this);
proxyModel->setSourceModel(table);
proxyModel->setFilterRegularExpression(regExp);
proxyModel->setFilterKeyColumn(0);
QTableView *tableView = new QTableView;
tableView->setModel(proxyModel);
tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
tableView->horizontalHeader()->setStretchLastSection(true);
tableView->verticalHeader()->hide();
tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
tableView->setSelectionMode(QAbstractItemView::SingleSelection);
tableView->setSortingEnabled(true);
connect(tableView->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &AddressWidget::selectionChanged);
connect(this, &QTabWidget::currentChanged, this, [this, tableView](int tabIndex) {
if (widget(tabIndex) == tableView)
emit selectionChanged(tableView->selectionModel()->selection());
});
addTab(tableView, str);
}
}
//! [1]
//! [7]
void AddressWidget::readFromFile()
{
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly)) {
QMessageBox::information(this, tr("Unable to open file"),
file.errorString());
return;
}
QList<Contact> contacts;
QDataStream in(&file);
in >> contacts;
if (contacts.isEmpty()) {
QMessageBox::information(this, tr("No contacts in file"),
tr("The file you are attempting to open contains no contacts."));
} else {
for (const auto &contact: std::as_const(contacts))
addEntry(contact.name, contact.address);
}
}
//! [7]
//! [6]
void AddressWidget::writeToFile()
{
QFile file(fileName);
if (!file.open(QIODevice::WriteOnly)) {
QMessageBox::information(this, tr("Unable to open file"), file.errorString());
return;
}
QDataStream out(&file);
out << table->getContacts();
}
//! [6]

View File

@ -0,0 +1,49 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef ADDRESSWIDGET_H
#define ADDRESSWIDGET_H
#include "newaddresstab.h"
#include "tablemodel.h"
#include <QItemSelection>
#include <QTabWidget>
#include <QStandardPaths>
QT_BEGIN_NAMESPACE
class QSortFilterProxyModel;
class QItemSelectionModel;
QT_END_NAMESPACE
//! [0]
class AddressWidget : public QTabWidget
{
Q_OBJECT
public:
AddressWidget(QWidget *parent = nullptr);
void readFromFile();
void writeToFile();
public slots:
void showAddEntryDialog();
void addEntry(const QString &name, const QString &address);
void editEntry();
void removeEntry();
signals:
void selectionChanged (const QItemSelection &selected);
private:
void setupTabs();
inline static QString fileName =
QStandardPaths::standardLocations(QStandardPaths::TempLocation).value(0)
+ QStringLiteral("/addressbook.dat");
TableModel *table;
NewAddressTab *newAddressTab;
};
//! [0]
#endif // ADDRESSWIDGET_H

View File

@ -0,0 +1,16 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "mainwindow.h"
#include <QApplication>
//! [0]
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MainWindow mw;
mw.show();
return app.exec();
}
//! [0]

View File

@ -0,0 +1,93 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "mainwindow.h"
#include <QAction>
#include <QFileDialog>
#include <QMenuBar>
//! [0]
MainWindow::MainWindow()
: QMainWindow(),
addressWidget(new AddressWidget)
{
setCentralWidget(addressWidget);
createMenus();
setWindowTitle(tr("Address Book"));
}
//! [0]
//! [1a]
void MainWindow::createMenus()
{
QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
QAction *openAct = new QAction(tr("&Open..."), this);
fileMenu->addAction(openAct);
connect(openAct, &QAction::triggered, this, &MainWindow::openFile);
//! [1a]
QAction *saveAct = new QAction(tr("&Save"), this);
fileMenu->addAction(saveAct);
connect(saveAct, &QAction::triggered, this, &MainWindow::saveFile);
fileMenu->addSeparator();
QAction *exitAct = new QAction(tr("E&xit"), this);
fileMenu->addAction(exitAct);
connect(exitAct, &QAction::triggered, this, &QWidget::close);
QMenu *toolMenu = menuBar()->addMenu(tr("&Tools"));
QAction *addAct = new QAction(tr("&Add Entry..."), this);
toolMenu->addAction(addAct);
connect(addAct, &QAction::triggered,
addressWidget, &AddressWidget::showAddEntryDialog);
//! [1b]
editAct = new QAction(tr("&Edit Entry..."), this);
editAct->setEnabled(false);
toolMenu->addAction(editAct);
connect(editAct, &QAction::triggered, addressWidget, &AddressWidget::editEntry);
toolMenu->addSeparator();
removeAct = new QAction(tr("&Remove Entry"), this);
removeAct->setEnabled(false);
toolMenu->addAction(removeAct);
connect(removeAct, &QAction::triggered, addressWidget, &AddressWidget::removeEntry);
connect(addressWidget, &AddressWidget::selectionChanged,
this, &MainWindow::updateActions);
}
//! [1b]
//! [2]
void MainWindow::openFile()
{
addressWidget->readFromFile();
}
//! [2]
//! [3]
void MainWindow::saveFile()
{
addressWidget->writeToFile();
}
//! [3]
//! [4]
void MainWindow::updateActions(const QItemSelection &selection)
{
QModelIndexList indexes = selection.indexes();
if (!indexes.isEmpty()) {
removeAct->setEnabled(true);
editAct->setEnabled(true);
} else {
removeAct->setEnabled(false);
editAct->setEnabled(false);
}
}
//! [4]

View File

@ -0,0 +1,33 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include "addresswidget.h"
#include <QMainWindow>
//! [0]
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow();
private slots:
void updateActions(const QItemSelection &selection);
void openFile();
void saveFile();
private:
void createMenus();
AddressWidget *addressWidget;
QAction *editAct;
QAction *removeAct;
};
//! [0]
#endif // MAINWINDOW_H

View File

@ -0,0 +1,36 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "newaddresstab.h"
#include "adddialog.h"
#include <QtWidgets>
//! [0]
NewAddressTab::NewAddressTab(QWidget *parent)
: QWidget(parent)
{
auto descriptionLabel = new QLabel(tr("There are currently no contacts in your address book. "
"\nClick Add to add new contacts."));
auto addButton = new QPushButton(tr("Add"));
connect(addButton, &QAbstractButton::clicked, this, &NewAddressTab::addEntry);
auto mainLayout = new QVBoxLayout;
mainLayout->addWidget(descriptionLabel);
mainLayout->addWidget(addButton, 0, Qt::AlignCenter);
setLayout(mainLayout);
}
//! [0]
//! [1]
void NewAddressTab::addEntry()
{
AddDialog aDialog;
if (aDialog.exec())
emit sendDetails(aDialog.name(), aDialog.address());
}
//! [1]

View File

@ -0,0 +1,31 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef NEWADDRESSTAB_H
#define NEWADDRESSTAB_H
#include <QWidget>
QT_BEGIN_NAMESPACE
class QLabel;
class QPushButton;
class QVBoxLayout;
QT_END_NAMESPACE
//! [0]
class NewAddressTab : public QWidget
{
Q_OBJECT
public:
NewAddressTab(QWidget *parent = nullptr);
public slots:
void addEntry();
signals:
void sendDetails(const QString &name, const QString &address);
};
//! [0]
#endif

View File

@ -0,0 +1,145 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "tablemodel.h"
//! [0]
TableModel::TableModel(QObject *parent)
: QAbstractTableModel(parent)
{
}
TableModel::TableModel(const QList<Contact> &contacts, QObject *parent)
: QAbstractTableModel(parent), contacts(contacts)
{
}
//! [0]
//! [1]
int TableModel::rowCount(const QModelIndex &parent) const
{
return parent.isValid() ? 0 : contacts.size();
}
int TableModel::columnCount(const QModelIndex &parent) const
{
return parent.isValid() ? 0 : 2;
}
//! [1]
//! [2]
QVariant TableModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
if (index.row() >= contacts.size() || index.row() < 0)
return QVariant();
if (role == Qt::DisplayRole) {
const auto &contact = contacts.at(index.row());
switch (index.column()) {
case 0:
return contact.name;
case 1:
return contact.address;
default:
break;
}
}
return QVariant();
}
//! [2]
//! [3]
QVariant TableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (role != Qt::DisplayRole)
return QVariant();
if (orientation == Qt::Horizontal) {
switch (section) {
case 0:
return tr("Name");
case 1:
return tr("Address");
default:
break;
}
}
return QVariant();
}
//! [3]
//! [4]
bool TableModel::insertRows(int position, int rows, const QModelIndex &index)
{
Q_UNUSED(index);
beginInsertRows(QModelIndex(), position, position + rows - 1);
for (int row = 0; row < rows; ++row)
contacts.insert(position, { QString(), QString() });
endInsertRows();
return true;
}
//! [4]
//! [5]
bool TableModel::removeRows(int position, int rows, const QModelIndex &index)
{
Q_UNUSED(index);
beginRemoveRows(QModelIndex(), position, position + rows - 1);
for (int row = 0; row < rows; ++row)
contacts.removeAt(position);
endRemoveRows();
return true;
}
//! [5]
//! [6]
bool TableModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (index.isValid() && role == Qt::EditRole) {
const int row = index.row();
auto contact = contacts.value(row);
switch (index.column()) {
case 0:
contact.name = value.toString();
break;
case 1:
contact.address = value.toString();
break;
default:
return false;
}
contacts.replace(row, contact);
emit dataChanged(index, index, {Qt::DisplayRole, Qt::EditRole});
return true;
}
return false;
}
//! [6]
//! [7]
Qt::ItemFlags TableModel::flags(const QModelIndex &index) const
{
if (!index.isValid())
return Qt::ItemIsEnabled;
return QAbstractTableModel::flags(index) | Qt::ItemIsEditable;
}
//! [7]
//! [8]
const QList<Contact> &TableModel::getContacts() const
{
return contacts;
}
//! [8]

View File

@ -0,0 +1,56 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef TABLEMODEL_H
#define TABLEMODEL_H
#include <QAbstractTableModel>
#include <QList>
//! [0]
struct Contact
{
QString name;
QString address;
bool operator==(const Contact &other) const
{
return name == other.name && address == other.address;
}
};
inline QDataStream &operator<<(QDataStream &stream, const Contact &contact)
{
return stream << contact.name << contact.address;
}
inline QDataStream &operator>>(QDataStream &stream, Contact &contact)
{
return stream >> contact.name >> contact.address;
}
class TableModel : public QAbstractTableModel
{
Q_OBJECT
public:
TableModel(QObject *parent = nullptr);
TableModel(const QList<Contact> &contacts, QObject *parent = nullptr);
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;
Qt::ItemFlags flags(const QModelIndex &index) const override;
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
bool insertRows(int position, int rows, const QModelIndex &index = QModelIndex()) override;
bool removeRows(int position, int rows, const QModelIndex &index = QModelIndex()) override;
const QList<Contact> &getContacts() const;
private:
QList<Contact> contacts;
};
//! [0]
#endif // TABLEMODEL_H

View File

@ -0,0 +1,37 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
cmake_minimum_required(VERSION 3.16)
project(basicsortfiltermodel LANGUAGES CXX)
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/widgets/itemviews/basicsortfiltermodel")
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
qt_standard_project_setup()
qt_add_executable(basicsortfiltermodel
main.cpp
window.cpp window.h
)
set_target_properties(basicsortfiltermodel PROPERTIES
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
)
target_link_libraries(basicsortfiltermodel PRIVATE
Qt6::Core
Qt6::Gui
Qt6::Widgets
)
install(TARGETS basicsortfiltermodel
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
)

View File

@ -0,0 +1,10 @@
QT += widgets
requires(qtConfig(combobox))
HEADERS = window.h
SOURCES = main.cpp \
window.cpp
# install
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/itemviews/basicsortfiltermodel
INSTALLS += target

View File

@ -0,0 +1,58 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "window.h"
#include <QApplication>
#include <QStandardItemModel>
#include <QTime>
void addMail(QAbstractItemModel *model, const QString &subject,
const QString &sender, const QDateTime &date)
{
model->insertRow(0);
model->setData(model->index(0, 0), subject);
model->setData(model->index(0, 1), sender);
model->setData(model->index(0, 2), date);
}
QAbstractItemModel *createMailModel(QObject *parent)
{
QStandardItemModel *model = new QStandardItemModel(0, 3, parent);
model->setHeaderData(0, Qt::Horizontal, QObject::tr("Subject"));
model->setHeaderData(1, Qt::Horizontal, QObject::tr("Sender"));
model->setHeaderData(2, Qt::Horizontal, QObject::tr("Date"));
addMail(model, "Happy New Year!", "Grace K. <grace@software-inc.com>",
QDateTime(QDate(2006, 12, 31), QTime(17, 03)));
addMail(model, "Radically new concept", "Grace K. <grace@software-inc.com>",
QDateTime(QDate(2006, 12, 22), QTime(9, 44)));
addMail(model, "Accounts", "pascale@nospam.com",
QDateTime(QDate(2006, 12, 31), QTime(12, 50)));
addMail(model, "Expenses", "Joe Bloggs <joe@bloggs.com>",
QDateTime(QDate(2006, 12, 25), QTime(11, 39)));
addMail(model, "Re: Expenses", "Andy <andy@nospam.com>",
QDateTime(QDate(2007, 01, 02), QTime(16, 05)));
addMail(model, "Re: Accounts", "Joe Bloggs <joe@bloggs.com>",
QDateTime(QDate(2007, 01, 03), QTime(14, 18)));
addMail(model, "Re: Accounts", "Andy <andy@nospam.com>",
QDateTime(QDate(2007, 01, 03), QTime(14, 26)));
addMail(model, "Sports", "Linda Smith <linda.smith@nospam.com>",
QDateTime(QDate(2007, 01, 05), QTime(11, 33)));
addMail(model, "AW: Sports", "Rolf Newschweinstein <rolfn@nospam.com>",
QDateTime(QDate(2007, 01, 05), QTime(12, 00)));
addMail(model, "RE: Sports", "Petra Schmidt <petras@nospam.com>",
QDateTime(QDate(2007, 01, 05), QTime(12, 01)));
return model;
}
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
Window window;
window.setSourceModel(createMailModel(&window));
window.show();
return app.exec();
}

View File

@ -0,0 +1,153 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include <QtWidgets>
#include "window.h"
static inline QColor textColor(const QPalette &palette)
{
return palette.color(QPalette::Active, QPalette::Text);
}
static void setTextColor(QWidget *w, const QColor &c)
{
auto palette = w->palette();
if (textColor(palette) != c) {
palette.setColor(QPalette::Active, QPalette::Text, c);
w->setPalette(palette);
}
}
Window::Window()
{
proxyModel = new QSortFilterProxyModel;
sourceView = new QTreeView;
sourceView->setRootIsDecorated(false);
sourceView->setAlternatingRowColors(true);
proxyView = new QTreeView;
proxyView->setRootIsDecorated(false);
proxyView->setAlternatingRowColors(true);
proxyView->setModel(proxyModel);
proxyView->setSortingEnabled(true);
sortCaseSensitivityCheckBox = new QCheckBox(tr("Case sensitive sorting"));
filterCaseSensitivityCheckBox = new QCheckBox(tr("Case sensitive filter"));
filterPatternLineEdit = new QLineEdit;
filterPatternLineEdit->setClearButtonEnabled(true);
filterPatternLabel = new QLabel(tr("&Filter pattern:"));
filterPatternLabel->setBuddy(filterPatternLineEdit);
filterSyntaxComboBox = new QComboBox;
filterSyntaxComboBox->addItem(tr("Regular expression"), RegularExpression);
filterSyntaxComboBox->addItem(tr("Wildcard"), Wildcard);
filterSyntaxComboBox->addItem(tr("Fixed string"), FixedString);
filterSyntaxLabel = new QLabel(tr("Filter &syntax:"));
filterSyntaxLabel->setBuddy(filterSyntaxComboBox);
filterColumnComboBox = new QComboBox;
filterColumnComboBox->addItem(tr("Subject"));
filterColumnComboBox->addItem(tr("Sender"));
filterColumnComboBox->addItem(tr("Date"));
filterColumnLabel = new QLabel(tr("Filter &column:"));
filterColumnLabel->setBuddy(filterColumnComboBox);
connect(filterPatternLineEdit, &QLineEdit::textChanged,
this, &Window::filterRegularExpressionChanged);
connect(filterSyntaxComboBox, &QComboBox::currentIndexChanged,
this, &Window::filterRegularExpressionChanged);
connect(filterColumnComboBox, &QComboBox::currentIndexChanged,
this, &Window::filterColumnChanged);
connect(filterCaseSensitivityCheckBox, &QAbstractButton::toggled,
this, &Window::filterRegularExpressionChanged);
connect(sortCaseSensitivityCheckBox, &QAbstractButton::toggled,
this, &Window::sortChanged);
sourceGroupBox = new QGroupBox(tr("Original Model"));
proxyGroupBox = new QGroupBox(tr("Sorted/Filtered Model"));
QHBoxLayout *sourceLayout = new QHBoxLayout;
sourceLayout->addWidget(sourceView);
sourceGroupBox->setLayout(sourceLayout);
QGridLayout *proxyLayout = new QGridLayout;
proxyLayout->addWidget(proxyView, 0, 0, 1, 3);
proxyLayout->addWidget(filterPatternLabel, 1, 0);
proxyLayout->addWidget(filterPatternLineEdit, 1, 1, 1, 2);
proxyLayout->addWidget(filterSyntaxLabel, 2, 0);
proxyLayout->addWidget(filterSyntaxComboBox, 2, 1, 1, 2);
proxyLayout->addWidget(filterColumnLabel, 3, 0);
proxyLayout->addWidget(filterColumnComboBox, 3, 1, 1, 2);
proxyLayout->addWidget(filterCaseSensitivityCheckBox, 4, 0, 1, 2);
proxyLayout->addWidget(sortCaseSensitivityCheckBox, 4, 2);
proxyGroupBox->setLayout(proxyLayout);
QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->addWidget(sourceGroupBox);
mainLayout->addWidget(proxyGroupBox);
setLayout(mainLayout);
setWindowTitle(tr("Basic Sort/Filter Model"));
resize(500, 450);
proxyView->sortByColumn(1, Qt::AscendingOrder);
filterColumnComboBox->setCurrentIndex(1);
filterPatternLineEdit->setText("Andy|Grace");
filterCaseSensitivityCheckBox->setChecked(true);
sortCaseSensitivityCheckBox->setChecked(true);
}
void Window::setSourceModel(QAbstractItemModel *model)
{
proxyModel->setSourceModel(model);
sourceView->setModel(model);
}
void Window::filterRegularExpressionChanged()
{
Syntax s = Syntax(filterSyntaxComboBox->itemData(filterSyntaxComboBox->currentIndex()).toInt());
QString pattern = filterPatternLineEdit->text();
switch (s) {
case Wildcard:
pattern = QRegularExpression::wildcardToRegularExpression(pattern);
break;
case FixedString:
pattern = QRegularExpression::escape(pattern);
break;
default:
break;
}
QRegularExpression::PatternOptions options = QRegularExpression::NoPatternOption;
if (!filterCaseSensitivityCheckBox->isChecked())
options |= QRegularExpression::CaseInsensitiveOption;
QRegularExpression regularExpression(pattern, options);
if (regularExpression.isValid()) {
filterPatternLineEdit->setToolTip(QString());
proxyModel->setFilterRegularExpression(regularExpression);
setTextColor(filterPatternLineEdit, textColor(style()->standardPalette()));
} else {
filterPatternLineEdit->setToolTip(regularExpression.errorString());
proxyModel->setFilterRegularExpression(QRegularExpression());
setTextColor(filterPatternLineEdit, Qt::red);
}
}
void Window::filterColumnChanged()
{
proxyModel->setFilterKeyColumn(filterColumnComboBox->currentIndex());
}
void Window::sortChanged()
{
proxyModel->setSortCaseSensitivity(
sortCaseSensitivityCheckBox->isChecked() ? Qt::CaseSensitive
: Qt::CaseInsensitive);
}

View File

@ -0,0 +1,57 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef WINDOW_H
#define WINDOW_H
#include <QWidget>
QT_BEGIN_NAMESPACE
class QAbstractItemModel;
class QCheckBox;
class QComboBox;
class QGroupBox;
class QLabel;
class QLineEdit;
class QSortFilterProxyModel;
class QTreeView;
QT_END_NAMESPACE
class Window : public QWidget
{
Q_OBJECT
public:
Window();
void setSourceModel(QAbstractItemModel *model);
private slots:
void filterRegularExpressionChanged();
void filterColumnChanged();
void sortChanged();
private:
QSortFilterProxyModel *proxyModel;
QGroupBox *sourceGroupBox;
QGroupBox *proxyGroupBox;
QTreeView *sourceView;
QTreeView *proxyView;
QCheckBox *filterCaseSensitivityCheckBox;
QCheckBox *sortCaseSensitivityCheckBox;
QLabel *filterPatternLabel;
QLabel *filterSyntaxLabel;
QLabel *filterColumnLabel;
QLineEdit *filterPatternLineEdit;
enum Syntax {
RegularExpression,
Wildcard,
FixedString
};
QComboBox *filterSyntaxComboBox;
QComboBox *filterColumnComboBox;
};
#endif // WINDOW_H

View 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}"
)

View 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

View File

@ -0,0 +1,5 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource prefix="/Charts" >
<file>qtdata.cht</file>
</qresource>
</RCC>

View 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 "mainwindow.h"
int main(int argc, char *argv[])
{
Q_INIT_RESOURCE(chart);
QApplication app(argc, argv);
MainWindow window;
window.show();
return app.exec();
}

View 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);
}

View 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

View 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;
}

View 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

View 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

View File

@ -0,0 +1,38 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
cmake_minimum_required(VERSION 3.16)
project(coloreditorfactory LANGUAGES CXX)
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/widgets/itemviews/coloreditorfactory")
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
qt_standard_project_setup()
qt_add_executable(coloreditorfactory
colorlisteditor.cpp colorlisteditor.h
main.cpp
window.cpp window.h
)
set_target_properties(coloreditorfactory PROPERTIES
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
)
target_link_libraries(coloreditorfactory PRIVATE
Qt6::Core
Qt6::Gui
Qt6::Widgets
)
install(TARGETS coloreditorfactory
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
)

View File

@ -0,0 +1,12 @@
QT += widgets
requires(qtConfig(combobox))
HEADERS = colorlisteditor.h \
window.h
SOURCES = colorlisteditor.cpp \
window.cpp \
main.cpp
# install
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/itemviews/coloreditorfactory
INSTALLS += target

View File

@ -0,0 +1,39 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "colorlisteditor.h"
#include <QtWidgets>
ColorListEditor::ColorListEditor(QWidget *widget) : QComboBox(widget)
{
populateList();
}
//! [0]
QColor ColorListEditor::color() const
{
return qvariant_cast<QColor>(itemData(currentIndex(), Qt::DecorationRole));
}
//! [0]
//! [1]
void ColorListEditor::setColor(const QColor &color)
{
setCurrentIndex(findData(color, Qt::DecorationRole));
}
//! [1]
//! [2]
void ColorListEditor::populateList()
{
const QStringList colorNames = QColor::colorNames();
for (int i = 0; i < colorNames.size(); ++i) {
QColor color(colorNames[i]);
insertItem(i, colorNames[i]);
setItemData(i, color, Qt::DecorationRole);
}
}
//! [2]

View File

@ -0,0 +1,32 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef COLORLISTEDITOR_H
#define COLORLISTEDITOR_H
#include <QComboBox>
QT_BEGIN_NAMESPACE
class QColor;
class QWidget;
QT_END_NAMESPACE
//! [0]
class ColorListEditor : public QComboBox
{
Q_OBJECT
Q_PROPERTY(QColor color READ color WRITE setColor USER true)
public:
ColorListEditor(QWidget *widget = nullptr);
public:
QColor color() const;
void setColor(const QColor &color);
private:
void populateList();
};
//! [0]
#endif

View File

@ -0,0 +1,16 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include <QtWidgets>
#include "window.h"
int main(int argv, char **args)
{
QApplication app(argv, args);
Window window;
window.show();
return app.exec();
}

View File

@ -0,0 +1,55 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "window.h"
#include "colorlisteditor.h"
#include <QtWidgets>
//! [0]
Window::Window()
{
QItemEditorFactory *factory = new QItemEditorFactory;
QItemEditorCreatorBase *colorListCreator =
new QStandardItemEditorCreator<ColorListEditor>();
factory->registerEditor(QMetaType::QColor, colorListCreator);
QItemEditorFactory::setDefaultFactory(factory);
createGUI();
}
//! [0]
void Window::createGUI()
{
const QList<QPair<QString, QColor>> list = { { tr("Alice"), QColor("aliceblue") },
{ tr("Neptun"), QColor("aquamarine") },
{ tr("Ferdinand"), QColor("springgreen") } };
QTableWidget *table = new QTableWidget(3, 2);
table->setHorizontalHeaderLabels({ tr("Name"), tr("Hair Color") });
table->verticalHeader()->setVisible(false);
table->resize(150, 50);
for (int i = 0; i < 3; ++i) {
const QPair<QString, QColor> &pair = list.at(i);
QTableWidgetItem *nameItem = new QTableWidgetItem(pair.first);
QTableWidgetItem *colorItem = new QTableWidgetItem;
colorItem->setData(Qt::DisplayRole, pair.second);
table->setItem(i, 0, nameItem);
table->setItem(i, 1, colorItem);
}
table->resizeColumnToContents(0);
table->horizontalHeader()->setStretchLastSection(true);
QGridLayout *layout = new QGridLayout;
layout->addWidget(table, 0, 0);
setLayout(layout);
setWindowTitle(tr("Color Editor Factory"));
}

View File

@ -0,0 +1,20 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef WINDOW_H
#define WINDOW_H
#include <QWidget>
class Window : public QWidget
{
Q_OBJECT
public:
Window();
private:
void createGUI();
};
#endif

View File

@ -0,0 +1,37 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
cmake_minimum_required(VERSION 3.16)
project(combowidgetmapper LANGUAGES CXX)
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/widgets/itemviews/combowidgetmapper")
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
qt_standard_project_setup()
qt_add_executable(combowidgetmapper
main.cpp
window.cpp window.h
)
set_target_properties(combowidgetmapper PROPERTIES
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
)
target_link_libraries(combowidgetmapper PRIVATE
Qt6::Core
Qt6::Gui
Qt6::Widgets
)
install(TARGETS combowidgetmapper
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
)

View File

@ -0,0 +1,11 @@
QT += widgets
requires(qtConfig(combobox))
HEADERS = window.h
SOURCES = main.cpp \
window.cpp
# install
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/itemviews/combowidgetmapper
INSTALLS += target

View 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 "window.h"
int main(int argc, char **argv)
{
QApplication app(argc, argv);
Window window;
window.show();
return app.exec();
}

View File

@ -0,0 +1,99 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include <QtWidgets>
#include "window.h"
//! [Set up widgets]
Window::Window(QWidget *parent)
: QWidget(parent)
{
setupModel();
nameLabel = new QLabel(tr("Na&me:"));
nameEdit = new QLineEdit();
addressLabel = new QLabel(tr("&Address:"));
addressEdit = new QTextEdit();
typeLabel = new QLabel(tr("&Type:"));
typeComboBox = new QComboBox();
nextButton = new QPushButton(tr("&Next"));
previousButton = new QPushButton(tr("&Previous"));
nameLabel->setBuddy(nameEdit);
addressLabel->setBuddy(addressEdit);
typeLabel->setBuddy(typeComboBox);
typeComboBox->setModel(typeModel);
//! [Set up widgets]
//! [Set up the mapper]
mapper = new QDataWidgetMapper(this);
mapper->setModel(model);
mapper->addMapping(nameEdit, 0);
mapper->addMapping(addressEdit, 1);
mapper->addMapping(typeComboBox, 2, "currentIndex");
//! [Set up the mapper]
//! [Set up connections and layouts]
connect(previousButton, &QAbstractButton::clicked,
mapper, &QDataWidgetMapper::toPrevious);
connect(nextButton, &QAbstractButton::clicked,
mapper, &QDataWidgetMapper::toNext);
connect(mapper, &QDataWidgetMapper::currentIndexChanged,
this, &Window::updateButtons);
QGridLayout *layout = new QGridLayout();
layout->addWidget(nameLabel, 0, 0, 1, 1);
layout->addWidget(nameEdit, 0, 1, 1, 1);
layout->addWidget(previousButton, 0, 2, 1, 1);
layout->addWidget(addressLabel, 1, 0, 1, 1);
layout->addWidget(addressEdit, 1, 1, 2, 1);
layout->addWidget(nextButton, 1, 2, 1, 1);
layout->addWidget(typeLabel, 3, 0, 1, 1);
layout->addWidget(typeComboBox, 3, 1, 1, 1);
setLayout(layout);
setWindowTitle(tr("Delegate Widget Mapper"));
mapper->toFirst();
}
//! [Set up connections and layouts]
//! [Set up the model]
void Window::setupModel()
{
QStringList items;
items << tr("Home") << tr("Work") << tr("Other");
typeModel = new QStringListModel(items, this);
model = new QStandardItemModel(5, 3, this);
QStringList names;
names << "Alice" << "Bob" << "Carol" << "Donald" << "Emma";
QStringList addresses;
addresses << "<qt>123 Main Street<br/>Market Town</qt>"
<< "<qt>PO Box 32<br/>Mail Handling Service"
"<br/>Service City</qt>"
<< "<qt>The Lighthouse<br/>Remote Island</qt>"
<< "<qt>47338 Park Avenue<br/>Big City</qt>"
<< "<qt>Research Station<br/>Base Camp<br/>Big Mountain</qt>";
QStringList types;
types << "0" << "1" << "2" << "0" << "2";
for (int row = 0; row < 5; ++row) {
QStandardItem *item = new QStandardItem(names[row]);
model->setItem(row, 0, item);
item = new QStandardItem(addresses[row]);
model->setItem(row, 1, item);
item = new QStandardItem(types[row]);
model->setItem(row, 2, item);
}
}
//! [Set up the model]
//! [Slot for updating the buttons]
void Window::updateButtons(int row)
{
previousButton->setEnabled(row > 0);
nextButton->setEnabled(row < model->rowCount() - 1);
}
//! [Slot for updating the buttons]

View File

@ -0,0 +1,49 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef WINDOW_H
#define WINDOW_H
#include <QWidget>
QT_BEGIN_NAMESPACE
class QComboBox;
class QDataWidgetMapper;
class QLabel;
class QLineEdit;
class QPushButton;
class QStandardItemModel;
class QStringListModel;
class QTextEdit;
QT_END_NAMESPACE
//! [Window definition]
class Window : public QWidget
{
Q_OBJECT
public:
Window(QWidget *parent = nullptr);
private slots:
void updateButtons(int row);
private:
void setupModel();
QLabel *nameLabel;
QLabel *addressLabel;
QLabel *typeLabel;
QLineEdit *nameEdit;
QTextEdit *addressEdit;
QComboBox *typeComboBox;
QPushButton *nextButton;
QPushButton *previousButton;
QStandardItemModel *model;
QStringListModel *typeModel;
QDataWidgetMapper *mapper;
};
//! [Window definition]
#endif // WINDOW_H

View File

@ -0,0 +1,51 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
cmake_minimum_required(VERSION 3.16)
project(customsortfiltermodel LANGUAGES CXX)
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/widgets/itemviews/customsortfiltermodel")
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
qt_standard_project_setup()
qt_add_executable(customsortfiltermodel
filterwidget.cpp filterwidget.h
main.cpp
mysortfilterproxymodel.cpp mysortfilterproxymodel.h
window.cpp window.h
)
set_target_properties(customsortfiltermodel PROPERTIES
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
)
target_link_libraries(customsortfiltermodel PRIVATE
Qt6::Core
Qt6::Gui
Qt6::Widgets
)
# Resources:
set(customsortfiltermodel_resource_files
"images/find.png"
)
qt_add_resources(customsortfiltermodel "customsortfiltermodel"
PREFIX
"/"
FILES
${customsortfiltermodel_resource_files}
)
install(TARGETS customsortfiltermodel
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
)

View File

@ -0,0 +1,16 @@
QT += widgets
requires(qtConfig(treeview))
HEADERS = mysortfilterproxymodel.h \
window.h \
filterwidget.h
SOURCES = main.cpp \
mysortfilterproxymodel.cpp \
window.cpp \
filterwidget.cpp
RESOURCES += customsortfiltermodel.qrc
# install
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/itemviews/customsortfiltermodel
INSTALLS += target

View File

@ -0,0 +1,5 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource prefix="/">
<file>images/find.png</file>
</qresource>
</RCC>

View File

@ -0,0 +1,88 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "filterwidget.h"
#include <QIcon>
#include <QPixmap>
#include <QMenu>
#include <QAction>
#include <QActionGroup>
#include <QToolButton>
#include <QWidgetAction>
FilterWidget::FilterWidget(QWidget *parent)
: QLineEdit(parent)
, m_patternGroup(new QActionGroup(this))
{
setClearButtonEnabled(true);
connect(this, &QLineEdit::textChanged, this, &FilterWidget::filterChanged);
QMenu *menu = new QMenu(this);
m_caseSensitivityAction = menu->addAction(tr("Case Sensitive"));
m_caseSensitivityAction->setCheckable(true);
connect(m_caseSensitivityAction, &QAction::toggled, this, &FilterWidget::filterChanged);
menu->addSeparator();
m_patternGroup->setExclusive(true);
QAction *patternAction = menu->addAction("Regular Expression");
patternAction->setCheckable(true);
patternAction->setChecked(true);
patternAction->setData(QVariant(int(RegularExpression)));
m_patternGroup->addAction(patternAction);
patternAction = menu->addAction("Wildcard");
patternAction->setCheckable(true);
patternAction->setData(QVariant(int(Wildcard)));
m_patternGroup->addAction(patternAction);
patternAction = menu->addAction("Fixed String");
patternAction->setData(QVariant(int(FixedString)));
patternAction->setCheckable(true);
m_patternGroup->addAction(patternAction);
connect(m_patternGroup, &QActionGroup::triggered, this, &FilterWidget::filterChanged);
const QIcon icon = QIcon(QPixmap(":/images/find.png"));
QToolButton *optionsButton = new QToolButton;
#ifndef QT_NO_CURSOR
optionsButton->setCursor(Qt::ArrowCursor);
#endif
optionsButton->setFocusPolicy(Qt::NoFocus);
optionsButton->setStyleSheet("* { border: none; }");
optionsButton->setIcon(icon);
optionsButton->setMenu(menu);
optionsButton->setPopupMode(QToolButton::InstantPopup);
QWidgetAction *optionsAction = new QWidgetAction(this);
optionsAction->setDefaultWidget(optionsButton);
addAction(optionsAction, QLineEdit::LeadingPosition);
}
Qt::CaseSensitivity FilterWidget::caseSensitivity() const
{
return m_caseSensitivityAction->isChecked() ? Qt::CaseSensitive : Qt::CaseInsensitive;
}
void FilterWidget::setCaseSensitivity(Qt::CaseSensitivity cs)
{
m_caseSensitivityAction->setChecked(cs == Qt::CaseSensitive);
}
static inline FilterWidget::PatternSyntax patternSyntaxFromAction(const QAction *a)
{
return static_cast<FilterWidget::PatternSyntax>(a->data().toInt());
}
FilterWidget::PatternSyntax FilterWidget::patternSyntax() const
{
return patternSyntaxFromAction(m_patternGroup->checkedAction());
}
void FilterWidget::setPatternSyntax(PatternSyntax s)
{
const QList<QAction*> actions = m_patternGroup->actions();
for (QAction *a : actions) {
if (patternSyntaxFromAction(a) == s) {
a->setChecked(true);
break;
}
}
}

View File

@ -0,0 +1,43 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef FILTERWIDGET_H
#define FILTERWIDGET_H
#include <QLineEdit>
QT_BEGIN_NAMESPACE
class QAction;
class QActionGroup;
QT_END_NAMESPACE
class FilterWidget : public QLineEdit
{
Q_OBJECT
Q_PROPERTY(Qt::CaseSensitivity caseSensitivity READ caseSensitivity WRITE setCaseSensitivity)
Q_PROPERTY(PatternSyntax patternSyntax READ patternSyntax WRITE setPatternSyntax)
public:
explicit FilterWidget(QWidget *parent = nullptr);
Qt::CaseSensitivity caseSensitivity() const;
void setCaseSensitivity(Qt::CaseSensitivity);
enum PatternSyntax {
RegularExpression,
Wildcard,
FixedString
};
Q_ENUM(PatternSyntax)
PatternSyntax patternSyntax() const;
void setPatternSyntax(PatternSyntax);
signals:
void filterChanged();
private:
QAction *m_caseSensitivityAction;
QActionGroup *m_patternGroup;
};
#endif // FILTERWIDGET_H

Binary file not shown.

After

Width:  |  Height:  |  Size: 737 B

View File

@ -0,0 +1,58 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include <QtWidgets>
#include "window.h"
void addMail(QAbstractItemModel *model, const QString &subject,
const QString &sender, const QDateTime &date)
{
model->insertRow(0);
model->setData(model->index(0, 0), subject);
model->setData(model->index(0, 1), sender);
model->setData(model->index(0, 2), date);
}
QAbstractItemModel *createMailModel(QObject *parent)
{
QStandardItemModel *model = new QStandardItemModel(0, 3, parent);
model->setHeaderData(0, Qt::Horizontal, QObject::tr("Subject"));
model->setHeaderData(1, Qt::Horizontal, QObject::tr("Sender"));
model->setHeaderData(2, Qt::Horizontal, QObject::tr("Date"));
addMail(model, "Happy New Year!", "Grace K. <grace@software-inc.com>",
QDateTime(QDate(2006, 12, 31), QTime(17, 03)));
addMail(model, "Radically new concept", "Grace K. <grace@software-inc.com>",
QDateTime(QDate(2006, 12, 22), QTime(9, 44)));
addMail(model, "Accounts", "pascale@nospam.com",
QDateTime(QDate(2006, 12, 31), QTime(12, 50)));
addMail(model, "Expenses", "Joe Bloggs <joe@bloggs.com>",
QDateTime(QDate(2006, 12, 25), QTime(11, 39)));
addMail(model, "Re: Expenses", "Andy <andy@nospam.com>",
QDateTime(QDate(2007, 01, 02), QTime(16, 05)));
addMail(model, "Re: Accounts", "Joe Bloggs <joe@bloggs.com>",
QDateTime(QDate(2007, 01, 03), QTime(14, 18)));
addMail(model, "Re: Accounts", "Andy <andy@nospam.com>",
QDateTime(QDate(2007, 01, 03), QTime(14, 26)));
addMail(model, "Sports", "Linda Smith <linda.smith@nospam.com>",
QDateTime(QDate(2007, 01, 05), QTime(11, 33)));
addMail(model, "AW: Sports", "Rolf Newschweinstein <rolfn@nospam.com>",
QDateTime(QDate(2007, 01, 05), QTime(12, 00)));
addMail(model, "RE: Sports", "Petra Schmidt <petras@nospam.com>",
QDateTime(QDate(2007, 01, 05), QTime(12, 01)));
return model;
}
//! [0]
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
Window window;
window.setSourceModel(createMailModel(&window));
window.show();
return app.exec();
}
//! [0]

View File

@ -0,0 +1,83 @@
// Copyright (C) 2020 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "mysortfilterproxymodel.h"
#include <QtWidgets>
//! [0]
MySortFilterProxyModel::MySortFilterProxyModel(QObject *parent)
: QSortFilterProxyModel(parent)
{
}
//! [0]
//! [1]
void MySortFilterProxyModel::setFilterMinimumDate(QDate date)
{
minDate = date;
invalidateFilter();
}
//! [1]
//! [2]
void MySortFilterProxyModel::setFilterMaximumDate(QDate date)
{
maxDate = date;
invalidateFilter();
}
//! [2]
//! [3]
bool MySortFilterProxyModel::filterAcceptsRow(int sourceRow,
const QModelIndex &sourceParent) const
{
QModelIndex index0 = sourceModel()->index(sourceRow, 0, sourceParent);
QModelIndex index1 = sourceModel()->index(sourceRow, 1, sourceParent);
QModelIndex index2 = sourceModel()->index(sourceRow, 2, sourceParent);
return (sourceModel()->data(index0).toString().contains(filterRegularExpression())
|| sourceModel()->data(index1).toString().contains(filterRegularExpression()))
&& dateInRange(sourceModel()->data(index2).toDate());
}
//! [3]
//! [4] //! [5]
bool MySortFilterProxyModel::lessThan(const QModelIndex &left,
const QModelIndex &right) const
{
QVariant leftData = sourceModel()->data(left);
QVariant rightData = sourceModel()->data(right);
//! [4]
//! [6]
if (leftData.userType() == QMetaType::QDateTime) {
return leftData.toDateTime() < rightData.toDateTime();
} else {
static const QRegularExpression emailPattern("[\\w\\.]*@[\\w\\.]*");
QString leftString = leftData.toString();
if (left.column() == 1) {
const QRegularExpressionMatch match = emailPattern.match(leftString);
if (match.hasMatch())
leftString = match.captured(0);
}
QString rightString = rightData.toString();
if (right.column() == 1) {
const QRegularExpressionMatch match = emailPattern.match(rightString);
if (match.hasMatch())
rightString = match.captured(0);
}
return QString::localeAwareCompare(leftString, rightString) < 0;
}
}
//! [5] //! [6]
//! [7]
bool MySortFilterProxyModel::dateInRange(QDate date) const
{
return (!minDate.isValid() || date > minDate)
&& (!maxDate.isValid() || date < maxDate);
}
//! [7]

View File

@ -0,0 +1,36 @@
// Copyright (C) 2020 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef MYSORTFILTERPROXYMODEL_H
#define MYSORTFILTERPROXYMODEL_H
#include <QDate>
#include <QSortFilterProxyModel>
//! [0]
class MySortFilterProxyModel : public QSortFilterProxyModel
{
Q_OBJECT
public:
MySortFilterProxyModel(QObject *parent = nullptr);
QDate filterMinimumDate() const { return minDate; }
void setFilterMinimumDate(QDate date);
QDate filterMaximumDate() const { return maxDate; }
void setFilterMaximumDate(QDate date);
protected:
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
private:
bool dateInRange(QDate date) const;
QDate minDate;
QDate maxDate;
};
//! [0]
#endif // MYSORTFILTERPROXYMODEL_H

View File

@ -0,0 +1,131 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "window.h"
#include "mysortfilterproxymodel.h"
#include "filterwidget.h"
#include <QtWidgets>
//! [0]
Window::Window()
{
proxyModel = new MySortFilterProxyModel(this);
//! [0]
//! [1]
sourceView = new QTreeView;
sourceView->setRootIsDecorated(false);
sourceView->setAlternatingRowColors(true);
//! [1]
QHBoxLayout *sourceLayout = new QHBoxLayout;
//! [2]
sourceLayout->addWidget(sourceView);
sourceGroupBox = new QGroupBox(tr("Original Model"));
sourceGroupBox->setLayout(sourceLayout);
//! [2]
//! [3]
filterWidget = new FilterWidget;
filterWidget->setText(tr("Grace|Sports"));
connect(filterWidget, &FilterWidget::filterChanged, this, &Window::textFilterChanged);
filterPatternLabel = new QLabel(tr("&Filter pattern:"));
filterPatternLabel->setBuddy(filterWidget);
fromDateEdit = new QDateEdit;
fromDateEdit->setDate(QDate(1970, 01, 01));
fromLabel = new QLabel(tr("F&rom:"));
fromLabel->setBuddy(fromDateEdit);
toDateEdit = new QDateEdit;
toDateEdit->setDate(QDate(2099, 12, 31));
toLabel = new QLabel(tr("&To:"));
toLabel->setBuddy(toDateEdit);
connect(filterWidget, &QLineEdit::textChanged,
this, &Window::textFilterChanged);
connect(fromDateEdit, &QDateTimeEdit::dateChanged,
this, &Window::dateFilterChanged);
connect(toDateEdit, &QDateTimeEdit::dateChanged,
//! [3] //! [4]
this, &Window::dateFilterChanged);
//! [4]
//! [5]
proxyView = new QTreeView;
proxyView->setRootIsDecorated(false);
proxyView->setAlternatingRowColors(true);
proxyView->setModel(proxyModel);
proxyView->setSortingEnabled(true);
proxyView->sortByColumn(1, Qt::AscendingOrder);
QGridLayout *proxyLayout = new QGridLayout;
proxyLayout->addWidget(proxyView, 0, 0, 1, 3);
proxyLayout->addWidget(filterPatternLabel, 1, 0);
proxyLayout->addWidget(filterWidget, 1, 1);
proxyLayout->addWidget(fromLabel, 3, 0);
proxyLayout->addWidget(fromDateEdit, 3, 1, 1, 2);
proxyLayout->addWidget(toLabel, 4, 0);
proxyLayout->addWidget(toDateEdit, 4, 1, 1, 2);
proxyGroupBox = new QGroupBox(tr("Sorted/Filtered Model"));
proxyGroupBox->setLayout(proxyLayout);
//! [5]
//! [6]
QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->addWidget(sourceGroupBox);
mainLayout->addWidget(proxyGroupBox);
setLayout(mainLayout);
setWindowTitle(tr("Custom Sort/Filter Model"));
resize(500, 450);
}
//! [6]
//! [7]
void Window::setSourceModel(QAbstractItemModel *model)
{
proxyModel->setSourceModel(model);
sourceView->setModel(model);
for (int i = 0; i < proxyModel->columnCount(); ++i)
proxyView->resizeColumnToContents(i);
for (int i = 0; i < model->columnCount(); ++i)
sourceView->resizeColumnToContents(i);
}
//! [7]
//! [8]
void Window::textFilterChanged()
{
FilterWidget::PatternSyntax s = filterWidget->patternSyntax();
QString pattern = filterWidget->text();
switch (s) {
case FilterWidget::Wildcard:
pattern = QRegularExpression::wildcardToRegularExpression(pattern);
break;
case FilterWidget::FixedString:
pattern = QRegularExpression::escape(pattern);
break;
default:
break;
}
QRegularExpression::PatternOptions options = QRegularExpression::NoPatternOption;
if (filterWidget->caseSensitivity() == Qt::CaseInsensitive)
options |= QRegularExpression::CaseInsensitiveOption;
QRegularExpression regularExpression(pattern, options);
proxyModel->setFilterRegularExpression(regularExpression);
}
//! [8]
//! [9]
void Window::dateFilterChanged()
{
proxyModel->setFilterMinimumDate(fromDateEdit->date());
proxyModel->setFilterMaximumDate(toDateEdit->date());
}
//! [9]

View File

@ -0,0 +1,51 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef WINDOW_H
#define WINDOW_H
#include <QWidget>
QT_BEGIN_NAMESPACE
class QAbstractItemModel;
class QCheckBox;
class QComboBox;
class QDateEdit;
class QGroupBox;
class QLabel;
class QLineEdit;
class QTreeView;
QT_END_NAMESPACE
class MySortFilterProxyModel;
class FilterWidget;
//! [0]
class Window : public QWidget
{
Q_OBJECT
public:
Window();
void setSourceModel(QAbstractItemModel *model);
private slots:
void textFilterChanged();
void dateFilterChanged();
private:
MySortFilterProxyModel *proxyModel;
QGroupBox *sourceGroupBox;
QGroupBox *proxyGroupBox;
QTreeView *sourceView;
QTreeView *proxyView;
QLabel *filterPatternLabel;
QLabel *fromLabel;
QLabel *toLabel;
FilterWidget *filterWidget;
QDateEdit *fromDateEdit;
QDateEdit *toDateEdit;
};
//! [0]
#endif // WINDOW_H

View File

@ -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}"
)

View File

@ -0,0 +1,8 @@
QT += widgets
requires(qtConfig(treeview))
SOURCES = main.cpp
# install
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/itemviews/dirview
INSTALLS += target

View 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();
}

View File

@ -0,0 +1,51 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
cmake_minimum_required(VERSION 3.16)
project(editabletreemodel LANGUAGES CXX)
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/widgets/itemviews/editabletreemodel")
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
qt_standard_project_setup()
qt_add_executable(editabletreemodel
main.cpp
mainwindow.cpp mainwindow.h mainwindow.ui
treeitem.cpp treeitem.h
treemodel.cpp treemodel.h
)
set_target_properties(editabletreemodel PROPERTIES
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
)
target_link_libraries(editabletreemodel PRIVATE
Qt6::Core
Qt6::Gui
Qt6::Widgets
)
# Resources:
set(editabletreemodel_resource_files
"default.txt"
)
qt_add_resources(editabletreemodel "editabletreemodel"
PREFIX
"/"
FILES
${editabletreemodel_resource_files}
)
install(TARGETS editabletreemodel
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
)

View File

@ -0,0 +1,40 @@
Getting Started How to familiarize yourself with Qt Designer
Launching Designer Running the Qt Designer application
The User Interface How to interact with Qt Designer
Designing a Component Creating a GUI for your application
Creating a Dialog How to create a dialog
Composing the Dialog Putting widgets into the dialog example
Creating a Layout Arranging widgets on a form
Signal and Slot Connections Making widget communicate with each other
Using a Component in Your Application Generating code from forms
The Direct Approach Using a form without any adjustments
The Single Inheritance Approach Subclassing a form's base class
The Multiple Inheritance Approach Subclassing the form itself
Automatic Connections Connecting widgets using a naming scheme
A Dialog Without Auto-Connect How to connect widgets without a naming scheme
A Dialog With Auto-Connect Using automatic connections
Form Editing Mode How to edit a form in Qt Designer
Managing Forms Loading and saving forms
Editing a Form Basic editing techniques
The Property Editor Changing widget properties
The Object Inspector Examining the hierarchy of objects on a form
Layouts Objects that arrange widgets on a form
Applying and Breaking Layouts Managing widgets in layouts
Horizontal and Vertical Layouts Standard row and column layouts
The Grid Layout Arranging widgets in a matrix
Previewing Forms Checking that the design works
Using Containers How to group widgets together
General Features Common container features
Frames QFrame
Group Boxes QGroupBox
Stacked Widgets QStackedWidget
Tab Widgets QTabWidget
Toolbox Widgets QToolBox
Connection Editing Mode Connecting widgets together with signals and slots
Connecting Objects Making connections in Qt Designer
Editing Connections Changing existing connections

View File

@ -0,0 +1,16 @@
QT += widgets
requires(qtConfig(treeview))
FORMS = mainwindow.ui
HEADERS = mainwindow.h \
treeitem.h \
treemodel.h
RESOURCES = editabletreemodel.qrc
SOURCES = mainwindow.cpp \
treeitem.cpp \
treemodel.cpp \
main.cpp
# install
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/itemviews/editabletreemodel
INSTALLS += target

View File

@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/" >
<file>default.txt</file>
</qresource>
</RCC>

View File

@ -0,0 +1,16 @@
// 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[])
{
Q_INIT_RESOURCE(editabletreemodel);
QApplication app(argc, argv);
MainWindow window;
window.show();
return app.exec();
}

View File

@ -0,0 +1,137 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "mainwindow.h"
#include "treemodel.h"
#include <QFile>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
setupUi(this);
const QStringList headers({tr("Title"), tr("Description")});
QFile file(":/default.txt");
file.open(QIODevice::ReadOnly);
TreeModel *model = new TreeModel(headers, file.readAll(), this);
file.close();
view->setModel(model);
for (int column = 0; column < model->columnCount(); ++column)
view->resizeColumnToContents(column);
connect(exitAction, &QAction::triggered, qApp, &QCoreApplication::quit);
connect(view->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &MainWindow::updateActions);
connect(actionsMenu, &QMenu::aboutToShow, this, &MainWindow::updateActions);
connect(insertRowAction, &QAction::triggered, this, &MainWindow::insertRow);
connect(insertColumnAction, &QAction::triggered, this, &MainWindow::insertColumn);
connect(removeRowAction, &QAction::triggered, this, &MainWindow::removeRow);
connect(removeColumnAction, &QAction::triggered, this, &MainWindow::removeColumn);
connect(insertChildAction, &QAction::triggered, this, &MainWindow::insertChild);
updateActions();
}
void MainWindow::insertChild()
{
const QModelIndex index = view->selectionModel()->currentIndex();
QAbstractItemModel *model = view->model();
if (model->columnCount(index) == 0) {
if (!model->insertColumn(0, index))
return;
}
if (!model->insertRow(0, index))
return;
for (int column = 0; column < model->columnCount(index); ++column) {
const QModelIndex child = model->index(0, column, index);
model->setData(child, QVariant(tr("[No data]")), Qt::EditRole);
if (!model->headerData(column, Qt::Horizontal).isValid())
model->setHeaderData(column, Qt::Horizontal, QVariant(tr("[No header]")), Qt::EditRole);
}
view->selectionModel()->setCurrentIndex(model->index(0, 0, index),
QItemSelectionModel::ClearAndSelect);
updateActions();
}
bool MainWindow::insertColumn()
{
QAbstractItemModel *model = view->model();
int column = view->selectionModel()->currentIndex().column();
// Insert a column in the parent item.
bool changed = model->insertColumn(column + 1);
if (changed)
model->setHeaderData(column + 1, Qt::Horizontal, QVariant("[No header]"), Qt::EditRole);
updateActions();
return changed;
}
void MainWindow::insertRow()
{
const QModelIndex index = view->selectionModel()->currentIndex();
QAbstractItemModel *model = view->model();
if (!model->insertRow(index.row()+1, index.parent()))
return;
updateActions();
for (int column = 0; column < model->columnCount(index.parent()); ++column) {
const QModelIndex child = model->index(index.row() + 1, column, index.parent());
model->setData(child, QVariant(tr("[No data]")), Qt::EditRole);
}
}
bool MainWindow::removeColumn()
{
QAbstractItemModel *model = view->model();
const int column = view->selectionModel()->currentIndex().column();
// Insert columns in each child of the parent item.
const bool changed = model->removeColumn(column);
if (changed)
updateActions();
return changed;
}
void MainWindow::removeRow()
{
const QModelIndex index = view->selectionModel()->currentIndex();
QAbstractItemModel *model = view->model();
if (model->removeRow(index.row(), index.parent()))
updateActions();
}
void MainWindow::updateActions()
{
const bool hasSelection = !view->selectionModel()->selection().isEmpty();
removeRowAction->setEnabled(hasSelection);
removeColumnAction->setEnabled(hasSelection);
const bool hasCurrent = view->selectionModel()->currentIndex().isValid();
insertRowAction->setEnabled(hasCurrent);
insertColumnAction->setEnabled(hasCurrent);
if (hasCurrent) {
view->closePersistentEditor(view->selectionModel()->currentIndex());
const int row = view->selectionModel()->currentIndex().row();
const int column = view->selectionModel()->currentIndex().column();
if (view->selectionModel()->currentIndex().parent().isValid())
statusBar()->showMessage(tr("Position: (%1,%2)").arg(row).arg(column));
else
statusBar()->showMessage(tr("Position: (%1,%2) in top level").arg(row).arg(column));
}
}

View File

@ -0,0 +1,29 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include "ui_mainwindow.h"
#include <QMainWindow>
class MainWindow : public QMainWindow, private Ui::MainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
public slots:
void updateActions();
private slots:
void insertChild();
bool insertColumn();
void insertRow();
bool removeColumn();
void removeRow();
};
#endif // MAINWINDOW_H

View File

@ -0,0 +1,128 @@
<ui version="4.0" >
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>573</width>
<height>468</height>
</rect>
</property>
<property name="windowTitle" >
<string>Editable Tree Model</string>
</property>
<widget class="QWidget" name="centralwidget" >
<layout class="QVBoxLayout" >
<property name="margin" >
<number>0</number>
</property>
<property name="spacing" >
<number>0</number>
</property>
<item>
<widget class="QTreeView" name="view" >
<property name="alternatingRowColors" >
<bool>true</bool>
</property>
<property name="selectionBehavior" >
<enum>QAbstractItemView::SelectItems</enum>
</property>
<property name="horizontalScrollMode" >
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="animated" >
<bool>false</bool>
</property>
<property name="allColumnsShowFocus" >
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>573</width>
<height>31</height>
</rect>
</property>
<widget class="QMenu" name="fileMenu" >
<property name="title" >
<string>&amp;File</string>
</property>
<addaction name="exitAction" />
</widget>
<widget class="QMenu" name="actionsMenu" >
<property name="title" >
<string>&amp;Actions</string>
</property>
<addaction name="insertRowAction" />
<addaction name="insertColumnAction" />
<addaction name="separator" />
<addaction name="removeRowAction" />
<addaction name="removeColumnAction" />
<addaction name="separator" />
<addaction name="insertChildAction" />
</widget>
<addaction name="fileMenu" />
<addaction name="actionsMenu" />
</widget>
<widget class="QStatusBar" name="statusbar" />
<action name="exitAction" >
<property name="text" >
<string>E&amp;xit</string>
</property>
<property name="shortcut" >
<string>Ctrl+Q</string>
</property>
</action>
<action name="insertRowAction" >
<property name="text" >
<string>Insert Row</string>
</property>
<property name="shortcut" >
<string>Ctrl+I, R</string>
</property>
</action>
<action name="removeRowAction" >
<property name="text" >
<string>Remove Row</string>
</property>
<property name="shortcut" >
<string>Ctrl+R, R</string>
</property>
</action>
<action name="insertColumnAction" >
<property name="text" >
<string>Insert Column</string>
</property>
<property name="shortcut" >
<string>Ctrl+I, C</string>
</property>
</action>
<action name="removeColumnAction" >
<property name="text" >
<string>Remove Column</string>
</property>
<property name="shortcut" >
<string>Ctrl+R, C</string>
</property>
</action>
<action name="insertChildAction" >
<property name="text" >
<string>Insert Child</string>
</property>
<property name="shortcut" >
<string>Ctrl+N</string>
</property>
</action>
</widget>
<resources>
<include location="editabletreemodel.qrc" />
</resources>
<connections/>
</ui>

View File

@ -0,0 +1,141 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
/*
treeitem.cpp
A container for items of data supplied by the simple tree model.
*/
#include "treeitem.h"
//! [0]
TreeItem::TreeItem(const QList<QVariant> &data, TreeItem *parent)
: itemData(data), parentItem(parent)
{}
//! [0]
//! [1]
TreeItem::~TreeItem()
{
qDeleteAll(childItems);
}
//! [1]
//! [2]
TreeItem *TreeItem::child(int number)
{
if (number < 0 || number >= childItems.size())
return nullptr;
return childItems.at(number);
}
//! [2]
//! [3]
int TreeItem::childCount() const
{
return childItems.count();
}
//! [3]
//! [4]
int TreeItem::childNumber() const
{
if (parentItem)
return parentItem->childItems.indexOf(const_cast<TreeItem*>(this));
return 0;
}
//! [4]
//! [5]
int TreeItem::columnCount() const
{
return itemData.count();
}
//! [5]
//! [6]
QVariant TreeItem::data(int column) const
{
if (column < 0 || column >= itemData.size())
return QVariant();
return itemData.at(column);
}
//! [6]
//! [7]
bool TreeItem::insertChildren(int position, int count, int columns)
{
if (position < 0 || position > childItems.size())
return false;
for (int row = 0; row < count; ++row) {
QList<QVariant> data(columns);
TreeItem *item = new TreeItem(data, this);
childItems.insert(position, item);
}
return true;
}
//! [7]
//! [8]
bool TreeItem::insertColumns(int position, int columns)
{
if (position < 0 || position > itemData.size())
return false;
for (int column = 0; column < columns; ++column)
itemData.insert(position, QVariant());
for (TreeItem *child : std::as_const(childItems))
child->insertColumns(position, columns);
return true;
}
//! [8]
//! [9]
TreeItem *TreeItem::parent()
{
return parentItem;
}
//! [9]
//! [10]
bool TreeItem::removeChildren(int position, int count)
{
if (position < 0 || position + count > childItems.size())
return false;
for (int row = 0; row < count; ++row)
delete childItems.takeAt(position);
return true;
}
//! [10]
bool TreeItem::removeColumns(int position, int columns)
{
if (position < 0 || position + columns > itemData.size())
return false;
for (int column = 0; column < columns; ++column)
itemData.remove(position);
for (TreeItem *child : std::as_const(childItems))
child->removeColumns(position, columns);
return true;
}
//! [11]
bool TreeItem::setData(int column, const QVariant &value)
{
if (column < 0 || column >= itemData.size())
return false;
itemData[column] = value;
return true;
}
//! [11]

View File

@ -0,0 +1,36 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef TREEITEM_H
#define TREEITEM_H
#include <QVariant>
#include <QList>
//! [0]
class TreeItem
{
public:
explicit TreeItem(const QList<QVariant> &data, TreeItem *parent = nullptr);
~TreeItem();
TreeItem *child(int number);
int childCount() const;
int columnCount() const;
QVariant data(int column) const;
bool insertChildren(int position, int count, int columns);
bool insertColumns(int position, int columns);
TreeItem *parent();
bool removeChildren(int position, int count);
bool removeColumns(int position, int columns);
int childNumber() const;
bool setData(int column, const QVariant &value);
private:
QList<TreeItem *> childItems;
QList<QVariant> itemData;
TreeItem *parentItem;
};
//! [0]
#endif // TREEITEM_H

View File

@ -0,0 +1,256 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "treemodel.h"
#include "treeitem.h"
#include <QtWidgets>
//! [0]
TreeModel::TreeModel(const QStringList &headers, const QString &data, QObject *parent)
: QAbstractItemModel(parent)
{
QList<QVariant> rootData;
for (const QString &header : headers)
rootData << header;
rootItem = new TreeItem(rootData);
setupModelData(data.split('\n'), rootItem);
}
//! [0]
//! [1]
TreeModel::~TreeModel()
{
delete rootItem;
}
//! [1]
//! [2]
int TreeModel::columnCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
return rootItem->columnCount();
}
//! [2]
QVariant TreeModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
if (role != Qt::DisplayRole && role != Qt::EditRole)
return QVariant();
TreeItem *item = getItem(index);
return item->data(index.column());
}
//! [3]
Qt::ItemFlags TreeModel::flags(const QModelIndex &index) const
{
if (!index.isValid())
return Qt::NoItemFlags;
return Qt::ItemIsEditable | QAbstractItemModel::flags(index);
}
//! [3]
//! [4]
TreeItem *TreeModel::getItem(const QModelIndex &index) const
{
if (index.isValid()) {
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
if (item)
return item;
}
return rootItem;
}
//! [4]
QVariant TreeModel::headerData(int section, Qt::Orientation orientation,
int role) const
{
if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
return rootItem->data(section);
return QVariant();
}
//! [5]
QModelIndex TreeModel::index(int row, int column, const QModelIndex &parent) const
{
if (parent.isValid() && parent.column() != 0)
return QModelIndex();
//! [5]
//! [6]
TreeItem *parentItem = getItem(parent);
if (!parentItem)
return QModelIndex();
TreeItem *childItem = parentItem->child(row);
if (childItem)
return createIndex(row, column, childItem);
return QModelIndex();
}
//! [6]
bool TreeModel::insertColumns(int position, int columns, const QModelIndex &parent)
{
beginInsertColumns(parent, position, position + columns - 1);
const bool success = rootItem->insertColumns(position, columns);
endInsertColumns();
return success;
}
bool TreeModel::insertRows(int position, int rows, const QModelIndex &parent)
{
TreeItem *parentItem = getItem(parent);
if (!parentItem)
return false;
beginInsertRows(parent, position, position + rows - 1);
const bool success = parentItem->insertChildren(position,
rows,
rootItem->columnCount());
endInsertRows();
return success;
}
//! [7]
QModelIndex TreeModel::parent(const QModelIndex &index) const
{
if (!index.isValid())
return QModelIndex();
TreeItem *childItem = getItem(index);
TreeItem *parentItem = childItem ? childItem->parent() : nullptr;
if (parentItem == rootItem || !parentItem)
return QModelIndex();
return createIndex(parentItem->childNumber(), 0, parentItem);
}
//! [7]
bool TreeModel::removeColumns(int position, int columns, const QModelIndex &parent)
{
beginRemoveColumns(parent, position, position + columns - 1);
const bool success = rootItem->removeColumns(position, columns);
endRemoveColumns();
if (rootItem->columnCount() == 0)
removeRows(0, rowCount());
return success;
}
bool TreeModel::removeRows(int position, int rows, const QModelIndex &parent)
{
TreeItem *parentItem = getItem(parent);
if (!parentItem)
return false;
beginRemoveRows(parent, position, position + rows - 1);
const bool success = parentItem->removeChildren(position, rows);
endRemoveRows();
return success;
}
//! [8]
int TreeModel::rowCount(const QModelIndex &parent) const
{
if (parent.isValid() && parent.column() > 0)
return 0;
const TreeItem *parentItem = getItem(parent);
return parentItem ? parentItem->childCount() : 0;
}
//! [8]
bool TreeModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (role != Qt::EditRole)
return false;
TreeItem *item = getItem(index);
bool result = item->setData(index.column(), value);
if (result)
emit dataChanged(index, index, {Qt::DisplayRole, Qt::EditRole});
return result;
}
bool TreeModel::setHeaderData(int section, Qt::Orientation orientation,
const QVariant &value, int role)
{
if (role != Qt::EditRole || orientation != Qt::Horizontal)
return false;
const bool result = rootItem->setData(section, value);
if (result)
emit headerDataChanged(orientation, section, section);
return result;
}
void TreeModel::setupModelData(const QStringList &lines, TreeItem *parent)
{
QList<TreeItem *> parents;
QList<int> indentations;
parents << parent;
indentations << 0;
int number = 0;
while (number < lines.count()) {
int position = 0;
while (position < lines[number].length()) {
if (lines[number].at(position) != ' ')
break;
++position;
}
const QString lineData = lines[number].mid(position).trimmed();
if (!lineData.isEmpty()) {
// Read the column data from the rest of the line.
const QStringList columnStrings =
lineData.split(QLatin1Char('\t'), Qt::SkipEmptyParts);
QList<QVariant> columnData;
columnData.reserve(columnStrings.size());
for (const QString &columnString : columnStrings)
columnData << columnString;
if (position > indentations.last()) {
// The last child of the current parent is now the new parent
// unless the current parent has no children.
if (parents.last()->childCount() > 0) {
parents << parents.last()->child(parents.last()->childCount()-1);
indentations << position;
}
} else {
while (position < indentations.last() && parents.count() > 0) {
parents.pop_back();
indentations.pop_back();
}
}
// Append a new item to the current parent's list of children.
TreeItem *parent = parents.last();
parent->insertChildren(parent->childCount(), 1, rootItem->columnCount());
for (int column = 0; column < columnData.size(); ++column)
parent->child(parent->childCount() - 1)->setData(column, columnData[column]);
}
++number;
}
}

View File

@ -0,0 +1,60 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef TREEMODEL_H
#define TREEMODEL_H
#include <QAbstractItemModel>
#include <QModelIndex>
#include <QVariant>
class TreeItem;
//! [0]
class TreeModel : public QAbstractItemModel
{
Q_OBJECT
public:
TreeModel(const QStringList &headers, const QString &data,
QObject *parent = nullptr);
~TreeModel();
//! [0] //! [1]
QVariant data(const QModelIndex &index, int role) const override;
QVariant headerData(int section, Qt::Orientation orientation,
int role = Qt::DisplayRole) const override;
QModelIndex index(int row, int column,
const QModelIndex &parent = QModelIndex()) const override;
QModelIndex parent(const QModelIndex &index) const override;
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
//! [1]
//! [2]
Qt::ItemFlags flags(const QModelIndex &index) const override;
bool setData(const QModelIndex &index, const QVariant &value,
int role = Qt::EditRole) override;
bool setHeaderData(int section, Qt::Orientation orientation,
const QVariant &value, int role = Qt::EditRole) override;
bool insertColumns(int position, int columns,
const QModelIndex &parent = QModelIndex()) override;
bool removeColumns(int position, int columns,
const QModelIndex &parent = QModelIndex()) override;
bool insertRows(int position, int rows,
const QModelIndex &parent = QModelIndex()) override;
bool removeRows(int position, int rows,
const QModelIndex &parent = QModelIndex()) override;
private:
void setupModelData(const QStringList &lines, TreeItem *parent);
TreeItem *getItem(const QModelIndex &index) const;
TreeItem *rootItem;
};
//! [2]
#endif // TREEMODEL_H

View File

@ -0,0 +1,38 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
cmake_minimum_required(VERSION 3.16)
project(fetchmore LANGUAGES CXX)
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/widgets/itemviews/fetchmore")
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
qt_standard_project_setup()
qt_add_executable(fetchmore
filelistmodel.cpp filelistmodel.h
main.cpp
window.cpp window.h
)
set_target_properties(fetchmore PROPERTIES
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
)
target_link_libraries(fetchmore PRIVATE
Qt6::Core
Qt6::Gui
Qt6::Widgets
)
install(TARGETS fetchmore
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
)

View File

@ -0,0 +1,12 @@
QT += widgets
requires(qtConfig(listview))
HEADERS = filelistmodel.h \
window.h
SOURCES = filelistmodel.cpp \
main.cpp \
window.cpp
# install
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/itemviews/fetchmore
INSTALLS += target

View File

@ -0,0 +1,95 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "filelistmodel.h"
#include <QGuiApplication>
#include <QDir>
#include <QPalette>
static const int batchSize = 100;
FileListModel::FileListModel(QObject *parent)
: QAbstractListModel(parent)
{}
//![4]
int FileListModel::rowCount(const QModelIndex &parent) const
{
return parent.isValid() ? 0 : fileCount;
}
QVariant FileListModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return {};
const int row = index.row();
if (row >= fileList.size() || row < 0)
return {};
switch (role) {
case Qt::DisplayRole:
return fileList.at(row).fileName();
case Qt::BackgroundRole: {
const int batch = row / batchSize;
const QPalette &palette = QGuiApplication::palette();
return (batch % 2) != 0 ? palette.alternateBase() : palette.base();
}
case Qt::DecorationRole:
return iconProvider.icon(fileList.at(row));
}
return {};
}
//![4]
QFileInfo FileListModel::fileInfoAt(const QModelIndex &index) const
{
return fileList.at(index.row());
}
//![1]
bool FileListModel::canFetchMore(const QModelIndex &parent) const
{
if (parent.isValid())
return false;
return (fileCount < fileList.size());
}
//![1]
//![2]
void FileListModel::fetchMore(const QModelIndex &parent)
{
if (parent.isValid())
return;
const int start = fileCount;
const int remainder = int(fileList.size()) - start;
const int itemsToFetch = qMin(batchSize, remainder);
if (itemsToFetch <= 0)
return;
beginInsertRows(QModelIndex(), start, start + itemsToFetch - 1);
fileCount += itemsToFetch;
endInsertRows();
emit numberPopulated(path, start, itemsToFetch, int(fileList.size()));
}
//![2]
//![0]
void FileListModel::setDirPath(const QString &path)
{
QDir dir(path);
beginResetModel();
this->path = path;
fileList = dir.entryInfoList(QDir::NoDot | QDir::AllEntries, QDir::Name);
fileCount = 0;
endResetModel();
}
//![0]

View File

@ -0,0 +1,42 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef FILELISTMODEL_H
#define FILELISTMODEL_H
#include <QAbstractListModel>
#include <QFileInfoList>
#include <QFileIconProvider>
//![0]
class FileListModel : public QAbstractListModel
{
Q_OBJECT
public:
FileListModel(QObject *parent = nullptr);
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
QFileInfo fileInfoAt(const QModelIndex &) const;
signals:
void numberPopulated(const QString &path, int start, int number, int total);
public slots:
void setDirPath(const QString &path);
protected:
bool canFetchMore(const QModelIndex &parent) const override;
void fetchMore(const QModelIndex &parent) override;
private:
QFileInfoList fileList;
QString path;
QFileIconProvider iconProvider;
int fileCount = 0;
};
//![0]
#endif // FILELISTMODEL_H

View File

@ -0,0 +1,14 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "window.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
Window window;
window.show();
return app.exec();
}

View File

@ -0,0 +1,51 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "window.h"
#include "filelistmodel.h"
#include <QtWidgets>
Window::Window(QWidget *parent)
: QWidget(parent)
{
model = new FileListModel(this);
model->setDirPath(QDir::rootPath());
view = new QListView;
view->setModel(model);
logViewer = new QPlainTextEdit(this);
logViewer->setReadOnly(true);
logViewer->setSizePolicy(QSizePolicy(QSizePolicy::Preferred,
QSizePolicy::Preferred));
connect(model, &FileListModel::numberPopulated,
this, &Window::updateLog);
connect(view, &QAbstractItemView::activated,
this, &Window::activated);
auto *layout = new QVBoxLayout(this);
layout->addWidget(view);
layout->addWidget(logViewer);
setWindowTitle(tr("Fetch More Example"));
}
void Window::updateLog(const QString &path, int start, int number, int total)
{
const int last = start + number - 1;
const QString nativePath = QDir::toNativeSeparators(path);
const QString message = tr("%1..%2/%3 items from \"%4\" added.")
.arg(start).arg(last).arg(total).arg(nativePath);
logViewer->appendPlainText(message);
}
void Window::activated(const QModelIndex &index)
{
const QFileInfo fi = model->fileInfoAt(index);
if (fi.isDir()) {
logViewer->clear();
model->setDirPath(fi.absoluteFilePath());
}
}

View File

@ -0,0 +1,34 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef WINDOW_H
#define WINDOW_H
#include <QWidget>
QT_BEGIN_NAMESPACE
class QModelIndex;
class QListView;
class QPlainTextEdit;
QT_END_NAMESPACE
class FileListModel;
class Window : public QWidget
{
Q_OBJECT
public:
Window(QWidget *parent = nullptr);
public slots:
void updateLog(const QString &path, int start, int number, int total);
void activated(const QModelIndex &);
private:
QPlainTextEdit *logViewer;
FileListModel *model;
QListView *view;
};
#endif // WINDOW_H

View File

@ -0,0 +1,36 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
cmake_minimum_required(VERSION 3.16)
project(flattreeview LANGUAGES CXX)
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/widgets/itemviews/flattreeview")
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
qt_standard_project_setup()
qt_add_executable(flattreeview
main.cpp
)
set_target_properties(flattreeview PROPERTIES
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
)
target_link_libraries(flattreeview PRIVATE
Qt6::Core
Qt6::Gui
Qt6::Widgets
)
install(TARGETS flattreeview
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
)

View File

@ -0,0 +1,7 @@
QT += widgets
SOURCES = main.cpp
# install
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/itemviews/flattreeview
INSTALLS += target

View File

@ -0,0 +1,37 @@
// Copyright (C) 2017 Klaralvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author David Faure <david.faure@kdab.com>
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
/*
main.cpp
A simple example that shows a multi-column list using QTreeView.
The data is not a tree, so the first column was made movable.
*/
#include <QApplication>
#include <QHeaderView>
#include <QStandardItemModel>
#include <QTreeView>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QStandardItemModel model(4, 2);
QTreeView treeView;
treeView.setModel(&model);
treeView.setRootIsDecorated(false);
treeView.header()->setFirstSectionMovable(true);
treeView.header()->setStretchLastSection(true);
for (int row = 0; row < 4; ++row) {
for (int column = 0; column < 2; ++column) {
QModelIndex index = model.index(row, column, QModelIndex());
model.setData(index, QVariant((row + 1) * (column + 1)));
}
}
treeView.setWindowTitle(QObject::tr("Flat Tree View"));
treeView.show();
return app.exec();
}

View File

@ -0,0 +1,49 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
cmake_minimum_required(VERSION 3.16)
project(frozencolumn LANGUAGES CXX)
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/widgets/itemviews/frozencolumn")
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
qt_standard_project_setup()
qt_add_executable(frozencolumn
freezetablewidget.cpp freezetablewidget.h
main.cpp
)
set_target_properties(frozencolumn PROPERTIES
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
)
target_link_libraries(frozencolumn PRIVATE
Qt6::Core
Qt6::Gui
Qt6::Widgets
)
# Resources:
set(grades_resource_files
"grades.txt"
)
qt_add_resources(frozencolumn "grades"
PREFIX
"/"
FILES
${grades_resource_files}
)
install(TARGETS frozencolumn
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
)

View File

@ -0,0 +1,126 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "freezetablewidget.h"
#include <QScrollBar>
#include <QHeaderView>
//! [constructor]
FreezeTableWidget::FreezeTableWidget(QAbstractItemModel * model)
{
setModel(model);
frozenTableView = new QTableView(this);
init();
//connect the headers and scrollbars of both tableviews together
connect(horizontalHeader(),&QHeaderView::sectionResized, this,
&FreezeTableWidget::updateSectionWidth);
connect(verticalHeader(),&QHeaderView::sectionResized, this,
&FreezeTableWidget::updateSectionHeight);
connect(frozenTableView->verticalScrollBar(), &QAbstractSlider::valueChanged,
verticalScrollBar(), &QAbstractSlider::setValue);
connect(verticalScrollBar(), &QAbstractSlider::valueChanged,
frozenTableView->verticalScrollBar(), &QAbstractSlider::setValue);
}
//! [constructor]
FreezeTableWidget::~FreezeTableWidget()
{
delete frozenTableView;
}
//! [init part1]
void FreezeTableWidget::init()
{
frozenTableView->setModel(model());
frozenTableView->setFocusPolicy(Qt::NoFocus);
frozenTableView->verticalHeader()->hide();
frozenTableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed);
viewport()->stackUnder(frozenTableView);
//! [init part1]
//! [init part2]
frozenTableView->setStyleSheet("QTableView { border: none;"
"background-color: #8EDE21;"
"selection-background-color: #999}"); //for demo purposes
frozenTableView->setSelectionModel(selectionModel());
for (int col = 1; col < model()->columnCount(); ++col)
frozenTableView->setColumnHidden(col, true);
frozenTableView->setColumnWidth(0, columnWidth(0) );
frozenTableView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
frozenTableView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
frozenTableView->show();
updateFrozenTableGeometry();
setHorizontalScrollMode(ScrollPerPixel);
setVerticalScrollMode(ScrollPerPixel);
frozenTableView->setVerticalScrollMode(ScrollPerPixel);
}
//! [init part2]
//! [sections]
void FreezeTableWidget::updateSectionWidth(int logicalIndex, int /* oldSize */, int newSize)
{
if (logicalIndex == 0){
frozenTableView->setColumnWidth(0, newSize);
updateFrozenTableGeometry();
}
}
void FreezeTableWidget::updateSectionHeight(int logicalIndex, int /* oldSize */, int newSize)
{
frozenTableView->setRowHeight(logicalIndex, newSize);
}
//! [sections]
//! [resize]
void FreezeTableWidget::resizeEvent(QResizeEvent * event)
{
QTableView::resizeEvent(event);
updateFrozenTableGeometry();
}
//! [resize]
//! [navigate]
QModelIndex FreezeTableWidget::moveCursor(CursorAction cursorAction,
Qt::KeyboardModifiers modifiers)
{
QModelIndex current = QTableView::moveCursor(cursorAction, modifiers);
if (cursorAction == MoveLeft && current.column() > 0
&& visualRect(current).topLeft().x() < frozenTableView->columnWidth(0) ){
const int newValue = horizontalScrollBar()->value() + visualRect(current).topLeft().x()
- frozenTableView->columnWidth(0);
horizontalScrollBar()->setValue(newValue);
}
return current;
}
//! [navigate]
void FreezeTableWidget::scrollTo (const QModelIndex & index, ScrollHint hint){
if (index.column() > 0)
QTableView::scrollTo(index, hint);
}
//! [geometry]
void FreezeTableWidget::updateFrozenTableGeometry()
{
frozenTableView->setGeometry(verticalHeader()->width() + frameWidth(),
frameWidth(), columnWidth(0),
viewport()->height()+horizontalHeader()->height());
}
//! [geometry]

View File

@ -0,0 +1,35 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef FREEZETABLEWIDGET_H
#define FREEZETABLEWIDGET_H
#include <QTableView>
//! [Widget definition]
class FreezeTableWidget : public QTableView {
Q_OBJECT
public:
FreezeTableWidget(QAbstractItemModel * model);
~FreezeTableWidget();
protected:
void resizeEvent(QResizeEvent *event) override;
QModelIndex moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers) override;
void scrollTo (const QModelIndex & index, ScrollHint hint = EnsureVisible) override;
private:
QTableView *frozenTableView;
void init();
void updateFrozenTableGeometry();
private slots:
void updateSectionWidth(int logicalIndex, int oldSize, int newSize);
void updateSectionHeight(int logicalIndex, int oldSize, int newSize);
};
//! [Widget definition]
#endif // FREEZETABLEWIDGET_H

View File

@ -0,0 +1,11 @@
QT += widgets
requires(qtConfig(tableview))
HEADERS += freezetablewidget.h
SOURCES += main.cpp freezetablewidget.cpp
RESOURCES += grades.qrc
# install
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/itemviews/frozencolumn
INSTALLS += target

View File

@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/" >
<file>grades.txt</file>
</qresource>
</RCC>

View File

@ -0,0 +1,36 @@
France , Norway , YDS , UK(tech.), UK(adj.) , UIAA , Ger , Australia , Finland , Brazil
1, , 5.2, , , I , I , , , Isup
2, , 5.3, , , II , II , 11, , II
3, 3, 5.4, , , III , III , 12, , IIsup
4, 4, 5.5, 4a , VD , IV , IV , 12, , III
5a , 5-, 5.6, , S , V- , V , 13, 5-, IIIsup
5b , 5, 5.7, 4b , HS , V , VI , 14, 5, IV
, , , 4c , , V+ , , 15, ,
5c , 5+, 5.8, , VS , VI- , VIIa , 16, 5, IVsup
6a , 6-, 5.9, 5a , HVS , VI , VIIb , 17, , V
6a+ , 6-/6 , 5.10a , , E1 , VI+ , VIIc , 18, 6-, VI
6b , , 5.10b , 5b , , , , 19, , VI/VI+
6b+ , 6, 5.10c , , E2 , VII- , VIIIa , 20, 6, VIsup/VI+
6c , 6+, 5.10d , 5c , , VII , VIIIb , 21, , VIsup
6c+ , 7-, 5.11a , , E3 , VII+ , VIIIc , 22, 6, 7a
6c+ , 7, 5.11b , , , , , 23, , 7b
7a , 7+, 5.11c , 6a , E4 , VIII- , IXa , 24, 7-, 7c
7a , 7+/8- , 5.11d , , , VIII , IXb , , , 7c
7a+ , 8-, 5.12a , , E5 , VIII+ , IXc , 25, 7, 8a
7b , 8, 5.12b , 6b , , , , 26, 8-, 8b
7b+ , 8/8+ , 5.12c , , E6 , IX- , Xa , 27, 8, 8c
7c , 8+, 5.12d , 6c , , IX , Xb , 28, 8, 9a
7c+ , 9-, 5.13a , , E7 , IX+ , Xc , 29, 9-, 9b
8a , , 5.13b , , , , , , 9, 9c
8a+ , 9-/9 , 5.13c , 7a , , X- , , 30, 9, 10a
8b , 9, 5.13d , , E8 , X , , 31, 10-, 10b
8b+ , 9/9+ , 5.14a , , , X+ , , 32, 10, 10c
8c , 9+, 5.14b , 7b , , , , 33, 10, 11a
8c+ , 10-, 5.14c , , E9 , XI- , , 34, 11-, 11b
9a , 10, 5.14d , 7c , , XI , , 35, 11, 11c
9a+ , , 5.15a , , , XI+ , , , , 12a
9b , , 5.15b , , , , , , , 12b
# Wikipedia contributors. Grade (climbing). Wikipedia, The Free Encyclopedia. May 15, 2009, 20:42 UTC.
# Available at: http://en.wikipedia.org/w/index.php?title=Grade_(climbing)&oldid=290165724. Accessed May 28, 2009.

View File

@ -0,0 +1,49 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include <QApplication>
#include <QStandardItemModel>
#include <QFile>
#include <QTextStream>
#include "freezetablewidget.h"
int main(int argc, char* argv[])
{
Q_INIT_RESOURCE(grades);
QApplication app( argc, argv );
QStandardItemModel *model=new QStandardItemModel();
QFile file(":/grades.txt");
if (file.open(QFile::ReadOnly)) {
QTextStream stream(&file);
QString line = stream.readLine();
QStringList list = line.simplified().split(',');
model->setHorizontalHeaderLabels(list);
int row = 0;
QStandardItem *newItem = nullptr;
while (!stream.atEnd()) {
line = stream.readLine();
if (!line.startsWith('#') && line.contains(',')) {
list = line.simplified().split(',');
for (int col = 0; col < list.length(); ++col){
newItem = new QStandardItem(list.at(col));
model->setItem(row, col, newItem);
}
++row;
}
}
}
file.close();
FreezeTableWidget *tableView = new FreezeTableWidget(model);
tableView->setWindowTitle(QObject::tr("Frozen Column Example"));
tableView->resize(560, 680);
tableView->show();
return app.exec();
}

View File

@ -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}"
)

View File

@ -0,0 +1,2 @@
The interview example shows the same model and selection being shared
between three different views.

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

@ -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

View File

@ -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>

View File

@ -0,0 +1,57 @@
// 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[])
{
Q_INIT_RESOURCE(interview);
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();
}

View 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;
}

View 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

View File

@ -0,0 +1,24 @@
TEMPLATE = subdirs
SUBDIRS = addressbook \
basicsortfiltermodel \
chart \
coloreditorfactory \
combowidgetmapper \
customsortfiltermodel \
dirview \
editabletreemodel \
fetchmore \
flattreeview \
frozencolumn \
interview \
pixelator \
puzzle \
simpledommodel \
simpletreemodel \
simplewidgetmapper \
spinboxdelegate \
spreadsheet \
stardelegate \
storageview
!qtConfig(draganddrop): SUBDIRS -= puzzle
!qtHaveModule(xml): SUBDIRS -= simpledommodel

View File

@ -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}"
)

View File

@ -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]

View File

@ -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

View File

@ -0,0 +1,5 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file>images/qt.png</file>
</qresource>
</RCC>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Some files were not shown because too many files have changed in this diff Show More