我有一个QTreeView设置显示QSortFilteredProxyModel,其中filterAcceptsRow()中的自定义过滤仅接受行,具体取决于父行值的值(通过QStyledItemDelegate派生类在QComboBox中选择。例如,如果我选择在行“键入”值“宝马”,我想为这个特殊情况显示孩子。 这适用于第一项,我可以在Item1中选择多个级别的这些值(最多5个级别)。一切都很好。
但是,我注意到,一旦我玩item1和这个自定义过滤,然后添加一个item2,问题就开始了。我注意到的第一件事是,QTreeView取消展开item1 / item2的公共父级并仅显示根项目的子级。正常行为(以及添加item1的行为就是这样)是扩展item1的父级。为什么这会在第二个项目上混淆,只有如果我一直在使用item1 children-settings,idk。 此外,我注意到在第2项中过滤无法正常工作。我在item2->类型中有一个QComboBox,具有子项取决于item2->类型值.. QComboBox的默认值的第一个子项仍然显示它应该,但是当更改QComboBox时,视图不会更新任何更长并保持第一个加载的子项在item2 / item3 / ...内但是,使用正确的值/索引调用Delegate :: setModelData并相应地调用TreeItem-> setData()。只是过滤似乎与TreeItem-> data()的旧值一致。请再次注意,这只会在我玩物品1之后才发生。如果我保持该物品不变,我可以正确地玩所有其他物品(物品2,物品3,......)并且它正常。
如果有人可以提供帮助,我会很高兴。
有没有人为我提供tipps,什么可能导致expandStates的“重置”,即使expand()被调用为item1和item2插入相同并且对item1有效? 什么可能导致我的进一步问题?
ExampleDelegate.h
class ExampleDelegate : public QStyledItemDelegate { Q_OBJECT public: ExampleDelegate(QObject* parent = 0); ~ExampleDelegate(void); QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const; void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const; void setEditorData(QWidget* editor, const QModelIndex &index) const; }
ProxyModel.h
class ProxyModel : public QSortFilterProxyModel { Q_OBJECT public: ProxyModel(QObject *parent); ~ProxyModel(void); void refresh(); void doReset(); pthread_mutex_t* proxyMutex; int rowCount(QModelIndex& parent) const; bool hasChildren ( const QModelIndex & parent = QModelIndex() ) const; QModelIndex parent(const QModelIndex &index) const; QModelIndex index(int row, int col, QModelIndex& parent) const; bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const; };
ProxyModel.cpp
bool ProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const { printf("ProxyModel::filterAcceptRow \n"); pthread_mutex_lock(this->proxyMutex); QAbstractItemModel* source = this->sourceModel(); QModelIndex index = source->index(sourceRow, 0, sourceParent); TreeItem* item = ((TreeItem*) index.internalPointer()); if(item != NULL) { int showOnly = item->showOnlyParentDetailDialog; if(showOnly != -1) { TreeItem* parent = ((TreeItem*) index.internalPointer())->parent(); if(parent != NULL) { int parentOption = parent->selectedIndex; //printf("parentOption: %u \n", parentOption); bool result = (showOnly == parent->selectOptions->at(parentOption).detailDialog); pthread_mutex_unlock(this->proxyMutex); return result; } else { pthread_mutex_unlock(this->proxyMutex); return true; } } } pthread_mutex_unlock(this->proxyMutex); return true; }