From c4366e477dd8f66ab7fcc188853b80349e9c0ce9 Mon Sep 17 00:00:00 2001 From: Ed Cooke Date: Wed, 1 Nov 2023 14:18:14 +0100 Subject: [PATCH] Update the books example Remove the .ui file and write the equivalent implementation. Replace the outdated star icons with new star icons. 5 empty stars are now provided and filled in depending on the rating. The new stars are SVG, however, we do not use an SvgRenderer as we cannot use the QtSvg API from QtBase directly. It is safe to assume the SVG image loading plugin is present, the worst case scenario would be empty icons, but it would still build. We instead use QIcon. For the rating, draw the star icons in a combobox, replacing the old spinbox. Update the layout by moving the table view to the bottom, and arranging the input fields at the top. The scrollbar policies have been set to Qt::ScrollBarAsNeeded for the table view. Fixes: QTBUG-118476 Pick-to: 6.5 Change-Id: I27c13534ab06e17531d155469a1cc6e7e05197af Reviewed-by: Axel Spoerl (cherry picked from commit 76b2852b7cff183ba31d6b09b00cbabdffb9ba71) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit a00c80e1ce1f0a901cdbe10366321c25e3135751) --- examples/sql/books/CMakeLists.txt | 5 +- examples/sql/books/bookdelegate.cpp | 38 ++-- examples/sql/books/bookdelegate.h | 3 +- examples/sql/books/books.pro | 1 - examples/sql/books/books.qrc | 3 +- examples/sql/books/bookwindow.cpp | 201 ++++++++++++++++------ examples/sql/books/bookwindow.h | 23 ++- examples/sql/books/bookwindow.ui | 167 ------------------ examples/sql/books/images/star-filled.svg | 1 + examples/sql/books/images/star.png | Bin 782 -> 0 bytes examples/sql/books/images/star.svg | 1 + examples/sql/doc/images/books-demo.png | Bin 14782 -> 13975 bytes 12 files changed, 193 insertions(+), 250 deletions(-) delete mode 100644 examples/sql/books/bookwindow.ui create mode 100644 examples/sql/books/images/star-filled.svg delete mode 100644 examples/sql/books/images/star.png create mode 100644 examples/sql/books/images/star.svg diff --git a/examples/sql/books/CMakeLists.txt b/examples/sql/books/CMakeLists.txt index 86ca051c3b8..36e6dca9e30 100644 --- a/examples/sql/books/CMakeLists.txt +++ b/examples/sql/books/CMakeLists.txt @@ -16,7 +16,7 @@ qt_standard_project_setup() qt_add_executable(books bookdelegate.cpp bookdelegate.h - bookwindow.cpp bookwindow.h bookwindow.ui + bookwindow.cpp bookwindow.h initdb.h main.cpp ) @@ -35,7 +35,8 @@ target_link_libraries(books PRIVATE # Resources: set(books_resource_files - "images/star.png" + "images/star.svg" + "images/star-filled.svg" ) qt_add_resources(books "books" diff --git a/examples/sql/books/bookdelegate.cpp b/examples/sql/books/bookdelegate.cpp index af2a2842985..6aac70b8600 100644 --- a/examples/sql/books/bookdelegate.cpp +++ b/examples/sql/books/bookdelegate.cpp @@ -6,9 +6,8 @@ #include BookDelegate::BookDelegate(QObject *parent) - : QSqlRelationalDelegate(parent), star(QPixmap(":images/star.png")) -{ -} + : QSqlRelationalDelegate(parent) +{} void BookDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const @@ -28,31 +27,34 @@ void BookDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, option.rect, option.palette.color(cg, QPalette::Highlight)); - int rating = model->data(index, Qt::DisplayRole).toInt(); - int width = star.width(); - int height = star.height(); - int x = option.rect.x(); + const int rating = model->data(index, Qt::DisplayRole).toInt(); + const int width = iconDimension; + const int height = width; + // add cellPadding / 2 to center the stars in the cell + int x = option.rect.x() + cellPadding / 2; int y = option.rect.y() + (option.rect.height() / 2) - (height / 2); - for (int i = 0; i < rating; ++i) { - painter->drawPixmap(x, y, star); + + QIcon starIcon(QStringLiteral(":images/star.svg")); + QIcon starFilledIcon(QStringLiteral(":images/star-filled.svg")); + + for (int i = 0; i < 5; ++i) { + if (i < rating) { + starFilledIcon.paint(painter, QRect(x, y, width, height)); + } else { + starIcon.paint(painter, QRect(x, y, width, height)); + } x += width; } } - - QPen pen = painter->pen(); - painter->setPen(option.palette.color(QPalette::Mid)); - painter->drawLine(option.rect.bottomLeft(), option.rect.bottomRight()); - painter->drawLine(option.rect.topRight(), option.rect.bottomRight()); - painter->setPen(pen); } QSize BookDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { if (index.column() == 5) - return QSize(5 * star.width(), star.height()) + QSize(1, 1); + return QSize(5 * iconDimension, iconDimension) + QSize(cellPadding, cellPadding); // Since we draw the grid ourselves: - return QSqlRelationalDelegate::sizeHint(option, index) + QSize(1, 1); + return QSqlRelationalDelegate::sizeHint(option, index) + QSize(cellPadding, cellPadding); } bool BookDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, @@ -65,7 +67,7 @@ bool BookDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, if (event->type() == QEvent::MouseButtonPress) { QMouseEvent *mouseEvent = static_cast(event); int stars = qBound(0, int(0.7 + qreal(mouseEvent->position().toPoint().x() - - option.rect.x()) / star.width()), 5); + - option.rect.x()) / iconDimension), 5); model->setData(index, QVariant(stars)); // So that the selection can change: return false; diff --git a/examples/sql/books/bookdelegate.h b/examples/sql/books/bookdelegate.h index d0b157b3951..5ddb635515e 100644 --- a/examples/sql/books/bookdelegate.h +++ b/examples/sql/books/bookdelegate.h @@ -30,7 +30,8 @@ public: const QModelIndex &index) const override; private: - QPixmap star; + const int cellPadding = 6; + const int iconDimension = 24; }; #endif diff --git a/examples/sql/books/books.pro b/examples/sql/books/books.pro index 870e4a6c007..953945912e5 100644 --- a/examples/sql/books/books.pro +++ b/examples/sql/books/books.pro @@ -4,7 +4,6 @@ INCLUDEPATH += . HEADERS = bookdelegate.h bookwindow.h initdb.h RESOURCES = books.qrc SOURCES = bookdelegate.cpp main.cpp bookwindow.cpp -FORMS = bookwindow.ui QT += sql widgets widgets requires(qtConfig(tableview)) diff --git a/examples/sql/books/books.qrc b/examples/sql/books/books.qrc index 342638ecb04..1a4dac32ccd 100644 --- a/examples/sql/books/books.qrc +++ b/examples/sql/books/books.qrc @@ -1,5 +1,6 @@ - images/star.png + images/star.svg + images/star-filled.svg diff --git a/examples/sql/books/bookwindow.cpp b/examples/sql/books/bookwindow.cpp index b7baad48cc0..8b34bd7a77b 100644 --- a/examples/sql/books/bookwindow.cpp +++ b/examples/sql/books/bookwindow.cpp @@ -9,8 +9,6 @@ BookWindow::BookWindow() { - ui.setupUi(this); - if (!QSqlDatabase::drivers().contains("QSQLITE")) QMessageBox::critical( this, @@ -25,71 +23,28 @@ BookWindow::BookWindow() return; } - // Create the data model: - model = new QSqlRelationalTableModel(ui.bookTable); - model->setEditStrategy(QSqlTableModel::OnManualSubmit); - model->setTable("books"); + // create the central widget for the window + window = new QWidget(this); + setCentralWidget(window); - // Remember the indexes of the columns: - authorIdx = model->fieldIndex("author"); - genreIdx = model->fieldIndex("genre"); + createLayout(); - // Set the relations to the other database tables: - model->setRelation(authorIdx, QSqlRelation("authors", "id", "name")); - model->setRelation(genreIdx, QSqlRelation("genres", "id", "name")); + createModel(); - // Set the localized header captions: - model->setHeaderData(authorIdx, Qt::Horizontal, tr("Author Name")); - model->setHeaderData(genreIdx, Qt::Horizontal, tr("Genre")); - model->setHeaderData(model->fieldIndex("title"), - Qt::Horizontal, tr("Title")); - model->setHeaderData(model->fieldIndex("year"), Qt::Horizontal, tr("Year")); - model->setHeaderData(model->fieldIndex("rating"), - Qt::Horizontal, tr("Rating")); - - // Populate the model: + // Populate the model if (!model->select()) { showError(model->lastError()); return; } - // Set the model and hide the ID column: - ui.bookTable->setModel(model); - ui.bookTable->setItemDelegate(new BookDelegate(ui.bookTable)); - ui.bookTable->setColumnHidden(model->fieldIndex("id"), true); - ui.bookTable->setSelectionMode(QAbstractItemView::SingleSelection); + configureWidgets(); - // Initialize the Author combo box: - ui.authorEdit->setModel(model->relationModel(authorIdx)); - ui.authorEdit->setModelColumn( - model->relationModel(authorIdx)->fieldIndex("name")); + // create the mappings between the UI elements and the SQL model + createMappings(); - ui.genreEdit->setModel(model->relationModel(genreIdx)); - ui.genreEdit->setModelColumn( - model->relationModel(genreIdx)->fieldIndex("name")); + tableView->setCurrentIndex(model->index(0, 0)); + tableView->selectRow(0); - // Lock and prohibit resizing of the width of the rating column: - ui.bookTable->horizontalHeader()->setSectionResizeMode( - model->fieldIndex("rating"), - QHeaderView::ResizeToContents); - - QDataWidgetMapper *mapper = new QDataWidgetMapper(this); - mapper->setModel(model); - mapper->setItemDelegate(new BookDelegate(this)); - mapper->addMapping(ui.titleEdit, model->fieldIndex("title")); - mapper->addMapping(ui.yearEdit, model->fieldIndex("year")); - mapper->addMapping(ui.authorEdit, authorIdx); - mapper->addMapping(ui.genreEdit, genreIdx); - mapper->addMapping(ui.ratingEdit, model->fieldIndex("rating")); - - connect(ui.bookTable->selectionModel(), - &QItemSelectionModel::currentRowChanged, - mapper, - &QDataWidgetMapper::setCurrentModelIndex - ); - - ui.bookTable->setCurrentIndex(model->index(0, 0)); - ui.bookTable->selectRow(0); createMenuBar(); } @@ -99,6 +54,140 @@ void BookWindow::showError(const QSqlError &err) "Error initializing database: " + err.text()); } +void BookWindow::createLayout() +{ + tableView = new QTableView(window); + + gridLayout = new QGridLayout(window); + + titleLabel = new QLabel(tr("Title:"), window); + titleLineEdit = new QLineEdit(window); + authorLabel = new QLabel(tr("Author:"), window); + authorComboBox = new QComboBox(window); + genreLabel = new QLabel(tr("Genre:"), window); + genreComboBox = new QComboBox(window); + yearLabel = new QLabel(tr("Year:"), window); + yearSpinBox = new QSpinBox(window); + ratingLabel = new QLabel(tr("Rating:"), window); + ratingComboBox = new QComboBox(window); + + gridLayout->addWidget(titleLabel, 0, 0, Qt::AlignRight); + gridLayout->addWidget(titleLineEdit, 0, 1, 1, 3); + gridLayout->addWidget(authorLabel, 1, 0, Qt::AlignRight); + gridLayout->addWidget(authorComboBox, 1, 1); + gridLayout->addWidget(yearLabel, 1, 2, Qt::AlignRight); + gridLayout->addWidget(yearSpinBox, 1, 3); + gridLayout->addWidget(genreLabel, 2, 0, Qt::AlignRight); + gridLayout->addWidget(genreComboBox, 2, 1); + gridLayout->addWidget(ratingLabel, 2, 2, Qt::AlignRight); + gridLayout->addWidget(ratingComboBox, 2, 3); + gridLayout->addWidget(tableView, 3, 0, 1, 4, Qt::AlignCenter); + gridLayout->setColumnStretch(1, 1000); + gridLayout->setColumnStretch(3, 1000); + + gridLayout->setContentsMargins(18, 18, 18, 18); + gridLayout->setSpacing(18); + gridLayout->setAlignment(Qt::AlignHCenter); +} + +void BookWindow::createModel() +{ + model = new QSqlRelationalTableModel(tableView); + model->setEditStrategy(QSqlTableModel::OnManualSubmit); + model->setTable("books"); + + authorIdx = model->fieldIndex("author"); + genreIdx = model->fieldIndex("genre"); + + // Set the relations to the other database tables + model->setRelation(authorIdx, QSqlRelation("authors", "id", "name")); + model->setRelation(genreIdx, QSqlRelation("genres", "id", "name")); + + // Set the localised header captions + model->setHeaderData(authorIdx, Qt::Horizontal, tr("Author Name")); + model->setHeaderData(genreIdx, Qt::Horizontal, tr("Genre")); + model->setHeaderData(model->fieldIndex("title"), + Qt::Horizontal, tr("Title")); + model->setHeaderData(model->fieldIndex("year"), Qt::Horizontal, tr("Year")); + model->setHeaderData(model->fieldIndex("rating"), + Qt::Horizontal, tr("Rating")); +} + +void BookWindow::configureWidgets() +{ + tableView->setModel(model); + tableView->setItemDelegate(new BookDelegate(tableView)); + tableView->setColumnHidden(model->fieldIndex("id"), true); + tableView->verticalHeader()->setVisible(false); + tableView->setSelectionMode(QAbstractItemView::ExtendedSelection); + tableView->setSelectionBehavior(QAbstractItemView::SelectRows); + + // Lock and prohibit resizing of the width of the columns + tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); + tableView->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); + tableView->horizontalHeader()->setFixedHeight(tableView->rowHeight(0)); + + // increment by two to consider the frame + tableView->setFixedWidth(tableView->horizontalHeader()->length() + + tableView->verticalScrollBar()->sizeHint().width() + 2); + tableView->setMaximumHeight(tableView->verticalHeader()->length() + + tableView->horizontalHeader()->height() + 2); + + authorComboBox->setModel(model->relationModel(authorIdx)); + authorComboBox->setModelColumn(model->relationModel(authorIdx)->fieldIndex("name")); + + genreComboBox->setModel(model->relationModel(genreIdx)); + genreComboBox->setModelColumn(model->relationModel(genreIdx)->fieldIndex("name")); + + yearSpinBox->setMaximum(9999); + + const int width = 16; + const int height = width; + const int y = 2; + const int padding = 2; + + QSize iconSize = QSize(width * 5 + padding * 2, width + padding * 2); + QIcon starIcon(QStringLiteral(":images/star.svg")); + QIcon starFilledIcon(QStringLiteral(":images/star-filled.svg")); + + for (int row = 0; row < 6; ++row) { + QPixmap icon(iconSize); + icon.fill(Qt::transparent); + QPainter painter(&icon); + int x = 2; + + for (int col = 0; col < 5; ++col) { + if (col < row) { + starFilledIcon.paint(&painter, QRect(x, y, width, height)); + } else { + starIcon.paint(&painter, QRect(x, y, width, height)); + } + x += width; + } + ratingComboBox->addItem(icon, ""); + ratingComboBox->setItemData(row, QString::number(row + 1)); + } + + ratingComboBox->setIconSize(iconSize); +} + +void BookWindow::createMappings() +{ + QDataWidgetMapper *mapper = new QDataWidgetMapper(this); + mapper->setModel(model); + mapper->setItemDelegate(new BookDelegate(this)); + mapper->addMapping(titleLineEdit, model->fieldIndex("title")); + mapper->addMapping(yearSpinBox, model->fieldIndex("year")); + mapper->addMapping(authorComboBox, authorIdx); + mapper->addMapping(genreComboBox, genreIdx); + mapper->addMapping(ratingComboBox, model->fieldIndex("rating"), "currentIndex"); + connect(tableView->selectionModel(), + &QItemSelectionModel::currentRowChanged, + mapper, + &QDataWidgetMapper::setCurrentModelIndex + ); +} + void BookWindow::createMenuBar() { QAction *quitAction = new QAction(tr("&Quit"), this); diff --git a/examples/sql/books/bookwindow.h b/examples/sql/books/bookwindow.h index 8030516e5b6..03d83e219df 100644 --- a/examples/sql/books/bookwindow.h +++ b/examples/sql/books/bookwindow.h @@ -7,9 +7,6 @@ #include #include -#include "ui_bookwindow.h" - - class BookWindow: public QMainWindow { Q_OBJECT @@ -21,11 +18,29 @@ private slots: private: void showError(const QSqlError &err); - Ui::BookWindow ui; QSqlRelationalTableModel *model = nullptr; int authorIdx = 0, genreIdx = 0; + void createLayout(); + void createModel(); + void configureWidgets(); + void createMappings(); void createMenuBar(); + + QWidget *window = nullptr; + + QGridLayout *gridLayout = nullptr; + QTableView *tableView = nullptr; + QLabel *titleLabel = nullptr; + QLineEdit *titleLineEdit = nullptr; + QLabel *authorLabel = nullptr; + QComboBox *authorComboBox = nullptr; + QLabel *genreLabel = nullptr; + QComboBox *genreComboBox = nullptr; + QLabel *yearLabel = nullptr; + QSpinBox *yearSpinBox = nullptr; + QLabel *ratingLabel = nullptr; + QComboBox *ratingComboBox = nullptr; }; #endif diff --git a/examples/sql/books/bookwindow.ui b/examples/sql/books/bookwindow.ui deleted file mode 100644 index c93726c5532..00000000000 --- a/examples/sql/books/bookwindow.ui +++ /dev/null @@ -1,167 +0,0 @@ - - - BookWindow - - - - 0 - 0 - 601 - 420 - - - - Books - - - - - 6 - - - 9 - - - 9 - - - 9 - - - 9 - - - - - - - - - 6 - - - 9 - - - 9 - - - 9 - - - 9 - - - - - QAbstractItemView::SelectRows - - - - - - - Details - - - - QFormLayout::ExpandingFieldsGrow - - - - - <b>Title:</b> - - - - - - - true - - - - - - - <b>Author: </b> - - - - - - - true - - - - - - - <b>Genre:</b> - - - - - - - true - - - - - - - <b>Year:</b> - - - - - - - true - - - - - - -1000 - - - 2100 - - - - - - - <b>Rating:</b> - - - - - - - 5 - - - - - - - - - - - - - - bookTable - titleEdit - authorEdit - genreEdit - yearEdit - - - - diff --git a/examples/sql/books/images/star-filled.svg b/examples/sql/books/images/star-filled.svg new file mode 100644 index 00000000000..8a2aee27fb9 --- /dev/null +++ b/examples/sql/books/images/star-filled.svg @@ -0,0 +1 @@ + diff --git a/examples/sql/books/images/star.png b/examples/sql/books/images/star.png deleted file mode 100644 index 87f4464bd5ea7af0c0ff30aad5464569a5df1b31..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 782 zcmV+p1M&QcP)Gk7=GnC00006VoOIv0RI600RN!9r;`8x0-H%h zK~y-)W0*Q)9wR#D{PkJQ|JUdI z{@>o9^?yZ_>`xXJR_kdq=c5MV6N#Z+5elIEd5SEKu8pu z0ZdRV2E-Xad?Gu_@aO6I2LFNV13S0I?nr7X$Ip zs6gGHtqDpX1O5Q diff --git a/examples/sql/doc/images/books-demo.png b/examples/sql/doc/images/books-demo.png index 77b3b308c9448475bbcbd6388b0d0e8b08d339c8..29f5c844730a7d80c0c665a345eca03241dd0466 100644 GIT binary patch literal 13975 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 ly%|8~IwR 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