示例#1
0
    def testWidgetIterator(self):
        treeWidget = QTreeWidget()
        treeWidget.setColumnCount(1)
        items = []
        for i in range(10):
            items.append(QTreeWidgetItem(None, ['item: %d' % i]))
        treeWidget.insertTopLevelItems(0, items)

        index = 0
        for it in QTreeWidgetItemIterator(treeWidget):
            self.assertEqual(it.value().text(0), 'item: %d' % index)
            index += 1
示例#2
0
    def testWidgetIterator(self):
        treeWidget = QTreeWidget()
        treeWidget.setColumnCount(1)
        items = []
        for i in range(10):
            items.append(QTreeWidgetItem(None, ['item: %d' % i]))
        treeWidget.insertTopLevelItems(0, items)

        index = 0
        for it in QTreeWidgetItemIterator(treeWidget):
            self.assertEqual(it.value().text(0), 'item: %d' % index)
            index += 1
示例#3
0
    def testCase(self):
        treeWidget = QTreeWidget()
        treeWidget.setColumnCount(1)
        items = []
        for i in range(10):
            items.append(QTreeWidgetItem(None, ["item: %i" % i]))

        treeWidget.insertTopLevelItems(0, items);
        _iter = QTreeWidgetItemIterator(treeWidget)
        index = 0
        while(_iter.value()):
            item = _iter.value()
            self.assertTrue(item is items[index])
            index += 1
            _iter += 1
示例#4
0
    def testCase(self):
        treeWidget = QTreeWidget()
        treeWidget.setColumnCount(1)
        items = []
        for i in range(10):
            items.append(QTreeWidgetItem(None, ["item: %i" % i]))

        treeWidget.insertTopLevelItems(0, items);
        _iter = QTreeWidgetItemIterator(treeWidget)
        index = 0
        while(_iter.value()):
            item = _iter.value()
            self.assert_(item is items[index])
            index += 1
            _iter += 1
 def reset_model(self, index):
     """Setup model according to current relationship_class selected in combobox.
     """
     self.class_name, self.object_class_name_list = self.relationship_class_keys[
         index]
     object_class_name_list = self.object_class_name_list.split(",")
     self.model.set_horizontal_header_labels(object_class_name_list)
     self.existing_items_model.set_horizontal_header_labels(
         object_class_name_list)
     self.new_items_model.set_horizontal_header_labels(
         object_class_name_list)
     self.relationship_ids.clear()
     for db_map in self.db_maps:
         relationship_classes = self.db_map_rel_cls_lookup[db_map]
         rel_cls = relationship_classes.get(
             (self.class_name, self.object_class_name_list), None)
         if rel_cls is None:
             continue
         for relationship in self.db_mngr.get_items_by_field(
                 db_map, "relationship", "class_id", rel_cls["id"]):
             key = tuple(relationship["object_name_list"].split(","))
             self.relationship_ids[key] = relationship["id"]
     existing_items = list(self.relationship_ids)
     self.existing_items_model.reset_model(existing_items)
     self.model.refresh()
     self.model.modelReset.emit()
     for wg in self.splitter_widgets():
         wg.deleteLater()
     for name in object_class_name_list:
         tree_widget = QTreeWidget(self)
         tree_widget.setSelectionMode(QAbstractItemView.ExtendedSelection)
         tree_widget.setColumnCount(1)
         tree_widget.setIndentation(0)
         header_item = QTreeWidgetItem([name])
         header_item.setTextAlignment(0, Qt.AlignHCenter)
         tree_widget.setHeaderItem(header_item)
         objects = self.db_mngr.get_items_by_field(self.db_map, "object",
                                                   "class_name", name)
         items = [QTreeWidgetItem([obj["name"]]) for obj in objects]
         tree_widget.addTopLevelItems(items)
         tree_widget.resizeColumnToContents(0)
         self.splitter.addWidget(tree_widget)
     sizes = [wg.columnWidth(0) for wg in self.splitter_widgets()]
     self.splitter.setSizes(sizes)
     for widget in self.hidable_widgets:
         widget.show()
示例#6
0
    def testSetItemWidget(self):

        treeWidget = QTreeWidget()
        treeWidget.setColumnCount(2)

        item = QTreeWidgetItem(['text of column 0', ''])
        treeWidget.insertTopLevelItem(0, item)
        # Adding QPushButton inside the method
        treeWidget.setItemWidget(item, 1,
                                 QPushButton('Push button on column 1'))

        # Getting the widget back
        w = treeWidget.itemWidget(treeWidget.itemAt(0, 1), 1)
        self.assertIsInstance(w, QPushButton)

        p = QPushButton('New independent button')
        # Adding QPushButton object from variable
        treeWidget.setItemWidget(item, 0, p)
        w = treeWidget.itemWidget(treeWidget.itemAt(0, 0), 0)
        self.assertIsInstance(w, QPushButton)
