Beispiel #1
0
 def add_settings(self):
     main_layout = QBoxLayout(QBoxLayout.TopToBottom)
     for box_title, settings in self.gui_settings.items():
         box = QGroupBox(box_title, self)
         box_layout = QBoxLayout(QBoxLayout.TopToBottom)
         for name, text in settings.items():
             control, layout = self.get_setting_control(name, text)
             box_layout.addLayout(layout)
             self.controls[name] = control
         box.setLayout(box_layout)
         main_layout.addWidget(box)
         if main_layout.count() > 2:
             self.settingsLayout.addItem(main_layout)
             main_layout = QBoxLayout(QBoxLayout.TopToBottom)
     main_layout.addStretch()
     self.settingsLayout.addItem(main_layout)
Beispiel #2
0
def remove_all_widgets(layout: QBoxLayout, min_count: int = 0):
    """Remove all widgets from the given layout

        Parameters
        ----------
        layout : Union[QBoxLayout, None] -
            Layout that widgets should be removed from.\n
        min_count : int, optional -
            Number of widgets that should remain in the layout, by default 0.
        """
    if layout is not None:
        while layout.count() - min_count:
            child = layout.takeAt(0)
            if child.widget() is not None:
                child.widget().deleteLater()
            elif child.layout() is not None:
                remove_all_widgets(child.layout())
Beispiel #3
0
    def rebuildTeamHotkeys(self, teamHotkeysHLayout: QBoxLayout, tabWidget: QTabWidget):
        """
        Delete all child widgets
        """
        while teamHotkeysHLayout.count():
            child = teamHotkeysHLayout.takeAt(0)
            if child.widget():
                child.widget().deleteLater()

        bar = tabWidget.tabBar()

        hotkeyRDict = {v: k for k, v in self.hotkeyDict.items()}
        # 		LOG.debug("tab count="+str(bar.count()))
        for i in range(0, bar.count()):
            #  An apparent bug causes the tabButton (a label) to not have a text attrubite;
            #  so, use the whatsThis attribute instead.
            callsign = bar.tabWhatsThis(i)
            hotkey = hotkeyRDict.get(callsign, "")
            label = QLabel(hotkey)
            label.setFixedWidth(bar.tabRect(i).width())
            label.setStyleSheet("border:0px solid black;margin:0px;font-style:italic;font-size:14px;background-image:url(:/radiolog_ui/blank-computer-key.png) 0 0 30 30;")
            label.setAlignment(Qt.AlignCenter)
            teamHotkeysHLayout.addWidget(label)
        teamHotkeysHLayout.addStretch()
Beispiel #4
0
def remove_widget_from_scroll(widget: QWidget, parent_layout: QBoxLayout,
                              data_list: List):
    """Remove a widget from a scroll area, and remove the associated data.

        Parameters
        ----------
        widget : QWidget
            Widget that should be removed
        parent_layout : QBoxLayout
            The layout of the scroll area the widget should be removed from
        data_list : List
            The list of data related to the widgets in this scroll area.

        Information
        -----------
        Only removes the widget and data if there will still be widgets
        in the scroll area after this widget is removed.
        """
    if parent_layout.count() > 2:  # ? 2 instead of 1 because of spacer.
        index = parent_layout.indexOf(widget)
        del data_list[index]
        remove_all_widgets(widget.layout())
        parent_layout.removeWidget(widget)
        widget.deleteLater()
