diff --git a/Orange/widgets/data/owdiscretize.py b/Orange/widgets/data/owdiscretize.py index c2dd624afa2..0c4459dd478 100644 --- a/Orange/widgets/data/owdiscretize.py +++ b/Orange/widgets/data/owdiscretize.py @@ -203,7 +203,10 @@ def _intbox(widget, attr, callback): ) # List view with all attributes - self.varview = QListView(selectionMode=QListView.ExtendedSelection) + self.varview = QListView( + selectionMode=QListView.ExtendedSelection, + uniformItemSizes=True, + ) self.varview.setItemDelegate(DiscDelegate()) self.varmodel = itemmodels.VariableListModel() self.varview.setModel(self.varmodel) diff --git a/Orange/widgets/data/oweditdomain.py b/Orange/widgets/data/oweditdomain.py index 1dde4a32712..4b107836eef 100644 --- a/Orange/widgets/data/oweditdomain.py +++ b/Orange/widgets/data/oweditdomain.py @@ -394,7 +394,8 @@ def __init__(self): self.domain_model = itemmodels.VariableListModel() self.domain_view = QListView( - selectionMode=QListView.SingleSelection + selectionMode=QListView.SingleSelection, + uniformItemSizes=True ) self.domain_view.setModel(self.domain_model) self.domain_view.selectionModel().selectionChanged.connect( diff --git a/Orange/widgets/data/owfeatureconstructor.py b/Orange/widgets/data/owfeatureconstructor.py index d458f755c00..96730b0f206 100644 --- a/Orange/widgets/data/owfeatureconstructor.py +++ b/Orange/widgets/data/owfeatureconstructor.py @@ -121,7 +121,7 @@ def __init__(self, *args, **kwargs): self.attrs_model = itemmodels.VariableListModel( ["Select Feature"], parent=self) - self.attributescb = QComboBox( + self.attributescb = gui.OrangeComboBox( minimumContentsLength=16, sizeAdjustPolicy=QComboBox.AdjustToMinimumContentsLengthWithIcon, sizePolicy=QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum) @@ -137,7 +137,7 @@ def __init__(self, *args, **kwargs): [''], [self.FUNCTIONS[func].__doc__ for func in sorted_funcs]) - self.functionscb = QComboBox( + self.functionscb = gui.OrangeComboBox( minimumContentsLength=16, sizeAdjustPolicy=QComboBox.AdjustToMinimumContentsLengthWithIcon, sizePolicy=QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)) diff --git a/Orange/widgets/data/owimpute.py b/Orange/widgets/data/owimpute.py index d3efbe67f44..fb017a213dd 100644 --- a/Orange/widgets/data/owimpute.py +++ b/Orange/widgets/data/owimpute.py @@ -189,7 +189,8 @@ def __init__(self): main_layout.addWidget(box) self.varview = QListView( - selectionMode=QListView.ExtendedSelection + selectionMode=QListView.ExtendedSelection, + uniformItemSizes=True ) self.varview.setItemDelegate(DisplayFormatDelegate()) self.varmodel = itemmodels.VariableListModel() diff --git a/Orange/widgets/data/owmergedata.py b/Orange/widgets/data/owmergedata.py index 921e33c0a5d..56da81d22f5 100644 --- a/Orange/widgets/data/owmergedata.py +++ b/Orange/widgets/data/owmergedata.py @@ -88,12 +88,14 @@ def add_option(label, pre_label, between_label, model[:] = [getattr(self, 'attr_{}_data'.format(merge_type))] extra_model[:] = [getattr(self, 'attr_{}_extra'.format(merge_type))] cb = gui.comboBox(box, self, 'attr_{}_data'.format(merge_type), - callback=self._invalidate, model=model) + contentsLength=12, callback=self._invalidate, + model=model) cb.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed) cb.setFixedWidth(190) gui.widgetLabel(box, between_label) cb = gui.comboBox(box, self, 'attr_{}_extra'.format(merge_type), - callback=self._invalidate, model=extra_model) + contentsLength=12, callback=self._invalidate, + model=extra_model) cb.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed) cb.setFixedWidth(190) vbox.layout().addSpacing(6) diff --git a/Orange/widgets/data/owselectrows.py b/Orange/widgets/data/owselectrows.py index fde749a958d..2a700a14c10 100644 --- a/Orange/widgets/data/owselectrows.py +++ b/Orange/widgets/data/owselectrows.py @@ -205,7 +205,7 @@ def add_row(self, attr=None, condition_type=None, condition_value=None): row = model.rowCount() model.insertRow(row) - attr_combo = QComboBox( + attr_combo = gui.OrangeComboBox( minimumContentsLength=12, sizeAdjustPolicy=QComboBox.AdjustToMinimumContentsLengthWithIcon) attr_combo.row = row diff --git a/Orange/widgets/data/owtranspose.py b/Orange/widgets/data/owtranspose.py index f3600f1624e..4860fe0839e 100644 --- a/Orange/widgets/data/owtranspose.py +++ b/Orange/widgets/data/owtranspose.py @@ -56,8 +56,8 @@ def __init__(self): alphabetical=True) self.feature_combo = gui.comboBox( gui.indentedBox(box, gui.checkButtonOffsetHint(button)), self, - "feature_names_column", callback=self._feature_combo_changed, - model=self.feature_model) + "feature_names_column", contentsLength=12, + callback=self._feature_combo_changed, model=self.feature_model) self.apply_button = gui.auto_commit( self.controlArea, self, "auto_apply", "&Apply", diff --git a/Orange/widgets/gui.py b/Orange/widgets/gui.py index 30c1b518639..f35275b994d 100644 --- a/Orange/widgets/gui.py +++ b/Orange/widgets/gui.py @@ -1090,6 +1090,7 @@ def listView(widget, master, value=None, model=None, box=None, callback=None, CallFrontListView(view), CallBackListView(model, view, master, value)) misc.setdefault('addSpace', True) + misc.setdefault('uniformItemSizes', True) miscellanea(view, bg, widget, **misc) return view @@ -1497,11 +1498,18 @@ def valueSlider(widget, master, value, box=None, label=None, class OrangeComboBox(QtWidgets.QComboBox): """ A QComboBox subclass extended to support bounded contents width hint. + + Prefer to use this class in place of plain QComboBox when the used + model will possibly contain many items. """ def __init__(self, parent=None, maximumContentsLength=-1, **kwargs): # Forward-declared for sizeHint() self.__maximumContentsLength = maximumContentsLength super().__init__(parent, **kwargs) + view = self.view() + # optimization for displaying large models + if isinstance(view, QListView): + view.setUniformItemSizes(True) def setMaximumContentsLength(self, length): """ @@ -1513,11 +1521,11 @@ def setMaximumContentsLength(self, length): .. note:: This property does not affect the widget's `maximumSize`. - The widget can still grow depending in it's sizePolicy. + The widget can still grow depending on its `sizePolicy`. Parameters ---------- - lenght : int + length : int Maximum contents length hint. """ if self.__maximumContentsLength != length: @@ -2493,6 +2501,7 @@ def action(self, values): selection = QItemSelection() for value in values: + index = None if not isinstance(value, int): if isinstance(value, Variable): search_role = TableVariable @@ -2501,9 +2510,12 @@ def action(self, values): value = str(value) for i in range(model.rowCount()): if model.data(model.index(i), search_role) == value: - value = i + index = i break - selection.select(model.index(value), model.index(value)) + else: + index = value + if index is not None: + selection.select(model.index(index), model.index(index)) sel_model.select(selection, sel_model.ClearAndSelect) diff --git a/Orange/widgets/unsupervised/owcorrespondence.py b/Orange/widgets/unsupervised/owcorrespondence.py index 214055707b3..2c3f953b506 100644 --- a/Orange/widgets/unsupervised/owcorrespondence.py +++ b/Orange/widgets/unsupervised/owcorrespondence.py @@ -72,7 +72,10 @@ def __init__(self): box = gui.vBox(self.controlArea, "Variables") self.varlist = itemmodels.VariableListModel() - self.varview = view = QListView(selectionMode=QListView.MultiSelection) + self.varview = view = QListView( + selectionMode=QListView.MultiSelection, + uniformItemSizes=True + ) view.setModel(self.varlist) view.selectionModel().selectionChanged.connect(self._var_changed) diff --git a/Orange/widgets/utils/itemmodels.py b/Orange/widgets/utils/itemmodels.py index 019dd25169d..0404b7ddf8d 100644 --- a/Orange/widgets/utils/itemmodels.py +++ b/Orange/widgets/utils/itemmodels.py @@ -536,14 +536,6 @@ def wrap(self, lst): self._other_data = [_store() for _ in lst] self.endResetModel() - - # noinspection PyMethodOverriding - def index(self, row, column=0, parent=QModelIndex()): - if self._is_index_valid(row) and column == 0: - return QAbstractListModel.createIndex(self, row, column, parent) - else: - return QModelIndex() - def headerData(self, section, orientation, role=Qt.DisplayRole): if role == Qt.DisplayRole: return str(section) @@ -551,7 +543,7 @@ def headerData(self, section, orientation, role=Qt.DisplayRole): # noinspection PyMethodOverriding def rowCount(self, parent=QModelIndex()): - return 0 if parent.isValid() else len(self) + return 0 if parent.isValid() else len(self._list) def columnCount(self, parent=QModelIndex()): return 0 if parent.isValid() else 1 diff --git a/Orange/widgets/utils/listfilter.py b/Orange/widgets/utils/listfilter.py index bb20363cb03..697a118f57b 100644 --- a/Orange/widgets/utils/listfilter.py +++ b/Orange/widgets/utils/listfilter.py @@ -53,6 +53,7 @@ def __init__(self, parent=None, acceptedType=Orange.data.Variable): self.setDragDropMode(self.DragDrop) self.setDefaultDropAction(Qt.MoveAction) self.setDragDropOverwriteMode(False) + self.setUniformItemSizes(True) self.viewport().setAcceptDrops(True) #: type | Tuple[type] diff --git a/Orange/widgets/visualize/owdistributions.py b/Orange/widgets/visualize/owdistributions.py index fbb8477b015..ad72d237b9b 100644 --- a/Orange/widgets/visualize/owdistributions.py +++ b/Orange/widgets/visualize/owdistributions.py @@ -177,7 +177,9 @@ def __init__(self): self.groupvarmodel = [] self.varview = QListView( - selectionMode=QListView.SingleSelection) + selectionMode=QListView.SingleSelection, + uniformItemSizes=True, + ) self.varview.setSizePolicy( QSizePolicy.Minimum, QSizePolicy.Expanding) self.varview.setModel(self.varmodel) diff --git a/Orange/widgets/visualize/owheatmap.py b/Orange/widgets/visualize/owheatmap.py index 84584c1cbf4..7eb98815d60 100644 --- a/Orange/widgets/visualize/owheatmap.py +++ b/Orange/widgets/visualize/owheatmap.py @@ -541,9 +541,9 @@ def __init__(self): annotbox = gui.vBox(box, "Row Annotations", addSpace=False) annotbox.setFlat(True) - self.annotations_cb = gui.comboBox(annotbox, self, "annotation_index", - items=self.annotation_vars, - callback=self.update_annotations) + self.annotations_cb = gui.comboBox( + annotbox, self, "annotation_index", contentsLength=12, + items=self.annotation_vars, callback=self.update_annotations) posbox = gui.vBox(box, "Column Labels Position", addSpace=False) posbox.setFlat(True) diff --git a/Orange/widgets/visualize/owscatterplot.py b/Orange/widgets/visualize/owscatterplot.py index 0c4466a84db..98598e11a84 100644 --- a/Orange/widgets/visualize/owscatterplot.py +++ b/Orange/widgets/visualize/owscatterplot.py @@ -158,7 +158,8 @@ def __init__(self): common_options = dict( labelWidth=50, orientation=Qt.Horizontal, sendSelectedValue=True, - valueType=str) + valueType=str, contentsLength=14 + ) box = gui.vBox(self.controlArea, "Axis Data") dmod = DomainModel self.xy_model = DomainModel(dmod.MIXED, valid_types=dmod.PRIMITIVE) diff --git a/Orange/widgets/visualize/owsilhouetteplot.py b/Orange/widgets/visualize/owsilhouetteplot.py index 44fe8511aa9..7bcaf302eb0 100644 --- a/Orange/widgets/visualize/owsilhouetteplot.py +++ b/Orange/widgets/visualize/owsilhouetteplot.py @@ -113,8 +113,9 @@ def __init__(self): box = gui.vBox(self.controlArea, "Cluster Label") self.cluster_var_cb = gui.comboBox( - box, self, "cluster_var_idx", addSpace=4, - callback=self._invalidate_scores) + box, self, "cluster_var_idx", contentsLength=14, addSpace=4, + callback=self._invalidate_scores + ) gui.checkBox( box, self, "group_by_cluster", "Group by cluster", callback=self._replot) @@ -128,7 +129,8 @@ def __init__(self): callback=self._update_bar_size, addSpace=6) gui.widgetLabel(box, "Annotations:") self.annotation_cb = gui.comboBox( - box, self, "annotation_var_idx", callback=self._update_annotations) + box, self, "annotation_var_idx", contentsLength=14, + callback=self._update_annotations) self.annotation_var_model = itemmodels.VariableListModel(parent=self) self.annotation_var_model[:] = ["None"] self.annotation_cb.setModel(self.annotation_var_model) diff --git a/Orange/widgets/visualize/owvenndiagram.py b/Orange/widgets/visualize/owvenndiagram.py index 1ea539fd6f7..bac2702d2a2 100644 --- a/Orange/widgets/visualize/owvenndiagram.py +++ b/Orange/widgets/visualize/owvenndiagram.py @@ -106,9 +106,10 @@ def __init__(self): addSpace=False) box.setFlat(True) model = itemmodels.VariableListModel(parent=self) - cb = QComboBox( + cb = gui.OrangeComboBox( minimumContentsLength=12, - sizeAdjustPolicy=QComboBox.AdjustToMinimumContentsLengthWithIcon) + sizeAdjustPolicy=QComboBox.AdjustToMinimumContentsLengthWithIcon + ) cb.setModel(model) cb.activated[int].connect(self._on_inputAttrActivated) box.setEnabled(False)