示例#7
0
class ObjectTreeDialog(QDialog):
    def __init__(self, parent=None, root_object=None):
        super(ObjectTreeDialog, self).__init__(parent)
        self.setWindowTitle("Object Tree")

        layout = QtWidgets.QVBoxLayout()

        # Tree widget for displaying our object hierarchy
        self.tree_widget = QTreeWidget()
        self.tree_widget_columns = [
            "TYPE", "OBJECT NAME", "TEXT", "ICONTEXT", "TITLE", "WINDOW_TITLE",
            "CLASSES", "POINTER_ADDRESS", "GEOMETRY"
        ]
        self.tree_widget.setColumnCount(len(self.tree_widget_columns))
        self.tree_widget.setHeaderLabels(self.tree_widget_columns)

        # Only show our type and object name columns.  The others we only use to store data so that
        # we can use the built-in QTreeWidget.findItems to query.
        for column_name in self.tree_widget_columns:
            if column_name == "TYPE" or column_name == "OBJECT NAME":
                continue

            column_index = self.tree_widget_columns.index(column_name)
            self.tree_widget.setColumnHidden(column_index, True)

        header = self.tree_widget.header()
        header.setSectionResizeMode(0, QHeaderView.ResizeToContents)
        header.setSectionResizeMode(1, QHeaderView.ResizeToContents)

        # Populate our object tree widget
        # If a root object wasn't specified, then use the Editor main window
        if not root_object:
            params = azlmbr.qt.QtForPythonRequestBus(
                azlmbr.bus.Broadcast, "GetQtBootstrapParameters")
            editor_id = QtWidgets.QWidget.find(params.mainWindowId)
            editor_main_window = wrapInstance(int(getCppPointer(editor_id)[0]),
                                              QtWidgets.QMainWindow)
            root_object = editor_main_window
        self.build_tree(root_object, self.tree_widget)

        # Listen for when the tree widget selection changes so we can update
        # selected item properties
        self.tree_widget.itemSelectionChanged.connect(
            self.on_tree_widget_selection_changed)

        # Split our tree widget with a properties view for showing more information about
        # a selected item. We also use a stacked layout for the properties view so that
        # when nothing has been selected yet, we can show a message informing the user
        # that something needs to be selected.
        splitter = QSplitter()
        splitter.addWidget(self.tree_widget)
        self.widget_properties = QWidget(self)
        self.stacked_layout = QtWidgets.QStackedLayout()
        self.widget_info = QWidget()
        form_layout = QtWidgets.QFormLayout()
        self.name_value = QLineEdit("")
        self.name_value.setReadOnly(True)
        self.type_value = QLabel("")
        self.geometry_value = QLabel("")
        self.text_value = QLabel("")
        self.icon_text_value = QLabel("")
        self.title_value = QLabel("")
        self.window_title_value = QLabel("")
        self.classes_value = QLabel("")
        form_layout.addRow("Name:", self.name_value)
        form_layout.addRow("Type:", self.type_value)
        form_layout.addRow("Geometry:", self.geometry_value)
        form_layout.addRow("Text:", self.text_value)
        form_layout.addRow("Icon Text:", self.icon_text_value)
        form_layout.addRow("Title:", self.title_value)
        form_layout.addRow("Window Title:", self.window_title_value)
        form_layout.addRow("Classes:", self.classes_value)
        self.widget_info.setLayout(form_layout)

        self.widget_properties.setLayout(self.stacked_layout)
        self.stacked_layout.addWidget(
            QLabel("Select an object to view its properties"))
        self.stacked_layout.addWidget(self.widget_info)
        splitter.addWidget(self.widget_properties)

        # Give our splitter stretch factor of 1 so it will expand to take more room over
        # the footer
        layout.addWidget(splitter, 1)

        # Create our popup widget for showing information when hovering over widgets
        self.hovered_widget = None
        self.inspect_mode = False
        self.inspect_popup = InspectPopup()
        self.inspect_popup.resize(100, 50)
        self.inspect_popup.hide()

        # Add a footer with a button to switch to widget inspect mode
        self.footer = QWidget()
        footer_layout = QtWidgets.QHBoxLayout()
        self.inspect_button = QPushButton("Pick widget to inspect")
        self.inspect_button.clicked.connect(self.on_inspect_clicked)
        footer_layout.addStretch(1)
        footer_layout.addWidget(self.inspect_button)
        self.footer.setLayout(footer_layout)
        layout.addWidget(self.footer)

        self.setLayout(layout)

        # Delete ourselves when the dialog is closed, so that we don't stay living in the background
        # since we install an event filter on the application
        self.setAttribute(Qt.WA_DeleteOnClose, True)

        # Listen to events at the application level so we can know when the mouse is moving
        app = QtWidgets.QApplication.instance()
        app.installEventFilter(self)

    def eventFilter(self, obj, event):
        # Look for mouse movement events so we can see what widget the mouse is hovered over
        event_type = event.type()
        if event_type == QEvent.MouseMove:
            global_pos = event.globalPos()

            # Make our popup follow the mouse, but we need to offset it by 1, 1 otherwise
            # the QApplication.widgetAt will always return our popup instead of the Editor
            # widget since it is on top
            self.inspect_popup.move(global_pos + QtCore.QPoint(1, 1))

            # Find out which widget is under our current mouse position
            hovered_widget = QtWidgets.QApplication.widgetAt(global_pos)
            if self.hovered_widget:
                # Bail out, this is the same widget we are already hovered on
                if self.hovered_widget is hovered_widget:
                    return False

            # Update our hovered widget and label
            self.hovered_widget = hovered_widget
            self.update_hovered_widget_popup()
        elif event_type == QEvent.KeyRelease:
            if event.key() == Qt.Key_Escape:
                # Cancel the inspect mode if the Escape key is pressed
                # We don't need to actually hide the inspect popup here because
                # it will be hidden already by the Escape action
                self.inspect_mode = False
        elif event_type == QEvent.MouseButtonPress or event_type == QEvent.MouseButtonRelease:
            # Trigger inspecting the currently hovered widget when the left mouse button is clicked
            # Don't continue processing this event
            if self.inspect_mode and event.button() == Qt.LeftButton:
                # Only trigger the inspect on the click release, but we want to also eat the press
                # event so that the widget we clicked on isn't stuck in a weird state (e.g. thinks its being dragged)
                # Also hide the inspect popup since it won't be hidden automatically by the mouse click since we are
                # consuming the event
                if event_type == event_type == QEvent.MouseButtonRelease:
                    self.inspect_popup.hide()
                    self.inspect_widget()
                return True

        # Pass every event through
        return False

    def build_tree(self, obj, parent_tree):
        if len(obj.children()) == 0:
            return
        for child in obj.children():
            object_type = type(child).__name__
            object_name = child.objectName()
            text = icon_text = title = window_title = geometry_str = classes = "(N/A)"
            if isinstance(child, QtGui.QWindow):
                title = child.title()
            if isinstance(child, QAction):
                text = child.text()
                icon_text = child.iconText()
            if isinstance(child, QWidget):
                window_title = child.windowTitle()
                if not (child.property("class") == ""):
                    classes = child.property("class")
            if isinstance(child, QAbstractButton):
                text = child.text()

            # Keep track of the pointer address for this object so we can search for it later
            pointer_address = str(int(getCppPointer(child)[0]))

            # Some objects might not have a geometry (e.g. actions, generic qobjects)
            if hasattr(child, 'geometry'):
                geometry_rect = child.geometry()
                geometry_str = "x: {x}, y: {y}, width: {width}, height: {height}".format(
                    x=geometry_rect.x(),
                    y=geometry_rect.y(),
                    width=geometry_rect.width(),
                    height=geometry_rect.height())

            child_tree = QTreeWidgetItem([
                object_type, object_name, text, icon_text, title, window_title,
                classes, pointer_address, geometry_str
            ])
            if isinstance(parent_tree, QTreeWidget):
                parent_tree.addTopLevelItem(child_tree)
            else:
                parent_tree.addChild(child_tree)
            self.build_tree(child, child_tree)

    def update_hovered_widget_popup(self):
        if self.inspect_mode and self.hovered_widget:
            if not self.inspect_popup.isVisible():
                self.inspect_popup.show()

            self.inspect_popup.update_widget(self.hovered_widget)
        else:
            self.inspect_popup.hide()

    def on_inspect_clicked(self):
        self.inspect_mode = True
        self.update_hovered_widget_popup()

    def on_tree_widget_selection_changed(self):
        selected_items = self.tree_widget.selectedItems()

        # If nothing is selected, then switch the stacked layout back to 0
        # to show the message
        if not selected_items:
            self.stacked_layout.setCurrentIndex(0)
            return

        # Update the selected widget properties and switch to the 1 index in
        # the stacked layout so that all the rows will be visible
        item = selected_items[0]
        self.name_value.setText(
            item.text(self.tree_widget_columns.index("OBJECT NAME")))
        self.type_value.setText(
            item.text(self.tree_widget_columns.index("TYPE")))
        self.geometry_value.setText(
            item.text(self.tree_widget_columns.index("GEOMETRY")))
        self.text_value.setText(
            item.text(self.tree_widget_columns.index("TEXT")))
        self.icon_text_value.setText(
            item.text(self.tree_widget_columns.index("ICONTEXT")))
        self.title_value.setText(
            item.text(self.tree_widget_columns.index("TITLE")))
        self.window_title_value.setText(
            item.text(self.tree_widget_columns.index("WINDOW_TITLE")))
        self.classes_value.setText(
            item.text(self.tree_widget_columns.index("CLASSES")))
        self.stacked_layout.setCurrentIndex(1)

    def inspect_widget(self):
        self.inspect_mode = False

        # Find the tree widget item that matches our hovered widget, and then set it as the current item
        # so that the tree widget will scroll to it, expand it, and select it
        widget_pointer_address = str(int(
            getCppPointer(self.hovered_widget)[0]))
        pointer_address_column = self.tree_widget_columns.index(
            "POINTER_ADDRESS")
        items = self.tree_widget.findItems(
            widget_pointer_address, Qt.MatchFixedString | Qt.MatchRecursive,
            pointer_address_column)
        if items:
            item = items[0]
            self.tree_widget.clearSelection()
            self.tree_widget.setCurrentItem(item)
        else:
            print("Unable to find widget")
