def slot_data_changed(self, start_index, end_index, model, attr): pattern_list = [ '^{}$'.format(display_formatter(get_obj_value(data_obj, 'value'))) for data_obj in model.get_data_list() if get_obj_value(data_obj, 'value_checked') ] self.sig_filter_changed.emit(attr, '|'.join(pattern_list))
def parent(self, index): if not index.isValid(): return QModelIndex() child_item = index.internalPointer() parent_item = get_obj_value(child_item, '_parent') if parent_item is None: return QModelIndex() grand_item = get_obj_value(parent_item, '_parent') if grand_item is None: return QModelIndex() parent_list = get_obj_value(grand_item, 'children') return self.createIndex(parent_list.index(parent_item), 0, parent_item)
def setData(self, index, value, role=Qt.EditRole): if index.isValid() and role in [Qt.CheckStateRole, Qt.EditRole]: column_obj = self.header_list[index.column()] key = column_obj.role('key') data_obj = index.internalPointer() if role == Qt.CheckStateRole and column_obj.role('checkable'): key += '_checked' # 更新自己 set_obj_value(data_obj, key, value) self.emit(SIGNAL('dataChanged(QModelIndex, QModelIndex)'), index, index) # 更新它的children for row, sub_obj in enumerate( get_obj_value(data_obj, 'children', [])): set_obj_value(sub_obj, key, value) sub_index = index.child(row, index.column()) self.emit(SIGNAL('dataChanged(QModelIndex, QModelIndex)'), sub_index, sub_index) # 更新它的parent parent_index = index.parent() if parent_index.isValid(): parent_obj = parent_index.internalPointer() new_parent_value = value old_parent_value = get_obj_value(parent_obj, key) for sibling_obj in get_obj_value( get_obj_value(data_obj, '_parent'), 'children', []): if value != get_obj_value(sibling_obj, key): new_parent_value = 1 break if new_parent_value != old_parent_value: set_obj_value(parent_obj, key, new_parent_value) self.emit( SIGNAL('dataChanged(QModelIndex, QModelIndex)'), parent_index, parent_index) else: set_obj_value(data_obj, key, value) # 采用 self.dataChanged.emit方式在houdini16里面会报错 # TypeError: dataChanged(QModelIndex,QModelIndex,QVector<int>) only accepts 3 arguments, 3 given! # 所以临时使用旧式信号的发射方式 self.emit(SIGNAL('dataChanged(QModelIndex, QModelIndex)'), index, index) # self.dataChanged.emit(index, index) return True else: return False
def rowCount(self, parent_index=None): if parent_index and parent_index.isValid(): parent_item = parent_index.internalPointer() else: parent_item = self.root_item children_obj = get_obj_value(parent_item, 'children') return len(children_obj) if not hasattr(children_obj, 'next') else 0
def mouse_move_event(self, event): index = self.indexAt(event.pos()) real_index = utils.real_index(index) column_obj = self.header_list[real_index.column()] if column_obj.role('clickable'): key_name = column_obj.role('key') value = utils.get_obj_value(real_index.internalPointer(), key_name) if value: # 只有值不为空的时候,才可以改变鼠标形状 self.setCursor(Qt.PointingHandCursor) return self.setCursor(Qt.ArrowCursor)
def hasChildren(self, parent_index=None): if parent_index and parent_index.isValid(): parent_data = parent_index.internalPointer() else: parent_data = self.root_item children_obj = get_obj_value(parent_data, 'children') if children_obj is None: return False if hasattr(children_obj, 'next'): return True else: return len(children_obj)
def index(self, row, column, parent_index=None): if parent_index and parent_index.isValid(): parent_item = parent_index.internalPointer() else: parent_item = self.root_item children_list = get_obj_value(parent_item, 'children') if children_list and len(children_list) > row: child_item = children_list[row] if child_item: set_obj_value(child_item, '_parent', parent_item) return self.createIndex(row, column, child_item) return QModelIndex()
def createEditor(self, parent, option, index): self.parent_widget = parent self.editor = MMenu(exclusive=self.exclusive, parent=parent) self.editor.setWindowFlags(Qt.FramelessWindowHint | Qt.Window) model = utils.real_model(index) real_index = utils.real_index(index) data_obj = real_index.internalPointer() attr = '{}_list'.format( model.header_list[real_index.column()].role('key')) self.editor.set_data(utils.get_obj_value(data_obj, attr, [])) self.editor.sig_value_changed.connect(self._slot_finish_edit) return self.editor
def _refresh_data(self, tool_item): if self.source_model is None: return value_counter = Counter([ display_formatter(get_obj_value(data, tool_item.attr)) for data in self.source_model.get_data_list() ]) tool_item.setup_data([{ 'value': v[0], 'count': v[1], 'value_checked': 0 } for v in sorted( value_counter.items(), key=itemgetter(1), reverse=True)])
def data(self, index, role=Qt.DisplayRole): if not index.isValid(): return None column_obj = self.header_list[index.column()] # 获取该列字段的配置 data_obj = index.internalPointer() key = column_obj.role('key') role_cell = column_obj.role(role) if role_cell: user_callback = role_cell.user_callback # header中该role的配置 if not user_callback and role not in [ Qt.DisplayRole, Qt.EditRole, Qt.ToolTipRole ]: # 如果header中没有配置该role,而且也不是 DisplayRole/EditRole,直接返回None return None else: value = apply_formatter(user_callback, get_obj_value(data_obj, key), data_obj) return apply_formatter(role_cell.final_formatter, value) if role == Qt.CheckStateRole and column_obj.role('checkable'): state = get_obj_value(data_obj, key + '_checked') return Qt.Unchecked if state is None else state return None
def _slot_set_select(self, column, state): current_model = self.model() source_model = utils.real_model(current_model) source_model.beginResetModel() attr = '{}_checked'.format( source_model.header_list[column].role('key')) for row in range(current_model.rowCount()): real_index = utils.real_index(current_model.index(row, column)) data_obj = real_index.internalPointer() if state is None: old_state = utils.get_obj_value(data_obj, attr) utils.set_obj_value( data_obj, attr, Qt.Unchecked if old_state == Qt.Checked else Qt.Checked) else: utils.set_obj_value(data_obj, attr, state) source_model.endResetModel() source_model.emit(SIGNAL('dataChanged(QModelIndex, QModelIndex)'), None, None)
def mouse_release_event(self, event): if event.button() != Qt.LeftButton: QTableView.mouseReleaseEvent(self, event) return index = self.indexAt(event.pos()) real_index = utils.real_index(index) column_obj = self.header_list[real_index.column()] if column_obj.role('clickable'): key_name = column_obj.role('key') data_obj = real_index.internalPointer() value = utils.get_obj_value(data_obj, key_name) if value: if isinstance(value, dict): self.sig_link_clicked.emit(value) elif isinstance(value, basestring): self.sig_link_clicked.emit(data_obj) elif isinstance(value, list): for i in value: self.sig_link_clicked.emit(i)