Beispiel #5
0
class CToolBarArea(QWidget):
    signalDragStart = pyqtSignal()
    signalDragEnd = pyqtSignal()
    signalItemDropped = pyqtSignal(CToolBarAreaItem, QWidget, int)

    def __init__(self, parent, orientation):
        super().__init__(parent)
        self.editor = parent
        self.orientation = orientation
        self.dropTargetSpacer = None
        self.actionContextPosition = QPoint()
        self.isLocked = False

        if self.orientation == Qt.Horizontal:
            self.layout_ = QBoxLayout(QBoxLayout.LeftToRight)
        else:
            self.layout_ = QBoxLayout(QBoxLayout.TopToBottom)

        self.layout_.setSpacing(0)
        self.layout_.setContentsMargins(0, 0, 0, 0)

        self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
        self.setLayout(self.layout_)
        self.setAcceptDrops(True)
        self.setContextMenuPolicy(Qt.CustomContextMenu)

        # print ( "CToolBarArea.__init__", parent )

    def getOrientation(self):
        return self.orientation

    def getToolBars(self):
        items = getAllItems(self)
        toolBarItems = []

        for item in items:
            if item.getType() != CToolBarAreaType.ToolBar:
                continue
            toolBarItems.append(item)

        return toolBarItems

    def getLargestItemMinimumSize(self):
        minSize = self.minimumSize()
        items = getAllItems(self)
        for item in items:
            minSize = minSize.expandedTo(item.getMinimumSize())

        return minSize

    def setOrientation(self, orientation):
        self.orientation = orientation
        self.layout_.setDirection(QBoxLayout.LeftToRight if self.orientation ==
                                  Qt.Horizontal else QBoxLayout.TopToBottom)
        self.updateLayoutAlignment()

        items = getAllItems(self)
        for item in items:
            item.setOrientation(self.orientation)

    def setActionContextPosition(self, actionContextPosition):
        self.actionContextPosition = actionContextPosition

    def fillContextMenu(self, menu):
        pass

    def addItem(self, item, targetIndex):
        item.signalDragStart.connect(self.onDragStart)
        item.signalDragEnd.connect(self.onDragEnd)
        item.setOrientation(self.orientation)
        item.setLocked(self.isLocked)
        self.layout_.insertWidget(targetIndex, item)
        item.setArea(self)

    def addToolBar(self, toolBar, targetIndex):
        self.addItem(CToolBarItem(self, toolBar, self.orientation),
                     targetIndex)

    def addSpacer(self, spacerType, targetIndex):
        self.addItem(CSpacerItem(self, spacerType, self.orientation),
                     targetIndex)
        if spacerType == CSpacerType.Expanding:
            self.layout_.setAlignment(0)

    def removeItem(self, item):
        self.layout_.removeWidget(item)
        item.signalDragStart.disconnect(self)
        item.signalDragEnd.disconnect(self)

        self.updateLayoutAlignment(item)

    def deleteToolBar(self, toolBarItem):
        if self.isAncestorOf(toolBarItem):
            qWarning("Trying to remove non-owned toolbar from area")
            return
        toolBarItem.deleteLater()

    def hideAll(self):
        items = getAllItems(self)
        for item in items:
            item.setVisible(False)

    def findToolBarByName(self, szToolBarName):
        toolBarItems = self.findChildren(CToolBarItem, "",
                                         Qt.FindDirectChildrenOnly)
        for toolBarItem in toolBarItems:
            if toolBarItem.getName() == szToolBarName:
                return toolBarItem

        print("Toolbar not found: %s" % szToolBarName)
        return None

    def setLocked(self, isLocked):
        self.isLocked = isLocked
        items = getAllItems(self)
        for item in items:
            item.setLocked(isLocked)

    def getState(self):
        pass

    def setState(self, state):
        pass

    def dragEnterEvent(self, event):
        print("CToolBarArea.dragEnterEvent", event)
        dragDropData = CDragDropData.fromMimeData(event.mimeData())
        if dragDropData.hasCustomData(CToolBarAreaItem.getMimeType()):
            byteArray = dragDropData.getCustomData(
                CToolBarAreaItem.getMimeType())
            stream = QDataStream(byteArray)
            value = None
            stream >> value
            draggedItem = value if isinstance(value,
                                              CToolBarAreaItem) else None

            if not self.parentWidget().isAncestorOf(draggedItem):
                return

            event.acceptProposedAction()

            self.setProperty("dragHover", True)
            self.style().unpolish(self)
            self.style().polish(self)

    def dragMoveEvent(self, event):
        dragDropData = CDragDropData.fromMimeData(event.mimeData())
        if dragDropData.hasCustomData(CToolBarAreaItem.getMimeType()):
            targetIndex = self.getPlacementIndexFromPosition(
                self.mapToGlobal(event.pos()))
            event.acceptProposedAction()

            if self.dropTargetSpacer and targetIndex == self.layout_.indexOf(
                    self.dropTargetSpacer):
                return

            byteArray = dragDropData.getCustomData(
                CToolBarAreaItem.getMimeType())
            stream = QDataStream(byteArray)
            value = None
            stream >> value
            draggedItem = value if isinstance(value,
                                              CToolBarAreaItem) else None

            if not self.parentWidget().isAncestorOf(draggedItem):
                return

            spacerWidth = draggedItem.width()
            spacerHeight = draggedItem.height()

            if draggedItem.getOrientation() != self.orientation:
                tempWidth = spacerWidth
                spacerWidth = spacerHeight
                spacerHeight = tempWidth

            if self.dropTargetSpacer == None:
                self.dropTargetSpacer = QSpacerItem(spacerWidth, spacerHeight,
                                                    QSizePolicy.Fixed,
                                                    QSizePolicy.Fixed)
            else:
                spacerIndex = self.layout_.indexOf(self.dropTargetSpacer)
                if spacerIndex == targetIndex - 1 or (
                        targetIndex == -1
                        and spacerIndex == self.layout_.count() - 1):
                    return

                self.removeDropTargetSpacer()
                self.dropTargetSpacer = QSpacerItem(spacerWidth, spacerHeight,
                                                    QSizePolicy.Fixed,
                                                    QSizePolicy.Fixed)

            self.layout_.insertSpacerItem(targetIndex, self.dropTargetSpacer)

    def dragLeaveEvent(self, event):
        self.removeDropTargetSpacer()

        self.setProperty("dragHover", False)
        self.style().unpolish(self)
        self.style().polish(self)

    def dropEvent(self, event):
        dragDropData = CDragDropData.fromMimeData(event.mimeData())
        if dragDropData.hasCustomData(CToolBarAreaItem.getMimeType()):
            event.acceptProposedAction()
            byteArray = dragDropData.getCustomData(
                CToolBarAreaItem.getMimeType())
            stream = QDataStream(byteArray)
            value = None
            stream >> value
            item = value if isinstance(value, CToolBarAreaItem) else None

            targetIndex = -1

            if self.dropTargetSpacer:
                targetIndex = self.layout_.indexOf(self.dropTargetSpacer)

                containerIndex = self.layout_.indexOf(item)
                if containerIndex >= 0 and containerIndex < targetIndex:
                    targetIndex -= 1

                self.removeDropTargetSpacer()

            if targetIndex >= self.layout_.count():
                targetIndex = -1

            self.signalItemDropped.emit(item, self, targetIndex)

    def customEvent(self, event):
        pass

    def paintEvent(self, event):
        styleOption = QStyleOption()
        styleOption.initFrom(self)
        painter = QPainter(self)
        self.style().drawPrimitive(QStyle.PE_Widget, styleOption, painter,
                                   self)

    def onDragStart(self, item):
        self.updateLayoutAlignment(item)
        item.setVisiable(False)
        self.signalDragStart.emit()

    def onDragEnd(self, item):
        item.setVisiable(True)
        self.signalDragEnd.emit()

    def removeDropTargetSpacer(self):
        if self.dropTargetSpacer:
            self.layout_.removeItem(self.dropTargetSpacer)
            self.dropTargetSpacer = None

    def indexForItem(self, item):
        return self.layout_.indexOf(item)

    def moveItem(self, item, destinationIndex):
        sourceIndex = self.indexForItem(item)
        if sourceIndex == destinationIndex:
            return
        self.layout_.insertWidget(destinationIndex, item)

    def updateLayoutAlignment(self, itemToBeRemoved=None):
        spacers = self.findChildren(CSpacerItem, "", Qt.FindDirectChildrenOnly)
        expandingSpacers = []
        for spacer in spacers:
            if spacer.getSpacerType() == CSpacerType.Expanding:
                expandingSpacers.append(spacer)

        if len(expandingSpacers) == 0 or len(expandingSpacers) != 0 or (
                len(expandingSpacers) == 1
                and expandingSpacers[0] == itemToBeRemoved):
            if self.orientation == Qt.Horizontal:
                self.layout_.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
            else:
                self.layout_.setAlignment(Qt.AlignTop | Qt.AlignHCenter)

    def getItemAtPosition(self, globalPos):
        object = QApplication.widgetAt(globalPos)
        if object == None or object == self:
            return None

        item = object if isinstance(object, CToolBarAreaItem) else None
        while item == None and object.parent():
            object = object.parent()
            item = object if isinstance(object, CToolBarAreaItem) else None

        return item

    def getPlacementIndexFromPosition(self, globalPos):
        targetIndex = -1
        item = self.getItemAtPosition(globalPos)

        if item == None:
            localPos = self.mapFromGlobal(globalPos)
            if self.dropTargetSpacer:
                geom = self.dropTargetSpacer.geometry()
                if geom.contains(localPos):
                    targetIndex = self.layout_.indexOf(self.dropTargetSpacer)

            return targetIndex

        targetIndex = self.indexForItem(item)

        if self.orientation == Qt.Horizontal and item.mapFromGlobal(
                globalPos).x() > item.width() / 2:
            targetIndex += 1
        elif self.orientation == Qt.Vertical and item.mapFromGlobal(
                globalPos).y() > item.height() / 2:
            targetIndex += 1

        if targetIndex >= self.layout_.count():
            targetIndex = -1

        return targetIndex
