def initialize_item(self, ui): """ Initialize the item using the Traits UI `UI` object. """ item = self.item name = item.name object = eval(item.object_, globals(), ui.context) trait = object.base_trait(name) # 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) # If still no editor factory found, use a default text editor: if editor_factory is None: from traitsui.qt4.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) editor.trait_set( item=item, object_name=item.object, ) self._editor = editor self._ui = ui
def _add_items(self, content, outer=None): """Adds a list of Item objects, creating a layout if needed. Return the outermost layout. """ # Get local references to various objects we need: ui = self.ui info = ui.info handler = ui.handler group = self.group show_left = group.show_left columns = group.columns # See if a label is needed. show_labels = False for item in content: show_labels |= item.show_label # See if a grid layout is needed. if show_labels or columns > 1: inner = QtGui.QGridLayout() if outer is None: outer = inner else: outer.addLayout(inner) row = 0 if show_left: label_alignment = QtCore.Qt.AlignRight else: label_alignment = QtCore.Qt.AlignLeft else: # Use the existing layout if there is one. if outer is None: outer = QtGui.QBoxLayout(self.direction) inner = outer row = -1 label_alignment = 0 # Process each Item in the list: col = -1 for item in content: # Keep a track of the current logical row and column unless the # layout is not a grid. col += 1 if row >= 0 and col >= columns: col = 0 row += 1 # Get the name in order to determine its type: name = item.name # Check if is a label: if name == '': label = item.label if label != "": # Create the label widget. if item.style == 'simple': label = QtGui.QLabel(label) else: label = ui_panel.heading_text(None, text=label).control self._add_widget(inner, label, row, col, show_labels) if item.emphasized: self._add_emphasis(label) # Continue on to the next Item in the list: continue # 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) line.setFrameShadow(QtGui.QFrame.Sunken) # Continue on to the next Item in the list: continue # Convert a blank to a 5 pixel spacer: if name == ' ': name = '5' # Check if it is a spacer: if ui_panel.all_digits.match(name): # 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.desc or '' # Get the editor factory associated with the Item: editor_factory = item.editor if editor_factory is None: editor_factory = trait.get_editor().set(**item.editor_args) # If still no editor factory found, use a default text editor: if editor_factory is None: from traitsui.qt4.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 ).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 editor.label_control = label # Add emphasis to the editor control if requested: if item.emphasized: self._add_emphasis(control) # Give the editor focus if it requested it: if item.has_focus: control.setFocus() # 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) min_size = control.minimumSizeHint() width = min_size.width() height = min_size.height() force_width = False force_height = False if (0.0 < item_width <= 1.0) and is_horizontal: stretch = int(100 * item_width) item_width = int(item_width) if item_width < -1: item_width = -item_width force_width = True else: item_width = max(item_width, width) if (0.0 < item_height <= 1.0) and (not is_horizontal): stretch = int(100 * item_height) 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) return outer
def _add_items(self, content, outer=None): """Adds a list of Item objects, creating a layout if needed. Return the outermost layout. """ # Get local references to various objects we need: ui = self.ui info = ui.info handler = ui.handler group = self.group show_left = group.show_left columns = group.columns # See if a label is needed. show_labels = False for item in content: show_labels |= item.show_label # See if a grid layout is needed. if show_labels or columns > 1: inner = QtGui.QGridLayout() if outer is None: outer = inner else: outer.addLayout(inner) row = 0 if show_left: label_alignment = QtCore.Qt.AlignRight else: label_alignment = QtCore.Qt.AlignLeft else: # Use the existing layout if there is one. if outer is None: outer = QtGui.QBoxLayout(self.direction) inner = outer row = -1 label_alignment = 0 # Process each Item in the list: col = -1 for item in content: # Keep a track of the current logical row and column unless the # layout is not a grid. col += 1 if row >= 0 and col >= columns: col = 0 row += 1 # Get the name in order to determine its type: name = item.name # Check if is a label: if name == "": label = item.label if label != "": # Create the label widget. if item.style == "simple": label = QtGui.QLabel(label) else: label = ui_panel.heading_text(None, text=label).control self._add_widget(inner, label, row, col, show_labels) if item.emphasized: self._add_emphasis(label) # Continue on to the next Item in the list: continue # 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) line.setFrameShadow(QtGui.QFrame.Sunken) # Continue on to the next Item in the list: continue # Convert a blank to a 5 pixel spacer: if name == " ": name = "5" # Check if it is a spacer: if ui_panel.all_digits.match(name): # 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.desc or "" # Get the editor factory associated with the Item: editor_factory = item.editor if editor_factory is None: editor_factory = trait.get_editor().set(**item.editor_args) # If still no editor factory found, use a default text editor: if editor_factory is None: from traitsui.qt4.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).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 editor.label_control = label # Add emphasis to the editor control if requested: if item.emphasized: self._add_emphasis(control) # Give the editor focus if it requested it: if item.has_focus: control.setFocus() # 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 min_size = control.minimumSizeHint() width = min_size.width() height = min_size.height() force_width = False force_height = False if (0.0 < item_width <= 1.0) and is_horizontal: stretch = int(100 * item_width) item_width = int(item_width) if item_width < -1: item_width = -item_width force_width = True else: item_width = max(item_width, width) if (0.0 < item_height <= 1.0) and (not is_horizontal): stretch = int(100 * item_height) 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) return outer