Qt:Model-View架构学习详情,qtmodel-view
投稿于 被查看 49409 次 评论:285
Qt:Model-View架构学习详情,qtmodel-view
Qt之Model-View架构
简述
为什么会用这个模式,这里我就不解释了。这里我只是如何去使用的。供大家共同探讨学习,主要是参考了Qt的Demo。
效果图
代码
//主代码界面QMvcTest.cpp void QMvcTest::initControl() { QCustomItemModel* customModel = new QCustomItemModel(QJsonArray(), ui.treeView); ItemDelegate *delegate = new ItemDelegate(ui.treeView); ui.treeView->setModel(customModel); delegate->setView(ui.treeView); ui.treeView->setAnimated(true); ui.treeView->setMouseTracking(true); ui.treeView->setItemDelegate(delegate); ui.treeView->setCursor(Qt::PointingHandCursor); const QModelIndex&& curIndex = customModel->index(0, 0).child(0, 0); ui.treeView->setCurrentIndex(curIndex); connect(delegate, SIGNAL(expanded(const QModelIndex &)), this, SLOT(onTreeViewExpanded(const QModelIndex &))); } void QMvcTest::onTreeViewExpanded(const QModelIndex &index) { bool bExpanded = ui.treeView->isExpanded(index); if (!bExpanded) { ui.treeView->expand(index); } else { ui.treeView->collapse(index); } }
//QCustomItemModel.cpp QCustomItemModel::QCustomItemModel(const QJsonArray &data, QObject *parent) : QAbstractItemModel(parent) { QJsonArray objChildArray = { QStringLiteral("雨田哥1号"), QStringLiteral("雨田哥2号"), QStringLiteral("雨田哥3号"), QStringLiteral("雨田哥4号"), QStringLiteral("雨田哥5号") }; QJsonObject obj{ { QStringLiteral("雨田哥"), objChildArray } }; QJsonArray array = { obj, obj, obj }; QVectorrootData; rootData << ""; rootItem = new TreeItem(rootData); setModelData(array); } QCustomItemModel::~QCustomItemModel() { delete rootItem; } int QCustomItemModel::columnCount(const QModelIndex & /* parent */) const { return rootItem->columnCount(); } int QCustomItemModel::rowCount(const QModelIndex &parent) const { TreeItem *parentItem = getItem(parent); return parentItem->childCount(); } QVariant QCustomItemModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) return QVariant(); TreeItem *item = getItem(index); if (item == nullptr) { return QVariant(); } if (role == Qt::DisplayRole || role == Qt::EditRole) { return item->data(index.column()); } else if (role == Qt::UserRole + 1) { //是否是子节点 if (item->childCount() == 0) { return true; } return false; } else { return QVariant(); } } Qt::ItemFlags QCustomItemModel::flags(const QModelIndex &index) const { if (!index.isValid()) return 0; TreeItem *item = getItem(index); if (item && item->childCount() > 0) { return Qt::NoItemFlags; } return Qt::ItemIsEditable | QAbstractItemModel::flags(index); } TreeItem *QCustomItemModel::getItem(const QModelIndex &index) const { if (index.isValid()) { TreeItem *item = static_cast (index.internalPointer()); if (item) return item; } return rootItem; } QVariant QCustomItemModel::headerData(int section, Qt::Orientation orientation, int role) const { if (orientation == Qt::Horizontal && role == Qt::DisplayRole) return rootItem->data(section); return QVariant(); } QModelIndex QCustomItemModel::index(int row, int column, const QModelIndex &parent) const { if (parent.isValid() && parent.column() != 0) return QModelIndex(); TreeItem *parentItem = getItem(parent); TreeItem *childItem = parentItem->child(row); if (childItem) return createIndex(row, column, childItem); else return QModelIndex(); } bool QCustomItemModel::insertColumns(int position, int columns, const QModelIndex &parent) { bool success; beginInsertColumns(parent, position, position + columns - 1); success = rootItem->insertColumns(position, columns); endInsertColumns(); return success; } bool QCustomItemModel::insertRows(int position, int rows, const QModelIndex &parent) { TreeItem *parentItem = getItem(parent); bool success; beginInsertRows(parent, position, position + rows - 1); success = parentItem->insertChildren(position, rows, rootItem->columnCount()); endInsertRows(); return success; } QModelIndex QCustomItemModel::parent(const QModelIndex &index) const { if (!index.isValid()) return QModelIndex(); TreeItem *childItem = getItem(index); TreeItem *parentItem = childItem->parent(); if (parentItem == rootItem) return QModelIndex(); return createIndex(parentItem->childNumber(), 0, parentItem); } bool QCustomItemModel::removeColumns(int position, int columns, const QModelIndex &parent) { bool success; beginRemoveColumns(parent, position, position + columns - 1); success = rootItem->removeColumns(position, columns); endRemoveColumns(); if (rootItem->columnCount() == 0) removeRows(0, rowCount()); return success; } bool QCustomItemModel::removeRows(int position, int rows, const QModelIndex &parent) { TreeItem *parentItem = getItem(parent); bool success = true; beginRemoveRows(parent, position, position + rows - 1); success = parentItem->removeChildren(position, rows); endRemoveRows(); return success; } bool QCustomItemModel::setData(const QModelIndex &index, const QVariant &value, int role) { if (role == Qt::EditRole) { TreeItem *item = getItem(index); bool result = item->setData(index.column(), value); if (result) emit dataChanged(index, index); return result; } else if (role == Qt::FontRole) { TreeItem *item = getItem(index); if (item && item->childCount() == 0) { item->m_itemFontIsBold = value.toBool(); } return true; } else { return false; } } bool QCustomItemModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role) { if (role != Qt::EditRole || orientation != Qt::Horizontal) return false; bool result = rootItem->setData(section, value); if (result) emit headerDataChanged(orientation, section, section); return result; } void QCustomItemModel::setModelData(const QJsonArray &data) { for (int nRootIndex = 0; nRootIndex < data.size(); nRootIndex++) { const QJsonObject&& obj = data.at(nRootIndex).toObject(); for (auto itor = obj.begin(); itor != obj.end(); itor++) { const QString&& key = itor.key(); const QJsonArray&& childAray = itor.value().toArray(); QVector columnData; columnData << key; rootItem->insertChildren(nRootIndex, 1, rootItem->columnCount()); TreeItem* parent = rootItem->child(nRootIndex); parent->setData(0, key); for (int index = 0; index < childAray.size(); index++) { parent->insertChildren(index, 1, rootItem->columnCount()); parent->child(index)->setData(0, childAray.at(index).toString()); } } } }
//TreeItem.cpp TreeItem::TreeItem(const QVector&data, TreeItem *parent) { m_itemFontIsBold = true; parentItem = parent; itemData = data; } TreeItem::~TreeItem() { qDeleteAll(childItems); } TreeItem *TreeItem::child(int number) { return childItems.value(number); } int TreeItem::childCount() const { return childItems.count(); } int TreeItem::childNumber() const { if (parentItem) return parentItem->childItems.indexOf(const_cast (this)); return 0; } int TreeItem::columnCount() const { return itemData.count(); } QVariant TreeItem::data(int column) const { return itemData.value(column); } bool TreeItem::insertChildren(int position, int count, int columns) { if (position < 0 || position > childItems.size()) return false; for (int row = 0; row < count; ++row) { QVector data(columns); TreeItem *item = new TreeItem(data, this); childItems.insert(position, item); } return true; } 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()); foreach (TreeItem *child, childItems) child->insertColumns(position, columns); return true; } TreeItem *TreeItem::parent() { return parentItem; } 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; } 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); foreach (TreeItem *child, childItems) child->removeColumns(position, columns); return true; } bool TreeItem::setData(int column, const QVariant &value) { if (column < 0 || column >= itemData.size()) return false; itemData[column] = value; return true; }
//ItemDelegate.cpp void ItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { QStyleOptionViewItem viewOption(option); QStyledItemDelegate::paint(painter, viewOption, index); bool bExpanded = false; if (m_treeView != NULL) { const QAbstractItemModel *model = index.model(); if (!model->hasChildren(index)) { return; } bExpanded = m_treeView->isExpanded(index); } QPixmap pixmap = bExpanded ? QPixmap(m_expandIconName) : QPixmap(m_collapseIconName); QRect decorationRect = QRect(viewOption.rect.left() + 14, viewOption.rect.top() + 12, m_pixmapHeight, m_pixmapWidth); painter->drawPixmap(decorationRect, pixmap); } bool ItemDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) { if (event->type() == QEvent::MouseButtonPress && Qt::LeftButton == qApp->mouseButtons()) { m_treeView->update(); emit expanded(index); } return QStyledItemDelegate::editorEvent(event, model, option, index); } void ItemDelegate::setView(QTreeView *treeView) { m_treeView = treeView; }
//QSS样式 QTreeView { background-color: #ffffff; show-decoration-selected: 1; outline:0px; } QTreeView::item { background-color:transparent; font-family: Microsoft YaHei; font-size: 12px; color: #666666; text-align:left; height:32px; padding-left:22px; } QTreeView::item:has-children { background-color:transparent; font-family: Microsoft YaHei; font-size: 12px; color: #333333; text-align:left; height:32px; padding-left:22px; } QTreeView::item:hover,QTreeView::item:selected { background-color:#D3EFFF; font-size: 12px; color: #00A1FF; border:0px; text-align:left; } QTreeView::branch:has-children:!has-siblings:closed, QTreeView::branch:closed:has-children:has-siblings { border-image: none; image: url(:/QMvcTest/Resources/smallPackup.png:); } QTreeView::branch:open:has-children:!has-siblings, QTreeView::branch:open:has-children:has-siblings { border-image: none; image: url(:/QMvcTest/Resources/smallExp.png); }
用户评论