diff --git a/traitsui/qt4/ui_panel.py b/traitsui/qt4/ui_panel.py index 96d048c48..1e23186c0 100644 --- a/traitsui/qt4/ui_panel.py +++ b/traitsui/qt4/ui_panel.py @@ -777,241 +777,242 @@ def _add_items(self, content, outer=None): # Get the name in order to determine its type: name = item.name + # Convert a blank to a 5 pixel spacer: + if name == " ": + name = "5" + # Check if is a label: if name == "": label = item.label - if label != "": + if label != "": + self._add_label_item(item, inner, row, col, show_labels) - # Create the label widget. - if item.style == "simple": - label = QtGui.QLabel(label) - else: - label = heading_text(None, text=label).control + # Check if it is a separator: + elif name == "_": + self._add_separator_item(item, columns, inner, row, col, show_labels) - self._add_widget(inner, label, row, col, show_labels) + # Check if it is a spacer: + elif all_digits.match(name): + self._add_spacer_item(item, name, inner, row, col, show_labels) - if item.emphasized: - self._add_emphasis(label) + else: + # Otherwise, it must be a trait Item: + object = eval(item.object_, globals(), ui.context) + trait = object.base_trait(name) + desc = trait.tooltip + if desc is None: + desc = "Specifies " + trait.desc if trait.desc else "" + + # Get the editor factory associated with the Item: + editor_factory = item.editor + if editor_factory is None: + editor_factory = trait.get_editor().trait_set( + **item.editor_args + ) - # Continue on to the next Item in the list: - continue + # If still no editor factory found, use a default text editor: + if editor_factory is None: + from .text_editor import ToolkitEditorFactory + + editor_factory = ToolkitEditorFactory() + + # If the item has formatting traits set them in the editor + # factory: + if item.format_func is not None: + editor_factory.format_func = item.format_func + + if item.format_str != "": + editor_factory.format_str = item.format_str + + # If the item has an invalid state extended trait name, set it + # in the editor factory: + if item.invalid != "": + editor_factory.invalid = item.invalid + + # Create the requested type of editor from the editor factory: + factory_method = getattr(editor_factory, item.style + "_editor") + editor = factory_method( + ui, object, name, item.tooltip, None + ).trait_set(item=item, object_name=item.object) + + # Tell the editor to actually build the editing widget. Note that + # "inner" is a layout. This shouldn't matter as individual editors + # shouldn't be using it as a parent anyway. The important thing is + # that it is not None (otherwise the main TraitsUI code can change + # the "kind" of the created UI object). + editor.prepare(inner) + control = editor.control + + if item.style_sheet: + control.setStyleSheet(item.style_sheet) + + # Set the initial 'enabled' state of the editor from the factory: + editor.enabled = editor_factory.enabled + + # Handle any label. + if item.show_label: + label = self._create_label(item, ui, desc) + self._add_widget( + inner, label, row, col, show_labels, label_alignment + ) + else: + label = None - # Check if it is a separator: - if name == "_": - cols = columns - - # See if the layout is a grid. - if row >= 0: - # Move to the start of the next row if necessary. - if col > 0: - col = 0 - row += 1 - - # Skip the row we are about to do. - row += 1 - - # Allow for the columns. - if show_labels: - cols *= 2 - - for i in range(cols): - line = QtGui.QFrame() - - if self.direction == QtGui.QBoxLayout.LeftToRight: - # Add a vertical separator: - line.setFrameShape(QtGui.QFrame.VLine) - if row < 0: - inner.addWidget(line) - else: - inner.addWidget(line, i, row) - else: - # Add a horizontal separator: - line.setFrameShape(QtGui.QFrame.HLine) - if row < 0: - inner.addWidget(line) - else: - inner.addWidget(line, row, i) + editor.label_control = label - line.setFrameShadow(QtGui.QFrame.Sunken) + # Add emphasis to the editor control if requested: + if item.emphasized: + self._add_emphasis(control) - # Continue on to the next Item in the list: - continue + # If the item wants focus, remember the control so we can set focus + # immediately before opening the UI. + if item.has_focus: + self.ui._focus_control = control - # Convert a blank to a 5 pixel spacer: - if name == " ": - name = "5" + # Set the correct size on the control, as specified by the user: + stretch = 0 + item_width = item.width + item_height = item.height + if (item_width != -1) or (item_height != -1): + is_horizontal = self.direction == QtGui.QBoxLayout.LeftToRight - # Check if it is a spacer: - if all_digits.match(name): + min_size = control.minimumSizeHint() + width = min_size.width() + height = min_size.height() - # If so, add the appropriate amount of space to the layout: - n = int(name) - if self.direction == QtGui.QBoxLayout.LeftToRight: - # Add a horizontal spacer: - spacer = QtGui.QSpacerItem(n, 1) - else: - # Add a vertical spacer: - spacer = QtGui.QSpacerItem(1, n) - - self._add_widget(inner, spacer, row, col, show_labels) - - # Continue on to the next Item in the list: - continue - - # Otherwise, it must be a trait Item: - object = eval(item.object_, globals(), ui.context) - trait = object.base_trait(name) - desc = trait.tooltip - if desc is None: - desc = "Specifies " + trait.desc if trait.desc else "" - - # Get the editor factory associated with the Item: - editor_factory = item.editor - if editor_factory is None: - editor_factory = trait.get_editor().trait_set( - **item.editor_args - ) + force_width = False + force_height = False - # If still no editor factory found, use a default text editor: - if editor_factory is None: - from .text_editor import ToolkitEditorFactory - - editor_factory = ToolkitEditorFactory() - - # If the item has formatting traits set them in the editor - # factory: - if item.format_func is not None: - editor_factory.format_func = item.format_func - - if item.format_str != "": - editor_factory.format_str = item.format_str - - # If the item has an invalid state extended trait name, set it - # in the editor factory: - if item.invalid != "": - editor_factory.invalid = item.invalid - - # Create the requested type of editor from the editor factory: - factory_method = getattr(editor_factory, item.style + "_editor") - editor = factory_method( - ui, object, name, item.tooltip, None - ).trait_set(item=item, object_name=item.object) - - # Tell the editor to actually build the editing widget. Note that - # "inner" is a layout. This shouldn't matter as individual editors - # shouldn't be using it as a parent anyway. The important thing is - # that it is not None (otherwise the main TraitsUI code can change - # the "kind" of the created UI object). - editor.prepare(inner) - control = editor.control - - if item.style_sheet: - control.setStyleSheet(item.style_sheet) - - # Set the initial 'enabled' state of the editor from the factory: - editor.enabled = editor_factory.enabled - - # Handle any label. - if item.show_label: - label = self._create_label(item, ui, desc) - self._add_widget( - inner, label, row, col, show_labels, label_alignment - ) - else: - label = None + if (0.0 < item_width <= 1.0) and is_horizontal: + stretch = int(100 * item_width) - editor.label_control = label + item_width = int(item_width) + if item_width < -1: + item_width = -item_width + force_width = True + else: + item_width = max(item_width, width) - # Add emphasis to the editor control if requested: - if item.emphasized: - self._add_emphasis(control) + if (0.0 < item_height <= 1.0) and (not is_horizontal): + stretch = int(100 * item_height) - # If the item wants focus, remember the control so we can set focus - # immediately before opening the UI. - if item.has_focus: - self.ui._focus_control = control + item_height = int(item_height) + if item_height < -1: + item_height = -item_height + force_height = True + else: + item_height = max(item_height, height) + + control.setMinimumWidth(max(item_width, 0)) + control.setMinimumHeight(max(item_height, 0)) + if (stretch == 0 or not is_horizontal) and force_width: + control.setMaximumWidth(item_width) + if (stretch == 0 or is_horizontal) and force_height: + control.setMaximumHeight(item_height) + + # Set size and stretch policies + self._set_item_size_policy(editor, item, label, stretch) + + # Add the created editor control to the layout + # FIXME: Need to decide what to do about border_size and padding + self._add_widget(inner, control, row, col, show_labels) + + # ---- Update the UI object + + # Bind the editor into the UIInfo object name space so it can be + # referred to by a Handler while the user interface is active: + id = item.id or name + info.bind(id, editor, item.id) + + self.ui._scrollable |= editor.scrollable + + # Also, add the editors to the list of editors used to construct + # the user interface: + ui._editors.append(editor) + + # If the handler wants to be notified when the editor is created, + # add it to the list of methods to be called when the UI is + # complete: + defined = getattr(handler, id + "_defined", None) + if defined is not None: + ui.add_defined(defined) + + # If the editor is conditionally visible, add the visibility + # 'expression' and the editor to the UI object's list of monitored + # objects: + if item.visible_when != "": + ui.add_visible(item.visible_when, editor) + + # If the editor is conditionally enabled, add the enabling + # 'expression' and the editor to the UI object's list of monitored + # objects: + if item.enabled_when != "": + ui.add_enabled(item.enabled_when, editor) - # Set the correct size on the control, as specified by the user: - stretch = 0 - item_width = item.width - item_height = item.height - if (item_width != -1) or (item_height != -1): - is_horizontal = self.direction == QtGui.QBoxLayout.LeftToRight + return outer - min_size = control.minimumSizeHint() - width = min_size.width() - height = min_size.height() + def _add_label_item(self, item, inner, row, col, show_labels): + label = item.label + # Create the label widget. + if item.style == "simple": + label = QtGui.QLabel(label) + else: + label = heading_text(None, text=label).control - force_width = False - force_height = False + self._add_widget(inner, label, row, col, show_labels) - if (0.0 < item_width <= 1.0) and is_horizontal: - stretch = int(100 * item_width) + if item.emphasized: + self._add_emphasis(label) - item_width = int(item_width) - if item_width < -1: - item_width = -item_width - force_width = True - else: - item_width = max(item_width, width) + def _add_separator_item(self, item, columns, inner, row, col, show_labels): + cols = columns + + # See if the layout is a grid. + if row >= 0: + # Move to the start of the next row if necessary. + if col > 0: + col = 0 + row += 1 - if (0.0 < item_height <= 1.0) and (not is_horizontal): - stretch = int(100 * item_height) + # Skip the row we are about to do. + row += 1 - item_height = int(item_height) - if item_height < -1: - item_height = -item_height - force_height = True + # Allow for the columns. + if show_labels: + cols *= 2 + + for i in range(cols): + line = QtGui.QFrame() + + if self.direction == QtGui.QBoxLayout.LeftToRight: + # Add a vertical separator: + line.setFrameShape(QtGui.QFrame.VLine) + if row < 0: + inner.addWidget(line) + else: + inner.addWidget(line, i, row) + else: + # Add a horizontal separator: + line.setFrameShape(QtGui.QFrame.HLine) + if row < 0: + inner.addWidget(line) else: - item_height = max(item_height, height) - - control.setMinimumWidth(max(item_width, 0)) - control.setMinimumHeight(max(item_height, 0)) - if (stretch == 0 or not is_horizontal) and force_width: - control.setMaximumWidth(item_width) - if (stretch == 0 or is_horizontal) and force_height: - control.setMaximumHeight(item_height) - - # Set size and stretch policies - self._set_item_size_policy(editor, item, label, stretch) - - # Add the created editor control to the layout - # FIXME: Need to decide what to do about border_size and padding - self._add_widget(inner, control, row, col, show_labels) - - # ---- Update the UI object - - # Bind the editor into the UIInfo object name space so it can be - # referred to by a Handler while the user interface is active: - id = item.id or name - info.bind(id, editor, item.id) - - self.ui._scrollable |= editor.scrollable - - # Also, add the editors to the list of editors used to construct - # the user interface: - ui._editors.append(editor) - - # If the handler wants to be notified when the editor is created, - # add it to the list of methods to be called when the UI is - # complete: - defined = getattr(handler, id + "_defined", None) - if defined is not None: - ui.add_defined(defined) - - # If the editor is conditionally visible, add the visibility - # 'expression' and the editor to the UI object's list of monitored - # objects: - if item.visible_when != "": - ui.add_visible(item.visible_when, editor) - - # If the editor is conditionally enabled, add the enabling - # 'expression' and the editor to the UI object's list of monitored - # objects: - if item.enabled_when != "": - ui.add_enabled(item.enabled_when, editor) + inner.addWidget(line, row, i) - return outer + line.setFrameShadow(QtGui.QFrame.Sunken) + + def _add_spacer_item(self, item, name, inner, row, col, show_labels): + + # If so, add the appropriate amount of space to the layout: + n = int(name) + if self.direction == QtGui.QBoxLayout.LeftToRight: + # Add a horizontal spacer: + spacer = QtGui.QSpacerItem(n, 1) + else: + # Add a vertical spacer: + spacer = QtGui.QSpacerItem(1, n) + + self._add_widget(inner, spacer, row, col, show_labels) def _set_item_size_policy(self, editor, item, label, stretch): """ Set size policy of an item and its label (if any).