예제 #1
0
class RadioBox(QWidget):
    def __init__(self, parent=None, items=None, spread=True, **kwargs):
        # If spread is False, insert a spacer in the layout so that the items don't use all the
        # space they're given but rather align left.
        if items is None:
            items = []
        super().__init__(parent, **kwargs)
        self._buttons = []
        self._labels = items
        self._selected_index = 0
        self._spacer = horizontalSpacer() if not spread else None
        self._layout = QHBoxLayout(self)
        self._update_buttons()

    # --- Private
    def _update_buttons(self):
        if self._spacer is not None:
            self._layout.removeItem(self._spacer)
        to_remove = self._buttons[len(self._labels):]
        for button in to_remove:
            self._layout.removeWidget(button)
            button.setParent(None)
        del self._buttons[len(self._labels):]
        to_add = self._labels[len(self._buttons):]
        for _ in to_add:
            button = QRadioButton(self)
            self._buttons.append(button)
            self._layout.addWidget(button)
            button.toggled.connect(self.buttonToggled)
        if self._spacer is not None:
            self._layout.addItem(self._spacer)
        if not self._buttons:
            return
        for button, label in zip(self._buttons, self._labels):
            button.setText(label)
        self._update_selection()

    def _update_selection(self):
        self._selected_index = max(
            0, min(self._selected_index,
                   len(self._buttons) - 1))
        selected = self._buttons[self._selected_index]
        selected.setChecked(True)

    # --- Event Handlers
    def buttonToggled(self):
        for i, button in enumerate(self._buttons):
            if button.isChecked():
                self._selected_index = i
                self.itemSelected.emit(i)
                break

    # --- Signals
    itemSelected = pyqtSignal(int)

    # --- Properties
    @property
    def buttons(self):
        return self._buttons[:]

    @property
    def items(self):
        return self._labels[:]

    @items.setter
    def items(self, value):
        self._labels = value
        self._update_buttons()

    @property
    def selected_index(self):
        return self._selected_index

    @selected_index.setter
    def selected_index(self, value):
        self._selected_index = value
        self._update_selection()
예제 #2
0
class RadioBox(QWidget):
    def __init__(self, parent=None, items=None, spread=True, **kwargs):
        # If spread is False, insert a spacer in the layout so that the items don't use all the
        # space they're given but rather align left.
        if items is None:
            items = []
        super().__init__(parent, **kwargs)
        self._buttons = []
        self._labels = items
        self._selected_index = 0
        self._spacer = horizontalSpacer() if not spread else None
        self._layout = QHBoxLayout(self)
        self._update_buttons()
    
    #--- Private
    def _update_buttons(self):
        if self._spacer is not None:
            self._layout.removeItem(self._spacer)
        to_remove = self._buttons[len(self._labels):]
        for button in to_remove:
            self._layout.removeWidget(button)
            button.setParent(None)
        del self._buttons[len(self._labels):]
        to_add = self._labels[len(self._buttons):]
        for _ in to_add:
            button = QRadioButton(self)
            self._buttons.append(button)
            self._layout.addWidget(button)
            button.toggled.connect(self.buttonToggled)
        if self._spacer is not None:
            self._layout.addItem(self._spacer)
        if not self._buttons:
            return
        for button, label in zip(self._buttons, self._labels):
            button.setText(label)
        self._update_selection()
    
    def _update_selection(self):
        self._selected_index = max(0, min(self._selected_index, len(self._buttons)-1))
        selected = self._buttons[self._selected_index]
        selected.setChecked(True)
    
    #--- Event Handlers
    def buttonToggled(self):
        for i, button in enumerate(self._buttons):
            if button.isChecked():
                self._selected_index = i
                self.itemSelected.emit(i)
                break
    
    #--- Signals
    itemSelected = pyqtSignal(int)
    
    #--- Properties
    @property
    def buttons(self):
        return self._buttons[:]
    
    @property
    def items(self):
        return self._labels[:]
    
    @items.setter
    def items(self, value):
        self._labels = value
        self._update_buttons()
    
    @property
    def selected_index(self):
        return self._selected_index
    
    @selected_index.setter
    def selected_index(self, value):
        self._selected_index = value
        self._update_selection()
예제 #3
0
class CPinUI(QWidget):
    def __init__(self, pinID, parent=None):
        super(CPinUI, self).__init__(parent)
        self.m_PinID = pinID
        self.m_NodeID = interface.GetNodeIDByPinID(pinID)
        self.m_GraphicID = interface.GetGraphicIDByNodeID(self.m_NodeID)
        self.m_Btn = None
        self.m_Label = None
        self.m_HLayout = None
        self.m_DefaultWidget = None  # 默认值控件
        self._InitUI()
        self.SetIcon()
        self.SetText()
        self.ShowDefaultWidget()
        GetUIMgr().AddPinUI(pinID, self)

    def __del__(self):
        GetUIMgr().DelPinUI(self.m_PinID)

    def _InitUI(self):
        hBox = QHBoxLayout(self)
        hBox.setContentsMargins(0, 0, 0, 0)
        hBox.setSpacing(6)
        self.m_Btn = CTypeButton(self.m_PinID, self)
        self.m_Label = QLabel(self)
        self.m_HLayout = QHBoxLayout()
        self.m_HLayout.setContentsMargins(0, 0, 0, 0)
        self.m_HLayout.setSpacing(6)
        hBox.addWidget(self.m_Btn)
        hBox.addWidget(self.m_Label)
        hBox.addLayout(self.m_HLayout)

    def contextMenuEvent(self, event):
        super(CPinUI, self).contextMenuEvent(event)
        lstLineID = interface.GetAllLineByPin(self.m_PinID)
        menu = QMenu()
        for lineID in lstLineID:
            oPinID = interface.GetLineOtherPin(lineID, self.m_PinID)
            sPinDisplayName = interface.GetPinAttr(oPinID, bddefine.PinAttrName.DISPLAYNAME)
            nodeID = interface.GetNodeIDByPinID(oPinID)
            sNodeDisplayName = interface.GetNodeAttr(nodeID, bddefine.NodeAttrName.DISPLAYNAME)
            sMsg = "删除与\"%s\"-\"%s\"的连线" % (sNodeDisplayName, sPinDisplayName)
            func = functor.Functor(interface.DelLine, lineID)
            menu.addAction(sMsg, func)
        menu.exec_(QCursor.pos())
        event.accept()

    def SetIcon(self, iDataType=None):
        if iDataType is None:
            iPinType = interface.GetPinAttr(self.m_PinID, bddefine.PinAttrName.PIN_TYPE)
            if bddefine.PinIsFlow(iPinType):
                iDataType = -1
            else:
                iDataType = interface.GetPinAttr(self.m_PinID, bddefine.PinAttrName.DATA_TYPE)
        icon = QIcon()
        pix = ":/icon/btn_%s.png" % iDataType
        icon.addPixmap(QPixmap(pix), QIcon.Normal, QIcon.Off)
        self.m_Btn.setIcon(icon)

    def SetText(self, sText=None):
        if sText is None:
            sText = interface.GetPinAttr(self.m_PinID, bddefine.PinAttrName.DISPLAYNAME)
        self.m_Label.setText(sText)

    def ShowDefaultWidget(self):
        iPinType = interface.GetPinAttr(self.m_PinID, bddefine.PinAttrName.PIN_TYPE)
        if iPinType != bddefine.PIN_INPUT_DATA_TYPE:
            return
        lstLine = interface.GetAllLineByPin(self.m_PinID)
        if lstLine:
            return
        oWidget = None
        iDataTye = interface.GetPinAttr(self.m_PinID, bddefine.PinAttrName.DATA_TYPE)
        if iDataTye in (bddefine.Type.INT, bddefine.Type.FLOAT, bddefine.Type.STR):
            oWidget = subpinui.CValidatorLineEdit(self.m_PinID, iDataTye)
        elif iDataTye == bddefine.Type.BOOL:
            oWidget = subpinui.CCheckBox(self.m_PinID)
        elif iDataTye == bddefine.Type.ENUM:
            oWidget = subpinui.CEnum(self.m_PinID)
        elif iDataTye == bddefine.Type.VECTOR3:
            oWidget = subpinui.CVector3(self.m_PinID)
        elif iDataTye == bddefine.Type.CHECKBOX:
            oWidget = subpinui.CComCheckBox(self.m_PinID)
        if oWidget:
            self.m_HLayout.addWidget(oWidget)
            self.m_DefaultWidget = oWidget
            self.adjustSize()

    def HideDefaultWidget(self):
        if not self.m_DefaultWidget:
            return
        self.m_DefaultWidget.setParent(None)
        index = self.m_HLayout.indexOf(self.m_DefaultWidget)
        item = self.m_HLayout.itemAt(index)
        self.m_HLayout.removeWidget(self.m_DefaultWidget)
        self.m_HLayout.removeItem(item)
        self.m_DefaultWidget = None
        self.adjustSize()

    def enterEvent(self, event):
        super(CPinUI, self).enterEvent(event)
        GetSignal().UI_LINE_CONNECT.emit(self.m_GraphicID, self.m_PinID)
        event.accept()
예제 #4
0
class SaveDataWindow(QWidget):
    def __init__(self, dest, schema, callback, parent=None):
        super(SaveDataWindow, self).__init__()

        self.dests = ["console", "text", "file", "database"]
        self.dest = dest
        self.schema = schema

        #Determine screen settings
        geo = self.frameGeometry()
        self.width = QDesktopWidget().availableGeometry().width()
        self.height = QDesktopWidget().availableGeometry().height()

        #Define window par meters
        self.resize(self.width * .5, self.height * .5)
        self.setWindowTitle("Aqueti Schema Editor")

        #
        self.mainLayout = QVBoxLayout()
        self.titleLayout = QHBoxLayout()
        self.destLayout = QHBoxLayout()

        #Create title
        title = QLabel()
        title.setText("Schema Saving Dialog")
        self.titleLayout.addWidget(title)
        self.mainLayout.addLayout(self.titleLayout)

        #Destination Layout
        self.destLayout = QHBoxLayout()
        self.mainLayout.addLayout(self.destLayout)

        #Add Button Layout
        self.buttonLayout = QHBoxLayout()
        self.submitButton = QPushButton("Save")
        self.submitButton.clicked.connect(lambda: self.saveButtonCallback())
        self.buttonLayout.addWidget(self.submitButton)
        cancelButton = QPushButton("Cancel")
        cancelButton.clicked.connect(lambda: self.cancelButtonCallback())
        self.buttonLayout.addWidget(cancelButton)
        self.mainLayout.addLayout(self.buttonLayout)
        self.setLayout(self.mainLayout)
        self.show()

        self.updateDestLayout()
        self.draw()

    ##
    # \brief updates the destinatino layout
    #
    def updateDestLayout(self):
        #Remove current layout information
        #Remove all widgets from the current layout
        while self.destLayout.count():
            item = self.destLayout.takeAt(0)
            self.destLayout.removeItem(item)
            widget = item.widget()
            if widget is not None:
                widget.deleteLater()
            try:
                item.deleteLater()
            except:
                pass

        #############################################
        # Layout to select a destination
        #############################################
        destTitle = QLabel()
        destTitle.setText("OutputType:")
        self.destCombo = QComboBox()
        self.destCombo.addItems(self.dests)

        #Find what our current dest is and set the appropriate index
        index = 0
        for i in range(0, self.destCombo.count()):
            if self.destCombo.itemText(i) == self.dest["type"]:
                index = i

        self.destCombo.setCurrentIndex(index)

        self.destLayout.addWidget(destTitle)
        self.destLayout.addWidget(self.destCombo)

        ####
        # Fill in details base on source tpye
        ####
        if self.dest["type"] == "console":
            pass
        elif self.dest["type"] == "file":
            fileLabel = QLabel()
            fileLabel.setText("file: ")

            try:
                name = self.dest["filename"]
            except:
                name = ""

            self.fileNameBox = QLineEdit()
            self.fileNameBox.setText(name)

            self.destLayout.addWidget(fileLabel)
            self.destLayout.addWidget(self.fileNameBox)

    ##
    # \brief Function to draw the object
    def draw(self):

        #Add a submitDest Button
        selectDestButton = QPushButton("Select")
        selectDestButton.currentIndexChanged.connect(
            lambda: self.destChangeCallback())

        self.destLayout.addWidget(destTitle)
        self.destLayout.addWidget(self.destCombo)
        self.destLayout.addWidget(selectDestButton)

        self.destLayout.addLayout(self.destLayout)

    ##
    # \brief callback for the Cancel button
    #
    def cancelButtonCallback(self):
        self.close()

    ##
    # \brief callback for a save button press
    #
    def saveButtonCallback(self):
        print("Saving:" + str(self.dest))

        if self.dest["type"] == "console":
            print()
            print("Schema (" + str(time.time()) + ")")
            print(str(self.schema))

        elif self.dest["type"] == "file":
            with open(self.dest["filename"], 'w') as outfile:
                json.dump(self.schema, outfile)
        else:
            print("Source type: " + str(self.dest["type"]) +
                  " is not currently supported")

        self.close()
