@@ -24,42 +24,133 @@ RoleCombineModel::RoleCombineModel(QAbstractItemModel* major, QAbstractItemModel
2424 }
2525
2626 connect (sourceModel (), &QAbstractItemModel::rowsInserted, this , [this , majorRoles, func](const QModelIndex &parent, int first, int last) {
27- beginInsertRows (index (parent.row (), parent.column ()), first, last);
27+ // 对于QAbstractListModel,parent通常是无效的,我们直接使用QModelIndex()
28+ beginInsertRows (QModelIndex (), first, last);
29+
30+ // 先调整现有映射中后续行的索引
31+ QMap<QPair<int , int >, QPair<int , int >> newIndexMap;
32+ for (auto it = m_indexMap.constBegin (); it != m_indexMap.constEnd (); ++it) {
33+ int row = it.key ().first ;
34+ int col = it.key ().second ;
35+
36+ if (row >= first) {
37+ // 将后续行的索引向后移动
38+ int newRow = row + (last - first + 1 );
39+ newIndexMap[qMakePair (newRow, col)] = it.value ();
40+ } else {
41+ // 保持前面行的映射不变
42+ newIndexMap[it.key ()] = it.value ();
43+ }
44+ }
45+ m_indexMap = newIndexMap;
46+
47+ // 为新插入的行创建映射
48+ int columnCount = sourceModel ()->columnCount ();
2849 for (int i = first; i <= last; i++) {
29- QModelIndex majorIndex = sourceModel ()->index (i, 0 );
30- QModelIndex minorIndex = func (majorIndex.data (majorRoles), m_minor);
31- if (majorIndex.isValid () && minorIndex.isValid ())
32- m_indexMap[qMakePair (i, 0 )] = qMakePair (minorIndex.row (), minorIndex.column ());
50+ for (int j = 0 ; j < columnCount; j++) {
51+ QModelIndex majorIndex = sourceModel ()->index (i, j);
52+ QModelIndex minorIndex = func (majorIndex.data (majorRoles), m_minor);
53+ if (majorIndex.isValid () && minorIndex.isValid ())
54+ m_indexMap[qMakePair (i, j)] = qMakePair (minorIndex.row (), minorIndex.column ());
55+ }
3356 }
3457 endInsertRows ();
3558 });
59+
3660 connect (sourceModel (), &QAbstractItemModel::columnsInserted, this , [this , majorRoles, func](const QModelIndex &parent, int first, int last) {
37- beginInsertColumns (index (parent.row (), parent.column ()), first, last);
61+ beginInsertColumns (QModelIndex (), first, last);
62+
63+ // 先调整现有映射中后续列的索引
64+ QMap<QPair<int , int >, QPair<int , int >> newIndexMap;
65+ for (auto it = m_indexMap.constBegin (); it != m_indexMap.constEnd (); ++it) {
66+ int row = it.key ().first ;
67+ int col = it.key ().second ;
68+
69+ if (col >= first) {
70+ // 将后续列的索引向后移动
71+ int newCol = col + (last - first + 1 );
72+ newIndexMap[qMakePair (row, newCol)] = it.value ();
73+ } else {
74+ // 保持前面列的映射不变
75+ newIndexMap[it.key ()] = it.value ();
76+ }
77+ }
78+ m_indexMap = newIndexMap;
79+
80+ // 为新插入的列创建映射
81+ int rowCount = sourceModel ()->rowCount ();
3882 for (int j = first; j <= last; j++) {
39- QModelIndex majorIndex = sourceModel ()->index (0 , j);
40- QModelIndex minorIndex = func (majorIndex.data (majorRoles), m_minor);
41- if (majorIndex.isValid () && minorIndex.isValid ())
42- m_indexMap[qMakePair (0 , j)] = qMakePair (minorIndex.row (), minorIndex.column ());
83+ for (int i = 0 ; i < rowCount; i++) {
84+ QModelIndex majorIndex = sourceModel ()->index (i, j);
85+ QModelIndex minorIndex = func (majorIndex.data (majorRoles), m_minor);
86+ if (majorIndex.isValid () && minorIndex.isValid ())
87+ m_indexMap[qMakePair (i, j)] = qMakePair (minorIndex.row (), minorIndex.column ());
88+ }
4389 }
4490 endInsertColumns ();
4591 });
4692
4793 connect (sourceModel (), &QAbstractItemModel::rowsRemoved, this , [this ](const QModelIndex &parent, int first, int last) {
48- beginRemoveRows (index (parent.row (), parent.column ()), first, last);
94+ beginRemoveRows (QModelIndex (), first, last);
95+
96+ // 删除被移除行的映射
97+ int columnCount = sourceModel ()->columnCount ();
4998 for (int i = first; i <= last; i++) {
50- if (m_indexMap.contains (qMakePair (i, 0 ))) {
51- m_indexMap.remove (qMakePair (i, 0 ));
99+ for (int j = 0 ; j < columnCount; j++) {
100+ m_indexMap.remove (qMakePair (i, j));
101+ }
102+ }
103+
104+ // 调整后续行的索引映射
105+ QMap<QPair<int , int >, QPair<int , int >> newIndexMap;
106+ for (auto it = m_indexMap.constBegin (); it != m_indexMap.constEnd (); ++it) {
107+ int row = it.key ().first ;
108+ int col = it.key ().second ;
109+
110+ if (row > last) {
111+ // 将后续行的索引向前移动
112+ int newRow = row - (last - first + 1 );
113+ newIndexMap[qMakePair (newRow, col)] = it.value ();
114+ } else if (row < first) {
115+ // 保持前面行的映射不变
116+ newIndexMap[it.key ()] = it.value ();
52117 }
118+ // 被删除行的映射已经在上面移除了
53119 }
120+ m_indexMap = newIndexMap;
121+
54122 endRemoveRows ();
55123 });
124+
56125 connect (sourceModel (), &QAbstractItemModel::columnsRemoved, this , [this ](const QModelIndex &parent, int first, int last) {
57- beginRemoveColumns (index (parent.row (), parent.column ()), first, last);
126+ beginRemoveColumns (QModelIndex (), first, last);
127+
128+ // 删除被移除列的映射
129+ int rowCount = sourceModel ()->rowCount ();
58130 for (int j = first; j <= last; j++) {
59- if (m_indexMap.contains (qMakePair (0 , j))) {
60- m_indexMap.remove (qMakePair (0 , j));
131+ for (int i = 0 ; i < rowCount; i++) {
132+ m_indexMap.remove (qMakePair (i, j));
133+ }
134+ }
135+
136+ // 调整后续列的索引映射
137+ QMap<QPair<int , int >, QPair<int , int >> newIndexMap;
138+ for (auto it = m_indexMap.constBegin (); it != m_indexMap.constEnd (); ++it) {
139+ int row = it.key ().first ;
140+ int col = it.key ().second ;
141+
142+ if (col > last) {
143+ // 将后续列的索引向前移动
144+ int newCol = col - (last - first + 1 );
145+ newIndexMap[qMakePair (row, newCol)] = it.value ();
146+ } else if (col < first) {
147+ // 保持前面列的映射不变
148+ newIndexMap[it.key ()] = it.value ();
61149 }
150+ // 被删除列的映射已经在上面移除了
62151 }
152+ m_indexMap = newIndexMap;
153+
63154 endRemoveColumns ();
64155 });
65156
@@ -104,13 +195,73 @@ RoleCombineModel::RoleCombineModel(QAbstractItemModel* major, QAbstractItemModel
104195 }
105196 });
106197
198+ // 添加对minor模型删除操作的处理
199+ connect (m_minor, &QAbstractItemModel::rowsRemoved, this , [this , majorRoles, func](const QModelIndex &parent, int first, int last) {
200+ // 当minor模型删除行时,需要更新映射并可能触发数据变化信号
201+ QList<QModelIndex> affectedMajorIndexes;
202+
203+ // 找到受影响的major索引
204+ for (auto it = m_indexMap.begin (); it != m_indexMap.end ();) {
205+ int minorRow = it.value ().first ;
206+ int minorCol = it.value ().second ;
207+
208+ if (minorRow >= first && minorRow <= last) {
209+ // 这个映射指向的minor行被删除了,需要重新建立映射
210+ int majorRow = it.key ().first ;
211+ int majorCol = it.key ().second ;
212+ auto majorIndex = sourceModel ()->index (majorRow, majorCol);
213+
214+ if (majorIndex.isValid ()) {
215+ affectedMajorIndexes.append (majorIndex);
216+ // 尝试重新建立映射
217+ QModelIndex newMinorIndex = func (majorIndex.data (majorRoles), m_minor);
218+ if (newMinorIndex.isValid ()) {
219+ it.value () = qMakePair (newMinorIndex.row (), newMinorIndex.column ());
220+ ++it;
221+ } else {
222+ // 无法建立新映射,删除这个映射
223+ it = m_indexMap.erase (it);
224+ }
225+ } else {
226+ it = m_indexMap.erase (it);
227+ }
228+ } else if (minorRow > last) {
229+ // 调整后续行的索引
230+ int newMinorRow = minorRow - (last - first + 1 );
231+ it.value ().first = newMinorRow;
232+ ++it;
233+ } else {
234+ ++it;
235+ }
236+ }
237+
238+ // 对受影响的major索引发送数据变化信号
239+ for (const auto &majorIndex : affectedMajorIndexes) {
240+ Q_EMIT dataChanged (majorIndex, majorIndex, m_minorRolesMap.values ());
241+ }
242+ });
243+
244+ connect (m_minor, &QAbstractItemModel::columnsRemoved, this , [this , majorRoles, func](const QModelIndex &parent, int first, int last) {
245+ // 当minor模型删除列时,需要更新映射
246+ for (auto it = m_indexMap.begin (); it != m_indexMap.end (); ++it) {
247+ int minorRow = it.value ().first ;
248+ int minorCol = it.value ().second ;
249+
250+ if (minorCol > last) {
251+ // 调整后续列的索引
252+ int newMinorCol = minorCol - (last - first + 1 );
253+ it.value ().second = newMinorCol;
254+ }
255+ }
256+ });
257+
107258 connect (m_minor, &QAbstractItemModel::rowsInserted, this ,
108259 [this , majorRoles, func](const QModelIndex &parent, int first, int last){
109260 auto rowCount = sourceModel ()->rowCount ();
110261 auto columnCount = sourceModel ()->columnCount ();
111262 for (int i = 0 ; i < rowCount; i++) {
112263 for (int j = 0 ; j < columnCount; j++) {
113- // alreay bind, pass this
264+ // already bind, pass this
114265 if (m_indexMap.contains (qMakePair (i ,j)))
115266 continue ;
116267
@@ -127,8 +278,25 @@ RoleCombineModel::RoleCombineModel(QAbstractItemModel* major, QAbstractItemModel
127278 // create minor role map
128279 auto minorRolenames = m_minor->roleNames ();
129280 m_roleNames = createRoleNames ();
130- std::for_each (minorRolenames.constBegin (), minorRolenames.constEnd (), [&minorRolenames, this ](auto &roleName) {
131- m_minorRolesMap.insert (m_roleNames.key (roleName), minorRolenames.key (roleName));
281+
282+ // 修复角色映射逻辑:应该映射到新创建的minor角色,而不是major角色
283+ auto majorRoleNames = sourceModel ()->roleNames ();
284+
285+ std::for_each (minorRolenames.constBegin (), minorRolenames.constEnd (), [&minorRolenames, &majorRoleNames, this ](auto &roleName) {
286+ int minorRoleKey = minorRolenames.key (roleName);
287+
288+ // 在组合角色中找到对应的key,但排除major模型已有的key
289+ int combinedRoleKey = -1 ;
290+ for (auto it = m_roleNames.constBegin (); it != m_roleNames.constEnd (); ++it) {
291+ if (it.value () == roleName && !majorRoleNames.contains (it.key ())) {
292+ combinedRoleKey = it.key ();
293+ break ;
294+ }
295+ }
296+
297+ if (combinedRoleKey != -1 ) {
298+ m_minorRolesMap.insert (combinedRoleKey, minorRoleKey);
299+ }
132300 });
133301}
134302
@@ -152,19 +320,31 @@ QHash<int, QByteArray> RoleCombineModel::roleNames() const
152320
153321int RoleCombineModel::rowCount (const QModelIndex &parent) const
154322{
323+ if (parent.isValid ())
324+ return 0 ; // 平坦列表模型:有效的parent表示某个项目,项目没有子项
155325 return sourceModel ()->rowCount ();
156326}
157327
158328int RoleCombineModel::columnCount (const QModelIndex &parent) const
159329{
330+ if (parent.isValid ())
331+ return 0 ; // 平坦列表模型:有效的parent表示某个项目,项目没有子项
160332 return sourceModel ()->columnCount ();
161333}
162334
163335QVariant RoleCombineModel::data (const QModelIndex &index, int role) const
164336{
165337 if (m_minorRolesMap.contains (role)) {
166- int row, column;
167- std::tie (row, column) = m_indexMap.value (qMakePair (index.row (), index.column ()), qMakePair (-1 , -1 ));
338+ auto majorKey = qMakePair (index.row (), index.column ());
339+ auto mapping = m_indexMap.value (majorKey, qMakePair (-1 , -1 ));
340+ int row = mapping.first ;
341+ int column = mapping.second ;
342+
343+ // 检查映射是否有效
344+ if (row == -1 || column == -1 ) {
345+ return QVariant (); // 返回空值而不是用无效索引访问
346+ }
347+
168348 return m_minor->data (m_minor->index (row, column), m_minorRolesMap[role]);
169349 } else {
170350 return sourceModel ()->data (sourceModel ()->index (index.row (), index.column ()), role);
@@ -176,6 +356,12 @@ bool RoleCombineModel::hasIndex(int row, int column, const QModelIndex &parent)
176356 return sourceModel ()->hasIndex (row, column, parent);
177357}
178358
359+ bool RoleCombineModel::hasChildren (const QModelIndex &parent) const
360+ {
361+ // 平坦列表模型:只有根节点有子项,其他项目都没有子项
362+ return !parent.isValid () && rowCount (parent) > 0 ;
363+ }
364+
179365QModelIndex RoleCombineModel::index (int row, int column, const QModelIndex &parent) const
180366{
181367 if (!hasIndex (row, column, parent))
0 commit comments