Calculate number of selected rows manually

`len(self._view.selectionModel().selectedRows())` is slow for large
selections, because Qt queries flags() for every selected cell, so we
calculate the number of selected rows ourselves.
This commit is contained in:
RumovZ 2021-09-27 10:15:53 +02:00
parent 18f0d026b5
commit f89811870e

View file

@ -67,10 +67,9 @@ class Table:
return self._model.len_rows() return self._model.len_rows()
def len_selection(self, refresh: bool = False) -> int: def len_selection(self, refresh: bool = False) -> int:
# This may be slow because Qt queries flags() for the whole selection, # `len(self._view.selectionModel().selectedRows())` is slow for large
# so we update the cached value directly where possible # selections, because Qt queries flags() for every selected cell, so we
if refresh: # calculate the number of selected rows ourselves
self._len_selection = len(self._view.selectionModel().selectedRows())
return self._len_selection return self._len_selection
def has_current(self) -> bool: def has_current(self) -> bool:
@ -117,6 +116,7 @@ class Table:
self._view.selectAll() self._view.selectAll()
def clear_selection(self) -> None: def clear_selection(self) -> None:
self._len_selection = 0
self._view.selectionModel().clear() self._view.selectionModel().clear()
def invert_selection(self) -> None: def invert_selection(self) -> None:
@ -345,8 +345,11 @@ class Table:
# Slots # Slots
def _on_selection_changed(self, _c: Any, _p: Any) -> None: def _on_selection_changed(
self.len_selection(refresh=True) self, selected: QItemSelection, deselected: QItemSelection
) -> None:
self._len_selection += len(selected.indexes()) // self._model.len_columns()
self._len_selection -= len(deselected.indexes()) // self._model.len_columns()
self.browser.on_row_changed() self.browser.on_row_changed()
def _on_row_state_will_change(self, index: QModelIndex, was_restored: bool) -> None: def _on_row_state_will_change(self, index: QModelIndex, was_restored: bool) -> None:
@ -475,7 +478,7 @@ class Table:
self._select_rows(rows) self._select_rows(rows)
self._set_current(current) self._set_current(current)
self._scroll_to_row(current) self._scroll_to_row(current)
if self.len_selection(refresh=True) == 0: if self.len_selection() == 0:
# no row change will fire # no row change will fire
self.browser.on_row_changed() self.browser.on_row_changed()
self._selected_items = [] self._selected_items = []