class AddOrManageObjectGroupDialog(QDialog):
    def __init__(self, parent, object_class_item, db_mngr, *db_maps):
        """
        Args:
            parent (SpineDBEditor): data store widget
            object_class_item (ObjectClassItem)
            db_mngr (SpineDBManager)
            *db_maps: database mappings
        """
        super().__init__(parent)
        self.object_class_item = object_class_item
        self.db_mngr = db_mngr
        self.db_maps = db_maps
        self.db_map = db_maps[0]
        self.db_maps_by_codename = {
            db_map.codename: db_map
            for db_map in db_maps
        }
        self.db_combo_box = QComboBox(self)
        self.header_widget = QWidget(self)
        self.group_name_line_edit = QLineEdit(self)
        header_layout = QHBoxLayout(self.header_widget)
        header_layout.addWidget(QLabel(f"Group name: "))
        header_layout.addWidget(self.group_name_line_edit)
        header_layout.addSpacing(32)
        header_layout.addWidget(QLabel("Database"))
        header_layout.addWidget(self.db_combo_box)
        self.non_members_tree = QTreeWidget(self)
        self.non_members_tree.setHeaderLabel("Non members")
        self.non_members_tree.setSelectionMode(QTreeWidget.ExtendedSelection)
        self.non_members_tree.setColumnCount(1)
        self.non_members_tree.setIndentation(0)
        self.members_tree = QTreeWidget(self)
        self.members_tree.setHeaderLabel("Members")
        self.members_tree.setSelectionMode(QTreeWidget.ExtendedSelection)
        self.members_tree.setColumnCount(1)
        self.members_tree.setIndentation(0)
        self.add_button = QToolButton()
        self.add_button.setToolTip("<p>Add selected non-members.</p>")
        self.add_button.setIcon(QIcon(":/icons/menu_icons/cube_plus.svg"))
        self.add_button.setIconSize(QSize(24, 24))
        self.add_button.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
        self.add_button.setText(">>")
        self.remove_button = QToolButton()
        self.remove_button.setToolTip("<p>Remove selected members.</p>")
        self.remove_button.setIcon(QIcon(":/icons/menu_icons/cube_minus.svg"))
        self.remove_button.setIconSize(QSize(24, 24))
        self.remove_button.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
        self.remove_button.setText("<<")
        self.vertical_button_widget = QWidget()
        vertical_button_layout = QVBoxLayout(self.vertical_button_widget)
        vertical_button_layout.addStretch()
        vertical_button_layout.addWidget(self.add_button)
        vertical_button_layout.addWidget(self.remove_button)
        vertical_button_layout.addStretch()
        self.button_box = QDialogButtonBox(self)
        self.button_box.setStandardButtons(QDialogButtonBox.Cancel
                                           | QDialogButtonBox.Ok)
        layout = QGridLayout(self)
        layout.addWidget(self.header_widget, 0, 0, 1, 3, Qt.AlignHCenter)
        layout.addWidget(self.non_members_tree, 1, 0)
        layout.addWidget(self.vertical_button_widget, 1, 1)
        layout.addWidget(self.members_tree, 1, 2)
        layout.addWidget(self.button_box, 2, 0, 1, 3)
        self.setAttribute(Qt.WA_DeleteOnClose)
        self.db_combo_box.addItems(list(self.db_maps_by_codename))
        self.db_map_object_ids = {
            db_map: {
                x["name"]: x["id"]
                for x in self.db_mngr.get_items_by_field(
                    self.db_map, "object", "class_id",
                    self.object_class_item.db_map_id(db_map))
            }
            for db_map in db_maps
        }
        self.reset_list_widgets(db_maps[0].codename)
        self.connect_signals()

    def connect_signals(self):
        """Connect signals to slots."""
        self.button_box.accepted.connect(self.accept)
        self.button_box.rejected.connect(self.reject)
        self.db_combo_box.currentTextChanged.connect(self.reset_list_widgets)
        self.add_button.clicked.connect(self.add_members)
        self.remove_button.clicked.connect(self.remove_members)

    def reset_list_widgets(self, database):
        self.db_map = self.db_maps_by_codename[database]
        object_ids = self.db_map_object_ids[self.db_map]
        members = []
        non_members = []
        for obj_name, obj_id in object_ids.items():
            if obj_id in self.initial_member_ids():
                members.append(obj_name)
            elif obj_id != self.initial_entity_id():
                non_members.append(obj_name)
        member_items = [QTreeWidgetItem([obj_name]) for obj_name in members]
        non_member_items = [
            QTreeWidgetItem([obj_name]) for obj_name in non_members
        ]
        self.members_tree.addTopLevelItems(member_items)
        self.non_members_tree.addTopLevelItems(non_member_items)

    def initial_member_ids(self):
        raise NotImplementedError()

    def initial_entity_id(self):
        raise NotImplementedError()

    @Slot(bool)
    def add_members(self, checked=False):
        indexes = sorted([
            self.non_members_tree.indexOfTopLevelItem(x)
            for x in self.non_members_tree.selectedItems()
        ],
                         reverse=True)
        items = [
            self.non_members_tree.takeTopLevelItem(ind) for ind in indexes
        ]
        self.members_tree.addTopLevelItems(items)

    @Slot(bool)
    def remove_members(self, checked=False):
        indexes = sorted([
            self.members_tree.indexOfTopLevelItem(x)
            for x in self.members_tree.selectedItems()
        ],
                         reverse=True)
        items = [self.members_tree.takeTopLevelItem(ind) for ind in indexes]
        self.non_members_tree.addTopLevelItems(items)

    def _check_validity(self):
        if not self.members_tree.topLevelItemCount():
            self.parent().msg_error.emit(
                "Please select at least one member object.")
            return False
        return True
