#include "mainwindow.h" #include "corehost.h" #include #include #include #include #include #include #define GROUP_COVER0_PATH Qt::UserRole + 1 #define GROUP_COVER1_PATH Qt::UserRole + 2 #define GROUP_COVER2_PATH Qt::UserRole + 3 #define GROUP_TITLE Qt::DisplayRole #define GROUP_ITEMSCOUNT Qt::UserRole + 4 #define ITEM_ICON_PATH Qt::UserRole + 1 #define ITEM_TITLE Qt::DisplayRole CoreHost host; MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), groups_view(new QListView(this)), groups_list(new QStandardItemModel(this)), items_view(new QListView(this)), items_list(new QStandardItemModel(this)) { setMinimumSize(800, 600); groups_view->setModel(groups_list); items_view->setModel(items_list); // -------------------------- auto splitter = new QSplitter(this); setCentralWidget(splitter); splitter->addWidget(groups_view); splitter->addWidget(items_view); groups_list->setHorizontalHeaderLabels(QStringList() << "数量" << "名称"); groups_view->setItemDelegate(new GroupDisplayDelegate); groups_view->setMovement(QListView::Free); init_groups_list(groups_list); items_view->setItemDelegate(new ItemDisplayDelegate()); items_view->setViewMode(QListView::IconMode); items_view->setResizeMode(QListView::Adjust); connect(groups_view, &QListView::clicked, this, &MainWindow::init_items_present); } MainWindow::~MainWindow() { } void MainWindow::init_groups_list(QStandardItemModel* model) { model->removeRows(0, model->rowCount()); QRandomGenerator gen; for (int idx = 0; idx < 200; ++idx) { auto row = new QStandardItem("无名集合0"); row->setData(gen.generate() % 100, GROUP_ITEMSCOUNT); row->setData(":/imgs/default/cover_item.jpg", GROUP_COVER0_PATH); model->appendRow(row); } } void MainWindow::init_items_present(const QModelIndex& index) { QRandomGenerator gen; for (int idx = 0; idx < 200; ++idx) { auto item = new QStandardItem("随机名称"); item->setData((gen.generate() % 2 == 1 ? ":/imgs/default/cover.jpg" : ":/imgs/default/cover_item.jpg"), ITEM_ICON_PATH); items_list->appendRow(item); } } GroupDisplayDelegate::GroupDisplayDelegate() { } GroupDisplayDelegate::~GroupDisplayDelegate() { } QWidget* GroupDisplayDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const { auto font = option.font; font.setPointSize(26); auto ins = new QLineEdit(parent); ins->setFont(font); return ins; } void GroupDisplayDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const { static_cast(editor)->setText(index.data().toString()); } void GroupDisplayDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const { model->setData(index, static_cast(editor)->text()); } auto calc_textrect1 = [](const QRect& whole_rect, double font_height) -> QRectF { return QRectF(whole_rect.left() + 145, whole_rect.top() + 20, whole_rect.width() - 165, font_height); }; void GroupDisplayDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const { QStyleOptionViewItem new_ = option; new_.font.setPointSize(26); new_.fontMetrics = QFontMetrics(new_.font); editor->setGeometry(calc_textrect1(option.rect, new_.fontMetrics.height()).toRect()); } void GroupDisplayDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { drawBackground(painter, option, index); QIcon *icon0 = nullptr, *icon1 = nullptr, *icon2 = nullptr; auto cover0 = index.data(GROUP_COVER0_PATH); if (cover0.isNull()) icon0 = host.queryCoverIcon(":/imgs/default/cover.jpg"); else icon0 = host.queryCoverIcon(cover0.toString()); auto cover1 = index.data(GROUP_COVER1_PATH); if (cover1.isNull()) icon1 = host.queryCoverIcon(":/imgs/default/cover.jpg"); else icon1 = host.queryCoverIcon(cover1.toString()); auto cover2 = index.data(GROUP_COVER2_PATH); if (cover2.isNull()) icon2 = host.queryCoverIcon(":/imgs/default/cover.jpg"); else icon2 = host.queryCoverIcon(cover2.toString()); auto valid_rect = option.rect - QMargins(15, 15, 15, 15); auto pixmap1 = icon1->pixmap(100, 150); QRect rect1(valid_rect.left() + 60, valid_rect.top() + 20, 54, 80); painter->drawPixmap(rect1, pixmap1); auto pixmap2 = icon2->pixmap(100, 150); QRect rect2(valid_rect.left() + 34, valid_rect.top() + 10, 66, 100); painter->drawPixmap(rect2, pixmap2); auto pixmap0 = icon0->pixmap(100, 150); QRect rect0(valid_rect.left(), valid_rect.top(), 80, 120); painter->drawPixmap(rect0, pixmap0); QStyleOptionViewItem new_copy = option; new_copy.font.setPointSize(26); new_copy.fontMetrics = QFontMetrics(new_copy.font); drawDisplay(painter, new_copy, calc_textrect1(option.rect, new_copy.fontMetrics.height()).toRect(), index.data().toString()); new_copy.font.setPointSize(18); new_copy.fontMetrics = QFontMetrics(new_copy.font); drawDisplay(painter, new_copy, new_copy.rect - QMargins(160, 60, 0, 0), QString("总藏书:%1").arg(index.data(GROUP_ITEMSCOUNT).toUInt())); } QSize GroupDisplayDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const { return QSize(400, 145); } ItemDisplayDelegate::ItemDisplayDelegate() { } ItemDisplayDelegate::~ItemDisplayDelegate() { } auto calc_textrect2 = [](const QRect& boundrect, float height) -> QRect { return QRect(boundrect.left() + 5, boundrect.bottom() - height - 5, boundrect.width() - 10, height); }; void ItemDisplayDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { painter->save(); painter->setRenderHint(QPainter::Antialiasing); drawBackground(painter, option, index); QPen pen(QColor(0, 0, 200, 150), 3, Qt::SolidLine); painter->setPen(pen); QBrush brush(QColor(20, 20, 150, 100)); painter->setBrush(brush); if (option.state & QStyle::State_Selected) painter->drawRoundedRect(option.rect - QMargins(2, 2, 2, 2), 5, 5); QIcon* icon = nullptr; auto cover = index.data(ITEM_ICON_PATH); if (!cover.isValid()) icon = host.queryCoverIcon(":/imgs/default/cover.jpg"); else icon = host.queryCoverIcon(cover.toString()); auto valid_rect = option.rect - QMargins(15, 15, 15, 15); drawDecoration(painter, option, valid_rect, icon->pixmap(120, 180)); if (option.features & QStyleOptionViewItem::HasCheckIndicator) drawCheck(painter, option, QRect(option.rect.left() + 5, option.rect.top() + 5, 20, 20), option.checkState); painter->fillRect(calc_textrect2(option.rect, option.fontMetrics.height() * 1.3), QGradient::Preset::NightFade); drawDisplay(painter, option, calc_textrect2(option.rect, option.fontMetrics.height() * 1.3), index.data().toString()); painter->restore(); } QSize ItemDisplayDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const { return QSize(135, 195); } QWidget* ItemDisplayDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const { return new QLineEdit(parent); } void ItemDisplayDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const { static_cast(editor)->setText(index.data().toString()); } void ItemDisplayDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const { model->setData(index, static_cast(editor)->text()); } void ItemDisplayDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const { editor->setGeometry(calc_textrect2(option.rect, option.fontMetrics.height() * 1.3)); }