Qt: Model-View architecture learning details, qtmodel-view
Model-View architecture of Qt
Why is this mode used? I will not explain it here. Here I just want to use it. For discussion and learning, we mainly refer to the Qt Demo.
Code
// The main code interface QMvcTest. cppvoid 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: PointingHan DCursor); 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. cppQCustomItemModel: QCustomItemModel (const QJsonArray & data, QObject * parent): q1_actitemmodel (parent) {QJsonArray objChildArray = {QStringLiteral ("Yutian brother 1 "), QStringLiteral ("yu tian Ge 2"), QStringLiteral ("yu tian Ge 3"), QStringLiteral ("yu tian Ge 4 "), QStringLiteral (" 5 5")}; QJsonObject obj {QStringLiteral (""), objChildArray}; QJsonArray array = {obj, obj, obj}; QVector
RootData; 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) {// whether it is a subnode if (item-> childCount () = 0) {return true;} return false;} else {return QVariant () ;}} Qt: ItemFlags QCustomItemModel: flags (const QModelIndex & ind Ex) const {if (! Index. isValid () return 0; TreeItem * item = getItem (index); if (item & item-> childCount ()> 0) {return Qt: NoItemFlags ;} return Qt: ItemIsEditable | q1_actitemmodel: 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; beginsertcolumns (parent, position, 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; terminate (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.cppTreeItem::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.cppvoid 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 style 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 );}