示例#9
0
class TallyDock(PlotterDock):

    def __init__(self, model, font_metric, parent=None):
        super().__init__(model, font_metric, parent)

        self.setAllowedAreas(QtCore.Qt.RightDockWidgetArea)

        # Dock maps for tally information
        self.tally_map = {}
        self.filter_map = {}
        self.score_map = {}
        self.nuclide_map = {}

        # Tally selector
        self.tallySelectorLayout = QFormLayout()
        self.tallySelector = QComboBox(self)
        self.tallySelector.currentTextChanged[str].connect(
            self.main_window.editSelectedTally)
        self.tallySelectorLayout.addRow(self.tallySelector)
        self.tallySelectorLayout.setLabelAlignment(QtCore.Qt.AlignLeft)
        self.tallySelectorLayout.setFieldGrowthPolicy(
            QFormLayout.AllNonFixedFieldsGrow)

        # Add selector to its own box
        self.tallyGroupBox = QGroupBox('Selected Tally')
        self.tallyGroupBox.setLayout(self.tallySelectorLayout)

        # Create submit button
        self.applyButton = QPushButton("Apply Changes")
        self.applyButton.setMinimumHeight(self.font_metric.height() * 1.6)
        self.applyButton.clicked.connect(self.main_window.applyChanges)

        # Color options section
        self.tallyColorForm = ColorForm(self.model, self.main_window, 'tally')
        self.scoresGroupBox = Expander(title="Scores:")
        self.scoresListWidget = QListWidget()
        self.nuclidesListWidget = QListWidget()

        # Main layout
        self.dockLayout = QVBoxLayout()
        self.dockLayout.addWidget(QLabel("Tallies"))
        self.dockLayout.addWidget(HorizontalLine())
        self.dockLayout.addWidget(self.tallyGroupBox)
        self.dockLayout.addStretch()
        self.dockLayout.addWidget(HorizontalLine())
        self.dockLayout.addWidget(self.tallyColorForm)
        self.dockLayout.addWidget(HorizontalLine())
        self.dockLayout.addWidget(self.applyButton)

        # Create widget for dock and apply main layout
        self.scroll = QScrollArea()
        self.scroll.setWidgetResizable(True)
        self.widget = QWidget()
        self.widget.setLayout(self.dockLayout)
        self.scroll.setWidget(self.widget)
        self.setWidget(self.scroll)

    def _createFilterTree(self, spatial_filters):
        av = self.model.activeView
        tally = self.model.statepoint.tallies[av.selectedTally]
        filters = tally.filters

        # create a tree for the filters
        self.treeLayout = QVBoxLayout()
        self.filterTree = QTreeWidget()
        self.treeLayout.addWidget(self.filterTree)
        self.treeExpander = Expander("Filters:", layout=self.treeLayout)
        self.treeExpander.expand()  # start with filters expanded

        header = QTreeWidgetItem(["Filters"])
        self.filterTree.setHeaderItem(header)
        self.filterTree.setItemHidden(header, True)
        self.filterTree.setColumnCount(1)
        self.filterTree.itemChanged.connect(self.updateFilters)

        self.filter_map = {}
        self.bin_map = {}

        for tally_filter in filters:
            filter_label = str(type(tally_filter)).split(".")[-1][:-2]
            filter_item = QTreeWidgetItem(self.filterTree, (filter_label,))
            self.filter_map[tally_filter] = filter_item

            # make checkable
            if not spatial_filters:
                filter_item.setFlags(QtCore.Qt.ItemIsUserCheckable)
                filter_item.setToolTip(0, "Only tallies with spatial filters are viewable.")
            else:
                filter_item.setFlags(filter_item.flags() | QtCore.Qt.ItemIsTristate | QtCore.Qt.ItemIsUserCheckable)
            filter_item.setCheckState(0, QtCore.Qt.Unchecked)

            # all mesh bins are selected by default and not shown in the dock
            if isinstance(tally_filter, openmc.MeshFilter):
                filter_item.setCheckState(0, QtCore.Qt.Checked)
                filter_item.setFlags(QtCore.Qt.ItemIsUserCheckable)
                filter_item.setToolTip(0, "All Mesh bins are selected automatically")
                continue

            def _bin_sort_val(bin):
                if isinstance(bin, Iterable) and all([isinstance(val, float) for val in bin]):
                    return np.sum(bin)
                else:
                    return bin

            for bin in sorted(tally_filter.bins, key=_bin_sort_val):
                item = QTreeWidgetItem(filter_item, [str(bin),])
                if not spatial_filters:
                    item.setFlags(QtCore.Qt.ItemIsUserCheckable)
                    item.setToolTip(0, "Only tallies with spatial filters are viewable.")
                else:
                    item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable)
                item.setCheckState(0, QtCore.Qt.Unchecked)

                bin = bin if not isinstance(bin, Iterable) else tuple(bin)
                self.bin_map[tally_filter, bin] = item

            # start with all filters selected if spatial filters are present
            if spatial_filters:
                filter_item.setCheckState(0, QtCore.Qt.Checked)

    def selectFromModel(self):
        cv = self.model.currentView
        self.selectedTally(cv.selectedTally)

    def selectTally(self, tally_label=None):
        # using active view to populate tally options live
        av = self.model.activeView

        # reset form layout
        for i in reversed(range(self.tallySelectorLayout.count())):
            self.tallySelectorLayout.itemAt(i).widget().setParent(None)

        # always re-add the tally selector to the layout
        self.tallySelectorLayout.addRow(self.tallySelector)
        self.tallySelectorLayout.addRow(HorizontalLine())

        if tally_label is None or tally_label == "None" or tally_label == "":
            av.selectedTally = None
            self.score_map = None
            self.nuclide_map = None
            self.filter_map = None
            av.tallyValue = "Mean"
        else:
            # get the tally
            tally = self.model.statepoint.tallies[av.selectedTally]

            # populate filters
            filter_types = {type(f) for f in tally.filters}
            spatial_filters = bool(filter_types.intersection(_SPATIAL_FILTERS))

            if not spatial_filters:
                self.filter_description = QLabel("(No Spatial Filters)")
                self.tallySelectorLayout.addRow(self.filter_description)

            self._createFilterTree(spatial_filters)

            self.tallySelectorLayout.addRow(self.treeExpander)
            self.tallySelectorLayout.addRow(HorizontalLine())

            # value selection
            self.tallySelectorLayout.addRow(QLabel("Value:"))
            self.valueBox = QComboBox(self)
            self.values = tuple(_TALLY_VALUES.keys())
            for value in self.values:
                self.valueBox.addItem(value)
            self.tallySelectorLayout.addRow(self.valueBox)
            self.valueBox.currentTextChanged[str].connect(
                self.main_window.editTallyValue)
            self.updateTallyValue()

            if not spatial_filters:
                self.valueBox.setEnabled(False)
                self.valueBox.setToolTip("Only tallies with spatial filters are viewable.")

            # scores
            self.score_map = {}
            self.scoresListWidget.itemClicked.connect(
                self.main_window.updateScores)
            self.score_map.clear()
            self.scoresListWidget.clear()

            sorted_scores = sorted(tally.scores)
            # always put total first if present
            if 'total' in sorted_scores:
                idx = sorted_scores.index('total')
                sorted_scores.insert(0, sorted_scores.pop(idx))

            for score in sorted_scores:
                ql = QListWidgetItem()
                ql.setText(score.capitalize())
                ql.setCheckState(QtCore.Qt.Unchecked)
                if not spatial_filters:
                    ql.setFlags(QtCore.Qt.ItemIsUserCheckable)
                else:
                    ql.setFlags(ql.flags() | QtCore.Qt.ItemIsUserCheckable)
                    ql.setFlags(ql.flags() & ~QtCore.Qt.ItemIsSelectable)
                self.score_map[score] = ql
                self.scoresListWidget.addItem(ql)

            # select the first score item by default
            for item in self.score_map.values():
                item.setCheckState(QtCore.Qt.Checked)
                break
            self.updateScores()

            self.scoresGroupBoxLayout = QVBoxLayout()
            self.scoresGroupBoxLayout.addWidget(self.scoresListWidget)
            self.scoresGroupBox = Expander("Scores:", layout=self.scoresGroupBoxLayout)
            self.tallySelectorLayout.addRow(self.scoresGroupBox)

            # nuclides
            self.nuclide_map = {}
            self.nuclidesListWidget.itemClicked.connect(self.main_window.updateNuclides)
            self.nuclide_map.clear()
            self.nuclidesListWidget.clear()

            sorted_nuclides = sorted(tally.nuclides)
            # always put total at the top
            if 'total' in sorted_nuclides:
                idx = sorted_nuclides.index('total')
                sorted_nuclides.insert(0, sorted_nuclides.pop(idx))

            for nuclide in sorted_nuclides:
                ql = QListWidgetItem()
                ql.setText(nuclide.capitalize())
                ql.setCheckState(QtCore.Qt.Unchecked)
                if not spatial_filters:
                    ql.setFlags(QtCore.Qt.ItemIsUserCheckable)
                else:
                    ql.setFlags(ql.flags() | QtCore.Qt.ItemIsUserCheckable)
                    ql.setFlags(ql.flags() & ~QtCore.Qt.ItemIsSelectable)
                self.nuclide_map[nuclide] = ql
                self.nuclidesListWidget.addItem(ql)

            # select the first nuclide item by default
            for item in self.nuclide_map.values():
                item.setCheckState(QtCore.Qt.Checked)
                break
            self.updateNuclides()

            self.nuclidesGroupBoxLayout = QVBoxLayout()
            self.nuclidesGroupBoxLayout.addWidget(self.nuclidesListWidget)
            self.nuclidesGroupBox = Expander("Nuclides:", layout=self.nuclidesGroupBoxLayout)
            self.tallySelectorLayout.addRow(self.nuclidesGroupBox)

    def updateMinMax(self):
        self.tallyColorForm.updateMinMax()

    def updateTallyValue(self):
        cv = self.model.currentView
        idx = self.valueBox.findText(cv.tallyValue)
        self.valueBox.setCurrentIndex(idx)

    def updateSelectedTally(self):
        cv = self.model.currentView
        idx = 0
        if cv.selectedTally:
            idx = self.tallySelector.findData(cv.selectedTally)
        self.tallySelector.setCurrentIndex(idx)

    def updateFilters(self):
        applied_filters = defaultdict(tuple)
        for f, f_item in self.filter_map.items():
            if type(f) == openmc.MeshFilter:
                continue

            filter_checked = f_item.checkState(0)
            if filter_checked != QtCore.Qt.Unchecked:
                selected_bins = []
                for idx, b in enumerate(f.bins):
                    b = b if not isinstance(b, Iterable) else tuple(b)
                    bin_checked = self.bin_map[(f, b)].checkState(0)
                    if bin_checked == QtCore.Qt.Checked:
                        selected_bins.append(idx)
                applied_filters[f] = tuple(selected_bins)

            self.model.appliedFilters = applied_filters

    def updateScores(self):
        applied_scores = []
        for score, score_box in self.score_map.items():
            if score_box.checkState() == QtCore.Qt.CheckState.Checked:
                applied_scores.append(score)
        self.model.appliedScores = tuple(applied_scores)

        if not applied_scores:
            # if no scores are selected, enable all scores again
            for score, score_box in self.score_map.items():
                sunits = _SCORE_UNITS.get(score, _REACTION_UNITS)
                empty_item = QListWidgetItem()
                score_box.setFlags(empty_item.flags() | QtCore.Qt.ItemIsUserCheckable)
                score_box.setFlags(empty_item.flags() & ~QtCore.Qt.ItemIsSelectable)
        elif 'total' in applied_scores:
            self.model.appliedScores = ('total',)
            # if total is selected, disable all other scores
            for score, score_box in self.score_map.items():
                if score != 'total':
                    score_box.setFlags(QtCore.Qt.ItemIsUserCheckable)
                    score_box.setToolTip("De-select 'total' to enable other scores")
        else:
            # get units of applied scores
            selected_units = _SCORE_UNITS.get(applied_scores[0], _REACTION_UNITS)
            # disable scores with incompatible units
            for score, score_box in self.score_map.items():
                sunits = _SCORE_UNITS.get(score, _REACTION_UNITS)
                if sunits != selected_units:
                    score_box.setFlags(QtCore.Qt.ItemIsUserCheckable)
                    score_box.setToolTip("Score is incompatible with currently selected scores")
                else:
                    score_box.setFlags(score_box.flags() | QtCore.Qt.ItemIsUserCheckable)
                    score_box.setFlags(score_box.flags() & ~QtCore.Qt.ItemIsSelectable)

    def updateNuclides(self):
        applied_nuclides = []
        for nuclide, nuclide_box in self.nuclide_map.items():
            if nuclide_box.checkState() == QtCore.Qt.CheckState.Checked:
                applied_nuclides.append(nuclide)
        self.model.appliedNuclides = tuple(applied_nuclides)

        if 'total' in applied_nuclides:
            self.model.appliedNuclides = ['total',]
            for nuclide, nuclide_box in self.nuclide_map.items():
                if nuclide != 'total':
                    nuclide_box.setFlags(QtCore.Qt.ItemIsUserCheckable)
                    nuclide_box.setToolTip("De-select 'total' to enable other nuclides")
        elif not applied_nuclides:
            # if no nuclides are selected, enable all nuclides again
            for nuclide, nuclide_box in self.nuclide_map.items():
                empty_item = QListWidgetItem()
                nuclide_box.setFlags(empty_item.flags() | QtCore.Qt.ItemIsUserCheckable)
                nuclide_box.setFlags(empty_item.flags() & ~QtCore.Qt.ItemIsSelectable)

    def update(self):

        # update the color form
        self.tallyColorForm.update()

        if self.model.statepoint:
            self.tallySelector.clear()
            self.tallySelector.setEnabled(True)
            self.tallySelector.addItem("None")
            for idx, tally in enumerate(self.model.statepoint.tallies.values()):
                if tally.name == "":
                    self.tallySelector.addItem('Tally {}'.format(tally.id), userData=tally.id)
                else:
                    self.tallySelector.addItem('Tally {} "{}"'.format(tally.id, tally.name), userData=tally.id)
                self.tally_map[idx] = tally
            self.updateSelectedTally()
            self.updateMinMax()
        else:
            self.tallySelector.clear()
            self.tallySelector.setDisabled(True)
