def select_rows(self, rows): sel = QItemSelection() sm = self.selectionModel() m = self.model() # Create a range based selector for each set of contiguous rows # as supplying selectors for each individual row causes very poor # performance if a large number of rows has to be selected. for k, g in itertools.groupby(enumerate(rows), lambda i_x:i_x[0]-i_x[1]): group = list(map(operator.itemgetter(1), g)) sel.merge(QItemSelection(m.index(min(group), 0), m.index(max(group), 0)), QItemSelectionModel.SelectionFlag.Select) sm.select(sel, QItemSelectionModel.SelectionFlag.ClearAndSelect)
def handle_mouse_press_event(self, ev): if QApplication.keyboardModifiers( ) & Qt.KeyboardModifier.ShiftModifier: # Shift-Click in QListView is broken. It selects extra items in # various circumstances, for example, click on some item in the # middle of a row then click on an item in the next row, all items # in the first row will be selected instead of only items after the # middle item. index = self.indexAt(ev.pos()) if not index.isValid(): return ci = self.currentIndex() sm = self.selectionModel() sm.setCurrentIndex(index, QItemSelectionModel.SelectionFlag.NoUpdate) if not ci.isValid(): return if not sm.hasSelection(): sm.select(index, QItemSelectionModel.SelectionFlag.ClearAndSelect) return cr = ci.row() tgt = index.row() top = self.model().index(min(cr, tgt), 0) bottom = self.model().index(max(cr, tgt), 0) sm.select(QItemSelection(top, bottom), QItemSelectionModel.SelectionFlag.Select) else: return QListView.mousePressEvent(self, ev)
def keyPressEvent(self, ev): if handle_enter_press(self, ev, self.start_view_animation, False): return k = ev.key() if ev.modifiers() & Qt.KeyboardModifier.ShiftModifier and k in (Qt.Key.Key_Left, Qt.Key.Key_Right, Qt.Key.Key_Up, Qt.Key.Key_Down): ci = self.currentIndex() if not ci.isValid(): return c = ci.row() ncols = self.number_of_columns() or 1 delta = {Qt.Key.Key_Left: -1, Qt.Key.Key_Right: 1, Qt.Key.Key_Up: -ncols, Qt.Key.Key_Down: ncols}[k] n = max(0, min(c + delta, self.model().rowCount(None) - 1)) if n == c: return sm = self.selectionModel() rows = {i.row() for i in sm.selectedIndexes()} if rows: mi, ma = min(rows), max(rows) end = mi if c == ma else ma if c == mi else c else: end = c top = self.model().index(min(n, end), 0) bottom = self.model().index(max(n, end), 0) sm.select(QItemSelection(top, bottom), QItemSelectionModel.SelectionFlag.ClearAndSelect) sm.setCurrentIndex(self.model().index(n, 0), QItemSelectionModel.SelectionFlag.NoUpdate) else: return QListView.keyPressEvent(self, ev)
def selectAll(self): # We re-implement this to ensure that only indexes from column 0 are # selected. The base class implementation selects all columns. This # causes problems with selection syncing, see # https://bugs.launchpad.net/bugs/1236348 m = self.model() sm = self.selectionModel() sel = QItemSelection(m.index(0, 0), m.index(m.rowCount(QModelIndex())-1, 0)) sm.select(sel, QItemSelectionModel.SelectionFlag.ClearAndSelect)