예제 #5
0
class mywindow(QtWidgets.QMainWindow):

    def __init__(self):
        super(mywindow, self).__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.numberShapes = 0
        self.dict = {2: 1, 0: -1}
        self.cb = []
        self.layouts = []
        self.spasers = []
        self.layout = QHBoxLayout()
        self.sp = QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding,
                                QtWidgets.QSizePolicy.Minimum)
        self.hopfieldnet = HopfieldNet(SHAPE_SIDE_HEIGHT, SHAPE_SIDE_WIDHT)
        self.create_ui()

    def create_ui(self):
        gb = QGroupBox()
        gb.setLayout(self.layout)
        self.layout.addItem(self.sp)

        self.ui.scrollArea.setWidget(gb)
        self.ui.scrollArea.setWidgetResizable(True)
        self.ui.scrollArea.setFixedHeight((SHAPE_SIDE_HEIGHT + 2) * 30)

        self.ui.incorrect_share.addLayout(self.Add_Shape('Incorrect'))
        self.ui.correct_share.addLayout(self.Add_Shape('Reshare'))

        self.ui.save.clicked.connect(self.Save)
        self.ui.recognize.clicked.connect(self.Recognize)
        self.ui.recognize.setEnabled(False)
        self.ui.delete_shape.clicked.connect(self.Delete_Shape)
        self.ui.add_shape.clicked.connect(self.Add_Learned_Shape)

        for _ in range(3):
            self.Add_Learned_Shape()

    def Add_Shape(self, name):
        grid = QGridLayout()
        l1 = QLabel(name)
        l1.setFont(QtGui.QFont("SansSerif", 11))
        grid.addWidget(l1, 0, 0, 1, 3)
        cb1 = [QCheckBox('', self) for _ in range(SHAPE_SIDE_HEIGHT * SHAPE_SIDE_WIDHT)]
        _ = [cb.setFixedSize(20, 20) for cb in cb1]
        for i in range(len(cb1)):
            grid.addWidget(cb1[i], i // SHAPE_SIDE_WIDHT + 1, i % SHAPE_SIDE_WIDHT)
        self.cb.append(cb1)
        self.layouts.append(grid)
        return grid

    def Add_Learned_Shape(self):
        self.numberShapes += 1
        self.layout.removeItem(self.sp)
        if self.numberShapes > 1:
            sp = QSpacerItem(40, 20, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Minimum)
            self.spasers.append(sp)
            self.layout.addItem(sp)
        l1 = QLabel(f'{self.numberShapes} share')
        l1.setFont(QtGui.QFont("SansSerif", 11))
        self.layout.addLayout(self.Add_Shape(f"{self.numberShapes} shape"))
        self.layout.addItem(self.sp)

    def Save(self):
        self.hopfieldnet.clear()
        for i in range(2, len(self.cb)):
            tmp = [self.dict[check.checkState()] for check in self.cb[i]]
            if 1 in tmp:
                self.hopfieldnet.teach(tmp)
        if len(self.hopfieldnet.shapes):
            self.ui.recognize.setEnabled(True)

    def Recognize(self):
        redict = {1: 2, -1: 0}
        rezult, reshare = self.hopfieldnet.recognize([self.dict[check.checkState()] for check in self.cb[0]])
        _ = [checkbox.setCheckState(redict[reshare[i]]) for i, checkbox in enumerate(self.cb[1])]
        self.ui.status.setText(rezult)
        self.ui.status.setFont(QtGui.QFont("SansSerif", 16))
        self.ui.status.setStyleSheet(f"color: {'red' if rezult == 'Failed' else 'green'}")

    def Delete_Shape(self):
        if self.numberShapes < 3:
            return
        self.numberShapes -= 1
        self.cb.pop()
        for i in reversed(range(self.layouts[-1].count())):
            self.layouts[-1].itemAt(i).widget().deleteLater()
        self.layout.removeItem(self.layouts[-1])
        self.layout.removeItem(self.spasers[-1])
        self.spasers.pop()
        self.layouts.pop()
예제 #6
0
class Game(QWidget):
    add_number_signal = pyqtSignal(tuple)
    pop_number_signal = pyqtSignal()
    rotate_signal = pyqtSignal()

    def __init__(self):
        super().__init__()
        self.move(20, 20)
        self.hbox = QHBoxLayout()
        self.grid = Grid(self)
        self.vbox = QVBoxLayout()
        self.actual_piece = Piece("blank", self)
        self.rotate_button = QPushButton('Rotar', self)
        self.end_game_button = QPushButton('Terminar Juego', self)
        self.back_button = QPushButton('Retroceder', self)
        self.save_button = QPushButton('Guardar', self)
        self.state_grid = StateGrid(self)
        self.p1_points = QLabel(self)
        self.p2_points = QLabel(self)
        self.set_points(1, 0)
        self.set_points(2, 0)

    def initUi(self):
        self.setWindowTitle('Best Tarea Ever :P')
        self.setMouseTracking(True)
        self.setLayout(self.hbox)
        self.hbox.addStretch(1)
        self.hbox.addWidget(self.grid)
        self.hbox.addStretch(1)
        self.hbox.addLayout(self.vbox)
        self.hbox.addStretch(1)
        self.grid.show()
        self.piece_layout = QHBoxLayout(self)
        self.piece_layout.addStretch(1)
        self.piece_layout.addWidget(self.actual_piece)
        self.piece_layout.addStretch(1)
        self.vbox.addStretch(1)
        self.vbox.addLayout(self.piece_layout)
        self.vbox.addStretch(1)
        hlayout = QHBoxLayout(self)
        self.vbox.addLayout(hlayout, 1)
        hlayout.addWidget(self.save_button, 1)
        hlayout.addWidget(self.rotate_button, 1)
        hlayout.addWidget(self.end_game_button, 1)
        hlayout.addWidget(self.back_button, 1)
        self.vbox.addStretch(1)
        self.vbox.addWidget(self.state_grid, 1)
        hlayout_points = QHBoxLayout(self)
        self.vbox.addLayout(hlayout_points, 1)
        self.p1_points.show()
        self.p2_points.show()
        hlayout_points.addWidget(self.p1_points)
        hlayout_points.addWidget(self.p2_points)
        self.rotate_button.clicked.connect(self.rotate_piece)
        self.back_button.clicked.connect(self.back_move)
        self.end_game_button.clicked.connect(self.end_game)
        self.save_button.clicked.connect(self.save_game)
        self.add_number_signal.connect(self.state_grid.add_number)
        self.pop_number_signal.connect(self.state_grid.pop_number)
        self.rotate_signal.connect(self.rotate_piece)
        self.grid.initUI()
        self.new_piece()

    @staticmethod
    def back_move():
        variables.GAME_INTERFACE.retroceder()

    @staticmethod
    def end_game():
        variables.GAME_INTERFACE.terminar_juego()

    @staticmethod
    def save_game():
        variables.GAME_INTERFACE.guardar_juego()

    def user_rotate(self):
        self.rotate_signal.emit()

    def add_number(self, number, color):
        self.add_number_signal.emit((number, color))

    def pop_number(self):
        self.pop_number_signal.emit()

    def new_piece(self, color=None, piece_type=None):
        if piece_type is None:
            piece_type = choice(variables.TYPES)
        if color is None and piece_type != "hint":
            color = choice(variables.COLORS)
        self.piece_layout.removeItem(self.piece_layout.itemAt(2))
        self.piece_layout.removeWidget(self.actual_piece)
        self.actual_piece.hide()
        self.actual_piece.deleteLater()
        self.actual_piece = Piece(piece_type, color, self)
        self.piece_layout.addWidget(self.actual_piece)
        self.piece_layout.addStretch(1)

    def addPiece(self, i, j, color=None, piece_type=None, on_move_ended=None):
        if piece_type is None:
            self.grid.addPiece(i, j, self.actual_piece, on_move_ended)
        elif piece_type == 'blank' or piece_type == 'hint':
            self.grid.addPiece(i, j, Piece(piece_type, color, self.grid))
        else:
            raise TypeError('No es un tipo valido')

    def getPiece(self, i, j):
        return self.grid.getPiece(i, j)

    def popPiece(self, i, j):
        pop_piece = self.grid.popPiece(i, j)
        self.addPiece(i, j, piece_type='blank')
        return pop_piece

    def movePiece(self, i, j, piece, on_move_end=None):
        self.grid.movePiece(i, j, piece, on_move_end)

    def set_points(self, player_numb, points):
        # self.label_puntaje.setText(str(points))
        if player_numb == 1:
            self.p1_points.setText("Jugador 1: {}".format(points))
        elif player_numb == 2:
            self.p2_points.setText("Jugador 2: {}".format(points))

    def rotate_piece(self):
        self.actual_piece.rotate()
        variables.GAME_INTERFACE.rotar_pieza('Derecha')

    def keyPressEvent(self, event):
        if event.key() == Qt.Key_H:
            variables.GAME_INTERFACE.hint_asked()
예제 #7
0
class MainWindow(QWidget):
    ##
    # \brief Initialization Function
    def __init__(self):
        super(MainWindow, self).__init__()

        #Default variables
        self.valid = False  #Field to determine if the value is valid
        self.selectorLayout = None  #Layout used for selecting a specific source
        self.sources = ["none", "text", "file", "database"]
        self.source = {"type": None}
        self.dests = ["console", "file"]
        self.dest = {"type": "console"}

        self.sourceValue = None
        self.sourceSchema = None

        #Determine screen settings
        geo = self.frameGeometry()
        self.width = QDesktopWidget().availableGeometry().width()
        self.height = QDesktopWidget().availableGeometry().height()

        #Define window par meters
        self.resize(self.width * .5, self.height * .5)
        self.setWindowTitle("Aqueti Schema Editor")
        self.show()

        #create Layouts in UI
        self.titleLayout = QHBoxLayout()
        self.mainLayout = QVBoxLayout()
        self.sourceLayout = QHBoxLayout()
        self.destLayout = QHBoxLayout()
        self.valueLayout = QVBoxLayout()
        self.buttonLayout = QHBoxLayout()

        #Create frames
        self.sourceFrame = QFrame()
        self.destFrame = QFrame()
        self.valueFrame = QFrame()
        self.sourceFrame.setFrameStyle(QFrame.Box)
        self.valueFrame.setFrameStyle(QFrame.Box)
        self.destFrame.setFrameStyle(QFrame.Box)

        self.sourceFrame.setLayout(self.sourceLayout)
        self.destFrame.setLayout(self.destLayout)
        self.valueFrame.setLayout(self.valueLayout)
        self.valueFrame.setSizePolicy(QSizePolicy.Expanding,
                                      QSizePolicy.Expanding)

        #Create Scoll Area for valueFrame
        self.valueScrollArea = QScrollArea()
        self.valueScrollArea.updateGeometry()
        self.valueScrollArea.setWidget(self.valueFrame)
        self.valueScrollArea.setWidgetResizable(True)

        #Create title
        title = QLabel()
        title.setText("Aqueti Schema Editor")
        self.titleLayout.addWidget(title)

        #Add persistent source items
        sourceTitle = QLabel()
        sourceTitle.setText("Source:")
        self.sourceCombo = QComboBox()
        self.sourceCombo.addItems(self.sources)
        self.sourceCombo.currentTextChanged.connect(
            lambda: self.sourceChangeCallback())
        selectSourceButton = QPushButton("Load")
        self.sourceLayout.addWidget(sourceTitle)
        self.sourceLayout.addWidget(self.sourceCombo)

        self.sourceMetaLayout = QHBoxLayout()
        self.sourceMetaLayout.setSizeConstraint(QHBoxLayout.SetMinimumSize)
        self.sourceLayout.addLayout(self.sourceMetaLayout)
        self.sourceLayout.addWidget(selectSourceButton)

        #Add persistent dest
        destTitle = QLabel()
        destTitle.setText("Dest:")
        self.destCombo = QComboBox()
        self.destCombo.addItems(self.dests)
        self.destCombo.currentTextChanged.connect(
            lambda: self.destChangeCallback())
        selectDestButton = QPushButton("Load")
        self.destLayout.addWidget(destTitle)
        self.destLayout.addWidget(self.destCombo)

        self.destMetaLayout = QHBoxLayout()
        self.destMetaLayout.setSizeConstraint(QHBoxLayout.SetMinimumSize)
        self.destLayout.addLayout(self.destMetaLayout)
        self.destLayout.addWidget(selectDestButton)

        #Add Submit Button
        self.submitButton = QPushButton("Submit")
        self.submitButton.clicked.connect(lambda: self.submitCallback())
        self.buttonLayout.addWidget(self.submitButton)

        #Add cancel Button
        cancelButton = QPushButton("Cancel")
        cancelButton.clicked.connect(lambda: self.cancelCallback())
        self.buttonLayout.addWidget(cancelButton)

        #Add Layouts and draw
        self.mainLayout.addLayout(self.titleLayout)
        self.mainLayout.addWidget(self.sourceFrame)
        self.mainLayout.addWidget(self.destFrame)

        #        self.mainLayout.addWidget( self.valueFrame )
        self.mainLayout.addWidget(self.valueScrollArea)
        #        self.mainLayout.addStretch(1)
        self.mainLayout.addLayout(self.buttonLayout)
        self.draw()

    ##
    # \brief updates the source Layout
    def updateSourceLayout(self):
        #Remove current layout information
        #Remove all widgets from the current layout
        while self.sourceMetaLayout.count():
            item = self.sourceMetaLayout.takeAt(0)
            self.sourceMetaLayout.removeItem(item)
            widget = item.widget()
            if widget is not None:
                widget.deleteLater()
            try:
                item.deleteLater()
            except:
                pass

        #Find what our current source is and set the appropriate index
        index = 0
        for i in range(0, self.sourceCombo.count()):
            if self.sourceCombo.itemText(i) == self.source["type"]:
                index = i

        self.sourceCombo.setCurrentIndex(index)

        #Add fields based on source type
        if self.source["type"] == "file":
            #Add filename
            fileLabel = QLabel()
            fileLabel.setText("file: ")

            try:
                name = self.source["filename"]
            except:
                name = ""

            self.sourceFilenameBox = QLineEdit()
            self.sourceFilenameBox.setSizePolicy(QSizePolicy.Expanding,
                                                 QSizePolicy.Minimum)
            self.sourceFilenameBox.setText(name)
            #            self.sourceFilenameBox.readOnly = True
            #            self.sourceFilenameBox.sizeHint()
            #            self.sourceFilenameBox.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding)

            self.sourceMetaLayout.addWidget(fileLabel)
            self.sourceMetaLayout.addWidget(self.sourceFilenameBox)

#        #Add a submitSource Button
#        selectSourceButton = QPushButton("Load")
#        selectSourceButton.clicked.connect( lambda: self.sourceChangeCallback())

#        self.sourceLayout.addWidget(selectSourceButton)

#        self.sourceLayout.addStretch(1)

##
# \brief updates the destination layout
#

    def updateDestLayout(self):
        #Remove current layout information
        #Remove all widgets from the current layout
        while self.destMetaLayout.count():
            item = self.destMetaLayout.takeAt(0)
            self.destMetaLayout.removeItem(item)
            widget = item.widget()
            if widget is not None:
                widget.deleteLater()
            try:
                item.deleteLater()
            except:
                pass
        """
        #############################################
        # Layout to select a destination
        #############################################
        destTitle = QLabel()
        destTitle.setText("Dest:")
        self.destCombo = QComboBox()
        self.destCombo.addItems(self.dests)
        """

        #Find what our current dest is and set the appropriate index
        index = 0
        for i in range(0, self.destCombo.count()):
            if self.destCombo.itemText(i) == self.dest["type"]:
                index = i

        self.destCombo.setCurrentIndex(index)
        self.destCombo.currentTextChanged.connect(
            lambda: self.destChangeCallback())

        #        self.destLayout.addWidget(destTitle)
        #        self.destLayout.addWidget(self.destCombo)
        #        self.destLayout.addStretch(1)

        ####
        # Fill in details base on dest tpye
        ####
        if self.dest["type"] == "console":
            pass
        elif self.dest["type"] == "file":
            fileLabel = QLabel()
            fileLabel.setText("file: ")

            try:
                name = self.dest["filename"]
            except:
                name = ""

            self.fileNameBox = QLineEdit()
            self.fileNameBox.setText(name)

            #            self.destMetaLayout.addWidget(fileLabel)
            self.destMetaLayout.addWidget(self.fileNameBox)

    ##
    # \brief function that is called when the source is changed
    #
    def destChangeCallback(self):
        print("Changing dest")

        newType = self.destCombo.itemText(self.destCombo.currentIndex())

        print("New Type: " + str(newType))

        if newType != self.dest["type"]:
            self.dest = {}

        self.dest["type"] = newType

        if self.dest["type"] == "console":
            pass

        elif self.dest["type"] == "file":
            options = QFileDialog.Options()
            options |= QFileDialog.DontUseNativeDialog
            destName, _ = QFileDialog.getSaveFileName(
                self,
                "QFileDialog.getSaveFileName()",
                "",
                "All Files (*);;JSON Files (*.json)",
                options=options)

            self.dest["filename"] = str(destName)

        else:
            print("Unsupported Type")

        self.draw()

    ##
    # \brief Update the value layout
    def updateValueLayout(self):
        #Remove all widgets from the current layout
        while self.valueLayout.count():
            item = self.valueLayout.takeAt(0)
            self.valueLayout.removeItem(item)
            widget = item.widget()
            if widget is not None:
                widget.deleteLater()
            try:
                item.deleteLater()
            except:
                pass

        #If we have data, let's display it
        if self.sourceSchema != None:

            valueTitle = QLabel()
            valueTitle.setText("Schema")

            self.schemaWidget = SmartWidget().init("Schema",
                                                   self.sourceValue,
                                                   self.sourceSchema,
                                                   showSchema=False)
            self.valueLayout.addWidget(self.schemaWidget.frame)

        #Disable the submit button if we don't have a schema
        if self.sourceSchema == None:
            self.submitButton.setEnabled(False)
        else:
            self.submitButton.setEnabled(True)

        self.setLayout(self.mainLayout)

    ##
    # \brief redraws all dynamic layouts
    def draw(self):
        self.updateDestLayout()
        self.updateSourceLayout()
        self.updateValueLayout()

    ##
    # \brief callback for when the source type changes
    #
    def sourceChangeCallback(self):

        #SDF Add popup to notify of schema loss

        #Clear the schema to disable the submit button
        self.sourceSchema = None
        self.source["type"] = self.sourceCombo.itemText(
            self.sourceCombo.currentIndex())

        if self.source["type"] == "none":
            self.sourceSchema = {"bsonType": "object"}

        #If we are a file  read the file contents as the value
        elif self.source["type"] == "file":
            options = QFileDialog.Options()
            options |= QFileDialog.DontUseNativeDialog
            sourceName, _ = QFileDialog.getOpenFileName(
                self,
                "QFileDialog.getOpenFileName()",
                "",
                "All Files (*);;JSON Files (*.json)",
                options=options)

            self.source["filename"] = str(sourceName)
            print("Loading: " + str(self.source["filename"]))

            with open(self.source["filename"]) as json_file:
                self.sourceSchema = json.load(json_file)

            print("Loaded Schema:" +
                  str(json.dumps(self.sourceSchema, indent=4)))

        self.updateSourceLayout()
        self.updateValueLayout()

    ##
    #\brief callback to get result from SmartWidget
    #
    # This function assumes that the schema is done. It will produce a popup
    # asking where and how to save the data
    #
    def submitCallback(self):
        schema = self.schemaWidget.getSchema()

        if self.dest["type"] == "console":
            print()
            print("Schema: (" + str(time.time()) + ")")
            print(json.dumps(schema, indent=4))

        elif self.dest["type"] == "file":
            print("Writing to: " + str(self.dest["filename"]))
            with open(self.dest["filename"], 'w') as outfile:
                json.dump(schema, outfile, indent=4)
        else:
            print("Source type: " + str(self.dest["type"]) +
                  " is not currently supported")

        self.close()

        #Use save pop-up to save data
        #self.saveWindow = SaveDataWindow(self.source, schema, self.saveCallback )

        print(str(time.time()) + "- schema:")
        print(str(schema))

    ##
    # \brief Function called after data is saved
    #
    def saveCallback(self, success):
        print("Data Result: " + str(success))

    ##
    # \brief Cancels the change and exits
    #
    def cancelCallback(self):
        print("Exited. No changes were saved")
        sys.exit(1)
예제 #8
0
class OptionsBar(QWidget):
    def __init__(self, task_widget):
        super().__init__(task_widget)
        self.task_widget = task_widget
        self.area = None
        self.options = []
        self.v_options = []
        self.buttons = []
        self.layout = QHBoxLayout()
        self.layout.setSizeConstraint(QLayout.SetFixedSize)
        self.setLayout(self.layout)

    def with_area(self):
        self.area = AreaOptions()
        self.layout.addLayout(self.area)

        return self

    def with_int_options_v(self,
                           top=1,
                           bottom=10,
                           top_name='α',
                           bottom_name='β',
                           min=-10000):
        v_option = VerticalIntOption(top, bottom, top_name, bottom_name, min)

        self.v_options.append(v_option)
        self.layout.addLayout(v_option)

        return self

    def with_int_option(self, name, default=0, min=-10000, max=10000):
        option = IntOption(name, default, min, max)

        self.options.append(option)
        self.layout.addLayout(option)

        return self

    def with_button(self, name, callback):
        button = QPushButton(name, self)
        button.clicked.connect(callback)

        self.buttons.append(button)
        self.layout.addWidget(button)

        return self

    def with_image(self, path):
        pixmap = QPixmap(path)
        label = QLabel()
        label.setPixmap(pixmap)

        self.layout.addWidget(label)

        return self

    def clear(self):
        self.options = []
        self.v_options = []
        self.buttons = []
        for i in range(self.layout.count() - 1, -1, -1):
            item = self.layout.takeAt(i)
            self.layout.removeItem(item)
예제 #9
0
class App(QWidget):
    def __init__(self, controller):
        super().__init__()
        self.controller = controller

        self.window_edit = QComboBox()
        self.batch_edit = QComboBox()
        self.epochs_edit = QComboBox()
        self.eta_edit = QComboBox()
        self.layers_edit = QComboBox()
        self.layers = []
        self.nb_neurons = ['15', '25', '50', '100']
        self.train_button = QPushButton()
        self.layers_box = QHBoxLayout()

        self.init_UI()

    def init_UI(self):
        self.setFont(QFont("Arial", 18))
        info_label = QLabel(
            'This is an application for predicting protein secondary structure '
            +
            'using an artificial neural network. Please select the desired parameters '
            + 'and then train the network.')
        info_label.setWordWrap(True)

        # parameter labels and combo boxes
        window = QLabel('Window size')
        batch = QLabel('Batch size')
        epochs = QLabel('Number of epochs')
        eta = QLabel('Learning rate')
        layers = QLabel('Number of hidden layers')

        self.window_edit.addItems(['11', '13', '15', '25'])
        self.batch_edit.addItems(['50', '100', '200'])
        self.epochs_edit.addItems(['100', '1000', '5000', '10000'])
        self.eta_edit.addItems(['0.01', '0.02', '0.03'])
        self.layers_edit.addItems(['1', '2', '3', '4'])

        # add labels and combo boxes into grid layout
        params_box = QVBoxLayout()
        grid = QGridLayout()
        grid.setContentsMargins(10, 20, 20, 20)
        grid.addWidget(window, 1, 0)
        grid.addWidget(self.window_edit, 1, 1)
        grid.addWidget(batch, 2, 0)
        grid.addWidget(self.batch_edit, 2, 1)
        grid.addWidget(epochs, 3, 0)
        grid.addWidget(self.epochs_edit, 3, 1)
        grid.addWidget(eta, 4, 0)
        grid.addWidget(self.eta_edit, 4, 1)
        grid.addWidget(layers, 5, 0)
        grid.addWidget(self.layers_edit, 5, 1)
        params_box.addWidget(info_label)
        params_box.addLayout(grid)

        # layout for the button and hidden layers
        self.train_button.setText('Train network')
        self.train_button.clicked.connect(self.train_and_evaluate)
        self.layers_box.addWidget(self.train_button)
        self.create_layers_layout()

        # add parameters layout and layers layout to the overall layout
        general_box = QVBoxLayout()
        general_box.addLayout(params_box)
        general_box.addLayout(self.layers_box)
        self.layers_edit.currentIndexChanged.connect(self.create_layers_layout)

        self.setLayout(general_box)
        self.setGeometry(100, 100, 800, 500)
        self.setWindowIcon(QIcon('protein.png'))
        self.setWindowTitle('Secondary Structure Prediction')
        self.show()

    def create_layers_layout(self):
        layer_count = int(self.layers_edit.currentText())  # layers to be shown
        layers_on_window = len(self.layers)  # layers already shown
        # add new layout for more layers
        if layers_on_window < layer_count:
            for i in range(layers_on_window + 1, layer_count + 1):
                new_layer_neurons = QComboBox()
                self.layers.append(new_layer_neurons)
                new_layer_neurons.addItems(self.nb_neurons)
                new_layer = QVBoxLayout()
                new_label = QLabel('Layer ' + str(i) + ':')
                new_layer.addWidget(new_label)
                new_layer.addWidget(new_layer_neurons)
                self.layers_box.addLayout(new_layer)
        else:
            # remove layouts for less layers
            for j in range(layers_on_window, layer_count, -1):
                layout_item = self.layers_box.itemAt(j)
                # remove all the widgets from this layout
                while layout_item.count():
                    item = layout_item.takeAt(0)
                    widget = item.widget()
                    if widget is not None:
                        widget.setParent(None)
                self.layers_box.removeItem(layout_item)
                self.layers.pop()

    def train_and_evaluate(self):
        window_size = int(self.window_edit.currentText())
        batch_size = int(self.batch_edit.currentText())
        epochs = int(self.epochs_edit.currentText())
        learning_rate = float(self.eta_edit.currentText())
        hidden_layers = []
        for layer in self.layers:
            hidden_layers.append(int(layer.currentText()))
        ann = self.controller.ann
        self.controller = Controller(ann, window_size, batch_size, epochs,
                                     learning_rate, hidden_layers)
        self.controller.train_and_evaluate()
        self.enter_protein = EvaluateProtein(self.controller)
        self.enter_protein.show()
예제 #10
0
class KeyboardStatusWidget(QWidget):
    updateStatusSignal = pyqtSignal(list, list, list)

    def __init__(self):
        super(KeyboardStatusWidget, self).__init__()
        self.updateStatusSignal.connect(self.onUpdateStatus)
        self.hlayout = QHBoxLayout()
        self.hlayout.setAlignment(Qt.AlignLeft)
        self.items = []
        self.hlayout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(self.hlayout)

    def addPlusLabel(self):
        label = QLabel()
        label.setContentsMargins(5, 5, 5, 5)
        label.setAlignment(Qt.AlignVCenter)
        fontsize = 10
        label.setText(
            "<font size='{fontsize}'>+</font>".format(fontsize=fontsize))
        item = QVBoxLayout()
        item.addWidget(label)
        self.items.append(item)
        self.hlayout.addLayout(item)

    def onUpdateStatus(self, keys, modifiers, unknown_keys):
        def layout_del_inner(layout):
            for i in reversed(range(layout.count())):
                layout.itemAt(i).widget().setParent(None)

        for item in self.items:
            self.hlayout.removeItem(item)
            layout_del_inner(item)
        self.items = []
        for i in range(len(keys)):
            key = keys[i]
            label = QLabel()
            label.setContentsMargins(5, 5, 5, 5)
            label.setAlignment(Qt.AlignVCenter)
            fontsize = 10
            label.setText(
                "<font style='font-weight:bold;' size='{fontsize}'>{text}</font>"
                .format(text=key, fontsize=fontsize))
            item = QVBoxLayout()
            item.addWidget(label)
            self.items.append(item)
            self.hlayout.addLayout(item)
            if i + 1 != len(keys) or len(modifiers) > 0:
                self.addPlusLabel()

        for i in range(len(modifiers)):
            mod = modifiers[i]
            label = QLabel()
            label.setContentsMargins(5, 5, 5, 5)
            label.setAlignment(Qt.AlignVCenter)
            fontsize = 10
            label.setText(
                "<font style='font-weight:bold;' size='{fontsize}'>{text}</font>"
                .format(text=mod, fontsize=fontsize))
            item = QVBoxLayout()
            item.addWidget(label)
            self.items.append(item)
            self.hlayout.addLayout(item)
            if i + 1 != len(modifiers) or len(unknown_keys) > 0:
                self.addPlusLabel()

        for i in range(len(unknown_keys)):
            key = unknown_keys[i]
            label = QLabel()
            label.setContentsMargins(5, 5, 5, 5)
            label.setAlignment(Qt.AlignVCenter)
            fontsize = 10
            label.setText(
                "<font style='font-weight:bold;color:darkred;' size='{fontsize}'>{text}</font>"
                .format(text="??(0x{:02x})".format(key), fontsize=fontsize))
            item = QVBoxLayout()
            item.addWidget(label)
            self.items.append(item)
            self.hlayout.addLayout(item)
            if i + 1 != len(unknown_keys):
                self.addPlusLabel()
예제 #11
0
class UserWindow(QDialog):

    columnLabel = None
    columnTable = None
    userButtons = None
    windowButtons = None

    userButtonBox = None
    windowButtonBox = None

    mainLayout = None
    leftLayout = None
    rightLayout = None
    initLayout = None

    userGeneral = None
    userFolders = None

    userPage = None

    addUserDialog = None

    buttonAdd = None
    buttonRemove = None

    def __init__(self):
        super(UserWindow, self).__init__()
        self.setModal(True)
        self.setWindowTitle('Settings')
        self.setFixedSize(600, 400)

        self.userPage = UserPage()
        self.initLayout = FirstPage()

        self.initUi()
        self.initSetting()

    def initUi(self):
        self.initColumnLabel()
        self.initColumnTable()
        self.initUserButtons()
        self.initWindowButtons()

        self.leftLayout = QVBoxLayout()
        self.leftLayout.addStretch()
        self.leftLayout.addWidget(self.columnLabel)
        self.leftLayout.addWidget(self.columnTable)
        self.leftLayout.addWidget(self.userButtonBox)
        self.leftLayout.addWidget(self.windowButtonBox)

        self.rightLayout = self.initLayout

        self.mainLayout = QHBoxLayout()
        self.mainLayout.addLayout(self.leftLayout)
        self.mainLayout.addLayout(self.rightLayout)
        self.mainLayout.setStretchFactor(self.leftLayout, 1)
        self.mainLayout.setStretchFactor(self.rightLayout, 2)

        self.setLayout(self.mainLayout)

    def initColumnLabel(self):
        self.columnLabel = QLabel('Users:')

    def initColumnTable(self):
        self.columnTable = QTableWidget()
        self.columnTable.setColumnCount(1)
        self.columnTable.setRowCount(0)
        self.columnTable.verticalHeader().setHidden(True)
        self.columnTable.horizontalHeader().setHidden(True)
        self.columnTable.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.columnTable.setSelectionMode(QAbstractItemView.SingleSelection)

        self.columnTable.itemClicked.connect(self.itemClickedTriggered)

    def itemClickedTriggered(self):
        self.mainLayout.removeItem(self.rightLayout)

        self.rightLayout.accountSettingBox.close()
        self.rightLayout.sharedFolderBox.close()

        for index in range(self.columnTable.rowCount()):
            item = self.columnTable.item(index, 0)
            if item.isSelected():
                self.rightLayout = item.page
                break

        self.mainLayout.addLayout(self.rightLayout)
        self.mainLayout.setStretchFactor(self.leftLayout, 1)
        self.mainLayout.setStretchFactor(self.rightLayout, 2)
        self.rightLayout.accountSettingBox.show()
        self.rightLayout.sharedFolderBox.show()

    def initUserButtons(self):
        self.userButtonBox = QGroupBox()

        self.buttonAdd = QPushButton('Add')
        self.buttonRemove = QPushButton('Remove')
        self.buttonRemove.setEnabled(False)

        self.buttonAdd.clicked.connect(self.addTriggered)
        self.buttonRemove.clicked.connect(self.removeTriggered)

        subLayout = QHBoxLayout()
        subLayout.addWidget(self.buttonAdd)
        subLayout.addWidget(self.buttonRemove)

        self.userButtonBox.setLayout(subLayout)

    def addTriggered(self):
        self.addUserDialog = addDialog()
        self.addUserDialog.userOKButton.clicked.connect(self.addOKTriggered)
        self.addUserDialog.userCancelButton.clicked.connect(
            self.addCancelTriggered)
        self.addUserDialog.exec()

        name = self.addUserDialog.userNameEdit

    def addOKTriggered(self):
        name = self.addUserDialog.userNameEdit.text()

        icon = QPixmap('resource/fail.png')
        if name == '':
            box1 = QMessageBox()
            box1.setText('Please enter a name.')
            box1.setIconPixmap(icon.scaled(100, 100))
            box1.exec()
            return

        for index in range(self.columnTable.rowCount()):
            item = self.columnTable.item(index, 0)
            if name == item.text():
                box2 = QMessageBox()
                box2.setText('User %s has existed.' % name)
                box2.setIconPixmap(icon.scaled(100, 100))
                box2.exec()
                return

        nameItem = NewTypeItem()
        nameItem.setText(name)
        nameItem.page.sharedFolderEdit.setText('/%s' % name)

        self.columnTable.setRowCount(self.columnTable.rowCount() + 1)
        self.columnTable.setItem(self.columnTable.rowCount() - 1, 0, nameItem)

        self.addUserDialog.close()

        self.buttonRemove.setEnabled(True)

    def addCancelTriggered(self):
        self.addUserDialog.close()

    def removeTriggered(self):
        for index in range(self.columnTable.rowCount()):
            item = self.columnTable.item(index, 0)
            if item.isSelected():
                self.columnTable.removeRow(index)
                if self.columnTable.rowCount() == 0:
                    self.buttonRemove.setEnabled(False)
                    break

        self.mainLayout.removeItem(self.rightLayout)
        self.rightLayout.accountSettingBox.close()
        self.rightLayout.sharedFolderBox.close()

        self.rightLayout = self.initLayout
        self.mainLayout.addLayout(self.rightLayout)
        self.rightLayout.accountSettingBox.show()
        self.rightLayout.sharedFolderBox.show()

    def initWindowButtons(self):
        self.windowButtonBox = QGroupBox()

        buttonOK = QPushButton('OK')
        buttonCancel = QPushButton('Cancel')

        buttonOK.clicked.connect(self.okTriggered)
        buttonCancel.clicked.connect(self.cancelTriggered)

        subLayout = QVBoxLayout()
        subLayout.addWidget(buttonOK)
        subLayout.addWidget(buttonCancel)

        self.windowButtonBox.setLayout(subLayout)

    def okTriggered(self):
        self.updateSetting()

        msg = SettingMessage()
        msg.exec()

        self.close()

    def cancelTriggered(self):
        self.close()

    def initSetting(self):
        with open('./setting.json', 'r') as load_f:
            load_j = json.load(load_f)

        userList = load_j['Users']
        for user in userList:
            userItem = NewTypeItem()
            userItem.setText(user['Name'])
            userItem.page = UserPage()

            # if user['UsePassword']:
            #     userItem.page.passwordCheckBox.setChecked(True)
            # else:
            #     userItem.page.passwordCheckBox.setChecked(False)

            userItem.page.passwordEdit.setText(user['Password'])
            userItem.page.sharedFolderEdit.setText(user['SharedFolder'])

            self.columnTable.setRowCount(self.columnTable.rowCount() + 1)
            self.columnTable.setItem(self.columnTable.rowCount() - 1, 0,
                                     userItem)

        if self.columnTable.rowCount() != 0:
            self.buttonRemove.setEnabled(True)

        pass

    def updateSetting(self):
        with open('./setting.json', 'r+') as lw_f:
            lw_j = json.load(lw_f)
            lw_f.seek(0)
            lw_f.truncate()

            itemJsonList = []
            for index in range(self.columnTable.rowCount()):
                item = self.columnTable.item(index, 0)
                # if item.page.passwordCheckBox.isChecked() == True:
                #     itemJsonList.append({"Name": item.text(), "UsePassword": 1, "Password": item.page.passwordEdit.text(),
                #                          "SharedFolder": item.page.sharedFolderEdit.text()})
                # else:
                #     itemJsonList.append({"Name": item.text(), "UsePassword": 0, "Password": item.page.passwordEdit.text(),
                #                          "SharedFolder": item.page.sharedFolderEdit.text()})

                itemJsonList.append({
                    "Name":
                    item.text(),
                    "Password":
                    item.page.passwordEdit.text(),
                    "SharedFolder":
                    item.page.sharedFolderEdit.text()
                })

            lw_j['Users'] = itemJsonList
            json.dump(lw_j, lw_f)
        pass
예제 #12
0
class GridWidget(QWidget):
    def __init__(self, kind, im_width, num_rows=3, num_cols=4, labeler=False):
        super(GridWidget, self).__init__()
        self.num_rows = num_rows
        self.num_cols = num_cols
        self.page = 1
        self.gridLayout = QGridLayout()
        self.kind = kind
        #fullname=str(self.model)
        #self.name= (fullname[fullname.find(":")+2:fullname.find(">")].strip()+'_set').lower()
        self.images = [None] * (self.num_rows * self.num_cols)
        self.updated = True
        self.num_pages = 1
        for i in range(self.num_rows):
            for j in range(self.num_cols):
                index = i * self.num_cols + j
                self.images[index] = ImageView(im_width, labeler)
                self.gridLayout.addWidget(self.images[index], i, j)

        self.next = QPushButton('Next')
        self.previous = QPushButton('Previous')
        self.last = QPushButton('Last')
        self.first = QPushButton('First')
        self.of = QLabel('of')
        self.total = QLabel()
        self.current = QLineEdit("1")
        self.current.setValidator(QIntValidator())
        self.horizontalLayout = QHBoxLayout()
        self.horizontalLayout.addWidget(self.first)
        self.horizontalLayout.addWidget(self.previous)
        self.horizontalLayout.addWidget(self.current)
        self.horizontalLayout.addWidget(self.of)
        self.horizontalLayout.addWidget(self.total)
        self.horizontalLayout.addWidget(self.next)
        self.horizontalLayout.addWidget(self.last)
        self.verticalLayout = QVBoxLayout()
        self.verticalLayout.addLayout(self.gridLayout, stretch=1)
        self.verticalLayout.addLayout(self.horizontalLayout, stretch=0)
        self.labeler = labeler
        if labeler:
            self.horizontalLayout2 = QHBoxLayout()
            self.horizontalLayout2.addLayout(self.verticalLayout)
            self.refreshLabeler()
            self.setLayout(self.horizontalLayout2)
        else:
            self.setLayout(self.verticalLayout)
        self.updatePages()
        self.next.clicked.connect(self.doNext)
        self.previous.clicked.connect(self.doPrevious)
        self.last.clicked.connect(self.doLast)
        self.first.clicked.connect(self.doFirst)
        self.current.returnPressed.connect(self.doJump)

    def refreshLabeler(self):
        if hasattr(self, "labelerGrid"):
            for i in reversed(range(self.labelerGrid.count())):
                self.labelerGrid.itemAt(i).widget().deleteLater()

            self.labelerGrid.deleteLater()
            self.labelerGrid.setParent(None)
            self.horizontalLayout2.removeItem(self.labelerGrid)
            del self.labelerGrid
        self.labelerGrid = QGridLayout()
        query = Category.select()
        i = 0
        for cat in query:
            button = QPushButton(cat.name)
            button.clicked.connect(self.clickgen(cat))
            self.labelerGrid.addWidget(button, i // 2, i % 2)
            i += 1
        button = QPushButton("Delete")
        button.clicked.connect(self.delete)
        self.labelerGrid.addWidget(button, i // 2, i % 2)
        self.horizontalLayout2.addLayout(self.labelerGrid)
        self.update()

    def clickgen(self, cat):
        def labelerClicked(event):
            for i in range(self.num_rows):
                for j in range(self.num_cols):
                    index = i * self.num_cols + j
                    ex_label = self.images[index]
                    for label in ex_label.tags:
                        if label.tik.isVisible() and label.tik.checkState():
                            label.updateLabel(cat)

        return labelerClicked

    def delete(self, event):
        for i in range(self.num_rows):
            for j in range(self.num_cols):
                index = i * self.num_cols + j
                ex_label = self.images[index]
                for tag in ex_label.tags:
                    if tag.tik.isVisible() and tag.tik.checkState():
                        tag.setParent(None)
                        ex_label.tags.remove(tag)

    def updatePages(self):
        count = Image.select().join(Detection).where(
            Detection.kind == self.kind.value).count()
        self.num_pages = (count // (self.num_rows * self.num_cols)) + 1
        self.total.setText(str(self.num_pages))
        self.current.setText(str(self.page))
        if self.page == 1:
            self.previous.setEnabled(False)
        else:
            self.previous.setEnabled(True)
        if self.page == self.num_pages:
            self.next.setEnabled(False)
        else:
            self.next.setEnabled(True)

    def doNext(self, event):
        if self.page <= self.num_pages:
            self.page += 1
            self.updated = True
            self.showCurrentPage()
        self.updatePages()

    def doPrevious(self, event):
        if self.page > 1:
            self.page -= 1
            self.updated = True
            self.showCurrentPage()
        self.updatePages()

    def doLast(self, event):
        self.page = self.num_pages
        self.updated = True
        self.showCurrentPage()
        self.updatePages()

    def doFirst(self, event):
        self.page = 1
        self.updated = True
        self.showCurrentPage()
        self.updatePages()

    def doJump(self):
        val = int(self.current.text())
        if val >= 1 and val <= self.num_pages:
            self.page = val
            self.updated = True
            self.showCurrentPage()
        else:
            self.current.setText("1")
        self.updatePages()

    def showCurrentPage(self, force=False):
        if self.labeler:
            self.refreshLabeler()
        if self.updated or force:
            #print("Parent", self.parentWidget().width(), self.parentWidget().height())
            self.clear()
            query = Image.select().join(Detection).where(
                Detection.kind == self.kind.value).paginate(
                    self.page, self.num_rows * self.num_cols)
            #print(self.model,self.name,query.sql())
            index = 0
            for r in query:
                self.images[index].setSample(
                    r.id,
                    os.path.join('/project/evolvingai/mnorouzz/Serengiti/SER',
                                 r.file_name), r.detection_set)
                index += 1
            self.updated = False

    def clear(self):
        self.visited = False
        for i in range(self.num_rows):
            for j in range(self.num_cols):
                index = i * self.num_cols + j
                self.images[index].clear()
예제 #13
0
class PlotWidget(QWidget):
    """
    PlotWidget widget.
    Widget used to show data plots.

    Inherits from:
    QWidget

    Signals:
    None
    """
    def __init__(self,
                 label,
                 plot_typ,
                 dock_widget,
                 twin_container,
                 *args,
                 parent=None,
                 **kwargs):
        """
        Setup the layout for the widget.

        Arguments:
        label - Label of the plot.
        plot_typ - Type of plot (e.g. histogram, values)
        parent - Parent widget (Default None)
        *args - Unused additional arguments
        **kwargs - Unused named additional arguments

        Return:
        None
        """
        super(PlotWidget, self).__init__(parent=parent)

        self.parent = parent
        self.label = label
        self.plot_typ = plot_typ
        self.dock_widget = dock_widget
        self.twin_container = twin_container
        self.twin_canvas = None
        self._is_first = True

        layout_v = QVBoxLayout(self)
        self.layout_canvas = QHBoxLayout()
        self._plot_ref = []
        self._image_ref = []
        self._mean_ref = []
        self._median_ref = []
        self._canvas_list = []
        self._is_started = False
        self.setup_values()

        if self.plot_typ in ('values', 'histogram'):
            self._hide_marker = False

            self.markersize = 4

            self.trim_widget = TrimWidget(self.plot_typ, self._minimum_x,
                                          self._maximum_x, self._minimum_y,
                                          self._maximum_y, self._bins, self)
            self.trim_widget.sig_update.connect(self.update_trim)
            self.trim_widget.sig_hide.connect(self.hide_twin)
            layout_v.addWidget(self.trim_widget, stretch=0)

            self.view_widget = ViewWidget(self)
            self.view_widget.sig_hide.connect(self.hide_marker)
            layout_v.addWidget(self.view_widget, stretch=0)

        elif plot_typ == 'image' and label == 'image':
            self.select_widget = SelectWidget(self)
            self.select_widget.sig_update.connect(self.set_current_image_name)
            layout_v.addWidget(self.select_widget, stretch=0)

            self.current_image_name = 'latest'

        layout_v.addLayout(self.layout_canvas, stretch=1)

    def setup_values(self):
        self._xdata = np.array([])
        self._ydata = np.array([])
        self._data = None
        self._basenames = None
        self._directory_name = None
        self._color = '#68a3c3'

        self._cur_min_x = 0
        self._cur_max_x = 0
        self._cur_min_y = 0
        self._cur_max_y = 0

        self._applied_min_x = 0
        self._applied_max_x = 0
        self._applied_min_y = 0
        self._applied_max_y = 0

        self._xdata_raw = np.array([])
        self._ydata_raw = np.array([])
        self._bins = 50
        self._minimum_x = float('-inf')
        self._maximum_x = float('inf')
        self._minimum_y = float('-inf')
        self._maximum_y = float('inf')
        self._previous_dict = {}
        self.mean = None
        self.median = None

    @pyqtSlot()
    def hide_marker(self):
        self._hide_marker = not self._hide_marker
        self.force_update()

    @pyqtSlot(int)
    def hide_twin(self, state):
        if self.twin_canvas is not None:
            self.twin_container.handle_show(self.plot_typ, self.twin_canvas,
                                            not state)

    @pyqtSlot(str)
    def set_current_image_name(self, text):
        self.current_image_name = text
        self.update_figure()

    def start_plotting(self):
        if not self._is_started:
            self.add_canvas()
            self.parent.parent.content[
                self.parent.parent_layout].sig_start_plot.connect(
                    self.update_figure)
            self._is_started = True

    def add_canvas(self):
        layout_v = QVBoxLayout()
        is_image = self.plot_typ == 'image'
        canvas_settings = {
            'parent': self,
            'no_grid': is_image,
            'plot_type': self.plot_typ,
        }
        self.canvas = MplCanvasWidget(**canvas_settings)
        self._canvas_list.append(self.canvas)
        self._plot_ref.append(None)
        self._mean_ref.append(None)
        self._median_ref.append(None)

        if self.twin_container is not None and not is_image:
            self.twin_canvas = MplCanvasWidget(**canvas_settings, is_twin=True)
            self._canvas_list.append(self.twin_canvas)
            self.twin_container.add_to_layout(self.plot_typ, self.twin_canvas)
            self._plot_ref.append(None)
            self._mean_ref.append(None)
            self._median_ref.append(None)
        else:
            self.twin_canvas = None

        toolbar = NavigationToolbar(self.canvas.mpl_canvas, self)
        toolbar.actions()[0].triggered.connect(self.force_update)

        layout_v.addWidget(toolbar)
        layout_v.addWidget(self.canvas, stretch=1)

        self.layout_canvas.addLayout(layout_v)

    def clear_canvas(self):
        for idx in reversed(range(self.layout_canvas.count())):
            current_layout = self.layout_canvas.itemAt(idx)
            for idx2 in reversed(range(current_layout.count())):
                widget = current_layout.itemAt(idx2).widget()
                try:
                    self._canvas_list.remove(widget)
                except ValueError:
                    pass
                current_layout.removeWidget(widget)
                widget.setParent(None)
                widget = None
                del widget
            self.layout_canvas.removeItem(current_layout)
            current_layout.setParent(None)
            current_layout = None
            del current_layout
        self._plot_ref = []
        self._mean_ref = []
        self._median_ref = []

    @pyqtSlot(str, str, object, str, object)
    def set_settings(self, name, name_no_feedback, data, directory_name,
                     settings):
        self._directory_name = directory_name
        self._data = data
        self._basenames = np.array(
            [os.path.basename(entry) for entry in data['file_name']])
        if self.plot_typ in ('values', 'histogram'):
            self._xdata_raw, self._ydata_raw, labels_x, label_y, title = tu.get_function_dict(
            )[name_no_feedback]['plot'](
                data=data,
                settings=settings,
                label=self.label,
            )
            if self._is_first:
                self._is_first = False
                for canvas in self._canvas_list:
                    canvas.update_labels(title, labels_x, label_y)
            self.update_figure()

        elif self.plot_typ == 'image':
            self.select_widget.set_values(self._basenames)

    @pyqtSlot()
    def update_trim(self):
        return_value, self._previous_dict = self.trim_widget.get_values()
        if return_value is not None:
            self._minimum_x, self._maximum_x, self._minimum_y, self._maximum_y, self._bins = \
                return_value
            self.force_update(do_message=True)

        self.force_update()

    def update_data(self, do_message=False):
        if self.plot_typ in ('values', 'histogram'):
            mask_y = np.logical_and(self._ydata_raw >= self._minimum_y,
                                    self._ydata_raw <= self._maximum_y)
            mask_x = np.logical_and(self._xdata_raw >= self._minimum_x,
                                    self._xdata_raw <= self._maximum_x)
            mask = np.logical_and(mask_y, mask_x)

            if self._ydata_raw[mask].size == 0 or self._xdata_raw[
                    mask].size == 0:
                self.trim_widget.set_values(self._previous_dict)
                if do_message:
                    tu.message(
                        'Masking values do not contain any data points! Falling back to previous values!'
                    )
                return False

            self.mean = np.mean(self._ydata_raw[mask])
            self.median = np.median(self._ydata_raw[mask])
            self.view_widget.update_label({
                'Min': np.min(self._ydata_raw[mask]),
                'Max': np.max(self._ydata_raw[mask]),
                'Sum': np.sum(self._ydata_raw[mask]),
                'Mean': self.mean,
                'Median': self.median,
                'In range': np.count_nonzero(mask),
                'of': mask.shape[0],
            })

            if self.plot_typ == 'values':
                self._xdata = self._xdata_raw[mask]
                self._ydata = self._ydata_raw[mask]
            elif self.plot_typ == 'histogram':
                self._ydata, self._xdata = np.histogram(
                    self._ydata_raw[mask], self._bins)
        return True

    @pyqtSlot()
    def force_update(self, do_message=False):
        for plot_line in self._median_ref:
            if plot_line is not None:
                for entry in plot_line:
                    entry.remove()
        for plot_line in self._mean_ref:
            if plot_line is not None:
                for entry in plot_line:
                    entry.remove()
        for plot_line in self._plot_ref:
            if plot_line is not None:
                for entry in plot_line:
                    entry.remove()
        self._plot_ref = [None] * len(self._plot_ref)
        self._median_ref = [None] * len(self._median_ref)
        self._mean_ref = [None] * len(self._mean_ref)
        self.update_figure(do_message)

    def prepare_axes(self, update):
        if (
                (
                    self._cur_min_x > np.min(self._xdata) or \
                    self._cur_min_y > np.min(self._ydata) or \
                    self._cur_max_x < np.max(self._xdata) or \
                    self._cur_max_y < np.max(self._ydata)
                    ) and \
                    self.canvas.mpl_canvas.axes.get_xlim() == (self._applied_min_x, self._applied_max_x) and \
                    self.canvas.mpl_canvas.axes.get_ylim() == (self._applied_min_y, self._applied_max_y)
                ) or \
                update:

            is_histogram = bool(self.plot_typ == 'histogram')

            try:
                width = self._xdata[1] - self._xdata[0]
            except IndexError:
                width = 0
                assert not is_histogram, (self._xdata, self._ydata)

            diff_x = np.max(self._xdata) - np.min(self._xdata)
            diff_x = np.maximum(diff_x, 1)
            diff_y = np.max(
                self._ydata) - np.min(self._ydata) * bool(not is_histogram)
            diff_y = np.maximum(diff_y, 1)

            mult = 0.05
            boarder_x = np.maximum(diff_x * mult / 2, width * is_histogram)
            boarder_y = diff_y * mult / 2

            if self.plot_typ == 'values':
                self._cur_min_x = np.min(self._xdata) - boarder_x
                self._cur_min_y = np.min(self._ydata) - boarder_y
                self._cur_max_x = np.max(self._xdata) + boarder_x
                self._cur_max_y = np.max(self._ydata) + boarder_y

                self._applied_min_x = self._cur_min_x - boarder_x / 2
                self._applied_min_y = self._cur_min_y - boarder_y / 2
                self._applied_max_x = self._cur_max_x + boarder_x / 2
                self._applied_max_y = self._cur_max_y + boarder_y / 2

            elif self.plot_typ == 'histogram':
                self._cur_min_x = np.min(self._xdata[:-1]) - boarder_x
                self._cur_min_y = 0
                self._cur_max_x = np.max(self._xdata[:-1]) + boarder_x
                self._cur_max_y = np.max(self._ydata) + boarder_y

                self._applied_min_x = self._cur_min_x
                self._applied_min_y = self._cur_min_y
                self._applied_max_x = self._cur_max_x
                self._applied_max_y = self._cur_max_y + boarder_y / 2

            update = True
        return update

    @pyqtSlot()
    def do_data_reset(self):
        if self.plot_typ in ('values', 'histogram'):
            self._cur_min_x = 0.5
            self._cur_max_x = 0.6
            self._cur_min_y = 0.5
            self._cur_max_y = 0.6

            self._applied_min_x = 0.5
            self._applied_max_x = 0.6
            self._applied_min_y = 0.5
            self._applied_max_y = 0.6

            for canvas in self._canvas_list:
                canvas.mpl_canvas.axes.set_xlim(self._applied_min_x,
                                                self._applied_max_x)
                canvas.mpl_canvas.axes.set_ylim(self._applied_min_y,
                                                self._applied_max_y)
                canvas.mpl_canvas.draw()

    @pyqtSlot()
    def update_figure(self, do_message=False):

        try:
            is_active = self.parent.parent.content[
                self.parent.parent_layout] == self.parent.parent.content[
                    self.parent.parent_layout].latest_active[0]

            overview_is_floating = self.twin_container.dock_widget.isFloating(
            ) if self.twin_canvas is not None else False

            if not self.dock_widget.isFloating(
            ) and not is_active and not overview_is_floating:
                return

            if not self._plot_ref:
                return

            if not self.update_data(do_message):
                return

            if self.plot_typ in ('values', 'histogram'):
                try:
                    update = self.prepare_axes(
                        update=self._plot_ref[0] is None)
                except ValueError as e:
                    print(e)
                    return

                for plot_idx, canvas in enumerate(self._canvas_list):
                    if update and self._mean_ref[plot_idx] is not None:
                        for entry in self._mean_ref[plot_idx]:
                            entry.remove()
                    if update and self._median_ref[plot_idx] is not None:
                        for entry in self._median_ref[plot_idx]:
                            entry.remove()
                    if update and self._plot_ref[plot_idx] is not None:
                        for entry in self._plot_ref[plot_idx]:
                            entry.remove()

                    if self.plot_typ == 'values':
                        self.update_values(canvas.mpl_canvas, plot_idx, update)
                    elif self.plot_typ == 'histogram':
                        self.update_histogram(canvas.mpl_canvas, plot_idx,
                                              update)
                    self.update_helpers(canvas.mpl_canvas, plot_idx, update,
                                        self.plot_typ)

                    if update:
                        canvas.mpl_canvas.axes.set_xlim(
                            self._applied_min_x, self._applied_max_x)
                        canvas.mpl_canvas.axes.set_ylim(
                            self._applied_min_y, self._applied_max_y)
                        canvas.mpl_canvas.draw()
                    else:
                        canvas.mpl_canvas.update()
                        canvas.mpl_canvas.flush_events()
                    if plot_idx == 0:
                        output_name = os.path.join(
                            self._directory_name, 'overview_plots',
                            '{0}_{1}.png'.format(
                                self.label,
                                self.plot_typ,
                            )).replace(' ', '_')
                        try:
                            tu.mkdir_p(os.path.dirname(output_name))
                            canvas.mpl_canvas.fig.savefig(output_name)
                        except Exception as e:
                            print(e)
                            pass

            elif self.plot_typ in ('image'):
                self.update_image()
        except Exception:
            pass

    def update_image(self):
        current_name = self.current_image_name
        if current_name == 'latest':
            try:
                current_name = self._basenames[-1]
            except IndexError:
                return
            except TypeError:
                return
        elif not current_name:
            return

        try:
            data_list = self._data['image'][self._basenames ==
                                            current_name][0].split(';;;')
        except IndexError:
            return
        except KeyError:
            self.clear_canvas()
            return

        if len(data_list) != len(self._canvas_list):
            self.clear_canvas()
            for _ in range(len(data_list)):
                self.add_canvas()

        for idx, data_file in enumerate(data_list):
            label_x = ''
            label_y = ''
            if data_file.endswith('.jpg'):
                try:
                    data = imageio.imread(data_file)[::-1, ...]
                except Exception as e:
                    print('Error reading image: {}. - {}'.format(
                        data_file, str(e)))
                    continue
                if self._plot_ref[idx] is None:
                    self._plot_ref[idx] = [
                        self._canvas_list[idx].mpl_canvas.axes.imshow(
                            data, resample=False, aspect='equal')
                    ]
                    self._canvas_list[idx].mpl_canvas.axes.set_xlim(
                        0, data.shape[1] - 1)
                    self._canvas_list[idx].mpl_canvas.axes.set_ylim(
                        0, data.shape[0] - 1)
                else:
                    self._plot_ref[idx][0].set_data(data)
                self._canvas_list[idx].mpl_canvas.axes.grid(False)
                self._canvas_list[idx].mpl_canvas.axes.get_xaxis().set_visible(
                    False)
                self._canvas_list[idx].mpl_canvas.axes.get_yaxis().set_visible(
                    False)

            elif data_file.endswith('.json'):
                try:
                    with open(data_file, 'r') as read:
                        json_data = json.load(read)
                except Exception as e:
                    print('Error reading image: {}. - {}'.format(
                        data_file, str(e)))
                    continue

                for entry in self._image_ref:
                    for plot_obj in entry:
                        try:
                            plot_obj.remove()
                        except Exception as e:
                            print(e, plot_obj)
                self._image_ref = []

                plot_idx = 0
                label_x = json_data['label_x']
                label_y = json_data['label_y']
                try:
                    is_equal = json_data['is_equal']
                except KeyError:
                    is_equal = True
                min_x = []
                max_x = []
                min_y = []
                max_y = []
                for data_dict in json_data['data']:
                    if is_equal:
                        max_abs = np.maximum(
                            np.max(np.abs(data_dict['values_x'])),
                            np.max(np.abs(data_dict['values_y'])),
                        )
                        min_x.append(-max_abs - np.maximum(max_abs * 0.1, 1))
                        max_x.append(max_abs + np.maximum(max_abs * 0.1, 1))
                        min_y.append(-max_abs - np.maximum(max_abs * 0.1, 1))
                        max_y.append(max_abs + np.maximum(max_abs * 0.1, 1))
                    else:
                        min_x.append(np.min(data_dict['values_x']))
                        max_x.append(np.max(data_dict['values_x']))
                        min_y.append(np.min(data_dict['values_y']))
                        max_y.append(np.max(data_dict['values_y']))
                    self.update_image_plot(
                        self._canvas_list[idx].mpl_canvas,
                        data_dict['values_x'],
                        data_dict['values_y'],
                        data_dict['is_high_res'],
                        data_dict['label_plot'],
                        data_dict['marker'],
                        data_dict['color'],
                        plot_idx,
                    )
                    plot_idx += 1
                self._canvas_list[idx].mpl_canvas.axes.set_xlim(
                    np.min(min_x), np.max(max_x))
                self._canvas_list[idx].mpl_canvas.axes.set_ylim(
                    np.min(min_y), np.max(max_y))

            self._canvas_list[idx].update_labels(
                tu.split_maximum(tu.get_name(data_file), 20, '_'),
                label_x,
                label_y,
            )
            self._canvas_list[idx].mpl_canvas.draw()

    def update_histogram(self, canvas, plot_idx, update):
        try:
            width = self._xdata[1] - self._xdata[0]
        except IndexError:
            return
        if update:
            self._plot_ref[plot_idx] = canvas.axes.bar(self._xdata[:-1],
                                                       self._ydata,
                                                       width,
                                                       facecolor=self._color,
                                                       edgecolor='k')
        else:
            try:
                canvas.axes.draw_artist(canvas.axes.patch)
                canvas.axes.draw_artist(canvas.axes.gridline)
            except AttributeError:
                canvas.draw()

            for value, patch in zip(self._ydata, self._plot_ref[plot_idx]):
                if patch.get_height() != value:
                    patch.set_height(value)
                    patch.set_width(width)
                    try:
                        canvas.axes.draw_artist(patch)
                    except AttributeError:
                        canvas.draw()

    def update_helpers(self, canvas, plot_idx, update, plot_type):
        if not self._hide_marker:
            mean = [self.mean, self.mean]
            median = [self.median, self.median]
            if plot_type == 'values':
                max_x = np.max(np.abs(self._xdata)) * 1e5
                values_x = [
                    np.min(self._xdata) - max_x,
                    np.max(self._xdata) + max_x
                ]
                values = [[self._mean_ref, values_x, mean, LIGHTBLUE],
                          [self._median_ref, values_x, median, LIGHTRED]]
            elif plot_type == 'histogram':
                max_y = np.max(np.abs(self._ydata)) * 1e5
                values_y = [
                    np.min(self._ydata) - max_y,
                    np.max(self._ydata) + max_y
                ]
                values = [[self._mean_ref, mean, values_y, LIGHTBLUE],
                          [self._median_ref, median, values_y, LIGHTRED]]

            for aim_list, values_x, values_y, color in values:
                if update:
                    aim_list[plot_idx] = canvas.axes.plot(
                        values_x,
                        values_y,
                        color=color,
                        linewidth=0.8,
                    )
                else:
                    aim_list[plot_idx][0].set_data(values_x, values_y)

                try:
                    canvas.axes.draw_artist(aim_list[plot_idx][0])
                except AttributeError:
                    canvas.draw()

    def update_values(self, canvas, plot_idx, update):
        if update:
            self._plot_ref[plot_idx] = canvas.axes.plot(
                self._xdata,
                self._ydata,
                '.',
                color=self._color,
                markersize=self.markersize / (plot_idx + 1))
        else:
            self._plot_ref[plot_idx][0].set_data(self._xdata, self._ydata)
            try:
                canvas.axes.draw_artist(canvas.axes.patch)
                canvas.axes.draw_artist(canvas.axes.gridline)
                canvas.axes.draw_artist(self._plot_ref[plot_idx][0])
            except AttributeError:
                canvas.draw()

    @staticmethod
    def high_res(x_data, y_data, splits):
        cm = matplotlib.cm.get_cmap('viridis')
        if splits != 1:
            n_points = (len(x_data) - 1) * (splits - 1)
            colors = [cm(1. * i / (n_points - 1)) for i in range(n_points)]
            new_values = []
            for i in range(len(x_data) - 1):
                new_x = np.linspace(x_data[i], x_data[i + 1], splits)
                new_y = np.linspace(y_data[i], y_data[i + 1], splits)
                for i in range(splits - 1):
                    new_values.append([new_x[i:i + 2], new_y[i:i + 2]])
        else:
            n_points = len(x_data)
            colors = [cm(1. * i / (n_points - 1)) for i in range(n_points)]
            new_values = np.array([x_data, y_data]).T
        return colors, new_values

    def update_image_plot(self, canvas, data_x, data_y, high_res, label,
                          marker, color, idx):
        if high_res:
            color, vals = self.high_res(data_x, data_y, 30)
            canvas.axes.set_prop_cycle('color', color)
            for x, y in vals:
                self._image_ref.append(canvas.axes.plot(
                    x,
                    y,
                    '-',
                ))
            color, vals = self.high_res(data_x, data_y, 1)
            canvas.axes.set_prop_cycle('color', color)
            for x, y in vals:
                self._image_ref.append(canvas.axes.plot(
                    x,
                    y,
                    'o',
                ))
        else:
            if color is None:
                color = self._color
            self._image_ref.append(
                canvas.axes.plot(
                    data_x,
                    data_y,
                    marker,
                    label=label,
                    color=color,
                    markeredgecolor='black',
                    markersize=6,
                ))
            self._image_ref.append([canvas.axes.legend(loc='best')])
예제 #14
0
class View(QWidget):

    def __init__(self, W):
        self.W = int(W)
        super().__init__()
        self.sounds = Models(self)
        self.sounds.initSound()
        self.image_index = 0        # Keeps track of the first image in image list to be displayed in the thumbnail bar
        self.mode = 0         # Determines and Tracks current mode of view (1 - Full Screen, 0 - Thumbnail)
        self.selected_index = 0     # Keeps track of the current selected index in the thumbnail bar
        self.loadTags()
        self.initUI()

    def initUI(self):
        self.setWindowTitle("Image Browser")
        self.setStyleSheet("background-color: #324d7a")
        self.H = (self.W/4)*3
        self.move(250, 250)
        self.setFixedSize(self.W, self.H)

        # Setting-up Layout for images
        self.layout = QHBoxLayout(self)     # Creates a Horizontal Layout
        self.layout.setContentsMargins(20, 0, 20, 0)    # Removes margins around stored object in the layout
        self.layout.setSpacing(0)           # Removes spaces between layout objects
        self.layout.setAlignment(Qt.AlignCenter)    # Pushes image to the top of the window

        # Setting-up text box for adding tags
        self.textBox = QLineEdit(self)
        self.textBox.setStyleSheet("QLineEdit{ background: #f8f8f8; selection-background-color: #f8f8f8; }")
        self.textBox.setPlaceholderText("Enter your tags here")
        self.textBox.resize(self.W/2,self.H/10)
        self.textBox.move(20, self.H*(5/6))

        # Setting-up add and save buttons for tags
        self.addButton = QPushButton('Add Tag', self)
        self.addButton.setStyleSheet("background-color: #F5F5F5")
        self.addButton.move(self.W/1.9,self.H*(5/6))
        self.addButton.resize(self.W/6, self.H/10)
        self.addButton.clicked.connect(self.addTag)

        self.saveButton = QPushButton('Save Tags', self)
        self.saveButton.setStyleSheet("background-color: #F5F5F5")
        self.saveButton.move(self.W/1.42,self.H*(5/6))
        self.saveButton.resize(self.W/6, self.H/10)
        self.saveButton.clicked.connect(self.saveTags)

        # Setting up layout for holding tags
        self.tagList = QVBoxLayout()
        self.tagList.setSpacing(10)
        self.tagList.setContentsMargins(40, 0, 5, 0)

        self.textBox.hide()
        self.addButton.hide()
        self.saveButton.hide()

        self.thumbnail_bar()
        self.select(0) # Selects first image-box in layou
        self.show()

    def thumbnail_bar(self):     # Creates a List of QLabels and places them in a horizontal Layout
        labels = []
        for i in range(0, 6):
            labels.insert(i, QLabel(self))
            if i != (5):
                labels[i].setPixmap(QPixmap("data/"+Models.images[i]).scaled(((self.W-40)/5)-20, ((self.W-40)/5)-20, Qt.KeepAspectRatio))      # Sets images to each label in layout
                labels[i].setFixedSize((self.W-40)/5, (self.W-40)/5)
            labels[i].setAlignment(Qt.AlignCenter)      # Align images to the center of the label
            labels[i].setStyleSheet('border: 10px solid red')
            self.layout.addWidget(labels[i])        # Add label into layout container
            clickable(self.getWidget(i)).connect(self.indexOfLabel)     # Connects the click even to the indexOfLabel function

        # Properties of full screen view label:
        self.getWidget(5).setStyleSheet('border: 20px solid red')
        self.getWidget(5).setFixedSize(self.W/1.33, self.H/1.28)
        self.getWidget(5).hide()

    def drawTags(self):
        image_key = str((self.image_index+self.selected_index)%len(Models.images))
        if image_key in self.tags:
            for i in range(0, len(self.getTags())):
                self.getTags().itemAt(0).widget().setParent(None)
            for tag in self.tags[image_key]:
                self.getTags().addWidget(QPushButton(tag, self))
                self.getTags().itemAt(len(self.getTags())-1).widget().setStyleSheet("background-color: #f5f5f5")
        else:
            for i in range(0, len(self.getTags())):
                item = self.getTags().itemAt(0).widget().setParent(None)


    def enlarge(self, index):    # Makes necessary changes to change to Full Screen (Window Fill) Mode
        self.sounds.expand_sound.play()
        self.layout.addLayout(self.tagList)     # Adding TagList layout to main layout
        self.mode = 1
        self.selected_index = index
        pixContainer = self.getWidget(index).pixmap()
        for i in range(0, 5):
            self.getWidget(i).hide()
        self.getWidget(5).show()    # Shows label that displays in full screen
        self.getWidget(5).setPixmap(pixContainer.scaled((self.W/1.33)-40, (self.H/1.28)-40, Qt.KeepAspectRatio))   # Sets image in selected label to full screen label
        self.layout.setContentsMargins(0, 0, 0, 0)    # Pushes image to the top of the window
        self.layout.setAlignment(Qt.AlignTop | Qt.AlignLeft)    # Pushes image to the top of the window
        self.getTags().setAlignment(Qt.AlignRight)
        self.textBox.show()
        self.addButton.show()
        self.saveButton.show()
        self.drawTags()


    def circularTraverse(self, steps, direction):    # Responsible for Circular Traversing the image list in the given direction
        if direction == "left":
            return (self.image_index-steps)%(len(Models.images))
        else:
            return (self.image_index+steps)%(len(Models.images))

    def select(self, selected_index):   # Selects new item
        self.getWidget(self.selected_index).setStyleSheet("border: 10px solid red")   # Changes old image box to not selected border
        self.getWidget(selected_index).setStyleSheet("border: 10px solid green")    # Changes new image box to selected border
        self.selected_index = selected_index      # Updates Current selection index

    def shiftLeft(self):            # Shifts the select box and scope of the Thumbnail Bar to the left
        if self.selected_index != 0:         # Shift select box till first image
            if self.mode == 1:
                pixContainer = self.getWidget(self.selected_index-1).pixmap()
                self.getWidget(5).setPixmap(pixContainer.scaled((self.W/1.33)-40, (self.H/1.28)-40, Qt.KeepAspectRatio))
            self.select(self.selected_index-1)

        else:
            if 5 == 5:       # If there are more than 5 images, shift scope of Thumbnail Bar to left
                for i in range(4, 0, -1):     # Shifts scope
                    self.getWidget(i).setPixmap(self.getWidget(i-1).pixmap().scaled(((self.W-40)/5)-20, ((self.W-40)/5)-20, Qt.KeepAspectRatio))
                self.getWidget(0).setPixmap(QPixmap("data/"+Models.images[self.circularTraverse(1, "left")]).scaled(((self.W-40)/5)-20, ((self.W-40)/5)-20, Qt.KeepAspectRatio))
                if self.mode == 1:     # If in full screen mode, load previous image
                    self.getWidget(5).setPixmap(self.getWidget(0).pixmap().scaled((self.W/1.33)-40, (self.H/1.28)-40, Qt.KeepAspectRatio))
                self.image_index = self.circularTraverse(1, "left")

    def shiftRight(self):       # Shifts the select box and scope of the Thumbnail Bar to the right
        if self.selected_index != 4:      # Shift select box till last image
            if self.mode == 1:
                pixContainer = self.getWidget(self.selected_index+1).pixmap()
                self.getWidget(5).setPixmap(pixContainer.scaled((self.W/1.33)-40, (self.H/1.28)-40, Qt.KeepAspectRatio))
            self.select(self.selected_index+1)
        else:
            if 5 == 5:      # If there are more than 5 images, shift scope of Thumbnail Bar to rght
                for i in range(0, 4):    # Shifts scope
                    self.getWidget(i).setPixmap(self.getWidget(i+1).pixmap().scaled(((self.W-40)/5)-20, ((self.W-40)/5)-20, Qt.KeepAspectRatio))
                self.getWidget(4).setPixmap(QPixmap("data/"+Models.images[self.circularTraverse(5, "right")]).scaled(((self.W-40)/5)-20, ((self.W-40)/5)-20, Qt.KeepAspectRatio))
                if self.mode == 1:    # If in full screen mode, load next image
                    self.getWidget(5).setPixmap(self.getWidget(4).pixmap().scaled((self.W/1.33)-40, (self.H/1.28)-40, Qt.KeepAspectRatio))
                self.image_index = self.circularTraverse(1, "right")

    def shrink(self, index):     # Makes necessary changes to change back to Thumbnail Mode
        self.sounds.expand_sound.play()
        self.mode = 0       # Upadates mode variable
        self.getWidget(5).hide()    # Hides full screen label
        for i in range(0,5):    # Un-hides thumbnail labels
            self.getWidget(i).show()
        self.layout.setContentsMargins(20, 0, 20, 0)
        self.layout.setAlignment(Qt.AlignVCenter)    # Pushes image to the top of the window
        self.textBox.hide()
        self.addButton.hide()
        self.saveButton.hide()
        for i in range(0, len(self.getTags())):
            self.getTags().itemAt(0).widget().setParent(None)
        self.layout.removeItem(self.tagList)




#=========================================== EVENT HANDLERS =========================================

    def loadTags(self):
        # If file exists, open and load tags. If does not exist, initialize empty tags dictionary
        try:
            f = open("tags.json","r")
            self.tags = json.load(f)
            f.close()
        except:
            self.tags = {}

    def addTag(self):
        # Add tag if not empty string or spaces
        if not (self.textBox.text().isspace() or self.textBox.text() == ""):
            image_key = str((self.image_index+self.selected_index)%len(Models.images)) # Generating image key for dictionary from unique combination of image_index and selected_index
            if image_key not in self.tags:      # If no tags exist, create a new list for tags
                self.tags[image_key] = []
            self.tags[image_key].append(self.textBox.text())    # Append to the tags lis of image
            self.textBox.setText("")
            self.setFocus()     # Return focus to main window
            self.drawTags()

    def saveTags(self):
        f = open("tags.json", "w+")        # Create file if does not exist
        json.dump(self.tags, f)     # save tags in file
        print("{} saved".format(self.tags))
        f.close()
        self.setFocus()     # Return focus back to window

    def getWidget(self, index):     # Gets stored widget from layout in the passed index
        return self.layout.itemAt(index).widget()

    def getTags(self):
        return self.layout.itemAt(6).layout()

    def indexOfLabel(self, label):      # Provides the index of the clicked label for further operations
        self.setFocus()
        if self.mode == 0:
            self.select(self.layout.indexOf(label))
            self.enlarge(self.layout.indexOf(label))

    def keyPressEvent(self, e):     # Handles all key press events
        if e.key() == Qt.Key_Right:
            self.sounds.select_sound.play()
            self.shiftRight()
            if self.mode == 1:
                self.drawTags()


        if e.key() == Qt.Key_Left:
            self.sounds.select_sound.play()
            self.shiftLeft()
            if self.mode == 1:
                self.drawTags()

        elif e.key() == Qt.Key_Period and self.mode == 0 and 5 == 5:    # Moves to the next 5 images only if there are enough images to overflow
            self.sounds.next_set_sound.play()
            self.image_index=self.circularTraverse(5, "right")
            for i in range(0,5):
                self.getWidget(i).setPixmap(QPixmap("data/"+Models.images[self.circularTraverse(i, "right")]).scaled(((self.W-40)/5)-20, ((self.W-40)/5)-20, Qt.KeepAspectRatio))
            self.select(0)

        elif e.key() == Qt.Key_Comma and self.mode == 0 and 5 == 5:     # Moves to the previous 5 images only if there are enough images to overflow
            self.sounds.next_set_sound.play()
            self.image_index=self.circularTraverse(5, "left")
            for i in range(0,5):
                self.getWidget(i).setPixmap(QPixmap("data/"+Models.images[self.circularTraverse(i, "right")]).scaled(((self.W-40)/5)-20, ((self.W-40)/5)-20, Qt.KeepAspectRatio))
            self.select(0)

        elif e.key() == Qt.Key_Up and self.mode == 0:
            self.enlarge(self.selected_index)

        elif e.key() == Qt.Key_Down and self.mode == 1:
            self.setFocus()
            self.shrink(self.selected_index)
            if 5 == 5:      # Checks if there are more than 5 images
                center_distance = self.selected_index - 2      # Calculates the distance of the seleted image from the center box
                if center_distance > 0:     # Checks if the selected image is right of center
                    # Shifts thumbnail bar accordingly to place selected image in middle on coming back to thumbnai bar mode:
                    for i in range(0, center_distance):
                        for j in range(0,4):
                            self.getWidget(j).setPixmap(self.getWidget(j+1).pixmap().scaled(((self.W-40)/5)-20, ((self.W-40)/5)-20, Qt.KeepAspectRatio))
                        self.getWidget(4).setPixmap(QPixmap("data/"+Models.images[self.circularTraverse(5, "right")]).scaled(((self.W-40)/5)-20, ((self.W-40)/5)-20, Qt.KeepAspectRatio))
                        self.image_index = self.circularTraverse(1, "right")
                elif center_distance < 0:      # Checks if selected image is left of center
                    # Shifts thumbnail bar accordingly to place selected image in middle on coming back to thumbnai bar mode:
                    for i in range(0, abs(center_distance)):
                        for j in range(4, 0, -1):
                            self.getWidget(j).setPixmap(self.getWidget(j-1).pixmap().scaled(((self.W-40)/5)-20, ((self.W-40)/5)-20, Qt.KeepAspectRatio))
                        self.getWidget(0).setPixmap(QPixmap("data/"+Models.images[self.circularTraverse(1, "left")]).scaled(((self.W-40)/5)-20, ((self.W-40)/5)-20, Qt.KeepAspectRatio))
                        self.image_index = self.circularTraverse(1, "left")
                self.select(2)

        elif e.key() == Qt.Key_Escape:      # Returns focus back to main window
            self.setFocus()