示例#10
0
class MemTree(QWidget):
    def __init__(self, qmp, parent):
        super().__init__()
        self.qmp = qmp
        self.qmp.memoryMap.connect(self.update_tree)

        self.parent = parent

        self.tree_sem = QSemaphore(1)
        self.sending_sem = QSemaphore(
            1)  # used to prevent sending too many requests at once

        self.init_ui()
        self.get_map()

    def init_ui(self):

        self.vbox = QVBoxLayout()

        self.refresh = QPushButton('Refresh')
        self.refresh.clicked.connect(lambda: self.get_map())
        self.vbox.addWidget(self.refresh)

        self.tree = QTreeWidget()
        self.tree.itemDoubleClicked.connect(self.open_region)
        self.tree.setColumnCount(3)
        self.tree.header().setSectionResizeMode(QHeaderView.ResizeToContents)
        self.tree.header().setStretchLastSection(False)
        self.tree.setHeaderLabels(
            ['Memory Region', 'Start Address', 'End Address'])
        self.vbox.addWidget(self.tree)

        self.setLayout(self.vbox)
        self.setGeometry(100, 100, 500, 300)
        self.setWindowTitle("Memory Tree")
        self.show()

    def get_map(self):
        self.tree.clear()
        self.qmp.command('mtree')

    # finds item with name 'name' in self.tree
    # self.tree_sem must be acquired before use
    def find(self, name, node):
        if node.text(0) == name:
            return node
        else:
            for i in range(node.childCount()):
                result = self.find(name, node.child(i))
                if result:
                    return result
            return None

    def update_tree(self, value):
        if value != None:
            self.tree_sem.acquire()
            current_addr_space = ''

            for region in value:
                parent_node = self.tree
                parent = region['parent']

                if parent != '':
                    root = self.tree.invisibleRootItem()
                    for i in range(root.childCount()):
                        if root.child(i).text(0) == current_addr_space:
                            root = root.child(i)
                            break
                    parent_node = self.find(parent, root)
                else:
                    current_addr_space = region['name']

                node = QTreeWidgetItem(parent_node)
                node.setText(0, region['name'])
                start = region['start']
                end = region['end']
                if start < 0:
                    start = start + (1 << constants['bits'])
                if end < 0:
                    end = end + (1 << constants['bits'])
                node.setText(1, f'{start:016x}')
                node.setText(2, f'{end:016x}')
                node.setFont(0, QFont('Courier New'))
                node.setFont(1, QFont('Courier New'))
                node.setFont(2, QFont('Courier New'))

            self.tree_sem.release()

    def open_region(self, node, col):
        self.parent.open_new_window(
            MemDumpWindow(self.qmp,
                          base=int(node.text(1), 16),
                          max=int(node.text(2), 16)))