Beispiel #6
0
class Wyrmy(QWidget):
    def __init__(self, outside):
        super(Wyrmy, self).__init__()

        # get/set basic information
        self.app_control = outside
        screen_res = self.app_control.desktop().screenGeometry()
        self.screen_width, self.screen_height = screen_res.width(
        ), screen_res.height()
        self.setWindowIcon(QIcon(':/resources/wyrmytheworm.png'))

        # get images to use
        self.worms = {}
        self.index = 0
        self.file_names = []
        self.images = {}
        self.load_images()

        # create first image, determine all dimensions
        self.label, self.panel_height, self.width, self.height = QLabel(
            self), 0, 0, 0
        self.alive, self.dead = QLabel(), QLabel()
        self.percent = QLabel()
        self.open, self.save, self.export = QPushButton(), QPushButton(
        ), QPushButton()
        self.curr_img_disp = QLabel()
        self.alive.setText('Alive: 0')
        self.dead.setText('Dead: 0')
        self.percent.setText('Percent: 0%')
        self.open.setText('Open')
        self.open.setToolTip('Load a data file')
        self.save.setText('Save')
        self.save.setToolTip('Save a data file')
        self.export.setText('Export')
        self.export.setToolTip('Export data as CSV')
        self.open.setMaximumWidth(100)
        self.save.setMaximumWidth(100)
        self.export.setMaximumWidth(100)
        self.open.clicked.connect(self.open_file)
        self.save.clicked.connect(self.save_file)
        self.export.clicked.connect(self.export_data)

        self.layout = QGridLayout(self)
        self.layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(self.layout)

        self.panel_layout = QGridLayout(self.layout.widget())
        self.panel_layout.setContentsMargins(15, 0, 15, 0)

        self.orig = QtGui.QPixmap(self.file_names[self.index])
        scale_by = self.screen_height * 0.75 / self.orig.height()
        self.img = self.orig.scaled(self.orig.width() * scale_by,
                                    self.orig.height() * scale_by,
                                    QtCore.Qt.KeepAspectRatio)
        self.panel_height = self.screen_height * 0.1
        self.width, self.height = self.img.width(
        ), self.img.height() + self.panel_height

        # self.panel = QGroupBox()
        # self.layout.addWidget(self.panel)
        # self.panel.move(0, self.img.height())
        # self.panel.setFixedWidth(self.width)
        # self.panel.setFixedHeight(self.panel_height)

        self.layout.addLayout(self.panel_layout, 1, 0)

        self.panel_layout.addWidget(self.alive, 0, 0)
        self.panel_layout.addWidget(self.dead, 1, 0)
        self.panel_layout.addWidget(self.percent, 2, 0)
        self.panel_layout.addWidget(self.curr_img_disp, 1, 1)
        self.panel_layout.addWidget(self.open, 0, 2)
        self.panel_layout.addWidget(self.save, 1, 2)
        self.panel_layout.addWidget(self.export, 2, 2)

        startX = int((self.screen_width / 2) - (self.width / 2))
        startY = int(((self.screen_height - 100) / 2) - (self.height / 2))
        self.move(startX, startY)

        self.label.mousePressEvent = self.image_clicked
        self.dead_pic = QtGui.QPixmap(':/resources/red_target_scaled.png')
        self.alive_pic = QtGui.QPixmap(':/resources/green_target_scaled.png')

        self.layout.addWidget(self.label, 0, 0)

        self.markers = QBoxLayout(QBoxLayout.LeftToRight)
        self.layout.addChildLayout(self.markers)

        self.refresh()

        self.show()

    def load_images(self):
        file_names_import = QFileDialog.getOpenFileNames(
            self, "Open Image", "/",
            "Image Files (*.png *.jpg *.bmp *.tiff *.tif)")
        self.file_names = file_names_import[0]
        for name in self.file_names:
            self.worms[Wyrmy.pic_name(name)] = WormPic(
                filename=Wyrmy.pic_name(name))

    def refresh(self):
        # take care of index wraparounds
        if len(self.file_names) == 0:
            self.app_control.quit()
        if self.index > len(self.file_names) - 1:
            self.index = 0
        if self.index < 0:
            self.index = len(self.file_names) - 1

        curr_img_name = self.file_names[self.index]
        # self.panel.setTitle(Wyrmy.pic_name(self.file_names[self.index]))

        orig = QtGui.QPixmap(self.file_names[self.index])
        scale_by = self.screen_height * 0.75 / orig.height()
        self.img = orig.scaled(orig.width() * scale_by,
                               orig.height() * scale_by,
                               QtCore.Qt.KeepAspectRatio)

        self.label.setPixmap(self.img)
        self.setWindowTitle('Wyrmy - ' + curr_img_name)

        curr_pic = self.worms[Wyrmy.pic_name(self.file_names[self.index])]

        self.curr_img_disp.setText(Wyrmy.pic_name(curr_img_name))

        num_dead = len(curr_pic.dead)
        num_alive = len(curr_pic.alive)
        alive_text = 'Alive: ' + str(num_alive)
        self.alive.setText(alive_text)
        dead_text = 'Dead: ' + str(num_dead)
        self.dead.setText(dead_text)
        if num_dead + num_alive > 0:
            percent_text = '% Dead: ' + str(100 * num_dead /
                                            (num_dead + num_alive))
        else:
            percent_text = '% Dead: 0'
        self.percent.setText(percent_text)

        for ind in reversed(range(self.markers.count())):
            widget = self.markers.takeAt(ind).widget()
            if widget is not None:
                widget.deleteLater()

        for coords in curr_pic.dead:
            curr_dead = QLabel(self)
            curr_dead.setPixmap(self.dead_pic)
            self.markers.addWidget(curr_dead)
            curr_dead.move(coords.x * self.img.width() - 25,
                           coords.y * self.img.height() - 12.5)
            # print(coords.x, ', ', coords.y)
        for coords in curr_pic.alive:
            curr_alive = QLabel(self)
            curr_alive.setPixmap(self.alive_pic)
            self.markers.addWidget(curr_alive)
            curr_alive.move(coords.x * self.img.width() - 25,
                            coords.y * self.img.height() - 12.5)
            # print(coords.x, ', ', coords.y)

    def safe_index(self, index):
        if index < 0:
            new_ind = len(self.file_names) + index
        elif index > len(self.file_names) - 1:
            new_ind = index - len(self.file_names)
        else:
            new_ind = index
        if new_ind < 0:
            new_ind = 0
        elif new_ind > len(self.file_names) - 1:
            new_ind = len(self.file_names) - 1
        return new_ind

    @staticmethod
    def pic_name(file_name):
        last_index = file_name.rfind('/')
        return file_name[last_index + 1:last_index + 4]

    def keyPressEvent(self, event):
        if event.key() == QtCore.Qt.Key_W:
            self.index -= 1
        if event.key() == QtCore.Qt.Key_S:
            self.index += 1
        if event.key() == QtCore.Qt.Key_A:
            start = QWidget.mapToGlobal(self.label, self.label.pos())
            click_x = (QtGui.QCursor.pos().x() - start.x()) / self.img.width()
            click_y = (QtGui.QCursor.pos().y() - start.y()) / self.img.height()
            click = Pair(click_x, click_y)
            self.worms[Wyrmy.pic_name(
                self.file_names[self.index])].alive.append(click)
        if event.key() == QtCore.Qt.Key_D:
            start = QWidget.mapToGlobal(self.label, self.label.pos())
            click_x = (QtGui.QCursor.pos().x() - start.x()) / self.img.width()
            click_y = (QtGui.QCursor.pos().y() - start.y()) / self.img.height()
            click = Pair(click_x, click_y)
            self.worms[Wyrmy.pic_name(
                self.file_names[self.index])].dead.append(click)
        if event.key() == QtCore.Qt.Key_X:
            curr_pic = self.worms[Wyrmy.pic_name(self.file_names[self.index])]
            curr_pic.alive = []
            curr_pic.dead = []
        self.refresh()
        event.accept()

    def image_clicked(self, event):
        click = Pair(event.x() / self.img.width(),
                     event.y() / self.img.height())
        if event.button() == QtCore.Qt.LeftButton:
            self.worms[Wyrmy.pic_name(
                self.file_names[self.index])].alive.append(click)
        if event.button() == QtCore.Qt.RightButton:
            self.worms[Wyrmy.pic_name(
                self.file_names[self.index])].dead.append(click)
        # if event.button() == QtCore.Qt.MidButton:
        #     curr_pic = self.worms[Wyrmy.pic_name(self.file_names[self.index])]
        #     max_diff_x = 25/self.img.width()
        #     max_diff_y = 25/self.img.height()
        #     for ind, coords in enumerate(curr_pic.alive):
        #         if abs(coords.x-click.x) < max_diff_x and abs(coords.y-click.y) < max_diff_y:
        #             del curr_pic.alive[ind]
        #             break
        #     for ind, coords in enumerate(curr_pic.dead):
        #         if abs(coords.x-click.x) < max_diff_x and abs(coords.y-click.y) < max_diff_y:
        #             del curr_pic.dead[ind]
        #             break
        self.refresh()
        event.accept()

    @pyqtSlot()
    def open_file(self):
        input_from = QFileDialog.getOpenFileName(self,
                                                 caption='Open File',
                                                 filter='Wyrmy Data (*.wyrm)')
        if len(input_from[0]) > 0:
            with open(input_from[0], 'rb') as reading:
                self.worms = pickle.load(reading)
                reading.close()
        self.refresh()

    @pyqtSlot()
    def save_file(self):
        output_at = QFileDialog.getSaveFileName(self,
                                                caption='Save File',
                                                filter='Wyrmy Data (*.wyrm)')
        if len(output_at[0]) > 0:
            with open(output_at[0], 'wb') as out:
                pickle.dump(self.worms, out)
                out.close()

    @pyqtSlot()
    def export_data(self):
        output_at = QFileDialog.getSaveFileName(
            self, caption='Save File', filter='CSV (Comma delimited) (*.csv)')
        if len(output_at[0]) > 0:
            out = open(output_at[0], 'a')
            out.write('Name,Alive,Dead\n')
            for name in self.file_names:
                curr = self.worms[Wyrmy.pic_name(name)]
                this_pic = str(curr.filename) + ',' + str(len(
                    curr.alive)) + ',' + str(len(curr.dead)) + '\n'
                out.write(this_pic)
            out.close()