示例#11
0
class DiscoverUi(QWidget):
    
    def __init__(self):
        super().__init__()
        
        self.discover = Discover()
        self.devices = self.discover.devices
        self.listWidget = None
        self.treeWidget = None
        self.initUI()
        self.mac_addr = None

    def initDevices(self):
        for device in self.devices:
            newItem = QListWidgetItem()
            newItem.setText(device.name + " (" + device.address + ")")
            self.listWidget.addItem(newItem)

    def initUI(self):
        self.listWidget = QListWidget()
        self.initDevices()

        self.treeWidget = QTreeWidget()
        self.treeWidget.itemPressed.connect(self.onItemPressed)
        self.treeWidget.setColumnCount(4)
        self.treeWidget.setColumnWidth(0, 250)
        self.treeWidget.setColumnWidth(1, 300)
        self.treeWidget.setColumnWidth(2, 300)
        self.treeWidget.setColumnWidth(3, 150)
        self.treeWidget.setHeaderLabels(["Service", "Service UUID", "Characteristic UUID", "Characteristic Property"])

        btn = QPushButton("Read Services")
        btn.clicked.connect(self.onPushButton)

        groupDevices = QGroupBox("Devices")
        groupDevices.setMaximumWidth(300)

        vbox = QVBoxLayout()
        vbox.addWidget(self.listWidget)
        vbox.addWidget(btn)
        groupDevices.setLayout(vbox)

        self.btnR = QPushButton("Read")
        self.btnR.clicked.connect(self.onReadButton)
        self.btnW = QPushButton("Write")
        self.btnW.clicked.connect(self.onWriteButton)
        self.lneI = QLineEdit()
        self.chkN = QCheckBox("Notify")
        self.chkN.toggled.connect(self.onNotifyCheck)
        hbox = QHBoxLayout()
        hbox.addWidget(self.btnR)
        hbox.addWidget(self.btnW)
        hbox.addWidget(self.lneI)
        hbox.addWidget(self.chkN)

        groupProperty = QGroupBox("Property")
        #groupProperty.setLayout(vbox)
        groupProperty.setLayout(hbox)

        groupServices = QGroupBox("Services")

        vbox = QVBoxLayout()
        vbox.addWidget(self.treeWidget)
        vbox.addWidget(groupProperty)
        groupServices.setLayout(vbox)

        hbox = QHBoxLayout()
        hbox.addWidget(groupDevices)
        hbox.addWidget(groupServices)
        self.setLayout(hbox)
        
        self.setGeometry(300, 300, 800, 600)
        self.setWindowTitle('BLE Discover')
        self.show()

    def onPushButton(self):
        try:
            self.mac_addr = self.devices[self.listWidget.currentRow()].address
            self.discover.getServices(self.mac_addr)
        except:
            print("Could not get GATT services.")
        else:
            svcs = self.discover.svcs
            for serviceKey, serviceValue in svcs.services.items():
                item = QTreeWidgetItem(None, [serviceValue.description, serviceValue.uuid])
                
                for characteristic in serviceValue.characteristics:
                    for property in characteristic.properties:
                        child = QTreeWidgetItem(["", "", characteristic.uuid, property])
                        item.addChild(child)

                self.treeWidget.addTopLevelItem(item)


    def onReadButton(self):
        byteArray = self.discover.readGattChar(self.mac_addr, self.chosenUuid)
        text = ''.join('{:02x}'.format(x) for x in byteArray)
        self.lneI.setText(text)

    def onWriteButton(self):
        text = self.lneI.text()
        print("onWriteButton")
        self.discover.writeGattChar(self.mac_addr, self.chosenUuid, bytes.fromhex(text))

    def notifyCallback(self, sender, data):
        text = ''.join('{:02x}'.format(x) for x in data)
        self.lneI.textChanged.emit(text)

    def onNotifyCheck(self, checked):
        if checked:
            print("onNotifyCheck")
            self.discover.startNotify(self.mac_addr, self.chosenUuid, self.notifyCallback)
        else:
            print("onNotifyCheck else")
            

    def onItemPressed(self, item, column):
        if item.child(0) is None:
            print(item)
            print(item.text(2))
            print(item.text(3))
            self.chosenUuid = item.text(2)
            property = item.text(3)

            if property == "read":
                self.btnR.setEnabled(True)
                self.btnW.setEnabled(False)
                self.lneI.setEnabled(False)
                self.chkN.setEnabled(False)
            elif property == "write":
                self.btnR.setEnabled(True)
                self.btnW.setEnabled(True)
                self.lneI.setEnabled(True)
                self.chkN.setEnabled(False)
            elif property == "notify":
                self.btnR.setEnabled(False)
                self.btnW.setEnabled(False)
                self.lneI.setEnabled(False)
                self.chkN.setEnabled(True)