Example #1
0
    def __init__(self, previewImage, fileName):
        super(ImageView, self).__init__()

        self.fileName = fileName

        mainLayout = QVBoxLayout(self)
        self.imageLabel = QLabel()
        self.imageLabel.setPixmap(QPixmap.fromImage(previewImage))
        mainLayout.addWidget(self.imageLabel)

        topLayout = QHBoxLayout()
        self.fileNameLabel = QLabel(QDir.toNativeSeparators(fileName))
        self.fileNameLabel.setTextInteractionFlags(Qt.TextBrowserInteraction)

        topLayout.addWidget(self.fileNameLabel)
        topLayout.addStretch()
        copyButton = QPushButton("Copy")
        copyButton.setToolTip("Copy file name to clipboard")
        topLayout.addWidget(copyButton)
        copyButton.clicked.connect(self.copy)
        launchButton = QPushButton("Launch")
        launchButton.setToolTip("Launch image viewer")
        topLayout.addWidget(launchButton)
        launchButton.clicked.connect(self.launch)
        mainLayout.addLayout(topLayout)
Example #2
0
    def __init__(self,parent = None):
        QLabel.__init__(self, parent)
        self.headers = []
        self.position = 0
        self.viewWidth = 800
        self.viewHeight = 100
        self.hideFlag = False
        self.w = 180
        self.h = 40
        self.t = 10
        self.setMouseTracking(True)

        self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(self.createHeaderMenus)

        self.deleteAct = QAction('Hide', self)
        self.deleteAct.setStatusTip('Hide this life-line')
        self.deleteAct.triggered.connect(self.hideLifeLine)

        self.groupAct = QAction('Make a cluster', self)
        self.groupAct.setStatusTip('Make a cluster of multiple life-lines')
        self.groupAct.triggered.connect(self.showClusterDialog)

        self.scatterAct = QAction('Scatter', self)
        self.scatterAct.setStatusTip('Scatter this cluster')
        self.scatterAct.triggered.connect(self.scatterCluster)
Example #3
0
    def testReference(self):
        l = QLabel()
        p = QPixmap()
        l.setPixmap(p) # doesn't increment pixmap ref because this makes a copy
        self.assertEqual(sys.getrefcount(p), 2)

        p = l.pixmap() # this increment the reference because this is an internal pointer
        self.assertEqual(sys.getrefcount(p), 3)

        p2 = l.pixmap()
        self.assertEqual(p, p2)
Example #4
0
class ClusterDialog(QDialog):
    
    editClusterName = None
    def __init__(self, lifeline, defaultName, parent = None):
        super(ClusterDialog, self).__init__(parent)

        self.lifeline = lifeline
        layout = QVBoxLayout(self)

        message = QLabel('Enter group name')
        layout.addWidget(message)

        self.editClusterName = QLineEdit(defaultName)
        self.editClusterName.setFixedHeight(30)
        self.editClusterName.setFixedWidth(400)
        self.editClusterName.textChanged.connect(self.validateCluster)
        layout.addWidget(self.editClusterName)

        self.validation_msg = QLabel(' ')
        layout.addWidget(self.validation_msg)

        buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel, QtCore.Qt.Horizontal, self)
        buttons.accepted.connect(self.accept)
        buttons.rejected.connect(self.reject)
        layout.addWidget(buttons)

        self.validateCluster()

    def validateCluster(self):
        cnt = 0
        for l in self.lifeline:
            if self.editClusterName.text() in l.getClassName() and not l.getFlagCluster() and not l.getClusterLifeline():
                cnt += 1

        available_flag = True
        for l in self.lifeline:
            if self.editClusterName.text() in l.getClassName() and l.getFlagCluster():
                available_flag = False
                break

        if available_flag:
            self.validation_msg.setText("group name includes %d life-lines" % (cnt))
        else:
            self.validation_msg.setText("group name is not available")

    def getClusterText(self):
        return self.editClusterName.text()
    
    @staticmethod
    def getClusterName(lifelines, defaultName, parent = None):
        dialog = ClusterDialog(lifelines,defaultName,parent)
        result = dialog.exec_()
        return (result, dialog.getClusterText())
Example #5
0
 def __init__(self, parentQExampleScrollArea, parentQWidget = None):
     QLabel.__init__(self, parentQWidget)
     self.parentQExampleScrollArea = parentQExampleScrollArea
     self.scale = 1.0
     self.position = (0, 0)
     self.pressed = None
     self.anchor = None
     self.drawer = CaptainServer.CaptainServer(self)
     self.drawer.initUI()
     
     self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
     self.customContextMenuRequested.connect(self.drawer.createMenus) 
Example #6
0
    def paintEvent(self, event):
        QLabel.paintEvent(self,event)

        self.resize(self.viewWidth,self.viewHeight)

        for headInfo in self.headers:
            name = headInfo['name']
            x = headInfo['x']
            x = x - self.position

            if x+self.w < 0:
                continue

            if x > self.viewWidth:
                continue

            self.headLeftPos = x
            self.headRightPos = x+self.w
            self.headTopPos = self.t
            self.headBottomPos = self.t+self.h

            qp = QtGui.QPainter()
            qp.begin(self)

            qp.setBrush(headInfo['color'])
            qp.drawRect(x,self.t,self.w,self.h)
            qp.setPen(QtGui.QColor(20, 20, 30))
            qp.setFont(QtGui.QFont('Decorative', 10))

            leaf_name = list(reversed(name.split(".")))[0]
            parent_name = ".".join(list(reversed(list(reversed(name.split(".")))[1:])))

            if parent_name == "":
                qp.setFont(QtGui.QFont('Decorative', 11))
                wd = QtGui.QFontMetrics(self.font()).boundingRect(leaf_name).width()
                align_option = QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter if wd > self.w-20 else QtCore.Qt.AlignCenter | QtCore.Qt.AlignVCenter
                qp.drawText(QtCore.QRect(x+10,self.t,self.w-20,self.h), align_option, leaf_name) 
            else:
                qp.setFont(QtGui.QFont('Decorative', 7))
                wd = QtGui.QFontMetrics(self.font()).boundingRect(parent_name).width()
                align_option = QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter if wd > self.w-20 else QtCore.Qt.AlignCenter | QtCore.Qt.AlignVCenter
                qp.drawText(QtCore.QRect(x+10,self.t,self.w-20,self.h/2), align_option, parent_name) 
                qp.setFont(QtGui.QFont('Decorative', 11))
                qp.drawText(QtCore.QRect(x+10,self.t+self.h/2,self.w-20,self.h/2), QtCore.Qt.AlignCenter | QtCore.Qt.AlignVCenter, leaf_name) 

            qp.drawLine(x+self.w/2,self.h+self.t,x+self.w/2,90000)

            qp.end()
Example #7
0
    def testSetStyle(self):
        '''All this test have to do is not break with some invalid Python wrapper.'''

        def setStyleHelper(widget, style):
            widget.setStyle(style)
            widget.setPalette(style.standardPalette())
            for child in widget.children():
                if isinstance(child, QWidget):
                    setStyleHelper(child, style)

        container = QWidget()
        # QFontComboBox is used because it has an QLineEdit created in C++ inside it,
        # and if the QWidget.setStyle(style) steals the ownership of the style
        # for the C++ originated widget everything will break.
        fontComboBox = QFontComboBox(container)
        label = QLabel(container)
        label.setText('Label')
        style = QStyleFactory.create(QStyleFactory.keys()[0])
        setStyleHelper(container, style)
Example #8
0
class MyWidget(QWidget):
    def __init__(self):
        QWidget.__init__(self)
 
        self.hello = ["Hallo welt!", "Ciao mondo!",
            "Hei maailma!", "Hola mundo!", "Hei verden!"]
 
        self.button = QPushButton("Click me!")
        self.text = QLabel("Hello World")
        self.text.setAlignment(Qt.AlignCenter)
 
        self.layout = QVBoxLayout()
        self.layout.addWidget(self.text)
        self.layout.addWidget(self.button)
        self.setLayout(self.layout)
 
        self.button.clicked.connect(self.magic)
 
    def magic(self):
        self.text.setText(random.choice(self.hello))
    def __init__(self, parent=None):
        super(BlockingClient, self).__init__(parent)

        self.thread = FortuneThread()
        self.currentFortune = ''

        hostLabel = QLabel("&Server name:")
        portLabel = QLabel("S&erver port:")

        for ipAddress in QNetworkInterface.allAddresses():
            if ipAddress != QHostAddress.LocalHost and ipAddress.toIPv4Address() != 0:
                break
        else:
            ipAddress = QHostAddress(QHostAddress.LocalHost)

        ipAddress = ipAddress.toString()

        self.hostLineEdit = QLineEdit(ipAddress)
        self.portLineEdit = QLineEdit()
        self.portLineEdit.setValidator(QIntValidator(1, 65535, self))

        hostLabel.setBuddy(self.hostLineEdit)
        portLabel.setBuddy(self.portLineEdit)

        self.statusLabel = QLabel(
                "This example requires that you run the Fortune Server example as well.")
        self.statusLabel.setWordWrap(True)

        self.getFortuneButton = QPushButton("Get Fortune")
        self.getFortuneButton.setDefault(True)
        self.getFortuneButton.setEnabled(False)

        quitButton = QPushButton("Quit")

        buttonBox = QDialogButtonBox()
        buttonBox.addButton(self.getFortuneButton, QDialogButtonBox.ActionRole)
        buttonBox.addButton(quitButton, QDialogButtonBox.RejectRole)

        self.getFortuneButton.clicked.connect(self.requestNewFortune)
        quitButton.clicked.connect(self.close)
        self.hostLineEdit.textChanged.connect(self.enableGetFortuneButton)
        self.portLineEdit.textChanged.connect(self.enableGetFortuneButton)
        self.thread.newFortune.connect(self.showFortune)
        self.thread.error.connect(self.displayError)

        mainLayout = QGridLayout()
        mainLayout.addWidget(hostLabel, 0, 0)
        mainLayout.addWidget(self.hostLineEdit, 0, 1)
        mainLayout.addWidget(portLabel, 1, 0)
        mainLayout.addWidget(self.portLineEdit, 1, 1)
        mainLayout.addWidget(self.statusLabel, 2, 0, 1, 2)
        mainLayout.addWidget(buttonBox, 3, 0, 1, 2)
        self.setLayout(mainLayout)

        self.setWindowTitle("Blocking Fortune Client")
        self.portLineEdit.setFocus()
Example #10
0
    def __init__(self):
        super(MainWindow, self).__init__()

        self.setWindowTitle('PySide2 tabbed browser Example')

        self._tab_widget = BrowserTabWidget(create_main_window_with_browser)
        self._tab_widget.enabled_changed.connect(self._enabled_changed)
        self._tab_widget.download_requested.connect(self._download_requested)
        self.setCentralWidget(self._tab_widget)
        self.connect(self._tab_widget, QtCore.SIGNAL("url_changed(QUrl)"),
                     self.url_changed)

        self._bookmark_dock = QDockWidget()
        self._bookmark_dock.setWindowTitle('Bookmarks')
        self._bookmark_widget = BookmarkWidget()
        self._bookmark_widget.open_bookmark.connect(self.load_url)
        self._bookmark_widget.open_bookmark_in_new_tab.connect(self.load_url_in_new_tab)
        self._bookmark_dock.setWidget(self._bookmark_widget)
        self.addDockWidget(Qt.LeftDockWidgetArea, self._bookmark_dock)

        self._find_tool_bar = None

        self._actions = {}
        self._create_menu()

        self._tool_bar = QToolBar()
        self.addToolBar(self._tool_bar)
        for action in self._actions.values():
            if not action.icon().isNull():
                self._tool_bar.addAction(action)

        self._addres_line_edit = QLineEdit()
        self._addres_line_edit.setClearButtonEnabled(True)
        self._addres_line_edit.returnPressed.connect(self.load)
        self._tool_bar.addWidget(self._addres_line_edit)
        self._zoom_label = QLabel()
        self.statusBar().addPermanentWidget(self._zoom_label)
        self._update_zoom_label()

        self._bookmarksToolBar = QToolBar()
        self.addToolBar(Qt.TopToolBarArea, self._bookmarksToolBar)
        self.insertToolBarBreak(self._bookmarksToolBar)
        self._bookmark_widget.changed.connect(self._update_bookmarks)
        self._update_bookmarks()
    def _setupUI(self):
        self.setWindowTitle("Export Attributes to USD")
        layout = QVBoxLayout()

        # This section contains the attributes tagged for export.
        label = QLabel()
        label.setText('Exported Attributes:')
        layout.addWidget(label)

        self.exportedAttrsModel = ExportedAttributesModel()
        self.exportedAttrsView = ExportedAttributesView()
        self.exportedAttrsView.verticalHeader().hide()
        self.exportedAttrsView.setModel(self.exportedAttrsModel)
        selectionModel = self.exportedAttrsView.selectionModel()
        selectionModel.selectionChanged.connect(self._onExportedAttrsSelectionChanged)
        self.exportedAttrsModel.dataChanged.connect(self._onModelDataChanged)
        layout.addWidget(self.exportedAttrsView)

        self.removeExportedAttrButton = QPushButton("Remove Exported Attribute")
        self.removeExportedAttrButton.clicked.connect(self._onRemoveExportedAttrPressed)
        self.removeExportedAttrButton.setEnabled(False)
        layout.addWidget(self.removeExportedAttrButton)

        # This section contains the attributes available for export.
        label = QLabel()
        label.setText('Available Attributes:')
        layout.addWidget(label)

        self.userDefinedCheckBox = QCheckBox('User Defined')
        self.userDefinedCheckBox.setToolTip('Show only user-defined (dynamic) attributes')
        self.userDefinedCheckBox.setChecked(True)
        self.userDefinedCheckBox.stateChanged.connect(self._syncUI)
        layout.addWidget(self.userDefinedCheckBox)

        self.addAttrsModel = AddAttributesModel()
        self.addAttrsView = AddAttributesView()
        self.addAttrsView.setModel(self.addAttrsModel)
        selectionModel = self.addAttrsView.selectionModel()
        selectionModel.selectionChanged.connect(self._onAddAttrsSelectionChanged)
        self.addAttrsModel.dataChanged.connect(self._onModelDataChanged)
        layout.addWidget(self.addAttrsView)

        self.addExportedAttrButton = QPushButton("Add Exported Attribute")
        self.addExportedAttrButton.clicked.connect(self._onAddExportedAttrPressed)
        self.addExportedAttrButton.setEnabled(False)
        layout.addWidget(self.addExportedAttrButton)

        self.setLayout(layout)
    def __init__(self, parent=None):
        super(Dialog, self).__init__(parent)

        self.server = FortuneServer()

        statusLabel = QLabel()
        statusLabel.setTextInteractionFlags(Qt.TextBrowserInteraction)
        statusLabel.setWordWrap(True)
        quitButton = QPushButton("Quit")
        quitButton.setAutoDefault(False)

        if not self.server.listen():
            QMessageBox.critical(self, "Threaded Fortune Server",
                    "Unable to start the server: %s." % self.server.errorString())
            self.close()
            return

        for ipAddress in QNetworkInterface.allAddresses():
            if ipAddress != QHostAddress.LocalHost and ipAddress.toIPv4Address() != 0:
                break
        else:
            ipAddress = QHostAddress(QHostAddress.LocalHost)

        ipAddress = ipAddress.toString()

        statusLabel.setText("The server is running on\n\nIP: %s\nport: %d\n\n"
                "Run the Fortune Client example now." % (ipAddress, self.server.serverPort()))

        quitButton.clicked.connect(self.close)

        buttonLayout = QHBoxLayout()
        buttonLayout.addStretch(1)
        buttonLayout.addWidget(quitButton)
        buttonLayout.addStretch(1)

        mainLayout = QVBoxLayout()
        mainLayout.addWidget(statusLabel)
        mainLayout.addLayout(buttonLayout)
        self.setLayout(mainLayout)

        self.setWindowTitle("Threaded Fortune Server")
Example #13
0
    def __init__(self, lifeline, defaultName, parent = None):
        super(ClusterDialog, self).__init__(parent)

        self.lifeline = lifeline
        layout = QVBoxLayout(self)

        message = QLabel('Enter group name')
        layout.addWidget(message)

        self.editClusterName = QLineEdit(defaultName)
        self.editClusterName.setFixedHeight(30)
        self.editClusterName.setFixedWidth(400)
        self.editClusterName.textChanged.connect(self.validateCluster)
        layout.addWidget(self.editClusterName)

        self.validation_msg = QLabel(' ')
        layout.addWidget(self.validation_msg)

        buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel, QtCore.Qt.Horizontal, self)
        buttons.accepted.connect(self.accept)
        buttons.rejected.connect(self.reject)
        layout.addWidget(buttons)

        self.validateCluster()
Example #14
0
    def __init__(self, parent=None):
        super(SettingsDialog, self).__init__(parent, "Settings")

        mouse_box = QGroupBox("Mouse", self)
        mouse_box.setLayout(QVBoxLayout())

        label = QLabel("Scroll objects with mouse wheel:")
        label.setToolTip(
            "Select an object and scroll up and down to change its type.")
        self._scroll_check_box = QCheckBox("Enabled")
        self._scroll_check_box.setChecked(SETTINGS["object_scroll_enabled"])
        self._scroll_check_box.toggled.connect(self._update_settings)

        scroll_layout = QHBoxLayout()
        scroll_layout.addWidget(label)
        scroll_layout.addStretch(1)
        scroll_layout.addWidget(self._scroll_check_box)

        label = QLabel("Show object names on hover:")
        label.setToolTip(
            "When hovering your cursor over an object in a level, its name and position is shown in a tooltip."
        )
        self._tooltip_check_box = QCheckBox("Enabled")
        self._tooltip_check_box.setChecked(SETTINGS["object_tooltip_enabled"])
        self._tooltip_check_box.toggled.connect(self._update_settings)

        tooltip_layout = QHBoxLayout()
        tooltip_layout.addWidget(label)
        tooltip_layout.addStretch(1)
        tooltip_layout.addWidget(self._tooltip_check_box)

        self.lmb_radio = QRadioButton("Left Mouse Button")
        rmb_radio = QRadioButton("Right Mouse Button")

        self.lmb_radio.setChecked(SETTINGS["resize_mode"] == RESIZE_LEFT_CLICK)
        rmb_radio.setChecked(SETTINGS["resize_mode"] == RESIZE_RIGHT_CLICK)

        self.lmb_radio.toggled.connect(self._update_settings)

        radio_group = QButtonGroup()
        radio_group.addButton(self.lmb_radio)
        radio_group.addButton(rmb_radio)

        resize_layout = QHBoxLayout()
        resize_layout.addWidget(QLabel("Object resize mode:"))
        resize_layout.addStretch(1)
        resize_layout.addWidget(self.lmb_radio)
        resize_layout.addWidget(rmb_radio)

        mouse_box.layout().addLayout(scroll_layout)
        mouse_box.layout().addLayout(tooltip_layout)
        mouse_box.layout().addLayout(resize_layout)

        # -----------------------------------------------
        # GUI theme section

        self.gui_style_box = QGroupBox("GUI", self)
        QHBoxLayout(self.gui_style_box)

        self.gui_style_box.layout().addWidget(QLabel("Style:"))

        for gui_style in GUI_STYLE.keys():
            gui_style = gui_style.capitalize()

            style_radio_button = QRadioButton(gui_style)
            style_radio_button.setChecked(
                SETTINGS["gui_style"] == GUI_STYLE[gui_style.upper()]())
            style_radio_button.toggled.connect(self._update_settings)

            self.gui_style_box.layout().addWidget(style_radio_button)

        # -----------------------------------------------
        # emulator command

        self.emulator_command_input = QLineEdit(self)
        self.emulator_command_input.setPlaceholderText("Path to emulator")
        self.emulator_command_input.setText(SETTINGS["instaplay_emulator"])

        self.emulator_command_input.textChanged.connect(self._update_settings)

        self.emulator_path_button = QPushButton(icon("folder.svg"), "", self)
        self.emulator_path_button.pressed.connect(self._get_emulator_path)

        self.command_arguments_input = QLineEdit(self)
        self.command_arguments_input.setPlaceholderText("%f")
        self.command_arguments_input.setText(SETTINGS["instaplay_arguments"])

        self.command_arguments_input.textEdited.connect(self._update_settings)

        self.command_label = QLabel()

        command_box = QGroupBox("Emulator", self)
        command_layout = QVBoxLayout(command_box)

        command_layout.addWidget(QLabel('Emulator command or "path to exe":'))

        command_input_layout = QHBoxLayout()
        command_input_layout.addWidget(self.emulator_command_input)
        command_input_layout.addWidget(self.emulator_path_button)

        command_layout.addLayout(command_input_layout)
        command_layout.addWidget(
            QLabel("Command arguments (%f will be replaced with rom path):"))
        command_layout.addWidget(self.command_arguments_input)
        command_layout.addWidget(QLabel("Command used to play the rom:"))
        command_layout.addWidget(self.command_label)

        command_layout.addWidget(HorizontalLine())

        command_layout.addWidget(
            QLabel("Power up of Mario when playing level:"))
        self.powerup_combo_box = QComboBox()

        for name, x, y, value, p_wing in POWERUPS:
            powerup_icon = self._load_from_png(x, y)

            self.powerup_combo_box.addItem(powerup_icon, name)

        self.powerup_combo_box.currentIndexChanged.connect(
            self._update_settings)

        self.powerup_combo_box.setCurrentIndex(SETTINGS["default_powerup"])

        command_layout.addWidget(self.powerup_combo_box)

        # ----------------------

        layout = QVBoxLayout(self)
        layout.addWidget(mouse_box)
        layout.addWidget(self.gui_style_box)
        layout.addWidget(command_box)

        self.update()
Example #15
0
 def testWidgetStyle(self):
     w = QLabel('Hello')
     self.assertTrue(isinstance(w.style(), QMacStyle))
Example #16
0
    def __init__(self):
        super(Window, self).__init__()

        self.renderArea = RenderArea()

        self.shapeComboBox = QComboBox()
        self.shapeComboBox.addItem("Polygon", RenderArea.Polygon)
        self.shapeComboBox.addItem("Rectangle", RenderArea.Rect)
        self.shapeComboBox.addItem("Rounded Rectangle", RenderArea.RoundedRect)
        self.shapeComboBox.addItem("Ellipse", RenderArea.Ellipse)
        self.shapeComboBox.addItem("Pie", RenderArea.Pie)
        self.shapeComboBox.addItem("Chord", RenderArea.Chord)
        self.shapeComboBox.addItem("Path", RenderArea.Path)
        self.shapeComboBox.addItem("Line", RenderArea.Line)
        self.shapeComboBox.addItem("Polyline", RenderArea.Polyline)
        self.shapeComboBox.addItem("Arc", RenderArea.Arc)
        self.shapeComboBox.addItem("Points", RenderArea.Points)
        self.shapeComboBox.addItem("Text", RenderArea.Text)
        self.shapeComboBox.addItem("Pixmap", RenderArea.Pixmap)

        shapeLabel = QLabel("&Shape:")
        shapeLabel.setBuddy(self.shapeComboBox)

        self.penWidthSpinBox = QSpinBox()
        self.penWidthSpinBox.setRange(0, 20)
        self.penWidthSpinBox.setSpecialValueText("0 (cosmetic pen)")

        penWidthLabel = QLabel("Pen &Width:")
        penWidthLabel.setBuddy(self.penWidthSpinBox)

        self.penStyleComboBox = QComboBox()
        self.penStyleComboBox.addItem("Solid", Qt.SolidLine)
        self.penStyleComboBox.addItem("Dash", Qt.DashLine)
        self.penStyleComboBox.addItem("Dot", Qt.DotLine)
        self.penStyleComboBox.addItem("Dash Dot", Qt.DashDotLine)
        self.penStyleComboBox.addItem("Dash Dot Dot", Qt.DashDotDotLine)
        self.penStyleComboBox.addItem("None", Qt.NoPen)

        penStyleLabel = QLabel("&Pen Style:")
        penStyleLabel.setBuddy(self.penStyleComboBox)

        self.penCapComboBox = QComboBox()
        self.penCapComboBox.addItem("Flat", Qt.FlatCap)
        self.penCapComboBox.addItem("Square", Qt.SquareCap)
        self.penCapComboBox.addItem("Round", Qt.RoundCap)

        penCapLabel = QLabel("Pen &Cap:")
        penCapLabel.setBuddy(self.penCapComboBox)

        self.penJoinComboBox = QComboBox()
        self.penJoinComboBox.addItem("Miter", Qt.MiterJoin)
        self.penJoinComboBox.addItem("Bevel", Qt.BevelJoin)
        self.penJoinComboBox.addItem("Round", Qt.RoundJoin)

        penJoinLabel = QLabel("Pen &Join:")
        penJoinLabel.setBuddy(self.penJoinComboBox)

        self.brushStyleComboBox = QComboBox()
        self.brushStyleComboBox.addItem("Linear Gradient",
                Qt.LinearGradientPattern)
        self.brushStyleComboBox.addItem("Radial Gradient",
                Qt.RadialGradientPattern)
        self.brushStyleComboBox.addItem("Conical Gradient",
                Qt.ConicalGradientPattern)
        self.brushStyleComboBox.addItem("Texture", Qt.TexturePattern)
        self.brushStyleComboBox.addItem("Solid", Qt.SolidPattern)
        self.brushStyleComboBox.addItem("Horizontal", Qt.HorPattern)
        self.brushStyleComboBox.addItem("Vertical", Qt.VerPattern)
        self.brushStyleComboBox.addItem("Cross", Qt.CrossPattern)
        self.brushStyleComboBox.addItem("Backward Diagonal", Qt.BDiagPattern)
        self.brushStyleComboBox.addItem("Forward Diagonal", Qt.FDiagPattern)
        self.brushStyleComboBox.addItem("Diagonal Cross", Qt.DiagCrossPattern)
        self.brushStyleComboBox.addItem("Dense 1", Qt.Dense1Pattern)
        self.brushStyleComboBox.addItem("Dense 2", Qt.Dense2Pattern)
        self.brushStyleComboBox.addItem("Dense 3", Qt.Dense3Pattern)
        self.brushStyleComboBox.addItem("Dense 4", Qt.Dense4Pattern)
        self.brushStyleComboBox.addItem("Dense 5", Qt.Dense5Pattern)
        self.brushStyleComboBox.addItem("Dense 6", Qt.Dense6Pattern)
        self.brushStyleComboBox.addItem("Dense 7", Qt.Dense7Pattern)
        self.brushStyleComboBox.addItem("None", Qt.NoBrush)

        brushStyleLabel = QLabel("&Brush Style:")
        brushStyleLabel.setBuddy(self.brushStyleComboBox)

        otherOptionsLabel = QLabel("Other Options:")
        self.antialiasingCheckBox = QCheckBox("&Antialiasing")
        self.transformationsCheckBox = QCheckBox("&Transformations")

        self.shapeComboBox.activated.connect(self.shapeChanged)
        self.penWidthSpinBox.valueChanged.connect(self.penChanged)
        self.penStyleComboBox.activated.connect(self.penChanged)
        self.penCapComboBox.activated.connect(self.penChanged)
        self.penJoinComboBox.activated.connect(self.penChanged)
        self.brushStyleComboBox.activated.connect(self.brushChanged)
        self.antialiasingCheckBox.toggled.connect(self.renderArea.setAntialiased)
        self.transformationsCheckBox.toggled.connect(self.renderArea.setTransformed)

        mainLayout = QGridLayout()
        mainLayout.setColumnStretch(0, 1)
        mainLayout.setColumnStretch(3, 1)
        mainLayout.addWidget(self.renderArea, 0, 0, 1, 4)
        mainLayout.setRowMinimumHeight(1, 6)
        mainLayout.addWidget(shapeLabel, 2, 1, Qt.AlignRight)
        mainLayout.addWidget(self.shapeComboBox, 2, 2)
        mainLayout.addWidget(penWidthLabel, 3, 1, Qt.AlignRight)
        mainLayout.addWidget(self.penWidthSpinBox, 3, 2)
        mainLayout.addWidget(penStyleLabel, 4, 1, Qt.AlignRight)
        mainLayout.addWidget(self.penStyleComboBox, 4, 2)
        mainLayout.addWidget(penCapLabel, 5, 1, Qt.AlignRight)
        mainLayout.addWidget(self.penCapComboBox, 5, 2)
        mainLayout.addWidget(penJoinLabel, 6, 1, Qt.AlignRight)
        mainLayout.addWidget(self.penJoinComboBox, 6, 2)
        mainLayout.addWidget(brushStyleLabel, 7, 1, Qt.AlignRight)
        mainLayout.addWidget(self.brushStyleComboBox, 7, 2)
        mainLayout.setRowMinimumHeight(8, 6)
        mainLayout.addWidget(otherOptionsLabel, 9, 1, Qt.AlignRight)
        mainLayout.addWidget(self.antialiasingCheckBox, 9, 2)
        mainLayout.addWidget(self.transformationsCheckBox, 10, 2)
        self.setLayout(mainLayout)

        self.shapeChanged()
        self.penChanged()
        self.brushChanged()
        self.antialiasingCheckBox.setChecked(True)

        self.setWindowTitle("Basic Drawing")
Example #17
0
 def _initCodeEditor(self):
     self.codeView = CodeView(self.subject, viewTip=False)
     self.layout().addWidget(QLabel("Setup Code:", margin=10))
     self.layout().addWidget(self.codeView)
     self.codeView.setDelegate(self)
Example #18
0
class UiQuestion(object):
    '''Интерфейс диалогового окна программы.
    Created by: Qt User Interface Compiler.
    Задано:
        кнопка "подтвердить";

        кнопка "отклонить".
    '''
    def setupUi(self, Dialog):
        if not Dialog.objectName():
            Dialog.setObjectName(u"Dialog")
        Dialog.resize(300, 200)
        Dialog.setMinimumSize(QSize(300, 200))
        Dialog.setMaximumSize(QSize(300, 200))
        self.verticalLayout = QVBoxLayout(Dialog)
        self.verticalLayout.setSpacing(0)
        self.verticalLayout.setObjectName(u"verticalLayout")
        self.verticalLayout.setContentsMargins(0, 0, 0, 0)
        self.dialog_main_frame = QFrame(Dialog)
        self.dialog_main_frame.setObjectName(u"dialog_main_frame")
        self.dialog_main_frame.setFrameShape(QFrame.StyledPanel)
        self.dialog_main_frame.setFrameShadow(QFrame.Raised)
        self.verticalLayout_2 = QVBoxLayout(self.dialog_main_frame)
        self.verticalLayout_2.setSpacing(5)
        self.verticalLayout_2.setObjectName(u"verticalLayout_2")
        self.verticalLayout_2.setContentsMargins(5, 5, 5, 5)
        self.text_frame = QFrame(self.dialog_main_frame)
        self.text_frame.setObjectName(u"text_frame")
        self.text_frame.setFrameShape(QFrame.StyledPanel)
        self.text_frame.setFrameShadow(QFrame.Raised)
        self.verticalLayout_3 = QVBoxLayout(self.text_frame)
        self.verticalLayout_3.setObjectName(u"verticalLayout_3")
        self.question_label = QLabel(self.text_frame)
        self.question_label.setObjectName(u"question_label")
        self.question_label.setAlignment(Qt.AlignCenter)

        self.verticalLayout_3.addWidget(self.question_label)

        self.verticalLayout_2.addWidget(self.text_frame)

        self.buttons_frame = QFrame(self.dialog_main_frame)
        self.buttons_frame.setObjectName(u"buttons_frame")
        self.buttons_frame.setMinimumSize(QSize(0, 50))
        self.buttons_frame.setMaximumSize(QSize(16777215, 50))
        self.buttons_frame.setFrameShape(QFrame.StyledPanel)
        self.buttons_frame.setFrameShadow(QFrame.Raised)
        self.horizontalLayout = QHBoxLayout(self.buttons_frame)
        self.horizontalLayout.setSpacing(5)
        self.horizontalLayout.setObjectName(u"horizontalLayout")
        self.horizontalLayout.setContentsMargins(5, 5, 5, 5)
        self.question_nok_btn = QPushButton(self.buttons_frame)
        self.question_nok_btn.setObjectName(u"question_nok_btn")
        self.question_nok_btn.setMinimumSize(QSize(0, 35))
        self.question_nok_btn.setMaximumSize(QSize(16777215, 35))
        icon = QIcon()
        icon.addFile(DISAGREE_ICON, QSize(), QIcon.Normal, QIcon.Off)
        self.question_nok_btn.setIcon(icon)
        self.question_nok_btn.setIconSize(QSize(25, 25))

        self.horizontalLayout.addWidget(self.question_nok_btn)

        self.question_ok_btn = QPushButton(self.buttons_frame)
        self.question_ok_btn.setObjectName(u"question_ok_btn")
        self.question_ok_btn.setMinimumSize(QSize(0, 35))
        self.question_ok_btn.setMaximumSize(QSize(16777215, 35))
        icon1 = QIcon()
        icon1.addFile(AGREE_ICON, QSize(), QIcon.Normal, QIcon.Off)
        self.question_ok_btn.setIcon(icon1)
        self.question_ok_btn.setIconSize(QSize(25, 25))

        self.horizontalLayout.addWidget(self.question_ok_btn)

        self.verticalLayout_2.addWidget(self.buttons_frame)

        self.verticalLayout.addWidget(self.dialog_main_frame)

        self.retranslateUi(Dialog)

        QMetaObject.connectSlotsByName(Dialog)

    # setupUi

    def retranslateUi(self, Dialog):
        Dialog.setWindowTitle(
            QCoreApplication.translate("Dialog", u"new calculation", None))
        self.question_label.setText(
            QCoreApplication.translate("Dialog", u"Clear all fields?", None))
        # if QT_CONFIG(tooltip)
        self.question_nok_btn.setToolTip(
            QCoreApplication.translate("Dialog", u"cancel", None))
        # endif // QT_CONFIG(tooltip)
        self.question_nok_btn.setText("")
        # if QT_CONFIG(tooltip)
        self.question_ok_btn.setToolTip(
            QCoreApplication.translate("Dialog", u"continue", None))
        # endif // QT_CONFIG(tooltip)
        self.question_ok_btn.setText("")
Example #19
0
class StemOptions(QVBoxLayout):
    def __init__(self):
        super(StemOptions, self).__init__()
        self.curStems = '2 tracks'
        self.curOptions = (set(), set())
        self.buildLayout()

    def buildLayout(self, pastOptions=(set(), set())):
        isolateTitle = QLabel('Isolate')
        removeTitle = QLabel('Remove')

        isolateBoxes = self.buildBoxes(True, pastOptions[0])
        removeBoxes = self.buildBoxes(False, pastOptions[1])

        isolateCol = QVBoxLayout()
        removeCol = QVBoxLayout()

        isolateCol.addWidget(isolateTitle)
        isolateCol.addLayout(isolateBoxes)
        removeCol.addWidget(removeTitle)
        removeCol.addLayout(removeBoxes)

        columns = QHBoxLayout()
        columns.addLayout(isolateCol)
        columns.addLayout(removeCol)

        self.previewOutput = QLabel()
        self.previewOutput.setWordWrap(True)
        self.updatePreview()

        self.addLayout(columns)
        self.addWidget(self.previewOutput)

    def setStems(self, stems):
        self.curStems = stems
        if stems != '5 tracks':
            self.curOptions[0].discard('piano')
            self.curOptions[1].discard('piano')
        if stems == '2 tracks':
            self.curOptions[0].discard('bass')
            self.curOptions[1].discard('bass')
            self.curOptions[0].discard('drums')
            self.curOptions[1].discard('drums')
        clearLayout(self)
        self.buildLayout(self.curOptions)

    def setChecked(self, stem, isIsolate, checked):
        if checked:
            self.curOptions[0 if isIsolate else 1].add(stem)
        else:
            self.curOptions[0 if isIsolate else 1].remove(stem)
        self.updatePreview()

    def updatePreview(self):
        text = 'Output Tracks: '
        iso = map(lambda x: x + '.wav', self.curOptions[0])
        rem = map(lambda x: 'no_' + x + '.wav', self.curOptions[1])
        self.previewOutput.setText(text + ', '.join(list(iso) + list(rem)))

    def buildBoxes(self, isIsolate, pastOptions):
        boxColumn = QVBoxLayout()

        vocals = QCheckBox("Vocals")
        if 'vocals' in pastOptions:
            vocals.setChecked(True)
        vocals.toggled.connect(
            lambda x: self.setChecked('vocals', isIsolate, x))
        boxColumn.addWidget(vocals)

        if self.curStems != '2 tracks':
            if self.curStems == '5 tracks':
                piano = QCheckBox("Piano")
                if 'piano' in pastOptions:
                    piano.setChecked(True)
                piano.toggled.connect(
                    lambda x: self.setChecked('piano', isIsolate, x))
                boxColumn.addWidget(piano)

            bass = QCheckBox("Bass")
            if 'bass' in pastOptions:
                bass.setChecked(True)
            bass.toggled.connect(
                lambda x: self.setChecked('bass', isIsolate, x))
            boxColumn.addWidget(bass)

            drums = QCheckBox("Drums")
            if 'drums' in pastOptions:
                drums.setChecked(True)
            drums.toggled.connect(
                lambda x: self.setChecked('drums', isIsolate, x))
            boxColumn.addWidget(drums)

        other = QCheckBox('Other')
        if 'other' in pastOptions:
            other.setChecked(True)
        other.toggled.connect(lambda x: self.setChecked('other', isIsolate, x))
        boxColumn.addWidget(other)

        return boxColumn
Example #20
0
class GeneratorDialog(QDialog):
    """
    登录窗口
    """
    def __init__(self):
        """
        初始化产品验证登录界面
        """
        super().__init__()
        self.init_window()

        #
        # 创建布局并添加控件,用来显示提示信息
        #
        cpu_label = QLabel("CPU 序列号:")
        self.cpu_input = QLineEdit()
        h_box1 = QHBoxLayout()
        h_box1.addWidget(cpu_label)
        h_box1.addWidget(self.cpu_input)

        key_label = QLabel("  产品密钥:")
        self.key_input = QLineEdit()
        h_box2 = QHBoxLayout()
        h_box2.addWidget(key_label)
        h_box2.addWidget(self.key_input)

        policy = QSizePolicy()
        policy.setVerticalPolicy(QSizePolicy.Fixed)
        self.info_label = QLabel("")
        self.info_label.setSizePolicy(policy)

        self.ok_btn = QPushButton(text="获取产品密钥")
        self.ok_btn.clicked.connect(self.activate)
        h_box3 = QHBoxLayout()
        h_box3.addStretch()
        h_box3.addWidget(self.ok_btn)

        layout = QVBoxLayout()
        layout.addLayout(h_box1)
        layout.addLayout(h_box2)
        layout.addWidget(self.info_label)
        layout.addLayout(h_box3)

        self.setLayout(layout)

    def print_info(self, info: str):
        """
        输出提示信息
        :param info:提示信息
        :return: 无
        """
        self.info_label.setText(info)

    def init_window(self):
        """
        初始化对话框窗口
        :return: 无
        """
        self.setWindowTitle("密钥生成器")
        #app_icon = QIcon("./other/key.ico")
        #self.setWindowIcon(app_icon)
        self.setFixedSize(600, 400)
        self.setWindowFlags(
            self.windowFlags()
            & ~Qt.WindowContextHelpButtonHint)  # 去掉默认对话框样式左上角出现的问号

    def activate(self):
        """
        激活按钮响应事件
        :return: 无
        """
        cpu = self.cpu_input.text()
        if cpu != "":
            key = des_encrypt(cpu)
            if key != "":
                self.key_input.setText(key)
                self.print_info("")
            else:
                self.print_info("输入的 CPU 序列号有误!序列号仅包含数字和英文字母!")
        else:
            self.print_info("请输入 CPU 序列号!")
Example #21
0
class MainWindow(QMainWindow):
    """Provides the parent window that includes the BookmarkWidget,
    BrowserTabWidget, and a DownloadWidget, to offer the complete
    web browsing experience."""
    def __init__(self):
        super(MainWindow, self).__init__()

        self.setWindowTitle('PySide2 tabbed browser Example')

        self._tab_widget = BrowserTabWidget(create_main_window_with_browser)
        self._tab_widget.enabled_changed.connect(self._enabled_changed)
        self._tab_widget.download_requested.connect(self._download_requested)
        self.setCentralWidget(self._tab_widget)
        self.connect(self._tab_widget, QtCore.SIGNAL("url_changed(QUrl)"),
                     self.url_changed)

        self._bookmark_dock = QDockWidget()
        self._bookmark_dock.setWindowTitle('Bookmarks')
        self._bookmark_widget = BookmarkWidget()
        self._bookmark_widget.open_bookmark.connect(self.load_url)
        self._bookmark_widget.open_bookmark_in_new_tab.connect(self.load_url_in_new_tab)
        self._bookmark_dock.setWidget(self._bookmark_widget)
        self.addDockWidget(Qt.LeftDockWidgetArea, self._bookmark_dock)

        self._find_tool_bar = None

        self._actions = {}
        self._create_menu()

        self._tool_bar = QToolBar()
        self.addToolBar(self._tool_bar)
        for action in self._actions.values():
            if not action.icon().isNull():
                self._tool_bar.addAction(action)

        self._addres_line_edit = QLineEdit()
        self._addres_line_edit.setClearButtonEnabled(True)
        self._addres_line_edit.returnPressed.connect(self.load)
        self._tool_bar.addWidget(self._addres_line_edit)
        self._zoom_label = QLabel()
        self.statusBar().addPermanentWidget(self._zoom_label)
        self._update_zoom_label()

        self._bookmarksToolBar = QToolBar()
        self.addToolBar(Qt.TopToolBarArea, self._bookmarksToolBar)
        self.insertToolBarBreak(self._bookmarksToolBar)
        self._bookmark_widget.changed.connect(self._update_bookmarks)
        self._update_bookmarks()

    def _update_bookmarks(self):
        self._bookmark_widget.populate_tool_bar(self._bookmarksToolBar)
        self._bookmark_widget.populate_other(self._bookmark_menu, 3)

    def _create_menu(self):
        file_menu = self.menuBar().addMenu("&File")
        exit_action = QAction(QIcon.fromTheme("application-exit"), "E&xit",
                             self, shortcut = "Ctrl+Q", triggered=qApp.quit)
        file_menu.addAction(exit_action)

        navigation_menu = self.menuBar().addMenu("&Navigation")

        style_icons = ':/qt-project.org/styles/commonstyle/images/'
        back_action = QAction(QIcon.fromTheme("go-previous",
                                             QIcon(style_icons + 'left-32.png')),
                             "Back", self,
                             shortcut = QKeySequence(QKeySequence.Back),
                             triggered = self._tab_widget.back)
        self._actions[QWebEnginePage.Back] = back_action
        back_action.setEnabled(False)
        navigation_menu.addAction(back_action)
        forward_action = QAction(QIcon.fromTheme("go-next",
                                                QIcon(style_icons + 'right-32.png')),
                                "Forward", self,
                                shortcut = QKeySequence(QKeySequence.Forward),
                                triggered = self._tab_widget.forward)
        forward_action.setEnabled(False)
        self._actions[QWebEnginePage.Forward] = forward_action

        navigation_menu.addAction(forward_action)
        reload_action = QAction(QIcon(style_icons + 'refresh-32.png'),
                               "Reload", self,
                               shortcut = QKeySequence(QKeySequence.Refresh),
                               triggered = self._tab_widget.reload)
        self._actions[QWebEnginePage.Reload] = reload_action
        reload_action.setEnabled(False)
        navigation_menu.addAction(reload_action)

        navigation_menu.addSeparator()

        new_tab_action = QAction("New Tab", self,
                             shortcut = 'Ctrl+T',
                             triggered = self.add_browser_tab)
        navigation_menu.addAction(new_tab_action)

        close_tab_action = QAction("Close Current Tab", self,
                                 shortcut = "Ctrl+W",
                                 triggered = self._close_current_tab)
        navigation_menu.addAction(close_tab_action)

        edit_menu = self.menuBar().addMenu("&Edit")

        find_action = QAction("Find", self,
                             shortcut = QKeySequence(QKeySequence.Find),
                             triggered = self._show_find)
        edit_menu.addAction(find_action)

        edit_menu.addSeparator()
        undo_action = QAction("Undo", self,
                             shortcut = QKeySequence(QKeySequence.Undo),
                             triggered = self._tab_widget.undo)
        self._actions[QWebEnginePage.Undo] = undo_action
        undo_action.setEnabled(False)
        edit_menu.addAction(undo_action)

        redo_action = QAction("Redo", self,
                             shortcut = QKeySequence(QKeySequence.Redo),
                             triggered = self._tab_widget.redo)
        self._actions[QWebEnginePage.Redo] = redo_action
        redo_action.setEnabled(False)
        edit_menu.addAction(redo_action)

        edit_menu.addSeparator()

        cut_action = QAction("Cut", self,
                            shortcut = QKeySequence(QKeySequence.Cut),
                            triggered = self._tab_widget.cut)
        self._actions[QWebEnginePage.Cut] = cut_action
        cut_action.setEnabled(False)
        edit_menu.addAction(cut_action)

        copy_action = QAction("Copy", self,
                             shortcut = QKeySequence(QKeySequence.Copy),
                             triggered = self._tab_widget.copy)
        self._actions[QWebEnginePage.Copy] = copy_action
        copy_action.setEnabled(False)
        edit_menu.addAction(copy_action)

        paste_action = QAction("Paste", self,
                             shortcut = QKeySequence(QKeySequence.Paste),
                             triggered = self._tab_widget.paste)
        self._actions[QWebEnginePage.Paste] = paste_action
        paste_action.setEnabled(False)
        edit_menu.addAction(paste_action)

        edit_menu.addSeparator()

        select_all_action = QAction("Select All", self,
                                  shortcut = QKeySequence(QKeySequence.SelectAll),
                                  triggered = self._tab_widget.select_all)
        self._actions[QWebEnginePage.SelectAll] = select_all_action
        select_all_action.setEnabled(False)
        edit_menu.addAction(select_all_action)

        self._bookmark_menu = self.menuBar().addMenu("&Bookmarks")
        add_bookmark_action = QAction("&Add Bookmark", self,
                                    triggered = self._add_bookmark)
        self._bookmark_menu.addAction(add_bookmark_action)
        add_tool_bar_bookmark_action = QAction("&Add Bookmark to Tool Bar", self,
                                           triggered = self._add_tool_bar_bookmark)
        self._bookmark_menu.addAction(add_tool_bar_bookmark_action)
        self._bookmark_menu.addSeparator()

        tools_menu = self.menuBar().addMenu("&Tools")
        download_action = QAction("Open Downloads", self,
                                 triggered = DownloadWidget.open_download_directory)
        tools_menu.addAction(download_action)

        window_menu = self.menuBar().addMenu("&Window")

        window_menu.addAction(self._bookmark_dock.toggleViewAction())

        window_menu.addSeparator()

        zoom_in_action = QAction(QIcon.fromTheme("zoom-in"),
                               "Zoom In", self,
                               shortcut = QKeySequence(QKeySequence.ZoomIn),
                               triggered = self._zoom_in)
        window_menu.addAction(zoom_in_action)
        zoom_out_action = QAction(QIcon.fromTheme("zoom-out"),
                                "Zoom Out", self,
                                shortcut = QKeySequence(QKeySequence.ZoomOut),
                                triggered = self._zoom_out)
        window_menu.addAction(zoom_out_action)

        reset_zoom_action = QAction(QIcon.fromTheme("zoom-original"),
                                  "Reset Zoom", self,
                                  shortcut = "Ctrl+0",
                                  triggered = self._reset_zoom)
        window_menu.addAction(reset_zoom_action)

        about_menu = self.menuBar().addMenu("&About")
        about_action = QAction("About Qt", self,
                              shortcut = QKeySequence(QKeySequence.HelpContents),
                              triggered=qApp.aboutQt)
        about_menu.addAction(about_action)

    def add_browser_tab(self):
        return self._tab_widget.add_browser_tab()

    def _close_current_tab(self):
        if self._tab_widget.count() > 1:
            self._tab_widget.close_current_tab()
        else:
            self.close()

    def close_event(self, event):
        main_windows.remove(self)
        event.accept()

    def load(self):
        url_string = self._addres_line_edit.text().strip()
        if url_string:
            self.load_url_string(url_string)

    def load_url_string(self, url_s):
        url = QUrl.fromUserInput(url_s)
        if (url.isValid()):
            self.load_url(url)

    def load_url(self, url):
        self._tab_widget.load(url)

    def load_url_in_new_tab(self, url):
        self.add_browser_tab().load(url)

    def url_changed(self, url):
        self._addres_line_edit.setText(url.toString())

    def _enabled_changed(self, web_action, enabled):
        action = self._actions[web_action]
        if action:
            action.setEnabled(enabled)

    def _add_bookmark(self):
        index = self._tab_widget.currentIndex()
        if index >= 0:
            url = self._tab_widget.url()
            title = self._tab_widget.tabText(index)
            icon = self._tab_widget.tabIcon(index)
            self._bookmark_widget.add_bookmark(url, title, icon)

    def _add_tool_bar_bookmark(self):
        index = self._tab_widget.currentIndex()
        if index >= 0:
            url = self._tab_widget.url()
            title = self._tab_widget.tabText(index)
            icon = self._tab_widget.tabIcon(index)
            self._bookmark_widget.add_tool_bar_bookmark(url, title, icon)

    def _zoom_in(self):
        new_zoom = self._tab_widget.zoom_factor() * 1.5
        if (new_zoom <= WebEngineView.maximum_zoom_factor()):
            self._tab_widget.set_zoom_factor(new_zoom)
            self._update_zoom_label()

    def _zoom_out(self):
        new_zoom = self._tab_widget.zoom_factor() / 1.5
        if (new_zoom >= WebEngineView.minimum_zoom_factor()):
            self._tab_widget.set_zoom_factor(new_zoom)
            self._update_zoom_label()

    def _reset_zoom(self):
        self._tab_widget.set_zoom_factor(1)
        self._update_zoom_label()

    def _update_zoom_label(self):
        percent = int(self._tab_widget.zoom_factor() * 100)
        self._zoom_label.setText("{}%".format(percent))

    def _download_requested(self, item):
        # Remove old downloads before opening a new one
        for old_download in self.statusBar().children():
            if type(old_download).__name__ == 'download_widget' and \
                old_download.state() != QWebEngineDownloadItem.DownloadInProgress:
                self.statusBar().removeWidget(old_download)
                del old_download

        item.accept()
        download_widget = download_widget(item)
        download_widget.removeRequested.connect(self._remove_download_requested,
                                               Qt.QueuedConnection)
        self.statusBar().addWidget(download_widget)

    def _remove_download_requested(self):
            download_widget = self.sender()
            self.statusBar().removeWidget(download_widget)
            del download_widget

    def _show_find(self):
        if self._find_tool_bar is None:
            self._find_tool_bar = FindToolBar()
            self._find_tool_bar.find.connect(self._tab_widget.find)
            self.addToolBar(Qt.BottomToolBarArea, self._find_tool_bar)
        else:
            self._find_tool_bar.show()
        self._find_tool_bar.focus_find()

    def write_bookmarks(self):
        self._bookmark_widget.write_bookmarks()
Example #22
0
class PanAndZoom(ZoomOnWheel):
    """Class providing pan & zoom interaction to a matplotlib Figure. Left
    button for pan, right button for zoom area and zoom on wheel. Support
    subplots, twin Axes and log scales.

    This class extends the `ZoomOnWheel` class.
    """
    def __init__(self, figure=None, scale_factor=1.1):
        """
        Args:
            figure (figure): The matplotlib figure to attach the behavior to.
            scale_factor (float): The scale factor to apply on wheel event.
        """
        super(PanAndZoom, self).__init__(figure, scale_factor)
        self._add_connection('button_press_event', self._on_mouse_press)
        self._add_connection('button_release_event', self._on_mouse_release)
        self._add_connection('motion_notify_event', self._on_mouse_motion)

        self._pressed_button = None  # To store active button
        self._axes = None  # To store x and y axes concerned by interaction
        self._event = None  # To store reference event during interaction

        self.options = Dict(dict(report_point_position=True, ))
        self.logger = None
        self._statusbar_label = None

        # self._get_images_path()
        # self._add_toolbar_tools()
        self._style_figure()

        self._ix_iy_old = (0, 0)

    def _get_images_path(self):
        """Get the path to images.

        Returns:
            str: path

        Raises:
            Exception: path error
        """
        # to be removed
        try:  # Get tool image path
            from pathlib import Path
            from ... import _gui
            imgs_path = Path(_gui.__file__).parent / '_imgs'
            if imgs_path.is_dir() == False:
                print(f'Bad File path for images! {imgs_path}')
                imgs_path = None
        except Exception as e:
            print('ERROR: ', e)
            imgs_path = None
        self.imgs_path = imgs_path

        return imgs_path

    def _add_toolbar_tools(self):
        """Add tools."""
        # TODO: Outdated - to be removed

        from matplotlib.backend_tools import ToolToggleBase  # ToolBase

        class ToolPointPosition(ToolToggleBase):
            """Tools."""
            default_keymap = 'Ctrl+p'
            description = 'Click to get point coordinate printed'
            default_toggled = False
            image = None  # str(imgs_path)

            def __init__(self, *args, parent=None, **kwargs):
                super().__init__(*args, **kwargs)
                if parent is None:
                    raise ('Pass a parent')
                self.parent = parent

            def enable(self, *args):
                self.parent.options.report_point_position = True

            def disable(self, *args):
                self.parent.options.report_point_position = False

        fig = self.figure
        imgs_path = self.imgs_path
        # pylint: disable=attribute-defined-outside-init
        toolbar = self.toolbar = fig.canvas.manager.toolbar

        # Get tool manager

        # TODO: Remove use of tool manager just use PySide2 bare as below

        # ToolbarQt   --- https://github.com/matplotlib/matplotlib/blob/master/lib/matplotlib/backends/backend_qt5.py
        tm = fig.canvas.manager.toolmanager

        self.tm = tm
        # Tool: Print point location
        ToolPointPosition.image = str(imgs_path / 'click.png')
        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            tm.add_tool("Point_position", ToolPointPosition, parent=self)
        fig.canvas.manager.toolbar.add_tool(tm.get_tool("Point_position"),
                                            "toolgroup")

        # Tool: Copy to Clipboard
        from matplotlib.backend_tools import ToolCopyToClipboard
        ToolCopyToClipboard.image = str(imgs_path / 'copy.png')
        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            # OVvrwties Ctrl+C and issues warning
            tm.add_tool("Copy_to_clipboard", ToolCopyToClipboard)
        fig.canvas.manager.toolbar.add_tool(tm.get_tool("Copy_to_clipboard"),
                                            "toolgroup")

        if 1:  # add QT Pieces
            toolbar.action_ascale = QAction(
                QIcon(str(imgs_path / 'auto_zoom.png')), 'Auto scale', toolbar)
            toolbar.action_ascale.setShortcut('A')
            toolbar.action_ascale.setShortcutContext(Qt.WindowShortcut)
            toolbar.action_ascale.setStatusTip('Autoscale')
            toolbar.action_ascale.triggered.connect(self.auto_scale)
            toolbar.addAction(toolbar.action_ascale)

        # Status Bar: Second label to report
        figManager = fig.canvas.manager  # plt.get_current_fig_manager()
        status_bar = figManager.window.statusBar()
        self._status_label_2 = QLabel(status_bar)
        self._status_label_2.setText('')
        status_bar.addWidget(self._status_label_2)
        #from matplotlib.backends.backend_qt5 import StatusbarQt
        #st = StatusbarQt(figManager.window, figManager.toolmanager)
        # figManager.statusbar.set_message('')

    def auto_scale(self):
        """Auto scaler."""
        for ax in self.figure.axes:
            ax.autoscale()
        # self.figure.canvas.flush_events()
        self.figure.canvas.draw()

    def _style_figure(self):
        """Style figure."""
        #self.figure.dpi = 150
        pass

    @staticmethod
    def _pan_update_limits(ax, axis_id, event, last_event):
        """Compute limits with applied pan.

        Args:
            axis_id (int): ID of the axis
            event (event): The event
            last_event (event): The previous event

        Returns:
            double: New limit

        Raises:
            ValueError: Value error
            OverflowError: Overflow error
        """
        assert axis_id in (0, 1)
        if axis_id == 0:
            lim = ax.get_xlim()
            scale = ax.get_xscale()
        else:
            lim = ax.get_ylim()
            scale = ax.get_yscale()

        pixel_to_data = ax.transData.inverted()
        data = pixel_to_data.transform_point((event.x, event.y))
        last_data = pixel_to_data.transform_point((last_event.x, last_event.y))

        if scale == 'linear':
            delta = data[axis_id] - last_data[axis_id]
            new_lim = lim[0] - delta, lim[1] - delta
        elif scale == 'log':
            try:
                delta = math.log10(data[axis_id]) - \
                    math.log10(last_data[axis_id])
                new_lim = [
                    pow(10., (math.log10(lim[0]) - delta)),
                    pow(10., (math.log10(lim[1]) - delta))
                ]
            except (ValueError, OverflowError):
                new_lim = lim  # Keep previous limits
        else:
            logging.warning('Pan not implemented for scale "%s"' % scale)
            new_lim = lim
        return new_lim

    def _pan(self, event):
        """Pan.

        Args:
            event (event): The event
        """
        if event.name == 'button_press_event':  # begin pan
            self._event = event

        elif event.name == 'button_release_event':  # end pan
            self._event = None

        elif event.name == 'motion_notify_event':  # pan
            if self._event is None:
                return

            if event.x != self._event.x:
                for ax in self._axes[0]:
                    xlim = self._pan_update_limits(ax, 0, event, self._event)
                    ax.set_xlim(xlim)

            if event.y != self._event.y:
                for ax in self._axes[1]:
                    ylim = self._pan_update_limits(ax, 1, event, self._event)
                    ax.set_ylim(ylim)

            if event.x != self._event.x or event.y != self._event.y:
                self._draw()

            self._event = event

    def _zoom_area(self, event):
        """Zoom.

        Args:
            event (event): The event
        """
        if event.name == 'button_press_event':  # begin drag
            self._event = event
            # pylint: disable=attribute-defined-outside-init
            self._patch = _plt.Rectangle(xy=(event.xdata, event.ydata),
                                         width=0,
                                         height=0,
                                         fill=False,
                                         linewidth=1.,
                                         linestyle='solid',
                                         color='black')
            self._event.inaxes.add_patch(self._patch)

        elif event.name == 'button_release_event':  # end drag
            self._patch.remove()
            del self._patch

            if (abs(event.x - self._event.x) < 3
                    or abs(event.y - self._event.y) < 3):
                return  # No zoom when points are too close

            x_axes, y_axes = self._axes

            for ax in x_axes:
                pixel_to_data = ax.transData.inverted()
                begin_pt = pixel_to_data.transform_point((event.x, event.y))
                end_pt = pixel_to_data.transform_point(
                    (self._event.x, self._event.y))

                min_ = min(begin_pt[0], end_pt[0])
                max_ = max(begin_pt[0], end_pt[0])
                if not ax.xaxis_inverted():
                    ax.set_xlim(min_, max_)
                else:
                    ax.set_xlim(max_, min_)

            for ax in y_axes:
                pixel_to_data = ax.transData.inverted()
                begin_pt = pixel_to_data.transform_point((event.x, event.y))
                end_pt = pixel_to_data.transform_point(
                    (self._event.x, self._event.y))

                min_ = min(begin_pt[1], end_pt[1])
                max_ = max(begin_pt[1], end_pt[1])
                if not ax.yaxis_inverted():
                    ax.set_ylim(min_, max_)
                else:
                    ax.set_ylim(max_, min_)

            self._event = None

        elif event.name == 'motion_notify_event':  # drag
            if self._event is None:
                return

            if event.inaxes != self._event.inaxes:
                return  # Ignore event outside plot

            self._patch.set_width(event.xdata - self._event.xdata)
            self._patch.set_height(event.ydata - self._event.ydata)

        self._draw()

    def _on_mouse_press(self, event):
        """Mouse press event.

        Args:
            event (event): The event
        """
        if self._pressed_button is not None:
            return  # Discard event if a button is already pressed

        if event.button in (1, 3):  # Start
            x_axes, y_axes = self._axes_to_update(event)
            if x_axes or y_axes:
                self._axes = x_axes, y_axes
                self._pressed_button = event.button

                if self._pressed_button == 1:  # pan
                    self._pan(event)

                    if self.options.report_point_position:  # check if we want to report point
                        self._report_point_position(event)

                elif self._pressed_button == 3:  # zoom area
                    self._zoom_area(event)

    def _on_mouse_release(self, event):
        """Mouse release event.

        Args:
            event (event): The event
        """
        if self._pressed_button == event.button:
            if self._pressed_button == 1:  # pan
                self._pan(event)
            elif self._pressed_button == 3:  # zoom area
                self._zoom_area(event)
            self._pressed_button = None

    def _on_mouse_motion(self, event):
        """Mouse motion event.

        Args:
            event (event): The event
        """
        if self._pressed_button == 1:  # pan
            self._pan(event)
        elif self._pressed_button == 3:  # zoom area
            self._zoom_area(event)

    def _report_point_position(self, event):
        """Report point position.

        Args:
            event (event): the event
        """
        ix, iy = event.xdata, event.ydata

        if hasattr(self, '_ix_iy_old'):
            ix_old, iy_old = self._ix_iy_old
        else:
            ix_old, iy_old = (ix, iy)

        self._ix_iy_old = ix, iy

        _text = f'(x,y) = ({ix:.4f}, {iy:.4f})  Δ last point ({ix-ix_old:.4f}, {iy-iy_old:.4f})'
        if self.logger:
            self.logger.info(_text)
        if self._statusbar_label:
            self._statusbar_label.setText(_text)
    def __init__(self, params):
        MWB.__init__(self, params)
        QLabel.__init__(self)

        self.resize(200, 200)
Example #24
0
class SettingsDialog(CustomDialog):
    def __init__(self, parent=None):
        super(SettingsDialog, self).__init__(parent, "Settings")

        mouse_box = QGroupBox("Mouse", self)
        mouse_box.setLayout(QVBoxLayout())

        label = QLabel("Scroll objects with mouse wheel:")
        label.setToolTip(
            "Select an object and scroll up and down to change its type.")
        self._scroll_check_box = QCheckBox("Enabled")
        self._scroll_check_box.setChecked(SETTINGS["object_scroll_enabled"])
        self._scroll_check_box.toggled.connect(self._update_settings)

        scroll_layout = QHBoxLayout()
        scroll_layout.addWidget(label)
        scroll_layout.addStretch(1)
        scroll_layout.addWidget(self._scroll_check_box)

        label = QLabel("Show object names on hover:")
        label.setToolTip(
            "When hovering your cursor over an object in a level, its name and position is shown in a tooltip."
        )
        self._tooltip_check_box = QCheckBox("Enabled")
        self._tooltip_check_box.setChecked(SETTINGS["object_tooltip_enabled"])
        self._tooltip_check_box.toggled.connect(self._update_settings)

        tooltip_layout = QHBoxLayout()
        tooltip_layout.addWidget(label)
        tooltip_layout.addStretch(1)
        tooltip_layout.addWidget(self._tooltip_check_box)

        self.lmb_radio = QRadioButton("Left Mouse Button")
        rmb_radio = QRadioButton("Right Mouse Button")

        self.lmb_radio.setChecked(SETTINGS["resize_mode"] == RESIZE_LEFT_CLICK)
        rmb_radio.setChecked(SETTINGS["resize_mode"] == RESIZE_RIGHT_CLICK)

        self.lmb_radio.toggled.connect(self._update_settings)

        radio_group = QButtonGroup()
        radio_group.addButton(self.lmb_radio)
        radio_group.addButton(rmb_radio)

        resize_layout = QHBoxLayout()
        resize_layout.addWidget(QLabel("Object resize mode:"))
        resize_layout.addStretch(1)
        resize_layout.addWidget(self.lmb_radio)
        resize_layout.addWidget(rmb_radio)

        mouse_box.layout().addLayout(scroll_layout)
        mouse_box.layout().addLayout(tooltip_layout)
        mouse_box.layout().addLayout(resize_layout)

        # -----------------------------------------------
        # GUI theme section

        self.gui_style_box = QGroupBox("GUI", self)
        QHBoxLayout(self.gui_style_box)

        self.gui_style_box.layout().addWidget(QLabel("Style:"))

        for gui_style in GUI_STYLE.keys():
            gui_style = gui_style.capitalize()

            style_radio_button = QRadioButton(gui_style)
            style_radio_button.setChecked(
                SETTINGS["gui_style"] == GUI_STYLE[gui_style.upper()]())
            style_radio_button.toggled.connect(self._update_settings)

            self.gui_style_box.layout().addWidget(style_radio_button)

        # -----------------------------------------------
        # emulator command

        self.emulator_command_input = QLineEdit(self)
        self.emulator_command_input.setPlaceholderText("Path to emulator")
        self.emulator_command_input.setText(SETTINGS["instaplay_emulator"])

        self.emulator_command_input.textChanged.connect(self._update_settings)

        self.emulator_path_button = QPushButton(icon("folder.svg"), "", self)
        self.emulator_path_button.pressed.connect(self._get_emulator_path)

        self.command_arguments_input = QLineEdit(self)
        self.command_arguments_input.setPlaceholderText("%f")
        self.command_arguments_input.setText(SETTINGS["instaplay_arguments"])

        self.command_arguments_input.textEdited.connect(self._update_settings)

        self.command_label = QLabel()

        command_box = QGroupBox("Emulator", self)
        command_layout = QVBoxLayout(command_box)

        command_layout.addWidget(QLabel('Emulator command or "path to exe":'))

        command_input_layout = QHBoxLayout()
        command_input_layout.addWidget(self.emulator_command_input)
        command_input_layout.addWidget(self.emulator_path_button)

        command_layout.addLayout(command_input_layout)
        command_layout.addWidget(
            QLabel("Command arguments (%f will be replaced with rom path):"))
        command_layout.addWidget(self.command_arguments_input)
        command_layout.addWidget(QLabel("Command used to play the rom:"))
        command_layout.addWidget(self.command_label)

        command_layout.addWidget(HorizontalLine())

        command_layout.addWidget(
            QLabel("Power up of Mario when playing level:"))
        self.powerup_combo_box = QComboBox()

        for name, x, y, value, p_wing in POWERUPS:
            powerup_icon = self._load_from_png(x, y)

            self.powerup_combo_box.addItem(powerup_icon, name)

        self.powerup_combo_box.currentIndexChanged.connect(
            self._update_settings)

        self.powerup_combo_box.setCurrentIndex(SETTINGS["default_powerup"])

        command_layout.addWidget(self.powerup_combo_box)

        # ----------------------

        layout = QVBoxLayout(self)
        layout.addWidget(mouse_box)
        layout.addWidget(self.gui_style_box)
        layout.addWidget(command_box)

        self.update()

    def update(self):
        self.command_label.setText(
            f" > {SETTINGS['instaplay_emulator']} {SETTINGS['instaplay_arguments']}"
        )

    def _update_settings(self, _):
        SETTINGS["instaplay_emulator"] = self.emulator_command_input.text()
        SETTINGS["instaplay_arguments"] = self.command_arguments_input.text()

        if self.lmb_radio.isChecked():
            SETTINGS["resize_mode"] = RESIZE_LEFT_CLICK
        else:
            SETTINGS["resize_mode"] = RESIZE_RIGHT_CLICK

        # setup style sheets
        for child_widget in self.gui_style_box.children():
            if isinstance(child_widget, QRadioButton):
                if child_widget.isChecked():
                    selected_gui_style = child_widget.text().upper()

                    loaded_style_sheet = GUI_STYLE[selected_gui_style]()
                    SETTINGS["gui_style"] = loaded_style_sheet

                    self.parent().setStyleSheet(SETTINGS["gui_style"])
                    break

        SETTINGS["object_scroll_enabled"] = self._scroll_check_box.isChecked()
        SETTINGS["object_tooltip_enabled"] = self._tooltip_check_box.isChecked(
        )

        SETTINGS["default_powerup"] = self.powerup_combo_box.currentIndex()

        self.update()

    def _get_emulator_path(self):
        path_to_emulator, _ = QFileDialog.getOpenFileName(
            self, caption="Select emulator executable")

        if not path_to_emulator:
            return

        self.emulator_command_input.setText(path_to_emulator)

    @staticmethod
    def _load_from_png(x: int, y: int) -> QIcon:
        image = png.copy(
            QRect(x * Block.SIDE_LENGTH, y * Block.SIDE_LENGTH,
                  Block.SIDE_LENGTH, Block.SIDE_LENGTH))
        mask = image.createMaskFromColor(
            QColor(*MASK_COLOR).rgb(), Qt.MaskOutColor)
        image.setAlphaChannel(mask)

        pixmap = QPixmap.fromImage(image)
        icon_from_png = QIcon(pixmap)

        return icon_from_png

    def on_exit(self):
        save_settings()

        super(SettingsDialog, self).on_exit()
Example #25
0
class RaccourcisPage(QWidget):
    def __init__(self, parent):
        super(RaccourcisPage, self).__init__()
        self.parent = parent
        self.grid = QGridLayout()

        self.title = QLabel("Raccourcis URL")
        self.title.setAlignment(Qt.AlignHCenter)
        self.listeW = ListWidget(
            self.parent.parent.db.executewithreturn(
                """SELECT * FROM raccourcis"""))
        self.liste = self.listeW.liste
        self.supp = PushButton("Supprimer")
        self.suppAll = PushButton("Tout supprimer")
        self.spacerItem = QSpacerItem(20, 20)
        self.tEntryString = "Nom du raccourci"
        self.uEntryString = "URL du raccourci"
        self.tEntry = QLineEdit(self.tEntryString)
        self.uEntry = QLineEdit(self.uEntryString)
        self.addRac = PushButton("Ajouter un raccourci URL")

        self.listeW.itemDoubleClicked.connect(self.launch)
        self.suppAll.clicked.connect(self.deleteall)
        self.supp.clicked.connect(self.delete)
        self.addRac.clicked.connect(self.addraccourci)

        self.grid.addWidget(self.title, 1, 1, 1, 2)
        self.grid.addWidget(self.listeW, 2, 1, 1, 2)
        self.grid.addWidget(self.supp, 3, 1)
        self.grid.addWidget(self.suppAll, 3, 2)
        self.grid.addItem(self.spacerItem, 4, 1, 1, 2)
        self.grid.addWidget(self.tEntry, 5, 1)
        self.grid.addWidget(self.uEntry, 5, 2)
        self.grid.addWidget(self.addRac, 6, 1, 1, 2)

        self.setLayout(self.grid)

    def launch(self):
        if self.listeW.currentItem():
            for i in self.liste:
                if str(i[0]) == self.listeW.currentItem().text(3):
                    self.parent.close()
                    self.parent.parent.opennewongletwithurl(i[2])
                    break

    def addraccourci(self):
        raccourcis = self.parent.parent.db.executewithreturn(
            """SELECT * FROM raccourcis""")
        for i in raccourcis:
            if i[1] == self.tEntry.text():
                QMessageBox.warning(self, "Erreur",
                                    "Ce raccourcis existe déjà.")
                return

        tentrybool = self.tEntry.text() != "" and self.tEntry.text(
        ) != self.tEntryString
        uentrybool = self.uEntry.text() != "" and self.uEntry.text(
        ) != self.uEntryString
        if tentrybool and uentrybool:
            self.parent.parent.db.executewithoutreturn(
                """INSERT INTO raccourcis(name, url, date) VALUES(?, ?, ?)""",
                (self.tEntry.text(), self.uEntry.text(), getdate()))
            self.showupdate()

    def showupdate(self):
        self.listeW.deleteallitems()
        self.liste = self.parent.parent.db.executewithreturn(
            """SELECT * FROM raccourcis""")
        self.listeW.updatelist(self.liste)

    def delete(self):
        if self.listeW.currentItem():
            for i in self.liste:
                if str(i[0]) == self.listeW.currentItem().text(3):
                    self.parent.parent.db.executewithoutreturn(
                        """DELETE FROM raccourcis WHERE id = ?""", (i[0], ))
        self.showupdate()

    def deleteall(self):
        self.parent.parent.db.executewithoutreturn(
            """DELETE FROM raccourcis""")
        self.showupdate()
Example #26
0
    def createLayout(self):
        self.GridGroupBox = QGroupBox("ESD tranisent control")
        l1 = QLabel("HOST PORT")

        h1 = QHBoxLayout()

        a3host = QLineEdit('127.0.0.1')
        a3col = QLabel(':')
        a3port = QLineEdit('22222')
        h1.addWidget(a3host)
        h1.addWidget(a3col)
        h1.addWidget(a3port)

        l3 = QLabel("COM port")

        hbb = QHBoxLayout()
        comport = QComboBox()
        #comport.addItem('COM1')
        comport.addItems(['COM1', 'COM2', 'COM3', 'COM4', 'COM5'])
        l4 = QLabel("Baue rate")
        comBaud = QComboBox()
        comBaud.addItems(['9600', '115200'])
        hbb.addWidget(comport)
        hbb.addWidget(l4)
        hbb.addWidget(comBaud)

        l4 = QLabel("Profile CSV")
        self.prof = QLineEdit()
        hb = QHBoxLayout()
        btnSel = QPushButton("Select")
        btnSel.clicked.connect(self.openFileNameDialog)
        hb.addWidget(self.prof)
        hb.addWidget(btnSel)

        l5 = QLabel("INCA Label")
        self.label = QLineEdit("PhyMod_trq2qBas_MAP")
        self.labelType = QComboBox()
        l6 = QLabel("Type")
        self.labelType.addItems([r'MAP/CURVE', 'Single'])
        h2 = QHBoxLayout()
        h2.addWidget(self.label)
        h2.addWidget(l6)
        h2.addWidget(self.labelType)

        fbox = QFormLayout()
        fbox.addRow(l1, h1)
        fbox.addRow(l3, hbb)
        fbox.addRow(l4, hb)
        fbox.addRow(l5, h2)
        hbox = QHBoxLayout()

        init = QPushButton("Init")
        HeatBeat = QPushButton("Heart beat")
        run = QPushButton("Run")
        stop = QPushButton("Stop")
        hbox.addWidget(init)
        hbox.addWidget(stop)
        hbox.addWidget(run)
        hbox.addWidget(HeatBeat)
        fbox.addRow(QLabel("control"), hbox)

        self.GridGroupBox.setLayout(fbox)
Example #27
0
    def __init__(self, filename, image, parent=None):
        super(ComparisonWidget, self).__init__(parent)

        load_button = QPushButton(self.tr('Load reference image...'))
        self.comp_label = QLabel(self.tr('Comparison:'))
        self.normal_radio = QRadioButton(self.tr('Normal'))
        self.normal_radio.setToolTip(self.tr('Show reference (raw pixels)'))
        self.normal_radio.setChecked(True)
        self.difference_radio = QRadioButton(self.tr('Difference'))
        self.difference_radio.setToolTip(
            self.tr('Show evidence/reference difference'))
        self.ssim_radio = QRadioButton(self.tr('SSIM Map'))
        self.ssim_radio.setToolTip(self.tr('Structure similarity quality map'))
        self.butter_radio = QRadioButton(self.tr('Butteraugli'))
        self.butter_radio.setToolTip(
            self.tr('Butteraugli spatial changes heatmap'))
        self.gray_check = QCheckBox(self.tr('Grayscale'))
        self.gray_check.setToolTip(self.tr('Show desaturated output'))
        self.equalize_check = QCheckBox(self.tr('Equalized'))
        self.equalize_check.setToolTip(self.tr('Apply histogram equalization'))
        self.last_radio = self.normal_radio
        self.metric_button = QPushButton(self.tr('Compute metrics'))
        self.metric_button.setToolTip(
            self.tr('Image quality assessment metrics'))

        self.evidence = image
        self.reference = self.difference = self.ssim_map = self.butter_map = None
        basename = os.path.basename(filename)
        self.evidence_viewer = ImageViewer(
            self.evidence, None, self.tr('Evidence: {}'.format(basename)))
        self.reference_viewer = ImageViewer(np.full_like(self.evidence, 127),
                                            None, self.tr('Reference'))

        self.table_widget = QTableWidget(21, 3)
        self.table_widget.setHorizontalHeaderLabels(
            [self.tr('Metric'),
             self.tr('Value'),
             self.tr('Better')])
        self.table_widget.setItem(0, 0, QTableWidgetItem(self.tr('RMSE')))
        self.table_widget.setItem(
            0, 2, QTableWidgetItem(QIcon('icons/low.svg'), '(0)'))
        self.table_widget.item(0, 0).setToolTip(
            self.
            tr('Root Mean Square Error (RMSE) is commonly used to compare \n'
               'the difference between the reference and evidence images \n'
               'by directly computing the variation in pixel values. \n'
               'The combined image is close to the reference image when \n'
               'RMSE value is zero. RMSE is a good indicator of the spectral \n'
               'quality of the reference image.'))
        self.table_widget.setItem(1, 0, QTableWidgetItem(self.tr('SAM')))
        self.table_widget.setItem(
            1, 2, QTableWidgetItem(QIcon('icons/low.svg'), '(0)'))
        self.table_widget.item(1, 0).setToolTip(
            self.
            tr('It computes the spectral angle between the pixel, vector of the \n'
               'evidence image and reference image. It is worked out in either \n'
               'degrees or radians. It is performed on a pixel-by-pixel base. \n'
               'A SAM equal to zero denotes the absence of spectral distortion.'
               ))
        self.table_widget.setItem(2, 0, QTableWidgetItem(self.tr('ERGAS')))
        self.table_widget.setItem(
            2, 2, QTableWidgetItem(QIcon('icons/low.svg'), '(0)'))
        self.table_widget.item(2, 0).setToolTip(
            self.
            tr('It is used to compute the quality of reference image in terms \n'
               'of normalized average error of each band of the reference image. \n'
               'Increase in the value of ERGAS indicates distortion in the \n'
               'reference image, lower value of ERGAS indicates that it is \n'
               'similar to the reference image.'))
        self.table_widget.setItem(3, 0, QTableWidgetItem(self.tr('MB')))
        self.table_widget.setItem(
            3, 2, QTableWidgetItem(QIcon('icons/low.svg'), '(0)'))
        self.table_widget.item(3, 0).setToolTip(
            self.
            tr('Mean Bias is the difference between the mean of the evidence \n'
               'image and reference image. The ideal value is zero and indicates \n'
               'that the evidence and reference images are similar. Mean value \n'
               'refers to the grey level of pixels in an image.'))
        self.table_widget.setItem(4, 0, QTableWidgetItem(self.tr('PFE')))
        self.table_widget.setItem(
            4, 2, QTableWidgetItem(QIcon('icons/low.svg'), '(0)'))
        self.table_widget.item(4, 0).setToolTip(
            self.
            tr('It computes the norm of the difference between the corresponding \n'
               'pixels of the reference and fused image to the norm of the reference \n'
               'image. When the calculated value is zero, it indicates that both the \n'
               'reference and fused images are similar and value will be increased \n'
               'when the merged image is not similar to the reference image.'))
        self.table_widget.setItem(5, 0, QTableWidgetItem(self.tr('PSNR')))
        self.table_widget.setItem(
            5, 2,
            QTableWidgetItem(QIcon('icons/high.svg'), '(+' + u'\u221e' + ')'))
        self.table_widget.item(5, 0).setToolTip(
            self.
            tr('It is widely used metric it is computed by the number of gray levels \n'
               'in the image divided by the corresponding pixels in the evidence and \n'
               'the reference images. When the value is high, both images are similar.'
               ))
        self.table_widget.setItem(6, 0, QTableWidgetItem(self.tr('PSNR-B')))
        self.table_widget.setItem(
            6, 2,
            QTableWidgetItem(QIcon('icons/high.svg'), '(+' + u'\u221e' + ')'))
        self.table_widget.item(6, 0).setToolTip(
            self.tr('PSNR with Blocking Effect Factor.'))
        self.table_widget.setItem(7, 0, QTableWidgetItem(self.tr('SSIM')))
        self.table_widget.setItem(
            7, 2, QTableWidgetItem(QIcon('icons/high.svg'), '(1)'))
        self.table_widget.item(7, 0).setToolTip(
            self.
            tr('SSIM is used to compare the local patterns of pixel intensities between \n'
               ' the reference and fused images. The range varies between -1 to 1. \n'
               'The value 1 indicates the reference and fused images are similar.'
               ))
        self.table_widget.setItem(8, 0, QTableWidgetItem(self.tr('MS-SSIM')))
        self.table_widget.setItem(
            8, 2, QTableWidgetItem(QIcon('icons/high.svg'), '(1)'))
        self.table_widget.item(8, 0).setToolTip(
            self.tr('Multiscale version of SSIM.'))
        self.table_widget.setItem(9, 0, QTableWidgetItem(self.tr('RASE')))
        self.table_widget.setItem(
            9, 2, QTableWidgetItem(QIcon('icons/low.svg'), '(0)'))
        self.table_widget.item(9, 0).setToolTip(
            self.tr('Relative average spectral error'))
        self.table_widget.setItem(10, 0, QTableWidgetItem(self.tr('SCC')))
        self.table_widget.setItem(
            10, 2, QTableWidgetItem(QIcon('icons/high.svg'), '(1)'))
        self.table_widget.item(10, 0).setToolTip(
            self.tr('Spatial Correlation Coefficient'))
        self.table_widget.setItem(11, 0, QTableWidgetItem(self.tr('UQI')))
        self.table_widget.setItem(
            11, 2, QTableWidgetItem(QIcon('icons/high.svg'), '(1)'))
        self.table_widget.item(11, 0).setToolTip(
            self.tr('Universal Image Quality Index'))
        self.table_widget.setItem(12, 0, QTableWidgetItem(self.tr('VIF-P')))
        self.table_widget.setItem(
            12, 2, QTableWidgetItem(QIcon('icons/high.svg'), '(1)'))
        self.table_widget.item(12, 0).setToolTip(
            self.tr('Pixel-based Visual Information Fidelity'))
        self.table_widget.setItem(13, 0,
                                  QTableWidgetItem(self.tr('SSIMulacra')))
        self.table_widget.setItem(
            13, 2, QTableWidgetItem(QIcon('icons/low.svg'), '(0)'))
        self.table_widget.item(13, 0).setToolTip(
            self.tr('Structural SIMilarity Unveiling Local '
                    'And Compression Related Artifacts'))
        self.table_widget.setItem(14, 0,
                                  QTableWidgetItem(self.tr('Butteraugli')))
        self.table_widget.setItem(
            14, 2, QTableWidgetItem(QIcon('icons/low.svg'), '(0)'))
        self.table_widget.item(14, 0).setToolTip(
            self.tr('Estimate psychovisual error'))
        self.table_widget.setItem(15, 0,
                                  QTableWidgetItem(self.tr('Correlation')))
        self.table_widget.setItem(
            15, 2, QTableWidgetItem(QIcon('icons/high.svg'), '(1)'))
        self.table_widget.item(15,
                               0).setToolTip(self.tr('Histogram correlation'))
        self.table_widget.setItem(16, 0,
                                  QTableWidgetItem(self.tr('Chi-Square')))
        self.table_widget.setItem(
            16, 2, QTableWidgetItem(QIcon('icons/low.svg'), '(0)'))
        self.table_widget.item(16,
                               0).setToolTip(self.tr('Histogram Chi-Square'))
        self.table_widget.setItem(17, 0,
                                  QTableWidgetItem(self.tr('Chi-Square 2')))
        self.table_widget.setItem(
            17, 2, QTableWidgetItem(QIcon('icons/low.svg'), '(0)'))
        self.table_widget.item(17,
                               0).setToolTip(self.tr('Alternative Chi-Square'))
        self.table_widget.setItem(18, 0,
                                  QTableWidgetItem(self.tr('Intersection')))
        self.table_widget.setItem(
            18, 2,
            QTableWidgetItem(QIcon('icons/high.svg'), '(+' + u'\u221e' + ')'))
        self.table_widget.item(18,
                               0).setToolTip(self.tr('Histogram intersection'))
        self.table_widget.setItem(19, 0,
                                  QTableWidgetItem(self.tr('Hellinger')))
        self.table_widget.setItem(
            19, 2, QTableWidgetItem(QIcon('icons/low.svg'), '(0)'))
        self.table_widget.item(19, 0).setToolTip(
            self.tr('Histogram Hellinger distance'))
        self.table_widget.setItem(20, 0,
                                  QTableWidgetItem(self.tr('Divergence')))
        self.table_widget.setItem(
            20, 2, QTableWidgetItem(QIcon('icons/low.svg'), '(0)'))
        self.table_widget.item(20, 0).setToolTip(
            self.tr('Kullback-Leibler divergence'))

        for i in range(self.table_widget.rowCount()):
            modify_font(self.table_widget.item(i, 0), bold=True)
        self.table_widget.setSelectionMode(QAbstractItemView.SingleSelection)
        self.table_widget.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.table_widget.resizeColumnsToContents()
        self.table_widget.setMaximumWidth(250)
        self.table_widget.setAlternatingRowColors(True)
        self.stopped = False

        self.comp_label.setEnabled(False)
        self.normal_radio.setEnabled(False)
        self.difference_radio.setEnabled(False)
        self.ssim_radio.setEnabled(False)
        self.butter_radio.setEnabled(False)
        self.gray_check.setEnabled(False)
        self.equalize_check.setEnabled(False)
        self.metric_button.setEnabled(False)
        self.table_widget.setEnabled(False)

        load_button.clicked.connect(self.load)
        self.normal_radio.clicked.connect(self.change)
        self.difference_radio.clicked.connect(self.change)
        self.butter_radio.clicked.connect(self.change)
        self.gray_check.stateChanged.connect(self.change)
        self.equalize_check.stateChanged.connect(self.change)
        self.ssim_radio.clicked.connect(self.change)
        self.evidence_viewer.viewChanged.connect(
            self.reference_viewer.changeView)
        self.reference_viewer.viewChanged.connect(
            self.evidence_viewer.changeView)
        self.metric_button.clicked.connect(self.metrics)

        top_layout = QHBoxLayout()
        top_layout.addWidget(load_button)
        top_layout.addStretch()
        top_layout.addWidget(self.comp_label)
        top_layout.addWidget(self.normal_radio)
        top_layout.addWidget(self.difference_radio)
        top_layout.addWidget(self.ssim_radio)
        top_layout.addWidget(self.butter_radio)
        top_layout.addWidget(self.gray_check)
        top_layout.addWidget(self.equalize_check)

        metric_layout = QVBoxLayout()
        index_label = QLabel(self.tr('Image Quality Assessment'))
        index_label.setAlignment(Qt.AlignCenter)
        modify_font(index_label, bold=True)
        metric_layout.addWidget(index_label)
        metric_layout.addWidget(self.table_widget)
        metric_layout.addWidget(self.metric_button)

        center_layout = QHBoxLayout()
        center_layout.addWidget(self.evidence_viewer)
        center_layout.addWidget(self.reference_viewer)
        center_layout.addLayout(metric_layout)

        main_layout = QVBoxLayout()
        main_layout.addLayout(top_layout)
        main_layout.addLayout(center_layout)
        self.setLayout(main_layout)
Example #28
0
class ComparisonWidget(ToolWidget):
    def __init__(self, filename, image, parent=None):
        super(ComparisonWidget, self).__init__(parent)

        load_button = QPushButton(self.tr('Load reference image...'))
        self.comp_label = QLabel(self.tr('Comparison:'))
        self.normal_radio = QRadioButton(self.tr('Normal'))
        self.normal_radio.setToolTip(self.tr('Show reference (raw pixels)'))
        self.normal_radio.setChecked(True)
        self.difference_radio = QRadioButton(self.tr('Difference'))
        self.difference_radio.setToolTip(
            self.tr('Show evidence/reference difference'))
        self.ssim_radio = QRadioButton(self.tr('SSIM Map'))
        self.ssim_radio.setToolTip(self.tr('Structure similarity quality map'))
        self.butter_radio = QRadioButton(self.tr('Butteraugli'))
        self.butter_radio.setToolTip(
            self.tr('Butteraugli spatial changes heatmap'))
        self.gray_check = QCheckBox(self.tr('Grayscale'))
        self.gray_check.setToolTip(self.tr('Show desaturated output'))
        self.equalize_check = QCheckBox(self.tr('Equalized'))
        self.equalize_check.setToolTip(self.tr('Apply histogram equalization'))
        self.last_radio = self.normal_radio
        self.metric_button = QPushButton(self.tr('Compute metrics'))
        self.metric_button.setToolTip(
            self.tr('Image quality assessment metrics'))

        self.evidence = image
        self.reference = self.difference = self.ssim_map = self.butter_map = None
        basename = os.path.basename(filename)
        self.evidence_viewer = ImageViewer(
            self.evidence, None, self.tr('Evidence: {}'.format(basename)))
        self.reference_viewer = ImageViewer(np.full_like(self.evidence, 127),
                                            None, self.tr('Reference'))

        self.table_widget = QTableWidget(21, 3)
        self.table_widget.setHorizontalHeaderLabels(
            [self.tr('Metric'),
             self.tr('Value'),
             self.tr('Better')])
        self.table_widget.setItem(0, 0, QTableWidgetItem(self.tr('RMSE')))
        self.table_widget.setItem(
            0, 2, QTableWidgetItem(QIcon('icons/low.svg'), '(0)'))
        self.table_widget.item(0, 0).setToolTip(
            self.
            tr('Root Mean Square Error (RMSE) is commonly used to compare \n'
               'the difference between the reference and evidence images \n'
               'by directly computing the variation in pixel values. \n'
               'The combined image is close to the reference image when \n'
               'RMSE value is zero. RMSE is a good indicator of the spectral \n'
               'quality of the reference image.'))
        self.table_widget.setItem(1, 0, QTableWidgetItem(self.tr('SAM')))
        self.table_widget.setItem(
            1, 2, QTableWidgetItem(QIcon('icons/low.svg'), '(0)'))
        self.table_widget.item(1, 0).setToolTip(
            self.
            tr('It computes the spectral angle between the pixel, vector of the \n'
               'evidence image and reference image. It is worked out in either \n'
               'degrees or radians. It is performed on a pixel-by-pixel base. \n'
               'A SAM equal to zero denotes the absence of spectral distortion.'
               ))
        self.table_widget.setItem(2, 0, QTableWidgetItem(self.tr('ERGAS')))
        self.table_widget.setItem(
            2, 2, QTableWidgetItem(QIcon('icons/low.svg'), '(0)'))
        self.table_widget.item(2, 0).setToolTip(
            self.
            tr('It is used to compute the quality of reference image in terms \n'
               'of normalized average error of each band of the reference image. \n'
               'Increase in the value of ERGAS indicates distortion in the \n'
               'reference image, lower value of ERGAS indicates that it is \n'
               'similar to the reference image.'))
        self.table_widget.setItem(3, 0, QTableWidgetItem(self.tr('MB')))
        self.table_widget.setItem(
            3, 2, QTableWidgetItem(QIcon('icons/low.svg'), '(0)'))
        self.table_widget.item(3, 0).setToolTip(
            self.
            tr('Mean Bias is the difference between the mean of the evidence \n'
               'image and reference image. The ideal value is zero and indicates \n'
               'that the evidence and reference images are similar. Mean value \n'
               'refers to the grey level of pixels in an image.'))
        self.table_widget.setItem(4, 0, QTableWidgetItem(self.tr('PFE')))
        self.table_widget.setItem(
            4, 2, QTableWidgetItem(QIcon('icons/low.svg'), '(0)'))
        self.table_widget.item(4, 0).setToolTip(
            self.
            tr('It computes the norm of the difference between the corresponding \n'
               'pixels of the reference and fused image to the norm of the reference \n'
               'image. When the calculated value is zero, it indicates that both the \n'
               'reference and fused images are similar and value will be increased \n'
               'when the merged image is not similar to the reference image.'))
        self.table_widget.setItem(5, 0, QTableWidgetItem(self.tr('PSNR')))
        self.table_widget.setItem(
            5, 2,
            QTableWidgetItem(QIcon('icons/high.svg'), '(+' + u'\u221e' + ')'))
        self.table_widget.item(5, 0).setToolTip(
            self.
            tr('It is widely used metric it is computed by the number of gray levels \n'
               'in the image divided by the corresponding pixels in the evidence and \n'
               'the reference images. When the value is high, both images are similar.'
               ))
        self.table_widget.setItem(6, 0, QTableWidgetItem(self.tr('PSNR-B')))
        self.table_widget.setItem(
            6, 2,
            QTableWidgetItem(QIcon('icons/high.svg'), '(+' + u'\u221e' + ')'))
        self.table_widget.item(6, 0).setToolTip(
            self.tr('PSNR with Blocking Effect Factor.'))
        self.table_widget.setItem(7, 0, QTableWidgetItem(self.tr('SSIM')))
        self.table_widget.setItem(
            7, 2, QTableWidgetItem(QIcon('icons/high.svg'), '(1)'))
        self.table_widget.item(7, 0).setToolTip(
            self.
            tr('SSIM is used to compare the local patterns of pixel intensities between \n'
               ' the reference and fused images. The range varies between -1 to 1. \n'
               'The value 1 indicates the reference and fused images are similar.'
               ))
        self.table_widget.setItem(8, 0, QTableWidgetItem(self.tr('MS-SSIM')))
        self.table_widget.setItem(
            8, 2, QTableWidgetItem(QIcon('icons/high.svg'), '(1)'))
        self.table_widget.item(8, 0).setToolTip(
            self.tr('Multiscale version of SSIM.'))
        self.table_widget.setItem(9, 0, QTableWidgetItem(self.tr('RASE')))
        self.table_widget.setItem(
            9, 2, QTableWidgetItem(QIcon('icons/low.svg'), '(0)'))
        self.table_widget.item(9, 0).setToolTip(
            self.tr('Relative average spectral error'))
        self.table_widget.setItem(10, 0, QTableWidgetItem(self.tr('SCC')))
        self.table_widget.setItem(
            10, 2, QTableWidgetItem(QIcon('icons/high.svg'), '(1)'))
        self.table_widget.item(10, 0).setToolTip(
            self.tr('Spatial Correlation Coefficient'))
        self.table_widget.setItem(11, 0, QTableWidgetItem(self.tr('UQI')))
        self.table_widget.setItem(
            11, 2, QTableWidgetItem(QIcon('icons/high.svg'), '(1)'))
        self.table_widget.item(11, 0).setToolTip(
            self.tr('Universal Image Quality Index'))
        self.table_widget.setItem(12, 0, QTableWidgetItem(self.tr('VIF-P')))
        self.table_widget.setItem(
            12, 2, QTableWidgetItem(QIcon('icons/high.svg'), '(1)'))
        self.table_widget.item(12, 0).setToolTip(
            self.tr('Pixel-based Visual Information Fidelity'))
        self.table_widget.setItem(13, 0,
                                  QTableWidgetItem(self.tr('SSIMulacra')))
        self.table_widget.setItem(
            13, 2, QTableWidgetItem(QIcon('icons/low.svg'), '(0)'))
        self.table_widget.item(13, 0).setToolTip(
            self.tr('Structural SIMilarity Unveiling Local '
                    'And Compression Related Artifacts'))
        self.table_widget.setItem(14, 0,
                                  QTableWidgetItem(self.tr('Butteraugli')))
        self.table_widget.setItem(
            14, 2, QTableWidgetItem(QIcon('icons/low.svg'), '(0)'))
        self.table_widget.item(14, 0).setToolTip(
            self.tr('Estimate psychovisual error'))
        self.table_widget.setItem(15, 0,
                                  QTableWidgetItem(self.tr('Correlation')))
        self.table_widget.setItem(
            15, 2, QTableWidgetItem(QIcon('icons/high.svg'), '(1)'))
        self.table_widget.item(15,
                               0).setToolTip(self.tr('Histogram correlation'))
        self.table_widget.setItem(16, 0,
                                  QTableWidgetItem(self.tr('Chi-Square')))
        self.table_widget.setItem(
            16, 2, QTableWidgetItem(QIcon('icons/low.svg'), '(0)'))
        self.table_widget.item(16,
                               0).setToolTip(self.tr('Histogram Chi-Square'))
        self.table_widget.setItem(17, 0,
                                  QTableWidgetItem(self.tr('Chi-Square 2')))
        self.table_widget.setItem(
            17, 2, QTableWidgetItem(QIcon('icons/low.svg'), '(0)'))
        self.table_widget.item(17,
                               0).setToolTip(self.tr('Alternative Chi-Square'))
        self.table_widget.setItem(18, 0,
                                  QTableWidgetItem(self.tr('Intersection')))
        self.table_widget.setItem(
            18, 2,
            QTableWidgetItem(QIcon('icons/high.svg'), '(+' + u'\u221e' + ')'))
        self.table_widget.item(18,
                               0).setToolTip(self.tr('Histogram intersection'))
        self.table_widget.setItem(19, 0,
                                  QTableWidgetItem(self.tr('Hellinger')))
        self.table_widget.setItem(
            19, 2, QTableWidgetItem(QIcon('icons/low.svg'), '(0)'))
        self.table_widget.item(19, 0).setToolTip(
            self.tr('Histogram Hellinger distance'))
        self.table_widget.setItem(20, 0,
                                  QTableWidgetItem(self.tr('Divergence')))
        self.table_widget.setItem(
            20, 2, QTableWidgetItem(QIcon('icons/low.svg'), '(0)'))
        self.table_widget.item(20, 0).setToolTip(
            self.tr('Kullback-Leibler divergence'))

        for i in range(self.table_widget.rowCount()):
            modify_font(self.table_widget.item(i, 0), bold=True)
        self.table_widget.setSelectionMode(QAbstractItemView.SingleSelection)
        self.table_widget.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.table_widget.resizeColumnsToContents()
        self.table_widget.setMaximumWidth(250)
        self.table_widget.setAlternatingRowColors(True)
        self.stopped = False

        self.comp_label.setEnabled(False)
        self.normal_radio.setEnabled(False)
        self.difference_radio.setEnabled(False)
        self.ssim_radio.setEnabled(False)
        self.butter_radio.setEnabled(False)
        self.gray_check.setEnabled(False)
        self.equalize_check.setEnabled(False)
        self.metric_button.setEnabled(False)
        self.table_widget.setEnabled(False)

        load_button.clicked.connect(self.load)
        self.normal_radio.clicked.connect(self.change)
        self.difference_radio.clicked.connect(self.change)
        self.butter_radio.clicked.connect(self.change)
        self.gray_check.stateChanged.connect(self.change)
        self.equalize_check.stateChanged.connect(self.change)
        self.ssim_radio.clicked.connect(self.change)
        self.evidence_viewer.viewChanged.connect(
            self.reference_viewer.changeView)
        self.reference_viewer.viewChanged.connect(
            self.evidence_viewer.changeView)
        self.metric_button.clicked.connect(self.metrics)

        top_layout = QHBoxLayout()
        top_layout.addWidget(load_button)
        top_layout.addStretch()
        top_layout.addWidget(self.comp_label)
        top_layout.addWidget(self.normal_radio)
        top_layout.addWidget(self.difference_radio)
        top_layout.addWidget(self.ssim_radio)
        top_layout.addWidget(self.butter_radio)
        top_layout.addWidget(self.gray_check)
        top_layout.addWidget(self.equalize_check)

        metric_layout = QVBoxLayout()
        index_label = QLabel(self.tr('Image Quality Assessment'))
        index_label.setAlignment(Qt.AlignCenter)
        modify_font(index_label, bold=True)
        metric_layout.addWidget(index_label)
        metric_layout.addWidget(self.table_widget)
        metric_layout.addWidget(self.metric_button)

        center_layout = QHBoxLayout()
        center_layout.addWidget(self.evidence_viewer)
        center_layout.addWidget(self.reference_viewer)
        center_layout.addLayout(metric_layout)

        main_layout = QVBoxLayout()
        main_layout.addLayout(top_layout)
        main_layout.addLayout(center_layout)
        self.setLayout(main_layout)

    def load(self):
        filename, basename, reference = load_image(self)
        if filename is None:
            return
        if reference.shape != self.evidence.shape:
            QMessageBox.critical(
                self, self.tr('Error'),
                self.tr('Evidence and reference must have the same size!'))
            return
        self.reference = reference
        self.reference_viewer.set_title(
            self.tr('Reference: {}'.format(basename)))
        self.difference = norm_mat(cv.absdiff(self.evidence, self.reference))

        self.comp_label.setEnabled(True)
        self.normal_radio.setEnabled(True)
        self.difference_radio.setEnabled(True)
        self.ssim_radio.setEnabled(False)
        self.butter_radio.setEnabled(False)
        self.gray_check.setEnabled(True)
        self.equalize_check.setEnabled(True)
        self.metric_button.setEnabled(True)
        for i in range(self.table_widget.rowCount()):
            self.table_widget.setItem(i, 1, QTableWidgetItem())
        self.normal_radio.setChecked(True)
        self.table_widget.setEnabled(False)
        self.change()

    def change(self):
        if self.normal_radio.isChecked():
            result = self.reference
            self.gray_check.setEnabled(False)
            self.equalize_check.setEnabled(False)
            self.last_radio = self.normal_radio
        elif self.difference_radio.isChecked():
            result = self.difference
            self.gray_check.setEnabled(True)
            self.equalize_check.setEnabled(True)
            self.last_radio = self.difference_radio
        elif self.ssim_radio.isChecked():
            result = self.ssim_map
            self.gray_check.setEnabled(False)
            self.equalize_check.setEnabled(True)
            self.last_radio = self.ssim_radio
        elif self.butter_radio.isChecked():
            result = self.butter_map
            self.gray_check.setEnabled(True)
            self.equalize_check.setEnabled(False)
            self.last_radio = self.butter_radio
        else:
            self.last_radio.setChecked(True)
            return
        if self.equalize_check.isChecked():
            result = equalize_img(result)
        if self.gray_check.isChecked():
            result = desaturate(result)
        self.reference_viewer.update_original(result)

    def metrics(self):
        progress = QProgressDialog(self.tr('Computing metrics...'),
                                   self.tr('Cancel'), 1,
                                   self.table_widget.rowCount(), self)
        progress.canceled.connect(self.cancel)
        progress.setWindowModality(Qt.WindowModal)
        img1 = cv.cvtColor(self.evidence, cv.COLOR_BGR2GRAY)
        img2 = cv.cvtColor(self.reference, cv.COLOR_BGR2GRAY)
        x = img1.astype(np.float64)
        y = img2.astype(np.float64)

        rmse = self.rmse(x, y)
        progress.setValue(1)
        if self.stopped:
            return
        sam = sewar.sam(img1, img2)
        progress.setValue(2)
        if self.stopped:
            return
        ergas = sewar.ergas(img1, img2)
        progress.setValue(3)
        if self.stopped:
            return
        mb = self.mb(x, y)
        progress.setValue(4)
        if self.stopped:
            return
        pfe = self.pfe(x, y)
        progress.setValue(5)
        if self.stopped:
            return
        psnr = self.psnr(x, y)
        progress.setValue(6)
        if self.stopped:
            return
        try:
            psnrb = sewar.psnrb(img1, img2)
        except NameError:
            # FIXME: C'\`e un bug in psnrb (https://github.com/andrewekhalel/sewar/issues/17)
            psnrb = 0
        progress.setValue(7)
        if self.stopped:
            return
        ssim, self.ssim_map = self.ssim(x, y)
        progress.setValue(8)
        if self.stopped:
            return
        mssim = sewar.msssim(img1, img2).real
        progress.setValue(9)
        if self.stopped:
            return
        rase = sewar.rase(img1, img2)
        progress.setValue(10)
        if self.stopped:
            return
        scc = sewar.scc(img1, img2)
        progress.setValue(11)
        if self.stopped:
            return
        uqi = sewar.uqi(img1, img2)
        progress.setValue(12)
        if self.stopped:
            return
        vifp = sewar.vifp(img1, img2)
        progress.setValue(13)
        if self.stopped:
            return
        ssimul = self.ssimul(img1, img2)
        progress.setValue(14)
        if self.stopped:
            return
        butter, self.butter_map = self.butter(img1, img2)
        progress.setValue(15)
        if self.stopped:
            return

        sizes = [256, 256, 256]
        ranges = [0, 256] * 3
        channels = [0, 1, 2]
        hist1 = cv.calcHist([self.evidence], channels, None, sizes, ranges)
        hist2 = cv.calcHist([self.reference], channels, None, sizes, ranges)
        correlation = cv.compareHist(hist1, hist2, cv.HISTCMP_CORREL)
        progress.setValue(16)
        if self.stopped:
            return
        chi_square = cv.compareHist(hist1, hist2, cv.HISTCMP_CHISQR)
        progress.setValue(17)
        if self.stopped:
            return
        chi_square2 = cv.compareHist(hist1, hist2, cv.HISTCMP_CHISQR_ALT)
        progress.setValue(18)
        if self.stopped:
            return
        intersection = cv.compareHist(hist1, hist2, cv.HISTCMP_INTERSECT)
        progress.setValue(19)
        if self.stopped:
            return
        hellinger = cv.compareHist(hist1, hist2, cv.HISTCMP_HELLINGER)
        progress.setValue(20)
        if self.stopped:
            return
        divergence = cv.compareHist(hist1, hist2, cv.HISTCMP_KL_DIV)
        progress.setValue(21)

        self.table_widget.setItem(0, 1,
                                  QTableWidgetItem('{:.2f}'.format(rmse)))
        self.table_widget.setItem(1, 1, QTableWidgetItem('{:.4f}'.format(sam)))
        self.table_widget.setItem(2, 1,
                                  QTableWidgetItem('{:.2f}'.format(ergas)))
        self.table_widget.setItem(3, 1, QTableWidgetItem('{:.4f}'.format(mb)))
        self.table_widget.setItem(4, 1, QTableWidgetItem('{:.2f}'.format(pfe)))
        if psnr > 0:
            self.table_widget.setItem(
                5, 1, QTableWidgetItem('{:.2f} dB'.format(psnr)))
        else:
            self.table_widget.setItem(
                5, 1, QTableWidgetItem('+' + u'\u221e' + ' dB'))
        self.table_widget.setItem(6, 1,
                                  QTableWidgetItem('{:.2f}'.format(psnrb)))
        self.table_widget.setItem(7, 1,
                                  QTableWidgetItem('{:.4f}'.format(ssim)))
        self.table_widget.setItem(8, 1,
                                  QTableWidgetItem('{:.4f}'.format(mssim)))
        self.table_widget.setItem(9, 1,
                                  QTableWidgetItem('{:.2f}'.format(rase)))
        self.table_widget.setItem(10, 1,
                                  QTableWidgetItem('{:.4f}'.format(scc)))
        self.table_widget.setItem(11, 1,
                                  QTableWidgetItem('{:.4f}'.format(uqi)))
        self.table_widget.setItem(12, 1,
                                  QTableWidgetItem('{:.4f}'.format(vifp)))
        self.table_widget.setItem(13, 1,
                                  QTableWidgetItem('{:.4f}'.format(ssimul)))
        self.table_widget.setItem(14, 1,
                                  QTableWidgetItem('{:.2f}'.format(butter)))
        self.table_widget.setItem(
            15, 1, QTableWidgetItem('{:.2f}'.format(correlation)))
        self.table_widget.setItem(
            16, 1, QTableWidgetItem('{:.2f}'.format(chi_square)))
        self.table_widget.setItem(
            17, 1, QTableWidgetItem('{:.2f}'.format(chi_square2)))
        self.table_widget.setItem(
            18, 1, QTableWidgetItem('{:.2f}'.format(intersection)))
        self.table_widget.setItem(19, 1,
                                  QTableWidgetItem('{:.2f}'.format(hellinger)))
        self.table_widget.setItem(
            20, 1, QTableWidgetItem('{:.2f}'.format(divergence)))
        self.table_widget.resizeColumnsToContents()
        self.table_widget.setEnabled(True)
        self.metric_button.setEnabled(False)
        self.ssim_radio.setEnabled(True)
        self.butter_radio.setEnabled(True)

    def cancel(self):
        self.stopped = True

    @staticmethod
    def rmse(x, y):
        return np.sqrt(np.mean(np.square(x - y)))

    @staticmethod
    def mb(x, y):
        mx = np.mean(x)
        my = np.mean(y)
        return (mx - my) / mx

    @staticmethod
    def pfe(x, y):
        return np.linalg.norm(x - y) / np.linalg.norm(x) * 100

    @staticmethod
    def ssim(x, y):
        c1 = 6.5025
        c2 = 58.5225
        k = (11, 11)
        s = 1.5
        x2 = x**2
        y2 = y**2
        xy = x * y
        mu_x = cv.GaussianBlur(x, k, s)
        mu_y = cv.GaussianBlur(y, k, s)
        mu_x2 = mu_x**2
        mu_y2 = mu_y**2
        mu_xy = mu_x * mu_y
        s_x2 = cv.GaussianBlur(x2, k, s) - mu_x2
        s_y2 = cv.GaussianBlur(y2, k, s) - mu_y2
        s_xy = cv.GaussianBlur(xy, k, s) - mu_xy
        t1 = 2 * mu_xy + c1
        t2 = 2 * s_xy + c2
        t3 = t1 * t2
        t1 = mu_x2 + mu_y2 + c1
        t2 = s_x2 + s_y2 + c2
        t1 *= t2
        ssim_map = cv.divide(t3, t1)
        ssim = cv.mean(ssim_map)[0]
        return ssim, 255 - norm_mat(ssim_map, to_bgr=True)

    @staticmethod
    def corr(x, y):
        return np.corrcoef(x, y)[0, 1]

    @staticmethod
    def psnr(x, y):
        k = np.mean(np.square(x - y))
        if k == 0:
            return -1
        return 20 * math.log10((255**2) / k)

    @staticmethod
    def butter(x, y):
        try:
            exe = butter_exe()
            if exe is None:
                raise FileNotFoundError
            temp_dir = QTemporaryDir()
            if temp_dir.isValid():
                filename1 = os.path.join(temp_dir.path(), 'img1.png')
                cv.imwrite(filename1, x)
                filename2 = os.path.join(temp_dir.path(), 'img2.png')
                cv.imwrite(filename2, y)
                filename3 = os.path.join(temp_dir.path(), 'map.ppm')
                p = run([exe, filename1, filename2, filename3], stdout=PIPE)
                value = float(p.stdout)
                heatmap = cv.imread(filename3, cv.IMREAD_COLOR)
                return value, heatmap
        except FileNotFoundError:
            return -1, cv.cvtColor(np.full_like(x, 127), cv.COLOR_GRAY2BGR)

    @staticmethod
    def ssimul(x, y):
        try:
            exe = ssimul_exe()
            if exe is None:
                raise FileNotFoundError
            temp_dir = QTemporaryDir()
            if temp_dir.isValid():
                filename1 = os.path.join(temp_dir.path(), 'img1.png')
                cv.imwrite(filename1, x)
                filename2 = os.path.join(temp_dir.path(), 'img2.png')
                cv.imwrite(filename2, y)
                p = run([exe, filename1, filename2], stdout=PIPE)
                value = float(p.stdout)
                return value
        except FileNotFoundError:
            return -1
Example #29
0
    def _add_toolbar_tools(self):
        """Add tools."""
        # TODO: Outdated - to be removed

        from matplotlib.backend_tools import ToolToggleBase  # ToolBase

        class ToolPointPosition(ToolToggleBase):
            """Tools."""
            default_keymap = 'Ctrl+p'
            description = 'Click to get point coordinate printed'
            default_toggled = False
            image = None  # str(imgs_path)

            def __init__(self, *args, parent=None, **kwargs):
                super().__init__(*args, **kwargs)
                if parent is None:
                    raise ('Pass a parent')
                self.parent = parent

            def enable(self, *args):
                self.parent.options.report_point_position = True

            def disable(self, *args):
                self.parent.options.report_point_position = False

        fig = self.figure
        imgs_path = self.imgs_path
        # pylint: disable=attribute-defined-outside-init
        toolbar = self.toolbar = fig.canvas.manager.toolbar

        # Get tool manager

        # TODO: Remove use of tool manager just use PySide2 bare as below

        # ToolbarQt   --- https://github.com/matplotlib/matplotlib/blob/master/lib/matplotlib/backends/backend_qt5.py
        tm = fig.canvas.manager.toolmanager

        self.tm = tm
        # Tool: Print point location
        ToolPointPosition.image = str(imgs_path / 'click.png')
        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            tm.add_tool("Point_position", ToolPointPosition, parent=self)
        fig.canvas.manager.toolbar.add_tool(tm.get_tool("Point_position"),
                                            "toolgroup")

        # Tool: Copy to Clipboard
        from matplotlib.backend_tools import ToolCopyToClipboard
        ToolCopyToClipboard.image = str(imgs_path / 'copy.png')
        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            # OVvrwties Ctrl+C and issues warning
            tm.add_tool("Copy_to_clipboard", ToolCopyToClipboard)
        fig.canvas.manager.toolbar.add_tool(tm.get_tool("Copy_to_clipboard"),
                                            "toolgroup")

        if 1:  # add QT Pieces
            toolbar.action_ascale = QAction(
                QIcon(str(imgs_path / 'auto_zoom.png')), 'Auto scale', toolbar)
            toolbar.action_ascale.setShortcut('A')
            toolbar.action_ascale.setShortcutContext(Qt.WindowShortcut)
            toolbar.action_ascale.setStatusTip('Autoscale')
            toolbar.action_ascale.triggered.connect(self.auto_scale)
            toolbar.addAction(toolbar.action_ascale)

        # Status Bar: Second label to report
        figManager = fig.canvas.manager  # plt.get_current_fig_manager()
        status_bar = figManager.window.statusBar()
        self._status_label_2 = QLabel(status_bar)
        self._status_label_2.setText('')
        status_bar.addWidget(self._status_label_2)
import sys
from PySide2.QtWidgets import QApplication, QLabel

app = QApplication([])
label = QLabel("Hello World!")
label.show()

print('hello world')
app.exec_()
Example #31
0
class MainWindow(QMainWindow):
    def __init__(self,
                 font=QtGui.QFontMetrics(QtGui.QFont()),
                 screen_size=QtCore.QSize()):
        super().__init__()

        self.screen = screen_size
        self.font_metric = font
        self.setWindowTitle('OpenMC Plot Explorer')

    def loadGui(self):

        self.pixmap = None
        self.zoom = 100

        self.loadModel()

        # Create viewing area
        self.frame = QScrollArea(self)
        cw = QWidget()
        self.frame.setCornerWidget(cw)
        self.frame.setAlignment(QtCore.Qt.AlignCenter)
        self.frame.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.setCentralWidget(self.frame)

        # connect pinch gesture (OSX)
        self.grabGesture(QtCore.Qt.PinchGesture)

        # Create plot image
        self.plotIm = PlotImage(self.model, self.frame, self)
        self.frame.setWidget(self.plotIm)

        # Dock
        self.dock = DomainDock(self.model, self.font_metric, self)
        self.dock.setObjectName("Domain Options Dock")
        self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.dock)

        # Tally Dock
        self.tallyDock = TallyDock(self.model, self.font_metric, self)
        self.tallyDock.update()
        self.tallyDock.setObjectName("Tally Options Dock")
        self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.tallyDock)

        # Color DialogtallyDock
        self.colorDialog = ColorDialog(self.model, self.font_metric, self)
        self.colorDialog.hide()

        # Tools
        self.exportDataDialog = ExportDataDialog(self.model, self.font_metric,
                                                 self)

        # Restore Window Settings
        self.restoreWindowSettings()

        # Create menubar
        self.createMenuBar()
        self.updateEditMenu()

        # Status Bar
        self.coord_label = QLabel()
        self.statusBar().addPermanentWidget(self.coord_label)
        self.coord_label.hide()

        # Keyboard overlay
        self.shortcutOverlay = ShortcutsOverlay(self)
        self.shortcutOverlay.hide()

        # Load Plot
        self.statusBar().showMessage('Generating Plot...')
        self.dock.updateDock()
        self.tallyDock.update()
        self.colorDialog.updateDialogValues()
        self.statusBar().showMessage('')

        # Timer allows GUI to render before plot finishes loading
        QtCore.QTimer.singleShot(0, self.plotIm.generatePixmap)
        QtCore.QTimer.singleShot(0, self.showCurrentView)

    def event(self, event):
        # use pinch event to update zoom
        if isinstance(event, QGestureEvent):
            pinch = event.gesture(QtCore.Qt.PinchGesture)
            self.editZoom(self.zoom * pinch.scaleFactor())
        if isinstance(event, QKeyEvent) and hasattr(self, "shortcutOverlay"):
            self.shortcutOverlay.event(event)
        return super().event(event)

    def show(self):
        super().show()
        self.plotIm._resize()

    def toggleShortcuts(self):
        if self.shortcutOverlay.isVisible():
            self.shortcutOverlay.close()
        else:
            self.shortcutOverlay.move(0, 0)
            self.shortcutOverlay.resize(self.width(), self.height())
            self.shortcutOverlay.show()

    # Create and update menus:
    def createMenuBar(self):
        self.mainMenu = self.menuBar()

        # File Menu
        self.reloadModelAction = QAction("&Reload model...", self)
        self.reloadModelAction.setShortcut("Ctrl+Shift+R")
        self.reloadModelAction.setToolTip("Reload current model")
        self.reloadModelAction.setStatusTip("Reload current model")
        reload_connector = partial(self.loadModel, reload=True)
        self.reloadModelAction.triggered.connect(reload_connector)

        self.saveImageAction = QAction("&Save Image As...", self)
        self.saveImageAction.setShortcut("Ctrl+Shift+S")
        self.saveImageAction.setToolTip('Save plot image')
        self.saveImageAction.setStatusTip('Save plot image')
        self.saveImageAction.triggered.connect(self.saveImage)

        self.saveViewAction = QAction("Save &View...", self)
        self.saveViewAction.setShortcut(QtGui.QKeySequence.Save)
        self.saveViewAction.setStatusTip('Save current view settings')
        self.saveViewAction.triggered.connect(self.saveView)

        self.openAction = QAction("&Open View...", self)
        self.openAction.setShortcut(QtGui.QKeySequence.Open)
        self.openAction.setToolTip('Open saved view settings')
        self.openAction.setStatusTip('Open saved view settings')
        self.openAction.triggered.connect(self.openView)

        self.quitAction = QAction("&Quit", self)
        self.quitAction.setShortcut(QtGui.QKeySequence.Quit)
        self.quitAction.setToolTip('Quit OpenMC Plot Explorer')
        self.quitAction.setStatusTip('Quit OpenMC Plot Explorer')
        self.quitAction.triggered.connect(self.close)

        self.exportDataAction = QAction('E&xport...', self)
        self.exportDataAction.setToolTip('Export model and tally data VTK')
        self.setStatusTip('Export current model and tally data to VTK')
        self.exportDataAction.triggered.connect(self.exportTallyData)
        if not _HAVE_VTK:
            self.exportDataAction.setEnabled(False)
            self.exportDataAction.setToolTip(
                "Disabled: VTK Python module is not installed")

        self.fileMenu = self.mainMenu.addMenu('&File')
        self.fileMenu.addAction(self.reloadModelAction)
        self.fileMenu.addAction(self.saveImageAction)
        self.fileMenu.addAction(self.exportDataAction)
        self.fileMenu.addSeparator()
        self.fileMenu.addAction(self.saveViewAction)
        self.fileMenu.addAction(self.openAction)
        self.fileMenu.addSeparator()
        self.fileMenu.addAction(self.quitAction)

        # Data Menu
        self.openStatePointAction = QAction("&Open statepoint...", self)
        self.openStatePointAction.setToolTip('Open statepoint file')
        self.openStatePointAction.triggered.connect(self.openStatePoint)

        self.dataMenu = self.mainMenu.addMenu('D&ata')
        self.dataMenu.addAction(self.openStatePointAction)
        self.updateDataMenu()

        # Edit Menu
        self.applyAction = QAction("&Apply Changes", self)
        self.applyAction.setShortcut("Ctrl+Return")
        self.applyAction.setToolTip('Generate new view with changes applied')
        self.applyAction.setStatusTip('Generate new view with changes applied')
        self.applyAction.triggered.connect(self.applyChanges)

        self.undoAction = QAction('&Undo', self)
        self.undoAction.setShortcut(QtGui.QKeySequence.Undo)
        self.undoAction.setToolTip('Undo')
        self.undoAction.setStatusTip('Undo last plot view change')
        self.undoAction.setDisabled(True)
        self.undoAction.triggered.connect(self.undo)

        self.redoAction = QAction('&Redo', self)
        self.redoAction.setDisabled(True)
        self.redoAction.setToolTip('Redo')
        self.redoAction.setStatusTip('Redo last plot view change')
        self.redoAction.setShortcut(QtGui.QKeySequence.Redo)
        self.redoAction.triggered.connect(self.redo)

        self.restoreAction = QAction("&Restore Default Plot", self)
        self.restoreAction.setShortcut("Ctrl+R")
        self.restoreAction.setToolTip('Restore to default plot view')
        self.restoreAction.setStatusTip('Restore to default plot view')
        self.restoreAction.triggered.connect(self.restoreDefault)

        self.editMenu = self.mainMenu.addMenu('&Edit')
        self.editMenu.addAction(self.applyAction)
        self.editMenu.addSeparator()
        self.editMenu.addAction(self.undoAction)
        self.editMenu.addAction(self.redoAction)
        self.editMenu.addSeparator()
        self.editMenu.addAction(self.restoreAction)
        self.editMenu.addSeparator()
        self.editMenu.aboutToShow.connect(self.updateEditMenu)

        # Edit -> Basis Menu
        self.xyAction = QAction('&xy  ', self)
        self.xyAction.setCheckable(True)
        self.xyAction.setShortcut('Alt+X')
        self.xyAction.setToolTip('Change to xy basis')
        self.xyAction.setStatusTip('Change to xy basis')
        xy_connector = partial(self.editBasis, 'xy', apply=True)
        self.xyAction.triggered.connect(xy_connector)

        self.xzAction = QAction('x&z  ', self)
        self.xzAction.setCheckable(True)
        self.xzAction.setShortcut('Alt+Z')
        self.xzAction.setToolTip('Change to xz basis')
        self.xzAction.setStatusTip('Change to xz basis')
        xz_connector = partial(self.editBasis, 'xz', apply=True)
        self.xzAction.triggered.connect(xz_connector)

        self.yzAction = QAction('&yz  ', self)
        self.yzAction.setCheckable(True)
        self.yzAction.setShortcut('Alt+Y')
        self.yzAction.setToolTip('Change to yz basis')
        self.yzAction.setStatusTip('Change to yz basis')
        yz_connector = partial(self.editBasis, 'yz', apply=True)
        self.yzAction.triggered.connect(yz_connector)

        self.basisMenu = self.editMenu.addMenu('&Basis')
        self.basisMenu.addAction(self.xyAction)
        self.basisMenu.addAction(self.xzAction)
        self.basisMenu.addAction(self.yzAction)
        self.basisMenu.aboutToShow.connect(self.updateBasisMenu)

        # Edit -> Color By Menu
        self.cellAction = QAction('&Cell', self)
        self.cellAction.setCheckable(True)
        self.cellAction.setShortcut('Alt+C')
        self.cellAction.setToolTip('Color by cell')
        self.cellAction.setStatusTip('Color plot by cell')
        cell_connector = partial(self.editColorBy, 'cell', apply=True)
        self.cellAction.triggered.connect(cell_connector)

        self.materialAction = QAction('&Material', self)
        self.materialAction.setCheckable(True)
        self.materialAction.setShortcut('Alt+M')
        self.materialAction.setToolTip('Color by material')
        self.materialAction.setStatusTip('Color plot by material')
        material_connector = partial(self.editColorBy, 'material', apply=True)
        self.materialAction.triggered.connect(material_connector)

        self.temperatureAction = QAction('&Temperature', self)
        self.temperatureAction.setCheckable(True)
        self.temperatureAction.setShortcut('Alt+T')
        self.temperatureAction.setToolTip('Color by temperature')
        self.temperatureAction.setStatusTip('Color plot by temperature')
        temp_connector = partial(self.editColorBy, 'temperature', apply=True)
        self.temperatureAction.triggered.connect(temp_connector)

        self.densityAction = QAction('&Density', self)
        self.densityAction.setCheckable(True)
        self.densityAction.setShortcut('Alt+D')
        self.densityAction.setToolTip('Color by density')
        self.densityAction.setStatusTip('Color plot by density')
        density_connector = partial(self.editColorBy, 'density', apply=True)
        self.densityAction.triggered.connect(density_connector)

        self.colorbyMenu = self.editMenu.addMenu('&Color By')
        self.colorbyMenu.addAction(self.cellAction)
        self.colorbyMenu.addAction(self.materialAction)
        self.colorbyMenu.addAction(self.temperatureAction)
        self.colorbyMenu.addAction(self.densityAction)

        self.colorbyMenu.aboutToShow.connect(self.updateColorbyMenu)

        self.editMenu.addSeparator()

        # Edit -> Other Options
        self.maskingAction = QAction('Enable &Masking', self)
        self.maskingAction.setShortcut('Ctrl+M')
        self.maskingAction.setCheckable(True)
        self.maskingAction.setToolTip('Toggle masking')
        self.maskingAction.setStatusTip('Toggle whether masking is enabled')
        masking_connector = partial(self.toggleMasking, apply=True)
        self.maskingAction.toggled.connect(masking_connector)
        self.editMenu.addAction(self.maskingAction)

        self.highlightingAct = QAction('Enable High&lighting', self)
        self.highlightingAct.setShortcut('Ctrl+L')
        self.highlightingAct.setCheckable(True)
        self.highlightingAct.setToolTip('Toggle highlighting')
        self.highlightingAct.setStatusTip('Toggle whether '
                                          'highlighting is enabled')
        highlight_connector = partial(self.toggleHighlighting, apply=True)
        self.highlightingAct.toggled.connect(highlight_connector)
        self.editMenu.addAction(self.highlightingAct)

        self.overlapAct = QAction('Enable Overlap Coloring', self)
        self.overlapAct.setShortcut('Ctrl+P')
        self.overlapAct.setCheckable(True)
        self.overlapAct.setToolTip('Toggle overlapping regions')
        self.overlapAct.setStatusTip('Toggle display of overlapping '
                                     'regions when enabled')
        overlap_connector = partial(self.toggleOverlaps, apply=True)
        self.overlapAct.toggled.connect(overlap_connector)
        self.editMenu.addAction(self.overlapAct)

        self.outlineAct = QAction('Enable Domain Outlines', self)
        self.outlineAct.setShortcut('Ctrl+U')
        self.outlineAct.setCheckable(True)
        self.outlineAct.setToolTip('Display Cell/Material Boundaries')
        self.outlineAct.setStatusTip('Toggle display of domain '
                                     'outlines when enabled')
        outline_connector = partial(self.toggleOutlines, apply=True)
        self.outlineAct.toggled.connect(outline_connector)
        self.editMenu.addAction(self.outlineAct)

        # View Menu
        self.dockAction = QAction('Hide &Dock', self)
        self.dockAction.setShortcut("Ctrl+D")
        self.dockAction.setToolTip('Toggle dock visibility')
        self.dockAction.setStatusTip('Toggle dock visibility')
        self.dockAction.triggered.connect(self.toggleDockView)

        self.tallyDockAction = QAction('Tally &Dock', self)
        self.tallyDockAction.setShortcut("Ctrl+T")
        self.tallyDockAction.setToolTip('Toggle tally dock visibility')
        self.tallyDockAction.setStatusTip('Toggle tally dock visibility')
        self.tallyDockAction.triggered.connect(self.toggleTallyDockView)

        self.zoomAction = QAction('&Zoom...', self)
        self.zoomAction.setShortcut('Alt+Shift+Z')
        self.zoomAction.setToolTip('Edit zoom factor')
        self.zoomAction.setStatusTip('Edit zoom factor')
        self.zoomAction.triggered.connect(self.editZoomAct)

        self.viewMenu = self.mainMenu.addMenu('&View')
        self.viewMenu.addAction(self.dockAction)
        self.viewMenu.addAction(self.tallyDockAction)
        self.viewMenu.addSeparator()
        self.viewMenu.addAction(self.zoomAction)
        self.viewMenu.aboutToShow.connect(self.updateViewMenu)

        # Window Menu
        self.mainWindowAction = QAction('&Main Window', self)
        self.mainWindowAction.setCheckable(True)
        self.mainWindowAction.setToolTip('Bring main window to front')
        self.mainWindowAction.setStatusTip('Bring main window to front')
        self.mainWindowAction.triggered.connect(self.showMainWindow)

        self.colorDialogAction = QAction('Color &Options', self)
        self.colorDialogAction.setCheckable(True)
        self.colorDialogAction.setToolTip('Bring Color Dialog to front')
        self.colorDialogAction.setStatusTip('Bring Color Dialog to front')
        self.colorDialogAction.triggered.connect(self.showColorDialog)

        # Keyboard Shortcuts Overlay
        self.keyboardShortcutsAction = QAction("&Keyboard Shortcuts...", self)
        self.keyboardShortcutsAction.setShortcut("?")
        self.keyboardShortcutsAction.setToolTip("Display Keyboard Shortcuts")
        self.keyboardShortcutsAction.setStatusTip("Display Keyboard Shortcuts")
        self.keyboardShortcutsAction.triggered.connect(self.toggleShortcuts)

        self.windowMenu = self.mainMenu.addMenu('&Window')
        self.windowMenu.addAction(self.mainWindowAction)
        self.windowMenu.addAction(self.colorDialogAction)
        self.windowMenu.addAction(self.keyboardShortcutsAction)
        self.windowMenu.aboutToShow.connect(self.updateWindowMenu)

    def updateEditMenu(self):
        changed = self.model.currentView != self.model.defaultView
        self.restoreAction.setDisabled(not changed)

        self.maskingAction.setChecked(self.model.currentView.masking)
        self.highlightingAct.setChecked(self.model.currentView.highlighting)
        self.outlineAct.setChecked(self.model.currentView.outlines)

        num_previous_views = len(self.model.previousViews)
        self.undoAction.setText('&Undo ({})'.format(num_previous_views))
        num_subsequent_views = len(self.model.subsequentViews)
        self.redoAction.setText('&Redo ({})'.format(num_subsequent_views))

    def updateBasisMenu(self):
        self.xyAction.setChecked(self.model.currentView.basis == 'xy')
        self.xzAction.setChecked(self.model.currentView.basis == 'xz')
        self.yzAction.setChecked(self.model.currentView.basis == 'yz')

    def updateColorbyMenu(self):
        cv = self.model.currentView
        self.cellAction.setChecked(cv.colorby == 'cell')
        self.materialAction.setChecked(cv.colorby == 'material')
        self.temperatureAction.setChecked(cv.colorby == 'temperature')
        self.densityAction.setChecked(cv.colorby == 'density')

    def updateViewMenu(self):
        if self.dock.isVisible():
            self.dockAction.setText('Hide &Dock')
        else:
            self.dockAction.setText('Show &Dock')

    def updateWindowMenu(self):
        self.colorDialogAction.setChecked(self.colorDialog.isActiveWindow())
        self.mainWindowAction.setChecked(self.isActiveWindow())

    # Menu and shared methods
    def loadModel(self, reload=False):
        if reload:
            self.resetModels()
        else:
            # create new plot model
            self.model = PlotModel()
            self.restoreModelSettings()
            # update plot and model settings
            self.updateRelativeBases()

        self.cellsModel = DomainTableModel(self.model.activeView.cells)
        self.materialsModel = DomainTableModel(self.model.activeView.materials)

        if reload:
            loader_thread = Thread(target=_openmcReload)
            loader_thread.start()
            while loader_thread.is_alive():
                self.statusBar().showMessage("Reloading model...")
                QApplication.processEvents()

            self.plotIm.model = self.model
            self.applyChanges()

    def saveImage(self):
        filename, ext = QFileDialog.getSaveFileName(self, "Save Plot Image",
                                                    "untitled",
                                                    "Images (*.png)")
        if filename:
            if "." not in filename:
                filename += ".png"
            self.plotIm.figure.savefig(filename, transparent=True)
            self.statusBar().showMessage('Plot Image Saved', 5000)

    def saveView(self):
        filename, ext = QFileDialog.getSaveFileName(self, "Save View Settings",
                                                    "untitled",
                                                    "View Settings (*.pltvw)")
        if filename:
            if "." not in filename:
                filename += ".pltvw"

            saved = {
                'version': self.model.version,
                'current': self.model.currentView
            }
            with open(filename, 'wb') as file:
                pickle.dump(saved, file)

    def openView(self):
        filename, ext = QFileDialog.getOpenFileName(self, "Open View Settings",
                                                    ".", "*.pltvw")
        if filename:
            try:
                with open(filename, 'rb') as file:
                    saved = pickle.load(file)
            except Exception:
                message = 'Error loading plot settings'
                saved = {'version': None, 'current': None}
            if saved['version'] == self.model.version:
                self.model.activeView = saved['current']
                self.dock.updateDock()
                self.colorDialog.updateDialogValues()
                self.applyChanges()
                message = '{} settings loaded'.format(filename)
            else:
                message = 'Error loading plot settings. Incompatible model.'
            self.statusBar().showMessage(message, 5000)

    def openStatePoint(self):
        # check for an alread-open statepoint
        if self.model.statepoint:
            msg_box = QMessageBox()
            msg_box.setText("Please close the current statepoint file before "
                            "opening a new one.")
            msg_box.setIcon(QMessageBox.Information)
            msg_box.setStandardButtons(QMessageBox.Ok)
            msg_box.exec_()
            return
        filename, ext = QFileDialog.getOpenFileName(self, "Open StatePoint",
                                                    ".", "statepoint*.h5")
        if filename:
            try:
                self.model.openStatePoint(filename)
                message = 'Opened statepoint file: {}'
            except (FileNotFoundError, OSError):
                message = 'Error opening statepoint file: {}'
                msg_box = QMessageBox()
                msg = "Could open statepoint file: \n\n {} \n"
                msg_box.setText(msg.format(filename))
                msg_box.setIcon(QMessageBox.Warning)
                msg_box.setStandardButtons(QMessageBox.Ok)
                msg_box.exec_()
            finally:
                self.statusBar().showMessage(message.format(filename), 5000)
            self.updateDataMenu()
            self.tallyDock.update()

    def closeStatePoint(self):
        # remove the statepoint object and update the data menu
        filename = self.model.statepoint.filename
        self.model.statepoint = None
        self.model.currentView.selectedTally = None
        self.model.activeView.selectedTally = None

        msg = "Closed statepoint file {}".format(filename)
        self.statusBar().showMessage(msg)
        self.updateDataMenu()
        self.tallyDock.selectTally()
        self.tallyDock.update()
        self.plotIm.updatePixmap()

    def updateDataMenu(self):
        if self.model.statepoint:
            self.closeStatePointAction = QAction("&Close statepoint", self)
            self.closeStatePointAction.setToolTip("Close current statepoint")
            self.closeStatePointAction.triggered.connect(self.closeStatePoint)
            self.dataMenu.addAction(self.closeStatePointAction)
        elif hasattr(self, "closeStatePointAction"):
            self.dataMenu.removeAction(self.closeStatePointAction)

    def applyChanges(self):
        if self.model.activeView != self.model.currentView:
            self.statusBar().showMessage('Generating Plot...')
            QApplication.processEvents()
            self.model.storeCurrent()
            self.model.subsequentViews = []
            self.plotIm.generatePixmap()
            self.resetModels()
            self.showCurrentView()
            self.statusBar().showMessage('')
        else:
            self.statusBar().showMessage('No changes to apply.', 3000)

    def undo(self):
        self.statusBar().showMessage('Generating Plot...')
        QApplication.processEvents()

        self.model.undo()
        self.resetModels()
        self.showCurrentView()
        self.dock.updateDock()
        self.colorDialog.updateDialogValues()

        if not self.model.previousViews:
            self.undoAction.setDisabled(True)
        self.redoAction.setDisabled(False)
        self.statusBar().showMessage('')

    def redo(self):
        self.statusBar().showMessage('Generating Plot...')
        QApplication.processEvents()

        self.model.redo()
        self.resetModels()
        self.showCurrentView()
        self.dock.updateDock()
        self.colorDialog.updateDialogValues()

        if not self.model.subsequentViews:
            self.redoAction.setDisabled(True)
        self.undoAction.setDisabled(False)
        self.statusBar().showMessage('')

    def restoreDefault(self):
        if self.model.currentView != self.model.defaultView:

            self.statusBar().showMessage('Generating Plot...')
            QApplication.processEvents()

            self.model.storeCurrent()
            self.model.activeView.adopt_plotbase(self.model.defaultView)
            self.plotIm.generatePixmap()
            self.resetModels()
            self.showCurrentView()
            self.dock.updateDock()
            self.colorDialog.updateDialogValues()

            self.model.subsequentViews = []
            self.statusBar().showMessage('')

    def editBasis(self, basis, apply=False):
        self.model.activeView.basis = basis
        self.dock.updateBasis()
        if apply:
            self.applyChanges()

    def editColorBy(self, domain_kind, apply=False):
        self.model.activeView.colorby = domain_kind
        self.dock.updateColorBy()
        self.colorDialog.updateColorBy()
        if apply:
            self.applyChanges()

    def toggleOverlaps(self, state, apply=False):
        self.model.activeView.color_overlaps = bool(state)
        self.colorDialog.updateOverlap()
        if apply:
            self.applyChanges()

    def editColorMap(self, colormap_name, property_type, apply=False):
        self.model.activeView.colormaps[property_type] = colormap_name
        self.plotIm.updateColorMap(colormap_name, property_type)
        self.colorDialog.updateColorMaps()
        if apply:
            self.applyChanges()

    def editColorbarMin(self, min_val, property_type, apply=False):
        av = self.model.activeView
        current = av.user_minmax[property_type]
        av.user_minmax[property_type] = (min_val, current[1])
        self.colorDialog.updateColorMinMax()
        self.plotIm.updateColorMinMax(property_type)
        if apply:
            self.applyChanges()

    def editColorbarMax(self, max_val, property_type, apply=False):
        av = self.model.activeView
        current = av.user_minmax[property_type]
        av.user_minmax[property_type] = (current[0], max_val)
        self.colorDialog.updateColorMinMax()
        self.plotIm.updateColorMinMax(property_type)
        if apply:
            self.applyChanges()

    def toggleColorbarScale(self, state, property, apply=False):
        av = self.model.activeView
        av.color_scale_log[property] = bool(state)
        # temporary, should be resolved diferently in the future
        cv = self.model.currentView
        cv.color_scale_log[property] = bool(state)
        self.plotIm.updateColorbarScale()
        if apply:
            self.applyChanges()

    def toggleUserMinMax(self, state, property):
        av = self.model.activeView
        av.use_custom_minmax[property] = bool(state)
        if av.user_minmax[property] == (0.0, 0.0):
            av.user_minmax[property] = copy.copy(av.data_minmax[property])
        self.plotIm.updateColorMinMax('temperature')
        self.plotIm.updateColorMinMax('density')
        self.colorDialog.updateColorMinMax()

    def toggleDataIndicatorCheckBox(self, state, property, apply=False):
        av = self.model.activeView
        av.data_indicator_enabled[property] = bool(state)

        cv = self.model.currentView
        cv.data_indicator_enabled[property] = bool(state)

        self.plotIm.updateDataIndicatorVisibility()
        if apply:
            self.applyChanges()

    def toggleMasking(self, state, apply=False):
        self.model.activeView.masking = bool(state)
        self.colorDialog.updateMasking()
        if apply:
            self.applyChanges()

    def toggleHighlighting(self, state, apply=False):
        self.model.activeView.highlighting = bool(state)
        self.colorDialog.updateHighlighting()
        if apply:
            self.applyChanges()

    def toggleDockView(self):
        if self.dock.isVisible():
            self.dock.hide()
            if not self.isMaximized() and not self.dock.isFloating():
                self.resize(self.width() - self.dock.width(), self.height())
        else:
            self.dock.setVisible(True)
            if not self.isMaximized() and not self.dock.isFloating():
                self.resize(self.width() + self.dock.width(), self.height())
        self.resizePixmap()
        self.showMainWindow()

    def toggleTallyDockView(self):
        if self.tallyDock.isVisible():
            self.tallyDock.hide()
            if not self.isMaximized() and not self.tallyDock.isFloating():
                self.resize(self.width() - self.tallyDock.width(),
                            self.height())
        else:
            self.tallyDock.setVisible(True)
            if not self.isMaximized() and not self.tallyDock.isFloating():
                self.resize(self.width() + self.tallyDock.width(),
                            self.height())
        self.resizePixmap()
        self.showMainWindow()

    def editZoomAct(self):
        percent, ok = QInputDialog.getInt(self, "Edit Zoom", "Zoom Percent:",
                                          self.dock.zoomBox.value(), 25, 2000)
        if ok:
            self.dock.zoomBox.setValue(percent)

    def editZoom(self, value):
        self.zoom = value
        self.resizePixmap()
        self.dock.zoomBox.setValue(value)

    def showMainWindow(self):
        self.raise_()
        self.activateWindow()

    def showColorDialog(self):
        self.colorDialog.show()
        self.colorDialog.raise_()
        self.colorDialog.activateWindow()

    def showExportDialog(self):
        self.exportDataDialog.show()
        self.exportDataDialog.raise_()
        self.exportDataDialog.activateWindow()

    # Dock methods:

    def editSingleOrigin(self, value, dimension):
        self.model.activeView.origin[dimension] = value

    def editPlotAlpha(self, value):
        self.model.activeView.domainAlpha = value

    def editPlotVisibility(self, value):
        self.model.activeView.domainVisible = bool(value)

    def toggleOutlines(self, value, apply=False):
        self.model.activeView.outlines = bool(value)
        self.dock.updateOutlines()

        if apply:
            self.applyChanges()

    def editWidth(self, value):
        self.model.activeView.width = value
        self.onRatioChange()
        self.dock.updateWidth()

    def editHeight(self, value):
        self.model.activeView.height = value
        self.onRatioChange()
        self.dock.updateHeight()

    def toggleAspectLock(self, state):
        self.model.activeView.aspectLock = bool(state)
        self.onRatioChange()
        self.dock.updateAspectLock()

    def editVRes(self, value):
        self.model.activeView.v_res = value
        self.dock.updateVRes()

    def editHRes(self, value):
        self.model.activeView.h_res = value
        self.onRatioChange()
        self.dock.updateHRes()

    # Color dialog methods:

    def editMaskingColor(self):
        current_color = self.model.activeView.maskBackground
        dlg = QColorDialog(self)

        dlg.setCurrentColor(QtGui.QColor.fromRgb(*current_color))
        if dlg.exec_():
            new_color = dlg.currentColor().getRgb()[:3]
            self.model.activeView.maskBackground = new_color
            self.colorDialog.updateMaskingColor()

    def editHighlightColor(self):
        current_color = self.model.activeView.highlightBackground
        dlg = QColorDialog(self)

        dlg.setCurrentColor(QtGui.QColor.fromRgb(*current_color))
        if dlg.exec_():
            new_color = dlg.currentColor().getRgb()[:3]
            self.model.activeView.highlightBackground = new_color
            self.colorDialog.updateHighlightColor()

    def editAlpha(self, value):
        self.model.activeView.highlightAlpha = value

    def editSeed(self, value):
        self.model.activeView.highlightSeed = value

    def editOverlapColor(self, apply=False):
        current_color = self.model.activeView.overlap_color
        dlg = QColorDialog(self)
        dlg.setCurrentColor(QtGui.QColor.fromRgb(*current_color))
        if dlg.exec_():
            new_color = dlg.currentColor().getRgb()[:3]
            self.model.activeView.overlap_color = new_color
            self.colorDialog.updateOverlapColor()

        if apply:
            self.applyChanges()

    def editBackgroundColor(self, apply=False):
        current_color = self.model.activeView.domainBackground
        dlg = QColorDialog(self)

        dlg.setCurrentColor(QtGui.QColor.fromRgb(*current_color))
        if dlg.exec_():
            new_color = dlg.currentColor().getRgb()[:3]
            self.model.activeView.domainBackground = new_color
            self.colorDialog.updateBackgroundColor()

        if apply:
            self.applyChanges()

    def resetColors(self):
        self.model.resetColors()
        self.colorDialog.updateDialogValues()
        self.applyChanges()

    # Tally dock methods

    def editSelectedTally(self, event):
        av = self.model.activeView

        if event is None or event == "None" or event == "":
            av.selectedTally = None
        else:
            av.selectedTally = int(event.split()[1])
        self.tallyDock.selectTally(event)

    def editTallyValue(self, event):
        av = self.model.activeView
        av.tallyValue = event

    def updateScores(self, state):
        self.tallyDock.updateScores()

    def updateNuclides(self, state):
        self.tallyDock.updateNuclides()

    def toggleTallyVisibility(self, state, apply=False):
        av = self.model.activeView
        av.tallyDataVisible = bool(state)
        if apply:
            self.applyChanges()

    def toggleTallyLogScale(self, state, apply=False):
        av = self.model.activeView
        av.tallyDataLogScale = bool(state)
        if apply:
            self.applyChanges()

    def toggleTallyMaskZero(self, state):
        av = self.model.activeView
        av.tallyMaskZeroValues = bool(state)

    def editTallyAlpha(self, value, apply=False):
        av = self.model.activeView
        av.tallyDataAlpha = value
        if apply:
            self.applyChanges()

    def toggleTallyContours(self, state):
        av = self.model.activeView
        av.tallyContours = bool(state)

    def editTallyContourLevels(self, value):
        av = self.model.activeView
        av.tallyContourLevels = value

    def toggleTallyDataIndicator(self, state, apply=False):
        av = self.model.activeView
        av.tallyDataIndicator = bool(state)
        if apply:
            self.applyChanges()

    def toggleTallyDataClip(self, state):
        av = self.model.activeView
        av.clipTallyData = bool(state)

    def toggleTallyDataUserMinMax(self, state, apply=False):
        av = self.model.activeView
        av.tallyDataUserMinMax = bool(state)
        self.tallyDock.tallyColorForm.setMinMaxEnabled(bool(state))
        if apply:
            self.applyChanges()

    def editTallyDataMin(self, value, apply=False):
        av = self.model.activeView
        av.tallyDataMin = value
        if apply:
            self.applyChanges()

    def editTallyDataMax(self, value, apply=False):
        av = self.model.activeView
        av.tallyDataMax = value
        if apply:
            self.applyChanges()

    def editTallyDataColormap(self, cmap, apply=False):
        av = self.model.activeView
        av.tallyDataColormap = cmap
        if apply:
            self.applyChanges()

    def updateTallyMinMax(self):
        self.tallyDock.updateMinMax()

    # Plot image methods
    def editPlotOrigin(self, xOr, yOr, zOr=None, apply=False):
        if zOr is not None:
            self.model.activeView.origin = [xOr, yOr, zOr]
        else:
            origin = [None, None, None]
            origin[self.xBasis] = xOr
            origin[self.yBasis] = yOr
            origin[self.zBasis] = self.model.activeView.origin[self.zBasis]
            self.model.activeView.origin = origin

        self.dock.updateOrigin()

        if apply:
            self.applyChanges()

    def revertDockControls(self):
        self.dock.revertToCurrent()

    def editDomainColor(self, kind, id):
        if kind == 'Cell':
            domain = self.model.activeView.cells
        else:
            domain = self.model.activeView.materials

        current_color = domain[id].color
        dlg = QColorDialog(self)

        if isinstance(current_color, tuple):
            dlg.setCurrentColor(QtGui.QColor.fromRgb(*current_color))
        elif isinstance(current_color, str):
            current_color = openmc.plots._SVG_COLORS[current_color]
            dlg.setCurrentColor(QtGui.QColor.fromRgb(*current_color))
        if dlg.exec_():
            new_color = dlg.currentColor().getRgb()[:3]
            domain[id].color = new_color

        self.applyChanges()

    def toggleDomainMask(self, state, kind, id):
        if kind == 'Cell':
            domain = self.model.activeView.cells
        else:
            domain = self.model.activeView.materials

        domain[id].masked = bool(state)
        self.applyChanges()

    def toggleDomainHighlight(self, state, kind, id):
        if kind == 'Cell':
            domain = self.model.activeView.cells
        else:
            domain = self.model.activeView.materials

        domain[id].highlight = bool(state)
        self.applyChanges()

    # Helper methods:

    def restoreWindowSettings(self):
        settings = QtCore.QSettings()

        self.resize(settings.value("mainWindow/Size", QtCore.QSize(800, 600)))
        self.move(
            settings.value("mainWindow/Position", QtCore.QPoint(100, 100)))
        self.restoreState(settings.value("mainWindow/State"))

        self.colorDialog.resize(
            settings.value("colorDialog/Size", QtCore.QSize(400, 500)))
        self.colorDialog.move(
            settings.value("colorDialog/Position", QtCore.QPoint(600, 200)))
        is_visible = settings.value("colorDialog/Visible", 0)
        # some versions of PySide will return None rather than the default value
        if is_visible is None:
            is_visible = False
        else:
            is_visible = bool(int(is_visible))

        self.colorDialog.setVisible(is_visible)

    def restoreModelSettings(self):
        if os.path.isfile("plot_settings.pkl"):

            with open('plot_settings.pkl', 'rb') as file:
                model = pickle.load(file)

            # do not replace model if the version is out of date
            if model.version != self.model.version:
                print("WARNING: previous plot settings are for a different "
                      "version of the GUI. They will be ignored.")
                wrn_msg = "Existing version: {}, Current GUI version: {}"
                print(wrn_msg.format(model.version, self.model.version))
                return

            try:
                self.model.statepoint = model.statepoint
            except OSError:
                msg_box = QMessageBox()
                msg = "Could open statepoint file: \n\n {} \n"
                msg_box.setText(msg.format(self.model.statepoint.filename))
                msg_box.setIcon(QMessageBox.Warning)
                msg_box.setStandardButtons(QMessageBox.Ok)
                msg_box.exec_()
                self.model.statepoint = None

            self.model.currentView = model.currentView
            self.model.activeView = copy.deepcopy(model.currentView)
            self.model.previousViews = model.previousViews
            self.model.subsequentViews = model.subsequentViews

    def resetModels(self):
        self.cellsModel = DomainTableModel(self.model.activeView.cells)
        self.materialsModel = DomainTableModel(self.model.activeView.materials)
        self.cellsModel.beginResetModel()
        self.cellsModel.endResetModel()
        self.materialsModel.beginResetModel()
        self.materialsModel.endResetModel()
        self.colorDialog.updateDomainTabs()

    def showCurrentView(self):
        self.updateScale()
        self.updateRelativeBases()
        self.plotIm.updatePixmap()

        if self.model.previousViews:
            self.undoAction.setDisabled(False)
        if self.model.subsequentViews:
            self.redoAction.setDisabled(False)
        else:
            self.redoAction.setDisabled(True)

        self.adjustWindow()

    def updateScale(self):
        cv = self.model.currentView
        self.scale = (cv.h_res / cv.width, cv.v_res / cv.height)

    def updateRelativeBases(self):
        cv = self.model.currentView
        self.xBasis = 0 if cv.basis[0] == 'x' else 1
        self.yBasis = 1 if cv.basis[1] == 'y' else 2
        self.zBasis = 3 - (self.xBasis + self.yBasis)

    def adjustWindow(self):
        self.setMaximumSize(self.screen.width(), self.screen.height())

    def onRatioChange(self):
        av = self.model.activeView
        if av.aspectLock:
            ratio = av.width / max(av.height, .001)
            av.v_res = int(av.h_res / ratio)
            self.dock.updateVRes()

    def showCoords(self, xPlotPos, yPlotPos):
        cv = self.model.currentView
        if cv.basis == 'xy':
            coords = ("({}, {}, {})".format(round(xPlotPos, 2),
                                            round(yPlotPos, 2),
                                            round(cv.origin[2], 2)))
        elif cv.basis == 'xz':
            coords = ("({}, {}, {})".format(round(xPlotPos, 2),
                                            round(cv.origin[1], 2),
                                            round(yPlotPos, 2)))
        else:
            coords = ("({}, {}, {})".format(round(cv.origin[0], 2),
                                            round(xPlotPos, 2),
                                            round(yPlotPos, 2)))
        self.coord_label.setText('{}'.format(coords))

    def resizePixmap(self):
        self.plotIm._resize()
        self.plotIm.adjustSize()

    def moveEvent(self, event):
        self.adjustWindow()

    def resizeEvent(self, event):
        self.plotIm._resize()
        self.adjustWindow()
        self.updateScale()
        if self.shortcutOverlay.isVisible():
            self.shortcutOverlay.resize(self.width(), self.height())

    def closeEvent(self, event):
        settings = QtCore.QSettings()
        settings.setValue("mainWindow/Size", self.size())
        settings.setValue("mainWindow/Position", self.pos())
        settings.setValue("mainWindow/State", self.saveState())

        settings.setValue("colorDialog/Size", self.colorDialog.size())
        settings.setValue("colorDialog/Position", self.colorDialog.pos())
        visible = int(self.colorDialog.isVisible())
        settings.setValue("colorDialog/Visible", visible)

        openmc.lib.finalize()

        self.saveSettings()

    def saveSettings(self):

        if len(self.model.previousViews) > 10:
            self.model.previousViews = self.model.previousViews[-10:]
        if len(self.model.subsequentViews) > 10:
            self.model.subsequentViews = self.model.subsequentViews[-10:]

        with open('plot_settings.pkl', 'wb') as file:
            if self.model.statepoint:
                self.model.statepoint.close()
            pickle.dump(self.model, file)

    def exportTallyData(self):
        # show export tool dialog
        self.showExportDialog()
Example #32
0
import sys
from PySide2.QtWidgets import QApplication, QLabel

app = QApplication(sys.argv)
# label = QLabel("Hello World!")
label = QLabel("<font color=red size=40>Hello World!</font>")
label.show()
app.exec_()
Example #33
0
    def loadGui(self):

        self.pixmap = None
        self.zoom = 100

        self.loadModel()

        # Create viewing area
        self.frame = QScrollArea(self)
        cw = QWidget()
        self.frame.setCornerWidget(cw)
        self.frame.setAlignment(QtCore.Qt.AlignCenter)
        self.frame.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.setCentralWidget(self.frame)

        # connect pinch gesture (OSX)
        self.grabGesture(QtCore.Qt.PinchGesture)

        # Create plot image
        self.plotIm = PlotImage(self.model, self.frame, self)
        self.frame.setWidget(self.plotIm)

        # Dock
        self.dock = DomainDock(self.model, self.font_metric, self)
        self.dock.setObjectName("Domain Options Dock")
        self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.dock)

        # Tally Dock
        self.tallyDock = TallyDock(self.model, self.font_metric, self)
        self.tallyDock.update()
        self.tallyDock.setObjectName("Tally Options Dock")
        self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.tallyDock)

        # Color DialogtallyDock
        self.colorDialog = ColorDialog(self.model, self.font_metric, self)
        self.colorDialog.hide()

        # Tools
        self.exportDataDialog = ExportDataDialog(self.model, self.font_metric,
                                                 self)

        # Restore Window Settings
        self.restoreWindowSettings()

        # Create menubar
        self.createMenuBar()
        self.updateEditMenu()

        # Status Bar
        self.coord_label = QLabel()
        self.statusBar().addPermanentWidget(self.coord_label)
        self.coord_label.hide()

        # Keyboard overlay
        self.shortcutOverlay = ShortcutsOverlay(self)
        self.shortcutOverlay.hide()

        # Load Plot
        self.statusBar().showMessage('Generating Plot...')
        self.dock.updateDock()
        self.tallyDock.update()
        self.colorDialog.updateDialogValues()
        self.statusBar().showMessage('')

        # Timer allows GUI to render before plot finishes loading
        QtCore.QTimer.singleShot(0, self.plotIm.generatePixmap)
        QtCore.QTimer.singleShot(0, self.showCurrentView)
Example #34
0
    def __init__(self):
        super().__init__()

        hlayout = QHBoxLayout()

        layout = QVBoxLayout()

        self.filtert = QLineEdit()
        self.filtert.setPlaceholderText("Search...")
        self.table = QTableView()

        vlayout = QVBoxLayout()
        vlayout.addWidget(self.filtert)
        vlayout.addWidget(self.table)

        # Left/right pane.
        hlayout.addLayout(vlayout)
        hlayout.addLayout(layout)

        form = QFormLayout()

        self.track_id = QSpinBox()
        self.track_id.setDisabled(True)
        self.track_id.setRange(0, 2147483647)
        self.name = QLineEdit()
        self.album = QComboBox()
        self.media_type = QComboBox()
        self.genre = QComboBox()
        self.composer = QLineEdit()

        self.milliseconds = QSpinBox()
        self.milliseconds.setRange(0, 2147483647)
        self.milliseconds.setSingleStep(1)

        self.bytes = QSpinBox()
        self.bytes.setRange(0, 2147483647)
        self.bytes.setSingleStep(1)

        self.unit_price = QDoubleSpinBox()
        self.unit_price.setRange(0, 999)
        self.unit_price.setSingleStep(0.01)
        self.unit_price.setPrefix("$")

        form.addRow(QLabel("Track ID"), self.track_id)
        form.addRow(QLabel("Track name"), self.name)
        form.addRow(QLabel("Composer"), self.composer)
        form.addRow(QLabel("Milliseconds"), self.milliseconds)
        form.addRow(QLabel("Bytes"), self.bytes)
        form.addRow(QLabel("Unit Price"), self.unit_price)

        self.model = QSqlTableModel(db=db)

        self.proxy_model = QSortFilterProxyModel()
        self.proxy_model.setSourceModel(self.model)
        self.proxy_model.sort(1, Qt.AscendingOrder)
        self.proxy_model.setFilterKeyColumn(-1)  # all columns
        self.table.setModel(self.proxy_model)

        # Update search when filter changes.
        self.filtert.textChanged.connect(self.proxy_model.setFilterFixedString)

        self.mapper = QDataWidgetMapper()
        self.mapper.setModel(self.proxy_model)

        self.mapper.addMapping(self.track_id, 0)
        self.mapper.addMapping(self.name, 1)
        self.mapper.addMapping(self.composer, 5)
        self.mapper.addMapping(self.milliseconds, 6)
        self.mapper.addMapping(self.bytes, 7)
        self.mapper.addMapping(self.unit_price, 8)

        self.model.setTable("Track")
        self.model.select()

        # Change the mapper selection using the table.
        self.table.selectionModel().currentRowChanged.connect(
            self.mapper.setCurrentModelIndex)

        self.mapper.toFirst()

        # tag::controls[]
        self.setMinimumSize(QSize(800, 400))

        controls = QHBoxLayout()

        prev_rec = QPushButton("Previous")
        prev_rec.clicked.connect(self.mapper.toPrevious)

        next_rec = QPushButton("Next")
        next_rec.clicked.connect(self.mapper.toNext)

        save_rec = QPushButton("Save Changes")
        save_rec.clicked.connect(self.mapper.submit)

        controls.addWidget(prev_rec)
        controls.addWidget(next_rec)
        controls.addWidget(save_rec)

        layout.addLayout(form)
        layout.addLayout(controls)

        widget = QWidget()
        widget.setLayout(hlayout)
        self.setCentralWidget(widget)
    def widgets(self):
        # Facilities widgets ###########################################################
        # Top layout (search facilities) widgets
        self.searchFacilitiesText = QLabel("Search: ")
        self.searchFacilitesEntry = QLineEdit()
        self.searchFacilitesEntry.setPlaceholderText("Search facilities..")
        self.searchFacilitiesBtn = QPushButton("Search")
        self.searchFacilitiesBtn.clicked.connect(self.funcSearchFacilities)
        self.refreshFacilitiesBtn = QPushButton("Refresh")
        self.refreshFacilitiesBtn.clicked.connect(self.funcDisplayFacilities)

        # Middle layout (list people) widgets with radio buttons
        self.allFacilitiesRadioBtn = QRadioButton("All facilities")
        self.withOngoingIssuesFacilitiesRadioBtn = QRadioButton(
            "With pending issues")
        self.withLateIssuesRadioBtn = QRadioButton("With late issues")
        self.listFacilitiesBtn = QPushButton("List")

        # Bottom layout widget, a table showing people
        self.facilitiesTable = QTableWidget()
        self.facilitiesTable.verticalHeader().hide()
        self.facilitiesTable.setSortingEnabled(True)
        self.facilitiesTable.setShowGrid(False)
        self.facilitiesTable.verticalHeader().setDefaultSectionSize(40)
        self.facilitiesTable.setColumnCount(11)
        # self.peopleTable.setColumnHidden(0, True)
        self.facilitiesTable.setHorizontalHeaderItem(0, QTableWidgetItem(""))
        self.facilitiesTable.horizontalHeader().setSectionResizeMode(
            0, QHeaderView.ResizeToContents)
        self.facilitiesTable.setHorizontalHeaderItem(1, QTableWidgetItem("ID"))
        self.facilitiesTable.setHorizontalHeaderItem(2,
                                                     QTableWidgetItem("Name"))
        self.facilitiesTable.horizontalHeader().setSectionResizeMode(
            1, QHeaderView.Stretch)
        self.facilitiesTable.setHorizontalHeaderItem(
            3, QTableWidgetItem("Location"))
        self.facilitiesTable.horizontalHeader().setSectionResizeMode(
            2, QHeaderView.Stretch)
        self.facilitiesTable.setHorizontalHeaderItem(4,
                                                     QTableWidgetItem("Phone"))
        self.facilitiesTable.horizontalHeader().setSectionResizeMode(
            3, QHeaderView.Stretch)
        self.facilitiesTable.setHorizontalHeaderItem(5,
                                                     QTableWidgetItem("Email"))
        self.facilitiesTable.horizontalHeader().setSectionResizeMode(
            4, QHeaderView.Stretch)
        self.facilitiesTable.setHorizontalHeaderItem(
            6, QTableWidgetItem("Supervisor"))
        self.facilitiesTable.setHorizontalHeaderItem(
            7, QTableWidgetItem("Ongoing issues"))
        self.facilitiesTable.setHorizontalHeaderItem(
            8, QTableWidgetItem("Late issues"))
        self.facilitiesTable.setHorizontalHeaderItem(
            9, QTableWidgetItem("Total issues"))
        self.facilitiesTable.setHorizontalHeaderItem(
            10, QTableWidgetItem("Total inspections"))

        # Double clicking a row opens a window with person details
        self.facilitiesTable.doubleClicked.connect(self.funcSelectedFacility)

        # Buttons for actions on selected facilities
        self.addFacility = QPushButton("Add")
        self.addFacility.clicked.connect(self.funcAddFacility)
        self.viewFacility = QPushButton("View/Edit")
        self.viewFacility.clicked.connect(self.funcSelectedFacility)
        self.deleteFacility = QPushButton("Delete")
        self.deleteFacility.clicked.connect(self.funcDeleteFacility)

        self.exportFacilitiesCSVBtn = QPushButton("Export CSV")
        self.exportFacilitiesCSVBtn.setEnabled(False)
        self.exportFacilitiesCSVBtn.clicked.connect(self.funcFacilitiesToCSV)

        self.exportFacilitiesXSLXBtn = QPushButton("Export XLSX")
        self.exportFacilitiesXSLXBtn.setEnabled(False)
        self.exportFacilitiesXSLXBtn.clicked.connect(self.funcFacilitiesToXLSX)

        self.exportFacilitiesPDFBtn = QPushButton("Export PDF")
        self.exportFacilitiesPDFBtn.setEnabled(False)
        self.exportFacilitiesPDFBtn.clicked.connect(self.funcFacilitiesToPdf)
Example #36
0
    def __init__(self, db, own_path, language):
        QMainWindow.__init__(self, None)
        self.setupUi(self)

        self.db = db
        self.own_path = own_path
        self.currentLanguage = language

        self.ledger = Ledger(self.db)
        self.downloader = QuoteDownloader(self.db)
        self.downloader.download_completed.connect(self.onQuotesDownloadCompletion)
        self.taxes = TaxesRus(self.db)
        self.statements = StatementLoader(self, self.db)
        self.statements.load_completed.connect(self.onStatementLoaded)
        self.statements.load_failed.connect(self.onStatementLoadFailure)

        # Customize Status bar and logs
        self.NewLogEventLbl = QLabel(self)
        self.StatusBar.addPermanentWidget(VLine())
        self.StatusBar.addPermanentWidget(self.NewLogEventLbl)
        self.Logs.setNotificationLabel(self.NewLogEventLbl)
        self.Logs.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))
        self.logger = logging.getLogger()
        self.logger.addHandler(self.Logs)
        self.logger.setLevel(logging.INFO)

        # Setup reports tab
        self.ReportAccountBtn.init_db(self.db)
        self.reports = Reports(self.db, self.ReportTableView)
        self.reports.report_failure.connect(self.onReportFailure)

        # Customize UI configuration
        self.operations = LedgerOperationsView(self.OperationsTableView)
        self.ui_config = TableViewConfig(self)

        self.ui_config.configure_all()
        self.operation_details = {
            TransactionType.Action: (
                g_tr('TableViewConfig', "Income / Spending"), self.ui_config.mappers[self.ui_config.ACTIONS], 'actions',
                self.ActionDetailsTableView, 'action_details', LedgerInitValues[TransactionType.Action]),
            TransactionType.Trade: (
                g_tr('TableViewConfig', "Trade"), self.ui_config.mappers[self.ui_config.TRADES], 'trades', None, None,
                LedgerInitValues[TransactionType.Trade]),
            TransactionType.Dividend: (
                g_tr('TableViewConfig', "Dividend"), self.ui_config.mappers[self.ui_config.DIVIDENDS], 'dividends', None, None,
                LedgerInitValues[TransactionType.Dividend]),
            TransactionType.Transfer: (
                g_tr('TableViewConfig', "Transfer"), self.ui_config.mappers[self.ui_config.TRANSFERS], 'transfers_combined', None, None,
                LedgerInitValues[TransactionType.Transfer])
        }
        self.operations.setOperationsDetails(self.operation_details)
        self.operations.activateOperationView.connect(self.ShowOperationTab)
        self.operations.stateIsCommitted.connect(self.showCommitted)
        self.operations.stateIsModified.connect(self.showModified)

        # Setup balance and holdings tables
        self.ledger.setViews(self.BalancesTableView, self.HoldingsTableView)
        self.BalanceDate.setDateTime(QDateTime.currentDateTime())
        self.BalancesCurrencyCombo.init_db(self.db)   # this line will trigger onBalanceDateChange -> view updated
        self.HoldingsDate.setDateTime(QDateTime.currentDateTime())
        self.HoldingsCurrencyCombo.init_db(self.db)   # and this will trigger onHoldingsDateChange -> view updated

        # Create menu for different operations
        self.ChooseAccountBtn.init_db(self.db)
        self.NewOperationMenu = QMenu()
        for operation in self.operation_details:
            self.NewOperationMenu.addAction(self.operation_details[operation][LedgerOperationsView.OP_NAME],
                                            partial(self.operations.addNewOperation, operation))
        self.NewOperationBtn.setMenu(self.NewOperationMenu)

        self.ActionDetailsTableView.horizontalHeader().moveSection(self.ActionDetailsTableView.model().fieldIndex("note"),
                                                                   self.ActionDetailsTableView.model().fieldIndex("name"))

        self.langGroup = QActionGroup(self.menuLanguage)
        self.createLanguageMenu()
        self.langGroup.triggered.connect(self.onLanguageChanged)

        self.OperationsTableView.selectRow(0)  # TODO find a way to select last row from self.operations
        self.OnOperationsRangeChange(0)
    def _add_process(self):
        process_groupbox = QGroupBox("Process")
        process_groupbox.setSizePolicy(QSizePolicy.Expanding,
                                       QSizePolicy.Expanding)
        process_layout = QVBoxLayout()
        process_layout.setSpacing(0)
        process_groupbox.setLayout(process_layout)

        pbar_frame = QFrame()
        pbar_frame.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        pbar_hbox = QHBoxLayout()
        pbar_hbox.setContentsMargins(QtCore.QMargins(0, 0, 0, 16))
        pbar_hbox.setSpacing(16)

        # Run and stop buttons
        hbox = QHBoxLayout()
        hbox.setSpacing(8)
        self.run_button = QPushButton()
        # is only enabled when validation passes
        self.run_button.setEnabled(False)
        self.run_button.setText("Run")
        self.run_button.setFixedWidth(100)
        run_icon = qta.icon('fa.play', color='green')
        self.run_button.setIcon(run_icon)
        self.run_button.clicked.connect(self._click_run)
        hbox.addWidget(self.run_button)

        self.stop_button = QPushButton()
        self.stop_button.setEnabled(False)
        self.stop_button.setText("Stop")
        self.stop_button.setFixedWidth(100)
        stop_icon = qta.icon('fa.stop', color='red')
        self.stop_button.setIcon(stop_icon)
        self.stop_button.clicked.connect(self._click_stop)
        hbox.addWidget(self.stop_button)

        self.progress_bar = QProgressBar()
        self.progress_bar.setTextVisible(True)
        self.progress_bar.setAlignment(QtCore.Qt.AlignCenter)
        self.progress_bar.setValue(0)
        self.progress_bar.setSizePolicy(QSizePolicy.Expanding,
                                        QSizePolicy.Expanding)

        pbar_hbox.addLayout(hbox)
        pbar_hbox.addWidget(self.progress_bar)
        pbar_frame.setLayout(pbar_hbox)
        process_layout.addWidget(pbar_frame)

        self.warning_frame = QFrame()
        self.warning_frame.setVisible(False)
        self.warning_frame.setSizePolicy(QSizePolicy.Expanding,
                                         QSizePolicy.Fixed)
        hbox = QHBoxLayout()

        warning_icon_widget = qta.IconWidget('fa.warning', color='red')
        warning_icon_widget.setIconSize(QtCore.QSize(48, 48))
        warning_icon_widget.update()
        hbox.addWidget(warning_icon_widget)
        warning_label = QLabel(
            "Grid Transformer did not complete successfully. Please refer to "
            "log output.")
        warning_label.setStyleSheet("QLabel { color: red; }")
        warning_label.setWordWrap(True)
        warning_label.setSizePolicy(QSizePolicy.Expanding,
                                    QSizePolicy.Preferred)
        hbox.addWidget(warning_label)
        self.warning_frame.setLayout(hbox)
        process_layout.addWidget(self.warning_frame)

        self.success_frame = QFrame()
        self.success_frame.setVisible(False)
        self.success_frame.setSizePolicy(QSizePolicy.Expanding,
                                         QSizePolicy.Fixed)
        hbox = QHBoxLayout()

        success_icon_widget = qta.IconWidget('fa.check', color='green')
        success_icon_widget.setIconSize(QtCore.QSize(48, 48))
        success_icon_widget.update()
        hbox.addWidget(success_icon_widget)
        success_label = QLabel("Grid Transformer completed successfully.")
        success_label.setStyleSheet("QLabel { color: green; }")
        success_label.setWordWrap(True)
        success_label.setSizePolicy(QSizePolicy.Expanding,
                                    QSizePolicy.Preferred)
        hbox.addWidget(success_label)
        self.success_frame.setLayout(hbox)
        process_layout.addWidget(self.success_frame)

        log_layout = QVBoxLayout()
        log_layout.setSpacing(4)
        log_label = QLabel("Log messages")
        log_label.setStyleSheet("QLabel { color: grey; }")
        log_layout.addWidget(log_label)

        self.log_messages = QPlainTextEdit()
        log_font = QFont("monospace")
        log_font.setStyleHint(QFont.TypeWriter)
        self.log_messages.setFont(log_font)
        self.log_messages.setReadOnly(True)
        self.log_messages.setSizePolicy(QSizePolicy.Expanding,
                                        QSizePolicy.Expanding)
        # self.log_messages.sizePolicy.setVerticalStretch(1)
        log_layout.addWidget(self.log_messages)
        process_layout.addLayout(log_layout)

        self.layout.addWidget(process_groupbox)
    def displayWidgets(self):
        """
        Configura os widgets da janela
        """
        title_lbl = QLabel("Albuns Filipe Ret")
        title_lbl.setfont(QFont("Arial", 17))
        qust_lbl = QLabel("Qual é o melhor album do rapper?")

        title_hbox = QHBoxlayout()
        title_hbox.addStretch()
        title_hbox.addWidget(title_lbl)
        title_hbox.addStretch()

        # Criando Labels para 3 imagens
        vivaz_img = "Imagens/vivaz.png"
        revel_img = "Imagens/revel.png"
        audaz_img = "Imagens/audaz.png"
        try:
            with open(vivaz_img):
                vivaz1_img = QLabel(self)
                pixmap = QPixmap(vivaz_img)
                pixmap = pixmap.scaled(33, 33)
                vivaz1_img.SetPixmap(pixmap)
                vivaz1_img.Move(150, 60)
        except FileNotFoundError:
            print("A imagem não está disponível!")

        try:
            with open(revel_img):
                revel1_img = QLabel(self)
                pixmap = QPixmap(revel_img)
                pixmap = pixmap.scaled(66, 66)
                revel1_img.SetPixmap(pixmap)
                revel1_img.Move(150, 60)
        except FileNotFoundError:
            print("A imagem não está disponível!")

        try:
            with open(audaz_img):
                audaz1_img = QLabel(self)
                pixmap = QPixmap(audaz_img)
                pixmap = pixmap.scaled(99, 99)
                audaz1_img.SetPixmap(pixmap)
                audaz1_img.Move(150, 60)
        except FileNotFoundError:
            print("A imagem não está disponível!")

        escala = ["Vivaz", "Revel", "Audaz"]

        escala_hbox = QHBoxLayout()
        escala_hbox.setSpacing(33)

        escala_hbox.addStrech()
        for eval in escala:
            eval_lbl = QLabel(eval, self)
            escala_hbox.addWidget(eval_lbl)
        escala_hbox.addStrech()

        btng_hbox = QHBoxLayout()
        btng_hbox.setSpacing(55)
        escala_bgrp = QButtonGroup(self)
        btg_hbox.addStretch()
        for btn in range(len(escala)):
            eval_chkb = QCheckBox(str(btn), self)
            btng_hbox.addWidget(eval_chkb)
            escala_bgrp.addButton(eval_chkb)
        btng_hbox.addStretch()

        escala_bgrp.buttonClicked.connect(self.checkBoxClicked)

        close_btn = QPushButton("Fechar", self)
        close_btn.clicked.connect(self.close)

        vbox = QVBoxLayout()
        vbox.addLayout(title_hbox)
        vbox.addWidget(qust_lbl)
        vbox.addStretch(1)
        vbox.addLayout(escala_hbox)
        vbox.addLayout(btng_hbox)
        vbox.addStretch(2)
        vbox.addWidget(close_btn)

        self.setLayout(vbox)
Example #39
0
    def __init__(self, mode, parentQWidget = None):
        QVBoxLayout.__init__(self)

        self.sig.connect(self.addThreadList)
        self.mode = mode

        self.sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Expanding)

        self.groupBoxSearch = QGroupBox()
        self.groupBoxSearch.setStyleSheet("QGroupBox {border: 1px solid gray; border-radius: 4px; };")
        vboxSearch = QVBoxLayout()
        self.searchTitle = QLabel("Search Messages")
        vboxSearch.addWidget(self.searchTitle)
        self.searchHLayout = QHBoxLayout()
        self.editTextSearch = QTextEdit('')
        self.editTextSearch.setFixedSize(200,30)
        self.buttonSearch = QPushButton('Search')
        self.buttonSearch.setFixedSize(100,30)
        self.buttonSearch.clicked.connect(self.searchMsg)
        vboxSearch.addWidget(self.editTextSearch)
        self.searchHLayout.addWidget(self.buttonSearch)
        self.searchCursor = QLabel()
        self.searchHLayout.addWidget(self.searchCursor)
        vboxSearch.addLayout(self.searchHLayout)
        self.browseHLayout = QHBoxLayout()
        self.buttonLookUp = QPushButton('\u21e7')  #Arrow up
        self.buttonLookUp.setFixedWidth(100)
        self.buttonLookUp.clicked.connect(self.moveToPrev)
        self.buttonLookDown = QPushButton('\u21e9') #Arrow down
        self.buttonLookDown.setFixedWidth(100)
        self.buttonLookDown.clicked.connect(self.moveToNext)
        self.browseHLayout.addWidget(self.buttonLookUp)
        self.browseHLayout.addWidget(self.buttonLookDown)
        vboxSearch.addLayout(self.browseHLayout)
        self.groupBoxSearch.setLayout(vboxSearch)
        self.addWidget(self.groupBoxSearch)
        self.groupBoxSearch.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))

        self.buttonHiddenLifelines = QPushButton('Show hidden life-lines')
        self.buttonHiddenLifelines.setFixedWidth(200)
        self.buttonHiddenLifelines.clicked.connect(self.showHiddenLifelines)
        self.addWidget(self.buttonHiddenLifelines)

        self.buttonHiddenMessages = QPushButton('Show hidden Messages')
        self.buttonHiddenMessages.setFixedWidth(200)
        self.buttonHiddenMessages.clicked.connect(self.showHiddenMessages)
        self.addWidget(self.buttonHiddenMessages)

        if const.mode_interactive == mode:
            self.buttonCapture = QPushButton('Capture')
            self.buttonCapture.setFixedWidth(200)
            self.buttonCapture.clicked.connect(self.notifyCapture)
            self.addWidget(self.buttonCapture)
        self.msgRcv = []
        self.msgInfo = QLabel("Message Info.")
        self.groupBoxMessageInfo = QGroupBox()
        self.groupBoxMessageInfo.setStyleSheet("QGroupBox {border: 1px solid gray; border-radius: 9px; margin-top: 0.5em} QGroupBox::title {subcontrol-origin: margin; left: 10px; padding: 0 3px 0 3px;")
        vbox = QVBoxLayout()
        vbox.addWidget(self.msgInfo)
        self.tableTime = QTableWidget(3,2)
        self.tableTime.setHorizontalHeaderLabels(['-','time'])
        self.tableTime.setColumnWidth(0,80)
        self.tableTime.setColumnWidth(1,150)
        vwidth = self.tableTime.verticalHeader().length()
        hwidth = self.tableTime.horizontalHeader().height()
        fwidth = self.tableTime.frameWidth() * 2
        self.tableTime.setFixedHeight(vwidth + hwidth + fwidth)
        self.tableTime.horizontalHeader().setStretchLastSection(True)
        self.tableTime.setItem(0,0,QTableWidgetItem('begin'))
        self.tableTime.setItem(0,1,QTableWidgetItem(' - '))
        self.tableTime.setItem(1,0,QTableWidgetItem('end'))
        self.tableTime.setItem(1,1,QTableWidgetItem(' - '))
        self.tableTime.setItem(2,0,QTableWidgetItem('duration'))
        self.tableTime.setItem(2,1,QTableWidgetItem(' - '))
        vbox.addWidget(self.tableTime)

        self.titleArg = QLabel('Argument List')
        vbox.addWidget(self.titleArg)

        max_arg_num = 10
        self.tableArgs = QTableWidget(max_arg_num,2)
        self.tableArgs.setHorizontalHeaderLabels(['type','value'])
        for idx in range(0,max_arg_num):
            self.tableArgs.setItem(idx,0,QTableWidgetItem())
            self.tableArgs.setItem(idx,1,QTableWidgetItem())
        self.tableArgs.horizontalHeader().setStretchLastSection(True)
        vbox.addWidget(self.tableArgs)

        self.titleArg = QLabel('Return Value List')
        vbox.addWidget(self.titleArg)

        max_ret_num = 4
        self.tableRet = QTableWidget(max_ret_num,2)
        self.tableRet.setHorizontalHeaderLabels(['type','value'])
        for idx in range(0,max_ret_num):
            self.tableRet.setItem(idx,0,QTableWidgetItem())
            self.tableRet.setItem(idx,1,QTableWidgetItem())
        self.tableRet.horizontalHeader().setStretchLastSection(True)
        vwidth = self.tableRet.verticalHeader().length()
        hwidth = self.tableRet.horizontalHeader().height()
        fwidth = self.tableRet.frameWidth() * 2
        self.tableRet.setFixedHeight(vwidth + hwidth + fwidth)
        vbox.addWidget(self.tableRet)

        self.buttonSrcView = QPushButton('view code')
        self.buttonSrcView.setFixedWidth(200)
        self.buttonSrcView.clicked.connect(self.openSourceViewer)
        self.buttonHide = QPushButton('Hide')
        self.buttonHide.setFixedWidth(200)
        self.buttonHide.clicked.connect(self.notifyHide)
        self.buttonHideAllMsg = QPushButton('Hide All')
        self.buttonHideAllMsg.setFixedWidth(200)
        self.buttonHideAllMsg.clicked.connect(self.hideAllMsgNamedAsSelected)
        self.groupBoxMessageInfo.setLayout(vbox)
        self.checkHideCircular = QCheckBox('Hide Circular Messages')
        self.checkHideCircular.setCheckState(QtCore.Qt.Unchecked)
        self.checkHideCircular.stateChanged.connect(self.changeHideCircularMessage)
        self.addWidget(self.checkHideCircular)
        self.addWidget(self.groupBoxMessageInfo)
        self.groupBoxMessageInfo.setSizePolicy(self.sizePolicy)
class BlockingClient(QWidget):
    def __init__(self, parent=None):
        super(BlockingClient, self).__init__(parent)

        self.thread = FortuneThread()
        self.currentFortune = ''

        hostLabel = QLabel("&Server name:")
        portLabel = QLabel("S&erver port:")

        for ipAddress in QNetworkInterface.allAddresses():
            if ipAddress != QHostAddress.LocalHost and ipAddress.toIPv4Address() != 0:
                break
        else:
            ipAddress = QHostAddress(QHostAddress.LocalHost)

        ipAddress = ipAddress.toString()

        self.hostLineEdit = QLineEdit(ipAddress)
        self.portLineEdit = QLineEdit()
        self.portLineEdit.setValidator(QIntValidator(1, 65535, self))

        hostLabel.setBuddy(self.hostLineEdit)
        portLabel.setBuddy(self.portLineEdit)

        self.statusLabel = QLabel(
                "This example requires that you run the Fortune Server example as well.")
        self.statusLabel.setWordWrap(True)

        self.getFortuneButton = QPushButton("Get Fortune")
        self.getFortuneButton.setDefault(True)
        self.getFortuneButton.setEnabled(False)

        quitButton = QPushButton("Quit")

        buttonBox = QDialogButtonBox()
        buttonBox.addButton(self.getFortuneButton, QDialogButtonBox.ActionRole)
        buttonBox.addButton(quitButton, QDialogButtonBox.RejectRole)

        self.getFortuneButton.clicked.connect(self.requestNewFortune)
        quitButton.clicked.connect(self.close)
        self.hostLineEdit.textChanged.connect(self.enableGetFortuneButton)
        self.portLineEdit.textChanged.connect(self.enableGetFortuneButton)
        self.thread.newFortune.connect(self.showFortune)
        self.thread.error.connect(self.displayError)

        mainLayout = QGridLayout()
        mainLayout.addWidget(hostLabel, 0, 0)
        mainLayout.addWidget(self.hostLineEdit, 0, 1)
        mainLayout.addWidget(portLabel, 1, 0)
        mainLayout.addWidget(self.portLineEdit, 1, 1)
        mainLayout.addWidget(self.statusLabel, 2, 0, 1, 2)
        mainLayout.addWidget(buttonBox, 3, 0, 1, 2)
        self.setLayout(mainLayout)

        self.setWindowTitle("Blocking Fortune Client")
        self.portLineEdit.setFocus()

    def requestNewFortune(self):
        self.getFortuneButton.setEnabled(False)
        self.thread.requestNewFortune(self.hostLineEdit.text(),
                int(self.portLineEdit.text()))

    def showFortune(self, nextFortune):
        if nextFortune == self.currentFortune:
            self.requestNewFortune()
            return

        self.currentFortune = nextFortune
        self.statusLabel.setText(self.currentFortune)
        self.getFortuneButton.setEnabled(True)

    def displayError(self, socketError, message):
        if socketError == QAbstractSocket.HostNotFoundError:
            QMessageBox.information(self, "Blocking Fortune Client",
                    "The host was not found. Please check the host and port "
                    "settings.")
        elif socketError == QAbstractSocket.ConnectionRefusedError:
            QMessageBox.information(self, "Blocking Fortune Client",
                    "The connection was refused by the peer. Make sure the "
                    "fortune server is running, and check that the host name "
                    "and port settings are correct.")
        else:
            QMessageBox.information(self, "Blocking Fortune Client",
                    "The following error occurred: %s." % message)

        self.getFortuneButton.setEnabled(True)

    def enableGetFortuneButton(self):
        self.getFortuneButton.setEnabled(self.hostLineEdit.text() != '' and
                self.portLineEdit.text() != '')
Example #41
0
    def __init__(self):
        super().__init__()

        # Main Layout
        main_layout = QHBoxLayout(self)
        main_layout.setContentsMargins(0, 0, 0, 0)

        title = QLabel(
            "Sp<font color='#419DD1'>o</font>ng<font color='#F4D05C'>o</font>")
        title.setObjectName("title")

        subtitle = QLabel(
            "Outil de classification et de reconnaissance de morphotypes d’éponges marines"
        )
        subtitle.setObjectName("subtitle")

        start_button = StylizedButton("Commencer une analyse", "blue")
        self._history_button = StylizedButton("Historique des analyses",
                                              "blue")
        about_button = StylizedButton("À propos", "blue")
        exit_button = StylizedButton("Quitter", "yellow")

        buttons_layout = QGridLayout()
        buttons_layout.setAlignment(Qt.AlignCenter)
        buttons_layout.setVerticalSpacing(24)
        buttons_layout.setHorizontalSpacing(30)

        buttons_layout.addWidget(start_button, 0, 0, 1, 2)
        buttons_layout.addWidget(self._history_button, 1, 0, 1, 2)
        buttons_layout.addWidget(about_button, 2, 0)
        buttons_layout.addWidget(exit_button, 2, 1)

        version_label = QLabel(AppInfo.version())
        version_label.setAlignment(Qt.AlignCenter)
        version_label.setObjectName("version")

        center_layout = QVBoxLayout()
        center_layout.setAlignment(Qt.AlignCenter)
        center_layout.setContentsMargins(15, 15, 15, 15)
        center_layout.addStretch(4)
        center_layout.addWidget(title)
        center_layout.addWidget(subtitle)
        center_layout.addLayout(buttons_layout)
        center_layout.addStretch(5)
        center_layout.addWidget(version_label)

        isen_logo = QLabel()
        isen_logo.setPixmap(
            QPixmap(":/img/isen_logo.png").scaledToWidth(
                180, Qt.SmoothTransformation))

        left_layout = QVBoxLayout()
        left_layout.setContentsMargins(0, 0, 0, 0)
        left_layout.addWidget(isen_logo, alignment=Qt.AlignBottom)

        ifremer_logo = QLabel()
        ifremer_logo.setAlignment(Qt.AlignRight)
        ifremer_logo.setPixmap(
            QPixmap(":/img/ifremer_logo.png").scaledToWidth(
                180, Qt.SmoothTransformation))

        right_layout = QVBoxLayout()
        right_layout.setContentsMargins(0, 0, 0, 0)
        right_layout.addWidget(ifremer_logo, alignment=Qt.AlignBottom)

        main_layout.addLayout(left_layout, 1)
        main_layout.addLayout(center_layout, 3)
        main_layout.addLayout(right_layout, 1)

        self.setLayout(main_layout)

        # Button slots
        start_button.clicked.connect(self._startButtonClicked)
        self._history_button.clicked.connect(self._historyButtonClicked)
        about_button.clicked.connect(self._aboutButtonClicked)
        exit_button.clicked.connect(self._exitButtonClicked)
Example #42
0
def main():
    app = QApplication(sys.argv)
    vars = {}

    def createGui():
        nonlocal vars
        gui = G27CalibGui()
        gui.setMinimumSize(1024, 700)
        gui.setWindowTitle("G27 Pedalsand Shifter")
        coll = Collector(vars["tty"])
        coll.valuesChanged.connect(gui.newVals)
        app.aboutToQuit.connect(coll.stop)
        if vars["jsdev"] is not None:
            js = JoystickSink(vars["jsdev"])
            app.aboutToQuit.connect(js.stop)
        else:
            js = None
        gui.sendModeCmd.connect(coll.sendModeCmd)
        gui.show()
        if main_widget is not None: main_widget.hide()
        vars["gui"] = gui
        vars["coll"] = coll
        vars["js"] = js

    if len(list_ports.comports()) != 1 or len(inputs.devices.gamepads) != 1:
        main_widget = QWidget()
        main_widget.setWindowTitle("G27 Pedalsand Shifter - serial port")
        layout = QGridLayout(main_widget)
        layout.addWidget(QLabel("Select Arduino COM port:", main_widget), 0, 0)
        ttyCombo = QComboBox(main_widget)
        layout.addWidget(ttyCombo, 0, 1)
        layout.addWidget(QLabel("Select G27 joystick port:", main_widget), 1,
                         0)
        jsCombo = QComboBox(main_widget)
        layout.addWidget(jsCombo, 1, 1)

        def refresh():
            ttyCombo.clear()
            n = 0
            for p in list_ports.comports():
                ttyCombo.addItem(p.device)
                n += 1
            k = 0
            jsCombo.clear()
            for i, d in enumerate(inputs.devices.gamepads):
                jsCombo.addItem(d.name, userData=d)
                k += 1
            btnStart.setEnabled(n > 0)

        def startgui():
            idx = ttyCombo.currentIndex()
            vars["tty"] = ttyCombo.itemText(ttyCombo.currentIndex())
            vars["jsdev"] = jsCombo.itemData(jsCombo.currentIndex())
            createGui()

        btnRefresh = QPushButton("Refresh Devices")
        btnRefresh.clicked.connect(refresh)
        layout.addWidget(btnRefresh, 0, 2)
        btnStart = QPushButton("Start")
        btnStart.clicked.connect(startgui)
        refresh()
        layout.addWidget(btnStart, 1, 2)
        main_widget.show()
    else:
        main_widget = None
        vars["tty"] = list_ports.comports()[0].device
        vars["jsdev"] = inputs.devices.gamepads[0]
        createGui()
    os._exit(app.exec_())
Example #43
0
    def _create_ammo_pickup_boxes(self, size_policy, item_database: ItemDatabase):
        """
        Creates the GroupBox with SpinBoxes for selecting the pickup count of all the ammo
        :param item_database:
        :return:
        """

        self._ammo_maximum_spinboxes = collections.defaultdict(list)
        self._ammo_pickup_widgets = {}

        resource_database = default_prime2_resource_database()

        for ammo in item_database.ammo.values():
            title_layout = QHBoxLayout()
            title_layout.setObjectName(f"{ammo.name} Title Horizontal Layout")

            expand_ammo_button = QToolButton(self.ammo_box)
            expand_ammo_button.setGeometry(QRect(20, 30, 24, 21))
            expand_ammo_button.setText("+")
            title_layout.addWidget(expand_ammo_button)

            category_label = QLabel(self.ammo_box)
            category_label.setSizePolicy(size_policy)
            category_label.setText(ammo.name + "s")
            title_layout.addWidget(category_label)

            pickup_box = QGroupBox(self.ammo_box)
            pickup_box.setSizePolicy(size_policy)
            layout = QGridLayout(pickup_box)
            layout.setObjectName(f"{ammo.name} Box Layout")
            current_row = 0

            for ammo_item in ammo.items:
                item = resource_database.get_by_type_and_index(ResourceType.ITEM, ammo_item)

                target_count_label = QLabel(pickup_box)
                target_count_label.setText(f"{item.long_name} Target" if len(ammo.items) > 1 else "Target count")

                maximum_spinbox = QSpinBox(pickup_box)
                maximum_spinbox.setMaximum(ammo.maximum)
                maximum_spinbox.valueChanged.connect(partial(self._on_update_ammo_maximum_spinbox, ammo_item))
                self._ammo_maximum_spinboxes[ammo_item].append(maximum_spinbox)

                layout.addWidget(target_count_label, current_row, 0)
                layout.addWidget(maximum_spinbox, current_row, 1)
                current_row += 1

            count_label = QLabel(pickup_box)
            count_label.setText("Pickup Count")
            count_label.setToolTip("How many instances of this expansion should be placed.")

            pickup_spinbox = QSpinBox(pickup_box)
            pickup_spinbox.setMaximum(AmmoState.maximum_pickup_count())
            pickup_spinbox.valueChanged.connect(partial(self._on_update_ammo_pickup_spinbox, ammo))

            layout.addWidget(count_label, current_row, 0)
            layout.addWidget(pickup_spinbox, current_row, 1)
            current_row += 1

            if ammo.temporaries:
                require_major_item_check = QCheckBox(pickup_box)
                require_major_item_check.setText("Requires the major item to work?")
                require_major_item_check.stateChanged.connect(partial(self._on_update_ammo_require_major_item, ammo))
                layout.addWidget(require_major_item_check, current_row, 0, 1, 2)
                current_row += 1
            else:
                require_major_item_check = None

            expected_count = QLabel(pickup_box)
            expected_count.setWordWrap(True)
            expected_count.setText(_EXPECTED_COUNT_TEXT_TEMPLATE)
            expected_count.setToolTip("Some expansions may provide 1 extra, even with no variance, if the total count "
                                      "is not divisible by the pickup count.")
            layout.addWidget(expected_count, current_row, 0, 1, 2)
            current_row += 1

            self._ammo_pickup_widgets[ammo] = (pickup_spinbox, expected_count, expand_ammo_button,
                                               category_label, pickup_box, require_major_item_check)

            expand_ammo_button.clicked.connect(partial(_toggle_box_visibility, expand_ammo_button, pickup_box))
            pickup_box.setVisible(False)

            self.ammo_layout.addLayout(title_layout)
            self.ammo_layout.addWidget(pickup_box)
Example #44
0
    def __init__(self, app, parent=None):
        super(MainWindow, self).__init__(parent)
        self.imagesDir = app.dir + '/images/'
        self.setWindowIcon(QIcon(self.imagesDir + 'icon.png'))
        self.path = ''

        self.settings = QSettings()
        self.lastDir = self.settings.value('lastDir', '')

        self.setMinimumWidth(540)

        self.supportedFormats = []
        for f in QImageReader.supportedImageFormats():
            self.supportedFormats.append(str(f.data(), encoding="utf-8"))

        self.fileWatcher = QFileSystemWatcher()
        self.fileWatcher.fileChanged.connect(self.fileChanged)

        # widgets
        self.showPixmapWidget = None

        self.tileWidthSpinBox = QSpinBox()
        self.tileWidthSpinBox.setValue(16)
        self.tileWidthSpinBox.setFixedWidth(50)
        self.tileWidthSpinBox.setMinimum(1)

        self.tileHeightSpinBox = QSpinBox()
        self.tileHeightSpinBox.setValue(16)
        self.tileHeightSpinBox.setFixedWidth(50)
        self.tileHeightSpinBox.setMinimum(1)

        self.paddingSpinBox = QSpinBox()
        self.paddingSpinBox.setFixedWidth(50)
        self.paddingSpinBox.setMinimum(1)

        self.transparentCheckbox = QCheckBox("Transparent")
        self.transparentCheckbox.setChecked(True)
        self.transparentCheckbox.stateChanged.connect(self.transparentChanged)

        self.backgroundColorEdit = ColorEdit()
        self.backgroundColorEdit.setEnabled(False)
        self.backgroundColorLabel = QLabel("Background color:")
        self.backgroundColorLabel.setEnabled(False)

        self.forcePotCheckBox = QCheckBox("Force PoT")
        self.forcePotCheckBox.setChecked(True)
        self.forcePotCheckBox.stateChanged.connect(self.forcePotChanged)

        self.reorderTilesCheckBox = QCheckBox("Reorder tiles")

        self.generateAndExportButton = QPushButton("Generate and export")
        self.generateAndExportButton.setFixedHeight(32)
        self.generateAndExportButton.clicked.connect(self.generateAndExportClicked)
        self.generateAndExportButton.setEnabled(False)

        self.pixmapWidget = PixmapWidget()
        self.pixmapWidget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.pixmapWidget.setPixmap(self.createDropTextPixmap())
        self.pixmapWidget.dropSignal.connect(self.fileDropped)
        self.pixmapWidget.setMinimumHeight(300)

        # load settings
        self.tileWidthSpinBox.setValue(int(self.settings.value('tileWidth', 16)))
        self.tileHeightSpinBox.setValue(int(self.settings.value('tileHeight', 16)))
        self.paddingSpinBox.setValue(int(self.settings.value('padding', 1)))
        self.forcePotCheckBox.setChecked(True if self.settings.value('forcePot', 'true') == 'true' else False)
        self.reorderTilesCheckBox.setChecked(True if self.settings.value('reorderTiles', 'false') == 'true' else False)
        self.transparentCheckbox.setChecked(True if self.settings.value('transparent', 'false') == 'true' else False)
        self.backgroundColorEdit.setColorText(str(self.settings.value('backgroundColor', '#FF00FF')))
        self.restoreGeometry(QByteArray(self.settings.value('MainWindow/geometry')))
        self.restoreState(QByteArray(self.settings.value('MainWindow/windowState')))

        # layout
        hl1 = QHBoxLayout()
        hl1.setContentsMargins(5, 5, 5, 5)
        hl1.addWidget(QLabel("Tile width:"))
        hl1.addSpacing(5)
        hl1.addWidget(self.tileWidthSpinBox)
        hl1.addSpacing(15)
        hl1.addWidget(QLabel("Tile height:"))
        hl1.addSpacing(5)
        hl1.addWidget(self.tileHeightSpinBox)
        hl1.addSpacing(15)
        hl1.addWidget(QLabel("Padding:"))
        hl1.addSpacing(5)
        hl1.addWidget(self.paddingSpinBox)
        hl1.addSpacing(15)
        hl1.addWidget(self.forcePotCheckBox)
        hl1.addSpacing(15)
        hl1.addWidget(self.reorderTilesCheckBox)
        hl1.addStretch()

        hl2 = QHBoxLayout()
        hl2.setContentsMargins(5, 5, 5, 5)
        hl2.addWidget(self.transparentCheckbox)
        hl2.addSpacing(15)
        hl2.addWidget(self.backgroundColorLabel)
        hl2.addSpacing(5)
        hl2.addWidget(self.backgroundColorEdit)
        hl2.addStretch()

        hl3 = QHBoxLayout()
        hl3.setContentsMargins(5, 5, 5, 5)
        hl3.addWidget(self.generateAndExportButton)

        vl = QVBoxLayout()
        vl.setContentsMargins(0, 0, 0, 0)
        vl.setSpacing(0)
        vl.addLayout(hl1)
        vl.addLayout(hl2)
        vl.addWidget(self.pixmapWidget)
        vl.addLayout(hl3)

        w = QWidget()
        w.setLayout(vl)
        self.setCentralWidget(w)

        self.setTitle()
Example #45
0
    def __init__(self):
        super(AsemblerIDE, self).__init__()
        self.workspace = None
        self.backupTimer = 300000
        PathManager.START_DIRECTORY = os.getcwd()
        self.workspaceConfiguration = WorkspaceConfiguration.loadConfiguration(
        )
        self.snippetManager = SnippetManager.loadSnippetConfiguration()
        self.tooltipManager = TooltipManager.loadTooltipConfiguration()
        self.configurationManager = ConfigurationManager()
        self.editorTabs = EditorTabWidget(self.snippetManager,
                                          self.tooltipManager)
        self.menuBar = MenuBar()
        self.terminal = Terminal()
        self.toolBar = ToolBar(self.configurationManager)
        self.statusBar = StatusBar()
        self.treeView = TreeView(self.configurationManager)
        self.help = HelpWidget()
        self.ascii = AsciiTableWidget()
        self.setStatusBar(self.statusBar)
        self.addToolBar(self.toolBar)
        self.addDockWidget(Qt.BottomDockWidgetArea, self.terminal)
        self.addDockWidget(Qt.RightDockWidgetArea, self.help)
        self.addDockWidget(Qt.RightDockWidgetArea, self.ascii)
        self.splitDockWidget(self.help, self.ascii, Qt.Vertical)
        self.treeDock = QDockWidget()
        self.treeDock.setAllowedAreas(Qt.LeftDockWidgetArea
                                      | Qt.RightDockWidgetArea)
        self.treeDock.setStyleSheet("background-color: #2D2D30; color: white;")
        self.treeDock.setFeatures(QDockWidget.DockWidgetMovable
                                  | QDockWidget.DockWidgetClosable)
        self.treeDock.setWindowTitle("Workspace explorer")
        self.treeDock.setWidget(self.treeView)
        header = QLabel("Workspace explorer")
        # header.setStyleSheet("background-color: #007ACC;")
        self.treeDock.setTitleBarWidget(header)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.treeDock)
        self.setMenuBar(self.menuBar)
        self.setMinimumSize(1200, 800)
        self.setWindowTitle("i386 Assembly Integrated Development Environment")
        self.setCentralWidget(self.editorTabs)
        self.setStyleSheet("background-color: #3E3E42; color: white;")
        self.setWindowIcon(QIcon(resource_path("resources/app_icon.ico")))

        self.addTabWidgetEventHandlers()
        self.addMenuBarEventHandlers()
        self.addToolBarEventHandlers()
        self.addTreeViewEventHandlers()
        self.checkWorkspaceConfiguration()
        #self.populateTreeView()
        #self.statusBar.comboBox.currentTextChanged.connect(self.changeEditorSyntax)
        self.statusBar.tabWidthComboBox.currentTextChanged.connect(
            self.changeEditorTabWidth)
        self.timer = QTimer()
        self.timer.start(self.backupTimer)
        self.timer.timeout.connect(self.makeBackupSave)

        self.terminal.console.setFocus()
        self.tabSwitcher = TabSwitcher(self.editorTabs)
        self.tabSwitcher.hide()
        self.projectSwitcher = ProjectSwitcher(self.configurationManager,
                                               self.toolBar.projectComboBox)
        self.projectSwitcher.hide()
        self.terminal.projectSwitchRequested.connect(self.showProjectSwitcher)
        self.terminal.tabSwitchRequested.connect(self.showTabSwitcher)
        self.editorTabs.tabSwitchRequested.connect(self.showTabSwitcher)
        self.editorTabs.projectSwitchRequested.connect(
            self.showProjectSwitcher)

        self.helpDocsDialog = GettingStartedDialog()
        self.helpDocsDialog.hide()
 def createLabel(self, text):
     label = QLabel(text)
     label.setAlignment(Qt.AlignCenter)
     label.setMargin(2)
     label.setFrameStyle(QFrame.Box | QFrame.Sunken)
     return label
Example #47
0
class SettingsWidget(QWidget):
    """Widget to show and edit the settings."""
    def __init__(self):
        super(SettingsWidget, self).__init__()
        self.settings = QSettings(c.SETTINGS_PATH, QSettings.IniFormat)
        self.keyboard_settings = QSettings(c.KEYBOARD_SETTINGS_PATH,
                                           QSettings.IniFormat)

        self.value_dict_settings = {}
        self.value_dict_keyboard = {}
        self.f_reg = re.compile("F[1-9]|1[0-2]")
        self.ctrl_reg = re.compile("CTRL\+[a-xA-X0-9]")
        self.forbidden_reg = re.compile("CTRL\+[vVcCzZyY]")

        v_box = QVBoxLayout()

        theme = QGroupBox("Theme")
        theme_layout = QFormLayout()
        theme_value = QComboBox()
        theme_value.addItem(c.THEME_D)
        theme_value.addItem(c.THEME_L)
        theme_value.setCurrentText(
            self.settings.value(c.THEME, defaultValue=c.THEME_D))
        theme_layout.addRow(QLabel(c.THEME.capitalize()), theme_value)
        theme.setLayout(theme_layout)
        self.value_dict_settings[c.THEME] = theme_value

        keyboard = QGroupBox("Keyboard")
        keyboard_layout = QFormLayout()
        info_label = QLabel("Only F-Keys and CTRL+ Combinations are allowed.")
        info_label.setWordWrap(True)
        keyboard_layout.addRow(info_label)

        for key in self.keyboard_settings.allKeys():
            line_edit = QLineEdit()
            line_edit.setText(self.keyboard_settings.value(key))
            keyboard_layout.addRow(key, line_edit)
            self.value_dict_keyboard[key] = line_edit

        keyboard.setLayout(keyboard_layout)

        plugins = QGroupBox("Plug-ins")
        plugins_layout = QFormLayout()
        show_empty_buttons_check = QCheckBox(
            "Show Plug-ins without Buttons in Word By Word - List")
        show_empty_buttons_check.setChecked(
            self.settings.value(c.SHOW_EMPTY_BUTTONS,
                                defaultValue=True,
                                type=bool))
        plugins_layout.addRow(show_empty_buttons_check)
        self.value_dict_settings[
            c.SHOW_EMPTY_BUTTONS] = show_empty_buttons_check
        plugins.setLayout(plugins_layout)

        self.note = QLabel("Settings will be applied after restart")

        save = QPushButton("Save")
        save.clicked.connect(self.save_values)

        v_box.addWidget(theme)
        v_box.addWidget(keyboard)
        v_box.addWidget(plugins)
        v_box.addWidget(self.note)
        v_box.addWidget(save)

        self.setLayout(v_box)

    def save_values(self):
        """Saves the current values."""

        saved = True
        for key in self.value_dict_settings.keys():
            widget = self.value_dict_settings.get(key)
            if isinstance(widget, QLineEdit):
                self.settings.setValue(key, widget.text().strip())
            if isinstance(widget, QComboBox):
                self.settings.setValue(key, widget.currentText().strip())
            if isinstance(widget, QCheckBox):
                self.settings.setValue(key, widget.isChecked())

        occupied = []
        self.keyboard_settings.clear()
        for key in self.value_dict_keyboard.keys():
            value = self.value_dict_keyboard.get(key).text().strip().replace(
                " ", "").upper()
            if len(value) == 0 or ((bool(self.f_reg.search(value))
                                    or bool(self.ctrl_reg.search(value))) and
                                   not bool(self.forbidden_reg.search(value))):
                if value not in occupied:
                    self.keyboard_settings.setValue(key, value)
                    if len(value) != 0:
                        occupied.append(value)
                else:
                    saved = False
                    self.note.setStyleSheet("QLabel {color: red;}")
                    self.note.setText("Duplicate Values found!")
                    self.keyboard_settings.setValue(key, "")
        if saved:
            self.note.setStyleSheet("QLabel {color: green;}")
            self.note.setText("Saved!")

    def reset_note(self):
        """Resets the little now text at the bottom."""

        self.note.setStyleSheet("")
        self.note.setText("Settings will be applied after restart")
Example #48
0
class MainWindow(QMainWindow):

    def __init__(self, app, parent=None):
        super(MainWindow, self).__init__(parent)
        self.imagesDir = app.dir + '/images/'
        self.setWindowIcon(QIcon(self.imagesDir + 'icon.png'))
        self.path = ''

        self.settings = QSettings()
        self.lastDir = self.settings.value('lastDir', '')

        self.setMinimumWidth(540)

        self.supportedFormats = []
        for f in QImageReader.supportedImageFormats():
            self.supportedFormats.append(str(f.data(), encoding="utf-8"))

        self.fileWatcher = QFileSystemWatcher()
        self.fileWatcher.fileChanged.connect(self.fileChanged)

        # widgets
        self.showPixmapWidget = None

        self.tileWidthSpinBox = QSpinBox()
        self.tileWidthSpinBox.setValue(16)
        self.tileWidthSpinBox.setFixedWidth(50)
        self.tileWidthSpinBox.setMinimum(1)

        self.tileHeightSpinBox = QSpinBox()
        self.tileHeightSpinBox.setValue(16)
        self.tileHeightSpinBox.setFixedWidth(50)
        self.tileHeightSpinBox.setMinimum(1)

        self.paddingSpinBox = QSpinBox()
        self.paddingSpinBox.setFixedWidth(50)
        self.paddingSpinBox.setMinimum(1)

        self.transparentCheckbox = QCheckBox("Transparent")
        self.transparentCheckbox.setChecked(True)
        self.transparentCheckbox.stateChanged.connect(self.transparentChanged)

        self.backgroundColorEdit = ColorEdit()
        self.backgroundColorEdit.setEnabled(False)
        self.backgroundColorLabel = QLabel("Background color:")
        self.backgroundColorLabel.setEnabled(False)

        self.forcePotCheckBox = QCheckBox("Force PoT")
        self.forcePotCheckBox.setChecked(True)
        self.forcePotCheckBox.stateChanged.connect(self.forcePotChanged)

        self.reorderTilesCheckBox = QCheckBox("Reorder tiles")

        self.generateAndExportButton = QPushButton("Generate and export")
        self.generateAndExportButton.setFixedHeight(32)
        self.generateAndExportButton.clicked.connect(self.generateAndExportClicked)
        self.generateAndExportButton.setEnabled(False)

        self.pixmapWidget = PixmapWidget()
        self.pixmapWidget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.pixmapWidget.setPixmap(self.createDropTextPixmap())
        self.pixmapWidget.dropSignal.connect(self.fileDropped)
        self.pixmapWidget.setMinimumHeight(300)

        # load settings
        self.tileWidthSpinBox.setValue(int(self.settings.value('tileWidth', 16)))
        self.tileHeightSpinBox.setValue(int(self.settings.value('tileHeight', 16)))
        self.paddingSpinBox.setValue(int(self.settings.value('padding', 1)))
        self.forcePotCheckBox.setChecked(True if self.settings.value('forcePot', 'true') == 'true' else False)
        self.reorderTilesCheckBox.setChecked(True if self.settings.value('reorderTiles', 'false') == 'true' else False)
        self.transparentCheckbox.setChecked(True if self.settings.value('transparent', 'false') == 'true' else False)
        self.backgroundColorEdit.setColorText(str(self.settings.value('backgroundColor', '#FF00FF')))
        self.restoreGeometry(QByteArray(self.settings.value('MainWindow/geometry')))
        self.restoreState(QByteArray(self.settings.value('MainWindow/windowState')))

        # layout
        hl1 = QHBoxLayout()
        hl1.setContentsMargins(5, 5, 5, 5)
        hl1.addWidget(QLabel("Tile width:"))
        hl1.addSpacing(5)
        hl1.addWidget(self.tileWidthSpinBox)
        hl1.addSpacing(15)
        hl1.addWidget(QLabel("Tile height:"))
        hl1.addSpacing(5)
        hl1.addWidget(self.tileHeightSpinBox)
        hl1.addSpacing(15)
        hl1.addWidget(QLabel("Padding:"))
        hl1.addSpacing(5)
        hl1.addWidget(self.paddingSpinBox)
        hl1.addSpacing(15)
        hl1.addWidget(self.forcePotCheckBox)
        hl1.addSpacing(15)
        hl1.addWidget(self.reorderTilesCheckBox)
        hl1.addStretch()

        hl2 = QHBoxLayout()
        hl2.setContentsMargins(5, 5, 5, 5)
        hl2.addWidget(self.transparentCheckbox)
        hl2.addSpacing(15)
        hl2.addWidget(self.backgroundColorLabel)
        hl2.addSpacing(5)
        hl2.addWidget(self.backgroundColorEdit)
        hl2.addStretch()

        hl3 = QHBoxLayout()
        hl3.setContentsMargins(5, 5, 5, 5)
        hl3.addWidget(self.generateAndExportButton)

        vl = QVBoxLayout()
        vl.setContentsMargins(0, 0, 0, 0)
        vl.setSpacing(0)
        vl.addLayout(hl1)
        vl.addLayout(hl2)
        vl.addWidget(self.pixmapWidget)
        vl.addLayout(hl3)

        w = QWidget()
        w.setLayout(vl)
        self.setCentralWidget(w)

        self.setTitle()

    def setTitle(self):
        p = ' - ' + os.path.basename(self.path) if self.path else ''
        self.setWindowTitle(QCoreApplication.applicationName() + ' ' + QCoreApplication.applicationVersion() + p)

    def createDropTextPixmap(self):
        pixmap = QPixmap(481, 300)
        pixmap.fill(QColor("#333333"))
        painter = QPainter(pixmap)
        font = QFont("Arial")
        font.setPixelSize(28)
        font.setBold(True)
        fm = QFontMetrics(font)
        painter.setFont(font)
        painter.setPen(QPen(QColor("#888888"), 1))
        text = "Drop the tileset image here"
        x = (pixmap.width()-fm.width(text))/2
        y = (pixmap.height()+fm.height())/2
        painter.drawText(x, y, text)
        del painter
        return pixmap

    def fileDropped(self, path):
        path = str(path)
        name, ext = os.path.splitext(path)
        ext = ext[1:]
        if not ext in self.supportedFormats:
            QMessageBox.warning(self, "Warning", "The dropped file is not supported")
            return
        pixmap = QPixmap(path)
        if pixmap.isNull():
            QMessageBox.warning(self, "Warning", "Can't load the image")
            return
        if self.path:
            self.fileWatcher.removePath(self.path)
        self.path = path
        self.fileWatcher.addPath(self.path)
        self.pixmapWidget.setPixmap(pixmap)
        self.generateAndExportButton.setEnabled(True)
        self.setTitle()
        self.activateWindow()

    def fileChanged(self, path):
        #self.fileDropped(path)
        pass

    def transparentChanged(self):
        e = self.transparentCheckbox.isChecked()
        self.backgroundColorEdit.setEnabled(not e)
        self.backgroundColorLabel.setEnabled(not e)

    def forcePotChanged(self):
        e = self.forcePotCheckBox.isChecked()
        self.reorderTilesCheckBox.setEnabled(e)

    def generateAndExportClicked(self):

        g = Generator()
        g.tileWidth = self.tileWidthSpinBox.value()
        g.tileHeight = self.tileHeightSpinBox.value()
        g.forcePot = self.forcePotCheckBox.isChecked()
        g.isTransparent = self.transparentCheckbox.isChecked()
        g.bgColor = self.backgroundColorEdit.getColor()
        g.reorder = self.reorderTilesCheckBox.isChecked()
        g.padding = self.paddingSpinBox.value()

        target = g.create(self.pixmapWidget.pixmap);

        # export
        self.lastDir = os.path.dirname(self.path)
        targetPath = QFileDialog.getSaveFileName(self, 'Export', self.lastDir, 'PNG (*.png)')
        if targetPath:
            target.save(targetPath[0])
            showPixmap = QPixmap.fromImage(target)
            if self.showPixmapWidget:
                self.showPixmapWidget.deleteLater()
                del self.showPixmapWidget
            self.showPixmapWidget = PixmapWidget()
            self.showPixmapWidget.setWindowIcon(self.windowIcon())
            self.showPixmapWidget.setWindowTitle(os.path.basename(targetPath[0]))
            self.showPixmapWidget.resize(showPixmap.width(), showPixmap.height())
            self.showPixmapWidget.setPixmap(showPixmap)
            self.showPixmapWidget.show()

    def closeEvent(self, event):
        if self.showPixmapWidget:
            self.showPixmapWidget.close()

        # save settings
        self.settings.setValue('tileWidth', self.tileWidthSpinBox.value())
        self.settings.setValue('tileHeight', self.tileHeightSpinBox.value())
        self.settings.setValue('padding', self.paddingSpinBox.value())
        self.settings.setValue('forcePot', self.forcePotCheckBox.isChecked())
        self.settings.setValue('reorderTiles', self.reorderTilesCheckBox.isChecked())
        self.settings.setValue('transparent', self.transparentCheckbox.isChecked())
        self.settings.setValue('backgroundColor', self.backgroundColorEdit.getColor().name())
        self.settings.setValue('lastDir', self.lastDir)
        self.settings.setValue('MainWindow/geometry', self.saveGeometry())
        self.settings.setValue('MainWindow/windowState', self.saveState())

        super(MainWindow, self).closeEvent(event)
Example #49
0
    def __init__(self):
        super(SettingsWidget, self).__init__()
        self.settings = QSettings(c.SETTINGS_PATH, QSettings.IniFormat)
        self.keyboard_settings = QSettings(c.KEYBOARD_SETTINGS_PATH,
                                           QSettings.IniFormat)

        self.value_dict_settings = {}
        self.value_dict_keyboard = {}
        self.f_reg = re.compile("F[1-9]|1[0-2]")
        self.ctrl_reg = re.compile("CTRL\+[a-xA-X0-9]")
        self.forbidden_reg = re.compile("CTRL\+[vVcCzZyY]")

        v_box = QVBoxLayout()

        theme = QGroupBox("Theme")
        theme_layout = QFormLayout()
        theme_value = QComboBox()
        theme_value.addItem(c.THEME_D)
        theme_value.addItem(c.THEME_L)
        theme_value.setCurrentText(
            self.settings.value(c.THEME, defaultValue=c.THEME_D))
        theme_layout.addRow(QLabel(c.THEME.capitalize()), theme_value)
        theme.setLayout(theme_layout)
        self.value_dict_settings[c.THEME] = theme_value

        keyboard = QGroupBox("Keyboard")
        keyboard_layout = QFormLayout()
        info_label = QLabel("Only F-Keys and CTRL+ Combinations are allowed.")
        info_label.setWordWrap(True)
        keyboard_layout.addRow(info_label)

        for key in self.keyboard_settings.allKeys():
            line_edit = QLineEdit()
            line_edit.setText(self.keyboard_settings.value(key))
            keyboard_layout.addRow(key, line_edit)
            self.value_dict_keyboard[key] = line_edit

        keyboard.setLayout(keyboard_layout)

        plugins = QGroupBox("Plug-ins")
        plugins_layout = QFormLayout()
        show_empty_buttons_check = QCheckBox(
            "Show Plug-ins without Buttons in Word By Word - List")
        show_empty_buttons_check.setChecked(
            self.settings.value(c.SHOW_EMPTY_BUTTONS,
                                defaultValue=True,
                                type=bool))
        plugins_layout.addRow(show_empty_buttons_check)
        self.value_dict_settings[
            c.SHOW_EMPTY_BUTTONS] = show_empty_buttons_check
        plugins.setLayout(plugins_layout)

        self.note = QLabel("Settings will be applied after restart")

        save = QPushButton("Save")
        save.clicked.connect(self.save_values)

        v_box.addWidget(theme)
        v_box.addWidget(keyboard)
        v_box.addWidget(plugins)
        v_box.addWidget(self.note)
        v_box.addWidget(save)

        self.setLayout(v_box)
Example #50
0
class G27CalibGui(QWidget):
    sendModeCmd = Signal(object)
    setObjectCmd = Signal(object)

    def __init__(self):
        super().__init__()
        self.tl_layout = QGridLayout(self)
        rbtn_values = QGroupBox("Calibration Values", self)
        vbox = QVBoxLayout(rbtn_values)
        self.mode_btns = [
            QRadioButton(s, rbtn_values) for s in [
                "Idle", "Shifter neutral zone", "Shifter 135 zone",
                "Shifter 246R zone", "Shifter 12 zone", "Shifter 56 zone",
                "Gas pedal (if not auto-calibrated)",
                "Brake pedal (if not auto-calibrated)",
                "Clutch pedal (if not auto-calibrated)"
            ]
        ]
        self.mode_btns[0].setChecked(True)
        self.mode_cmds = [b"i", b"n", b"u", b"b", b"l", b"r", b"G", b"B", b"C"]
        self.help_cmds = [
            "First decide about the filtering needed (in middle panel). If there is a lot of noise in the signal, "
            "maybe because of old pots, you might want to use a multi-sample median filter. Note that this filter "
            "introduces some delay, so you want to keep the numbers reasonable low. Afterwards, iterate through "
            "the calibration values in the left panel.\n\n"
            "When you're done, you can save the calibration in the right panel to the EEPROM.",
            "Put the shifter in neutral position. Afterwards, keep the left red button pressed and move the "
            "shifter while still in neutral. When reaching the calibrated area, the gear will be set to neutral.",
            "Put the shifter in 3rd gear. Afterwards keep the left red button pressed and move the shifter "
            "while still in 3rd gear. When done, release the red button. Optionally repeat for gears 1st and 5th.",
            "Put the shifter in 4th gear. Afterwards keep the left red button pressed and move the shifter "
            "while still in 4th gear. When done, release the red button. Optionally repeat for gears 2nd and 6th.",
            "Put the shifter in 1st gear. Afterwards keep the left red button pressed and move the shifter "
            "while still in 1st gear. When done, release the red button. Optionally repeat for 2nd gear.",
            "Put the shifter in 5th gear. Afterwards keep the left red button pressed and move the shifter "
            "while still in 5th gear. When done, release the red button. Optionally repeat for 6th gear.",
            "Move the gas pedal multiple times between lowest and highest position.",
            "Move the brake pedal multiple times between lowest and highest position.",
            "Move the clutch pedal multiple times between lowest and highest position."
        ]
        for b in self.mode_btns:
            vbox.addWidget(b)
            b.toggled.connect(self.modeChanged)
        self.tl_layout.addWidget(rbtn_values, 0, 0, 1, 1)

        cbtn_options = QGroupBox("Options", self)
        grid = QGridLayout(cbtn_options)
        self.option_btns = [
            QCheckBox(s, cbtn_options) for s in [
                "Enable pedal auto-calibration", "Invert gas/throttle pedal",
                "Invert brake pedal", "Invert clutch pedal",
                "Use right red button for reverse instead pushing the gear",
                "Enable pedals", "Enable shifter"
            ]
        ] + [
            QComboBox(),
            QComboBox(),
            QComboBox(),
            QComboBox(),
            QComboBox(),
            QComboBox()
        ]
        self.option_cmds = [
            (b"p", b"P"),  #0
            (b"y", b"Y"),  #1
            (b"x", b"X"),  #2
            (b"z", b"Z"),  #3
            (b"q", b"Q"),  #4
            (b"e", b"E"),  #5
            (b"s", b"S"),  #6
            (b".", b"+", b"-"),  #7
            (b"[^", b"[!", b"[\"", b"[]", b"[$", b"[%", b"[&", b"[/"),
            (b"(^", b"(!", b"(\"", b"(]", b"($", b"(%", b"(&", b"(/"),
            (b")^", b")!", b")\"", b")]", b")$", b")%", b")&", b")/"),
            (b"0", b"3", b"5", b"7", b"9", b"f"),
            (b"1", b"2", b"4", b"6", b"8", b"F"),
        ]
        self.option_btns[-6].addItem("Do not combine clutch and gas")
        self.option_btns[-6].addItem(
            "Combine Clutch and Gas (Clutch = Gas - Clutch)")
        self.option_btns[-6].addItem(
            "Combine Clutch and Gas (Clutch = Clutch - Gas)")
        for (idx, name) in [(-5, "Gas"), (-4, "Brake"), (-3, "Clutch")]:
            for dz in [0, 2, 4, 6, 8, 10, 12, 14]:
                self.option_btns[idx].addItem("%s: %d%% dead zone" %
                                              (name, dz))
        for (idx, name) in [(-2, "pedals"), (-1, "shifter")]:
            for size in [0, 3, 5, 9, 15, 49]:
                self.option_btns[idx].addItem(
                    "off" if size == 0 else (str(size) + "-median"), size)
        for i, b in enumerate(self.option_btns):
            n_checkboxes = len(self.option_cmds) - 6
            if i < n_checkboxes:
                grid.addWidget(b, i, 0, 1, 2)
            else:
                names = {
                    n_checkboxes: "Combine",
                    n_checkboxes + 1: "Gas Dead Zone",
                    n_checkboxes + 2: "Brake Dead Zone",
                    n_checkboxes + 3: "Clutch Dead Zone",
                    n_checkboxes + 4: "Pedal filter",
                    n_checkboxes + 5: "Shifter filter"
                }
                grid.addWidget(QLabel(names[i], parent=self), i, 0)
                grid.addWidget(b, i, 1)
            if isinstance(b, QCheckBox):
                b.toggled.connect(self.optionChanged)
            else:
                b.currentIndexChanged.connect(self.optionChanged)
        self.tl_layout.addWidget(cbtn_options, 0, 1, 1, 1)

        cbtn_persistent = QGroupBox("Persistency")
        self.persistent_btns = [
            QPushButton(s, parent=self)
            for s in ["Save to EEPROM", "Load from EEPROM", "Defaults"]
        ]
        self.persistent_cmds = [b"w", b"U", b"c"]
        vbox = QVBoxLayout(cbtn_persistent)
        for i, b in enumerate(self.persistent_btns):
            vbox.addWidget(b)
            b.clicked.connect(self.persistent_cmd)
        self.tl_layout.addWidget(cbtn_persistent, 0, 2, 1, 1)

        self.helpArea = QLabel(self.help_cmds[0], self)
        self.helpArea.setWordWrap(True)
        f = self.helpArea.font()
        f.setBold(True)
        f.setPointSizeF(f.pointSizeF() * 1.5)
        self.helpArea.setFont(f)
        self.tl_layout.addWidget(self.helpArea, 0, 3, 1, 1)

        shifter_label = QLabel("Shifter")
        self.tl_layout.addWidget(shifter_label,
                                 1,
                                 2,
                                 1,
                                 2,
                                 alignment=Qt.AlignHCenter)
        shifter_plot = pg.PlotWidget(parent=self)
        shifter_plot.setMouseEnabled(x=False, y=False)
        self.tl_layout.addWidget(shifter_plot, 2, 2, 1, 2)
        shifter_plot.setRange(QRectF(0, 0, 1023, 1023), padding=0)
        pi = shifter_plot.getPlotItem()
        self.shifter_neutral_plot = pg.LinearRegionItem(
            values=(400, 600),
            orientation='horizontal',
            movable=False,
            brush=QBrush(QColor(200, 50, 50, 50)),
            pen=QPen(QColor(200, 50, 50)))
        shifter_plot.addItem(self.shifter_neutral_plot)
        self.shifter_135_plot = pg.LinearRegionItem(
            values=(800, 1024),
            orientation='horizontal',
            movable=False,
            brush=QBrush(QColor(50, 200, 50, 50)),
            pen=QPen(QColor(50, 200, 50)))
        shifter_plot.addItem(self.shifter_135_plot)
        self.shifter_246_plot = pg.LinearRegionItem(
            values=(0, 200),
            orientation='horizontal',
            movable=False,
            brush=QBrush(QColor(50, 50, 200, 50)),
            pen=QPen(QColor(50, 50, 200)))
        shifter_plot.addItem(self.shifter_246_plot)
        self.shifter_12_plot = pg.LinearRegionItem(
            values=(0, 200),
            orientation='vertical',
            movable=False,
            brush=QBrush(QColor(50, 200, 200, 50)),
            pen=QPen(QColor(50, 200, 200)))
        shifter_plot.addItem(self.shifter_12_plot)
        self.shifter_56_plot = pg.LinearRegionItem(
            values=(800, 1024),
            orientation='vertical',
            movable=False,
            brush=QBrush(QColor(200, 200, 50, 50)),
            pen=QPen(QColor(200, 200, 50)))
        shifter_plot.addItem(self.shifter_56_plot)
        self.shifter_pos_plot = pi.plot(x=[512], y=[512], symbol='+', pen=None)

        pedals_label = QLabel("Pedals")
        self.tl_layout.addWidget(pedals_label,
                                 1,
                                 0,
                                 1,
                                 2,
                                 alignment=Qt.AlignHCenter)
        pedals_plot = pg.PlotWidget(parent=self)
        pedals_plot.setMouseEnabled(x=False, y=False)
        pedals_plot.setRange(QRectF(-1, 0, 4, 1023), padding=0)
        pedals_plot.getAxis('bottom').setTicks([[(0.0, "Gas/Throttle"),
                                                 (1.0, "Brake"),
                                                 (2.0, "Clutch")], []])
        self.tl_layout.addWidget(pedals_plot, 2, 0, 1, 2)
        self.pedals_pos_plot = pg.BarGraphItem(x=np.arange(3),
                                               height=[512, 512, 512],
                                               width=0.5)
        self.pedals_gas_calib_plot = pedals_plot.getPlotItem().plot(
            x=[0],
            y=[0],
            pen=QPen(QColor(255, 0, 0), width=0.1),
            brush=QBrush(Qt.NoBrush))
        self.pedals_brake_calib_plot = pedals_plot.getPlotItem().plot(
            x=[0], y=[0], pen=QPen(QColor(0, 255, 0)))
        self.pedals_clutch_calib_plot = pedals_plot.getPlotItem().plot(
            x=[0], y=[0], pen=QPen(QColor(0, 0, 255)))
        self.pedals_pos_plot2 = pedals_plot.getPlotItem().plot(x=[],
                                                               y=[],
                                                               symbol='+',
                                                               pen=None)
        pedals_plot.addItem(self.pedals_pos_plot)

        self.status_line = QLabel(self)
        self.tl_layout.addWidget(self.status_line, 3, 0, 1, 2)
        self.status_line2 = QLabel(self)
        self.tl_layout.addWidget(self.status_line2, 3, 2, 1, 2)
        self.currentVals = Values()

    def modeChanged(self, toggled):
        if toggled:
            o = self.sender()
            idx = self.mode_btns.index(o)
            self.sendModeCmd.emit(self.mode_cmds[idx])
            self.helpArea.setText(self.help_cmds[idx])

    def optionChanged(self, option):
        o = self.sender()
        idx = self.option_btns.index(o)
        self.sendModeCmd.emit(self.option_cmds[idx][int(option)])

    def persistent_cmd(self):
        o = self.sender()
        idx = self.persistent_btns.index(o)
        self.sendModeCmd.emit(self.persistent_cmds[idx])

    def newVals(self, values, dbg):
        updateRate = 0.040 * 1e9  # 25 Hz
        if len(self.currentVals.times) == 0 or (
                len(values.times) > 0 and values.times[-1] >
                self.currentVals.times[-1] + updateRate):  # each 10ms
            self.currentVals.add(values)
            values = self.currentVals
            self.pedals_pos_plot.setOpts(
                height=[values.gas[-1], values.brake[-1], values.clutch[-1]])
            self.pedals_pos_plot2.setData(x=np.concatenate(
                ([-0.35] * len(values.gas), [0.65] * len(values.brake),
                 [1.65] * len(values.clutch))),
                                          y=np.concatenate(
                                              (values.gas, values.brake,
                                               values.clutch)))

            self.pedals_gas_calib_plot.setPen(QPen(QColor(255, 0, 0), width=0))
            self.pedals_gas_calib_plot.setData(
                x=[-0.0, -0.0, +0.0, +0.0, -0.0],
                y=[
                    values.calib.gasMin, values.calib.gasMax,
                    values.calib.gasMax, values.calib.gasMin,
                    values.calib.gasMin
                ])
            self.pedals_brake_calib_plot.setData(x=[1.0, 1.0, 1.0, 1.0, 1.0],
                                                 y=[
                                                     values.calib.brakeMin,
                                                     values.calib.brakeMax,
                                                     values.calib.brakeMax,
                                                     values.calib.brakeMin,
                                                     values.calib.brakeMin
                                                 ])
            self.pedals_clutch_calib_plot.setData(x=[2.0, 2.0, 2.0, 2.0, 2.0],
                                                  y=[
                                                      values.calib.clutchMin,
                                                      values.calib.clutchMax,
                                                      values.calib.clutchMax,
                                                      values.calib.clutchMin,
                                                      values.calib.clutchMin
                                                  ])

            self.shifter_pos_plot.setData(x=values.sx, y=values.sy)
            self.shifter_neutral_plot.setRegion(
                (values.calib.shifter_y_neutralMin,
                 values.calib.shifter_y_neutralMax))
            self.shifter_135_plot.setRegion(
                (values.calib.shifter_y_135_gearZone, 1024))
            self.shifter_246_plot.setRegion(
                (0, values.calib.shifter_y_246R_gearZone))
            self.shifter_12_plot.setRegion((0, values.calib.shifter_x_12))
            self.shifter_56_plot.setRegion((values.calib.shifter_x_56, 1024))

            blockers = []
            for b in self.option_btns:
                blockers.append(QSignalBlocker(b))
            self.option_btns[0].setChecked(values.calib.pedals_auto_calib)
            self.option_btns[1].setChecked(
                (values.calib.flag1 & FLAG1_INVERT_GAS) != 0)
            self.option_btns[2].setChecked(
                (values.calib.flag1 & FLAG1_INVERT_BRAKE) != 0)
            self.option_btns[3].setChecked(
                (values.calib.flag1 & FLAG1_INVERT_CLUTCH) != 0)
            self.option_btns[4].setChecked(
                (values.calib.flag1 & FLAG1_REVERSE_RIGHT_RED) != 0)
            self.option_btns[5].setChecked(
                (values.calib.flag2 & FLAG2_ENABLE_PEDALS) != 0)
            self.option_btns[6].setChecked(
                (values.calib.flag3 & FLAG3_ENABLE_SHIFTER) != 0)
            if (values.calib.flag1 &
                (FLAG1_COMBINE_Z_EQUALS_X_MINUS_Z
                 | FLAG1_COMBINE_Z_EQUALS_Z_MINUS_X)) == 0:
                self.option_btns[7].setCurrentIndex(0)
            elif (values.calib.flag1 & FLAG1_COMBINE_Z_EQUALS_X_MINUS_Z) != 0:
                self.option_btns[7].setCurrentIndex(1)
            else:
                self.option_btns[7].setCurrentIndex(2)
            self.option_btns[8].setCurrentIndex((values.calib.flag2
                                                 & FLAG2_GAS_DEAD_ZONE) >> 4)
            self.option_btns[9].setCurrentIndex((values.calib.flag2
                                                 & FLAG2_BRAKE_DEAD_ZONE) >> 1)
            self.option_btns[10].setCurrentIndex(
                (values.calib.flag3 & FLAG3_CLUTCH_DEAD_ZONE) >> 4)
            self.option_btns[11].setCurrentIndex(self.option_btns[11].findData(
                values.calib.pedals_median_size))
            self.option_btns[12].setCurrentIndex(self.option_btns[12].findData(
                values.calib.shifter_median_size))

            prof = "Total runtime: %9.2f ms | prof[0->1]: %9.2f ms | prof[1->2]: %9.2f ms | prof[2->3]: %9.2f ms | FPS: %04d" % (
                (dbg.profiling[-1] - dbg.profiling[0]) * 1e-3,
                (dbg.profiling[1] - dbg.profiling[0]) * 1e-3,
                (dbg.profiling[2] - dbg.profiling[1]) * 1e-3,
                (dbg.profiling[3] - dbg.profiling[2]) * 1e-3,
                ((len(values.times) * 1e9 /
                  (values.times[-1] - values.times[0]))
                 if len(values.times) > 1 else "N/A"),
            )
            self.status_line.setText(prof)

            # output values
            s = ""
            if dbg.out_axis[0] != 0xffff:
                s += "A0=%04d A1=%04d A2=%04d " % tuple(dbg.out_axis)
            else:
                s += "A0=N/A  A1=N/A  A2=N/A  "

            if dbg.out_buttons != 0xffffffff:
                bstr = "{:019b}".format(dbg.out_buttons)
                s += "ShifterBtn: " + bstr[:-7]
                gear = bstr[-7:][::-1]
                if "1" in gear:
                    gear = gear.index("1") + 1
                else:
                    gear = 0
                s += " ShifterGear=%d" % (gear)
            else:
                s += "Shifter=N/A"
            self.status_line2.setText(s)
Example #51
0
class RunTab(QtWidgets.QWidget):

    run_checks = QtCore.Signal()

    def __init__(self, prj: QAXProject):
        super(RunTab, self).__init__()
        self.prj = prj
        self.check_executor = None

        self.vbox = QtWidgets.QVBoxLayout()
        self.setLayout(self.vbox)

        self._add_check_outputs()
        self._add_process()

        # final setup
        self.set_run_stop_buttons_enabled(False)

    def _add_check_outputs(self):
        co_groupbox = QGroupBox("Check outputs")
        co_groupbox.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        co_layout = QVBoxLayout()
        co_layout.setSpacing(16)
        co_groupbox.setLayout(co_layout)

        self.qajson_spatial_checkbox = QCheckBox(
            "Include summary spatial output in QAJSON. "
            "Supports QAX visualisation.")
        self.qajson_spatial_checkbox.setCheckState(
            QtCore.Qt.CheckState.Checked)
        co_layout.addWidget(self.qajson_spatial_checkbox)

        export_layout = QVBoxLayout()
        export_layout.setSpacing(4)
        self.export_spatial_checkbox = QCheckBox(
            "Export detailed spatial outputs to file. "
            "Supports visualisation in other geospatial applications.")
        self.export_spatial_checkbox.stateChanged.connect(
            self._on_export_spatial_changed)
        export_layout.addWidget(self.export_spatial_checkbox)

        output_folder_layout = QHBoxLayout()
        output_folder_layout.setSpacing(4)
        output_folder_layout.addSpacerItem(QtWidgets.QSpacerItem(37, 20))
        self.output_folder_label = QLabel(
            "Detailed spatial output folder location:")
        output_folder_layout.addWidget(self.output_folder_label)
        self.output_folder_input = QLineEdit()
        self.output_folder_input.setText(
            GuiSettings.settings().value("spatial_outputs"))
        self.output_folder_input.setMinimumWidth(300)
        self.output_folder_input.setSizePolicy(QSizePolicy.Expanding,
                                               QSizePolicy.Expanding)
        output_folder_layout.addWidget(self.output_folder_input)

        self.open_output_folder_button = QPushButton()
        output_folder_layout.addWidget(self.open_output_folder_button)
        self.open_output_folder_button.setIcon(qta.icon('fa.folder-open'))
        self.open_output_folder_button.setToolTip(
            f"Select file containing data")
        self.open_output_folder_button.clicked.connect(
            self._click_open_spatial_export_folder)
        export_layout.addLayout(output_folder_layout)

        co_layout.addLayout(export_layout)

        self._on_export_spatial_changed()
        self.vbox.addWidget(co_groupbox)

    def _click_open_spatial_export_folder(self):
        output_folder = QFileDialog.getExistingDirectory(
            self, f"Select folder for spatial outputs",
            GuiSettings.settings().value("spatial_outputs"),
            QFileDialog.ShowDirsOnly)

        if os.path.exists(output_folder):
            GuiSettings.settings().setValue("spatial_outputs", output_folder)

        self.output_folder_input.setText(output_folder)

    def _on_export_spatial_changed(self):
        is_export = self.export_spatial_checkbox.isChecked()
        self.output_folder_label.setEnabled(is_export)
        self.output_folder_input.setEnabled(is_export)
        self.open_output_folder_button.setEnabled(is_export)

    def _add_process(self):
        process_groupbox = QGroupBox("Process")
        process_groupbox.setSizePolicy(QSizePolicy.Expanding,
                                       QSizePolicy.Expanding)
        process_layout = QVBoxLayout()
        process_layout.setSpacing(0)
        process_groupbox.setLayout(process_layout)

        pbar_frame = QFrame()
        pbar_frame.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        pbar_hbox = QHBoxLayout()
        pbar_hbox.setContentsMargins(QtCore.QMargins(0, 0, 0, 16))
        pbar_hbox.setSpacing(16)

        # Run and stop buttons
        hbox = QHBoxLayout()
        hbox.setSpacing(8)
        self.run_button = QPushButton()
        # is only enabled when validation passes
        self.run_button.setEnabled(False)
        self.run_button.setText("Run")
        self.run_button.setToolTip("Start check execution")
        self.run_button.setFixedWidth(100)
        run_icon = qta.icon('fa.play', color='green')
        self.run_button.setIcon(run_icon)
        self.run_button.clicked.connect(self._click_run)
        hbox.addWidget(self.run_button)

        self.stop_button = QPushButton()
        self.stop_button.setEnabled(False)
        self.stop_button.setText("Stop")
        self.stop_button.setToolTip("Stop check execution")
        self.stop_button.setFixedWidth(100)
        stop_icon = qta.icon('fa.stop', color='red')
        self.stop_button.setIcon(stop_icon)
        self.stop_button.clicked.connect(self._click_stop)
        hbox.addWidget(self.stop_button)

        self.progress_bar = QProgressBar()
        self.progress_bar.setTextVisible(True)
        self.progress_bar.setAlignment(QtCore.Qt.AlignCenter)
        self.progress_bar.setValue(0)
        self.progress_bar.setSizePolicy(QSizePolicy.Expanding,
                                        QSizePolicy.Expanding)

        pbar_hbox.addLayout(hbox)
        pbar_hbox.addWidget(self.progress_bar)
        pbar_frame.setLayout(pbar_hbox)
        process_layout.addWidget(pbar_frame)

        vbox = QVBoxLayout()
        vbox.setSpacing(8)
        vbox.setContentsMargins(QtCore.QMargins(0, 0, 0, 16))
        process_layout.addLayout(vbox)
        hbox = QHBoxLayout()
        vbox.addLayout(hbox)
        check_name_label = QLabel("Check:")
        check_name_label.setFixedWidth(80)
        hbox.addWidget(check_name_label)
        self.check_name_text_label = QLabel("n/a")
        hbox.addWidget(self.check_name_text_label)

        hbox = QHBoxLayout()
        vbox.addLayout(hbox)
        status_name_label = QLabel("Status:")
        status_name_label.setFixedWidth(80)
        hbox.addWidget(status_name_label)
        self.status_name_text_label = QLabel("Not started")
        hbox.addWidget(self.status_name_text_label)

        self.warning_frame = QFrame()
        self.warning_frame.setVisible(False)
        self.warning_frame.setSizePolicy(QSizePolicy.Expanding,
                                         QSizePolicy.Fixed)
        hbox = QHBoxLayout()

        warning_icon_widget = qta.IconWidget('fa.warning', color='red')
        warning_icon_widget.setIconSize(QtCore.QSize(48, 48))
        warning_icon_widget.update()
        hbox.addWidget(warning_icon_widget)
        warning_label = QLabel(
            "Grid Transformer did not complete successfully. Please refer to "
            "log output.")
        warning_label.setStyleSheet("QLabel { color: red; }")
        warning_label.setWordWrap(True)
        warning_label.setSizePolicy(QSizePolicy.Expanding,
                                    QSizePolicy.Preferred)
        hbox.addWidget(warning_label)
        self.warning_frame.setLayout(hbox)
        process_layout.addWidget(self.warning_frame)

        self.success_frame = QFrame()
        self.success_frame.setVisible(False)
        self.success_frame.setSizePolicy(QSizePolicy.Expanding,
                                         QSizePolicy.Fixed)
        hbox = QHBoxLayout()

        success_icon_widget = qta.IconWidget('fa.check', color='green')
        success_icon_widget.setIconSize(QtCore.QSize(48, 48))
        success_icon_widget.update()
        hbox.addWidget(success_icon_widget)
        success_label = QLabel("All checks completed successfully.")
        success_label.setStyleSheet("QLabel { color: green; }")
        success_label.setWordWrap(True)
        success_label.setSizePolicy(QSizePolicy.Expanding,
                                    QSizePolicy.Preferred)
        hbox.addWidget(success_label)
        self.success_frame.setLayout(hbox)
        process_layout.addWidget(self.success_frame)

        log_layout = QVBoxLayout()
        log_layout.setSpacing(4)
        log_label = QLabel("Log messages")
        log_label.setStyleSheet("QLabel { color: grey; }")
        log_layout.addWidget(log_label)

        self.log_messages = QPlainTextEdit()
        log_font = QFont("monospace")
        log_font.setStyleHint(QFont.TypeWriter)
        self.log_messages.setFont(log_font)
        self.log_messages.setReadOnly(True)
        self.log_messages.setSizePolicy(QSizePolicy.Expanding,
                                        QSizePolicy.Expanding)
        log_layout.addWidget(self.log_messages)
        process_layout.addLayout(log_layout)

        self.vbox.addWidget(process_groupbox)

    def set_run_stop_buttons_enabled(self, is_running: bool) -> NoReturn:
        if is_running:
            self.run_button.setEnabled(False)
            self.stop_button.setEnabled(True)
        else:
            self.run_button.setEnabled(True)
            self.stop_button.setEnabled(False)

    def _log_message(self, message):
        self.log_messages.appendPlainText(message)

    def run_executor(self, check_executor: QtCheckExecutorThread):
        # we pass the check_executor into the run tab as this is where the UI
        # components are that will display the execution status.
        self.set_run_stop_buttons_enabled(True)

        self._log_message("Check execution started")
        self.start_time = time.perf_counter()

        self.check_executor = check_executor
        self.check_executor.options = self.get_options()
        self.check_executor.check_tool_started.connect(
            self._on_check_tool_started)
        self.check_executor.progress.connect(self._on_progress)
        self.check_executor.qajson_updated.connect(self._on_qajson_update)
        self.check_executor.checks_complete.connect(self._on_checks_complete)
        self.check_executor.status_changed.connect(self._on_status_change)
        self.check_executor.start()

    def get_options(self) -> Dict:
        ''' Gets a list of options based on user entered data. eg; the spatial
        output specifications.
        '''
        return {
            CheckOption.spatial_output_qajson:
            self.qajson_spatial_checkbox.isChecked(),
            CheckOption.spatial_output_export:
            self.export_spatial_checkbox.isChecked(),
            CheckOption.spatial_output_export_location:
            self.output_folder_input.text()
        }

    def _click_run(self):
        self.run_checks.emit()

    def _click_stop(self):
        if self.check_executor is None:
            logger.warn("Check executor does not exist, cannot stop")
            return
        self._log_message("Stopping check execution")
        self.check_executor.stop()

    @QtCore.Slot(float)
    def _on_progress(self, progress):
        self.progress_bar.setValue(int(progress * 100))

    @QtCore.Slot()
    def _on_qajson_update(self):
        self.prj.qa_json = self.check_executor.qa_json

    @QtCore.Slot(object)
    def _on_check_tool_started(self, tpl):
        check_tool_name, check_number, total_check_count = tpl
        self.check_name_text_label.setText("{} ({}/{})".format(
            check_tool_name, check_number, total_check_count))

    @QtCore.Slot()
    def _on_checks_complete(self):
        run_time = time.perf_counter() - self.start_time
        self._log_message(
            f"Execution time for all checks = {run_time:.2f} sec")
        self._log_message("\n\n")

        self.set_run_stop_buttons_enabled(False)
        self.prj.qa_json = self.check_executor.qa_json

    @QtCore.Slot(str)
    def _on_status_change(self, status):
        self.status_name_text_label.setText(status)
Example #52
0
class ToolBox(QVBoxLayout):

    sig = QtCore.Signal(object)
    listThread = None
    groupBoxThreadInfo = None
    threadvbox = None
    mode = None

    def __init__(self, mode, parentQWidget = None):
        QVBoxLayout.__init__(self)

        self.sig.connect(self.addThreadList)
        self.mode = mode

        self.sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Expanding)

        self.groupBoxSearch = QGroupBox()
        self.groupBoxSearch.setStyleSheet("QGroupBox {border: 1px solid gray; border-radius: 4px; };")
        vboxSearch = QVBoxLayout()
        self.searchTitle = QLabel("Search Messages")
        vboxSearch.addWidget(self.searchTitle)
        self.searchHLayout = QHBoxLayout()
        self.editTextSearch = QTextEdit('')
        self.editTextSearch.setFixedSize(200,30)
        self.buttonSearch = QPushButton('Search')
        self.buttonSearch.setFixedSize(100,30)
        self.buttonSearch.clicked.connect(self.searchMsg)
        vboxSearch.addWidget(self.editTextSearch)
        self.searchHLayout.addWidget(self.buttonSearch)
        self.searchCursor = QLabel()
        self.searchHLayout.addWidget(self.searchCursor)
        vboxSearch.addLayout(self.searchHLayout)
        self.browseHLayout = QHBoxLayout()
        self.buttonLookUp = QPushButton('\u21e7')  #Arrow up
        self.buttonLookUp.setFixedWidth(100)
        self.buttonLookUp.clicked.connect(self.moveToPrev)
        self.buttonLookDown = QPushButton('\u21e9') #Arrow down
        self.buttonLookDown.setFixedWidth(100)
        self.buttonLookDown.clicked.connect(self.moveToNext)
        self.browseHLayout.addWidget(self.buttonLookUp)
        self.browseHLayout.addWidget(self.buttonLookDown)
        vboxSearch.addLayout(self.browseHLayout)
        self.groupBoxSearch.setLayout(vboxSearch)
        self.addWidget(self.groupBoxSearch)
        self.groupBoxSearch.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))

        self.buttonHiddenLifelines = QPushButton('Show hidden life-lines')
        self.buttonHiddenLifelines.setFixedWidth(200)
        self.buttonHiddenLifelines.clicked.connect(self.showHiddenLifelines)
        self.addWidget(self.buttonHiddenLifelines)

        self.buttonHiddenMessages = QPushButton('Show hidden Messages')
        self.buttonHiddenMessages.setFixedWidth(200)
        self.buttonHiddenMessages.clicked.connect(self.showHiddenMessages)
        self.addWidget(self.buttonHiddenMessages)

        if const.mode_interactive == mode:
            self.buttonCapture = QPushButton('Capture')
            self.buttonCapture.setFixedWidth(200)
            self.buttonCapture.clicked.connect(self.notifyCapture)
            self.addWidget(self.buttonCapture)
        self.msgRcv = []
        self.msgInfo = QLabel("Message Info.")
        self.groupBoxMessageInfo = QGroupBox()
        self.groupBoxMessageInfo.setStyleSheet("QGroupBox {border: 1px solid gray; border-radius: 9px; margin-top: 0.5em} QGroupBox::title {subcontrol-origin: margin; left: 10px; padding: 0 3px 0 3px;")
        vbox = QVBoxLayout()
        vbox.addWidget(self.msgInfo)
        self.tableTime = QTableWidget(3,2)
        self.tableTime.setHorizontalHeaderLabels(['-','time'])
        self.tableTime.setColumnWidth(0,80)
        self.tableTime.setColumnWidth(1,150)
        vwidth = self.tableTime.verticalHeader().length()
        hwidth = self.tableTime.horizontalHeader().height()
        fwidth = self.tableTime.frameWidth() * 2
        self.tableTime.setFixedHeight(vwidth + hwidth + fwidth)
        self.tableTime.horizontalHeader().setStretchLastSection(True)
        self.tableTime.setItem(0,0,QTableWidgetItem('begin'))
        self.tableTime.setItem(0,1,QTableWidgetItem(' - '))
        self.tableTime.setItem(1,0,QTableWidgetItem('end'))
        self.tableTime.setItem(1,1,QTableWidgetItem(' - '))
        self.tableTime.setItem(2,0,QTableWidgetItem('duration'))
        self.tableTime.setItem(2,1,QTableWidgetItem(' - '))
        vbox.addWidget(self.tableTime)

        self.titleArg = QLabel('Argument List')
        vbox.addWidget(self.titleArg)

        max_arg_num = 10
        self.tableArgs = QTableWidget(max_arg_num,2)
        self.tableArgs.setHorizontalHeaderLabels(['type','value'])
        for idx in range(0,max_arg_num):
            self.tableArgs.setItem(idx,0,QTableWidgetItem())
            self.tableArgs.setItem(idx,1,QTableWidgetItem())
        self.tableArgs.horizontalHeader().setStretchLastSection(True)
        vbox.addWidget(self.tableArgs)

        self.titleArg = QLabel('Return Value List')
        vbox.addWidget(self.titleArg)

        max_ret_num = 4
        self.tableRet = QTableWidget(max_ret_num,2)
        self.tableRet.setHorizontalHeaderLabels(['type','value'])
        for idx in range(0,max_ret_num):
            self.tableRet.setItem(idx,0,QTableWidgetItem())
            self.tableRet.setItem(idx,1,QTableWidgetItem())
        self.tableRet.horizontalHeader().setStretchLastSection(True)
        vwidth = self.tableRet.verticalHeader().length()
        hwidth = self.tableRet.horizontalHeader().height()
        fwidth = self.tableRet.frameWidth() * 2
        self.tableRet.setFixedHeight(vwidth + hwidth + fwidth)
        vbox.addWidget(self.tableRet)

        self.buttonSrcView = QPushButton('view code')
        self.buttonSrcView.setFixedWidth(200)
        self.buttonSrcView.clicked.connect(self.openSourceViewer)
        self.buttonHide = QPushButton('Hide')
        self.buttonHide.setFixedWidth(200)
        self.buttonHide.clicked.connect(self.notifyHide)
        self.buttonHideAllMsg = QPushButton('Hide All')
        self.buttonHideAllMsg.setFixedWidth(200)
        self.buttonHideAllMsg.clicked.connect(self.hideAllMsgNamedAsSelected)
        self.groupBoxMessageInfo.setLayout(vbox)
        self.checkHideCircular = QCheckBox('Hide Circular Messages')
        self.checkHideCircular.setCheckState(QtCore.Qt.Unchecked)
        self.checkHideCircular.stateChanged.connect(self.changeHideCircularMessage)
        self.addWidget(self.checkHideCircular)
        self.addWidget(self.groupBoxMessageInfo)
        self.groupBoxMessageInfo.setSizePolicy(self.sizePolicy)

    def reset(self):
        for idx in reversed(range(0,self.listThread.count())):
            self.listThread.takeItem(idx)

    def setMsgInfoMessage(self,msg):
        self.strMessage = msg

    def changeHideCircularMessage(self,state):
        if state == QtCore.Qt.Unchecked:
            self.diagramView.hideCircularChanged(False)
        elif state == QtCore.Qt.Checked:
            self.diagramView.hideCircularChanged(True)
    
    def setMsgInfoModule(self,module):
        self.strModule = module

    def updateSearchStatus(self,curr,number):
        self.searchCursor.setText("%d/%d" % (curr,number))

    def connectSourceViewer(self,viewer):
        self.srcViewer = viewer

    def openSourceViewer(self):
        self.srcViewer.openViewer(self.strModule,self.strMessage)

    def setMessageInfoTime(self,begin,end,duration):
        self.tableTime.item(0,1).setText(begin)
        self.tableTime.item(1,1).setText(end)
        self.tableTime.item(2,1).setText(duration + ' msec')

    def setMessageInfoArg(self,listParam,listArg):
        # Clear the contents in the table
        max_arg_num = 10
        for idx in range(0,max_arg_num):
            self.tableArgs.item(idx,0).setText('')
            self.tableArgs.item(idx,1).setText('')

        if listArg:
            for idx, text in enumerate(listArg):
                self.tableArgs.item(idx,1).setText(text)
            for idx, text in enumerate(listParam):
                self.tableArgs.item(idx,0).setText(text)
        else:
            for idx in range(0,self.tableArgs.rowCount()):
                self.tableArgs.item(idx,1).setText('')
                self.tableArgs.item(idx,0).setText('')

    def setMessageInfoRet(self,listRet):
        if listRet:
            for idx, text in enumerate(listRet):
                self.tableRet.item(idx,1).setText(text)
        else:
            for idx in range(0,self.tableRet.rowCount()):
                self.tableRet.item(idx,1).setText('')
                self.tableRet.item(idx,0).setText('')

    def notifyInteractiveStateChanged(self,state):
        if const.mode_interactive != self.mode:
            return

        if const.STATE_INTERACTIVE_CAPTURING == state:
            self.buttonCapture.setEnabled(True)
            self.buttonCapture.setText('Stop Capture')
        if const.STATE_INTERACTIVE_PROCESSING == state:
            self.buttonCapture.setEnabled(False)
        if const.STATE_INTERACTIVE_IDLE == state:
            self.buttonCapture.setEnabled(True)
            self.buttonCapture.setText('Capture')
        if const.STATE_INTERACTIVE_RESET == state:
            self.buttonCapture.setEnabled(True)
            self.buttonCapture.setText('Capture')
        elif const.STATE_INTERACTIVE_ACTIVE == state:
            self.buttonCapture.setEnabled(True)
            self.buttonCapture.setText('Capture')

    def setMessageInfo(self,info):
        self.msgInfo.setText(info)

    def setAvailable(self,threads):
        self.sig.emit(threads)

    def toggleThreadDisplay(self,item):
        print(self.listThread.currentRow())
        #if item.isSelected():
        #    print(item.text() + "  is selected")
        #else:
        #    print(item.text() + "  is not selected")
        self.diagramView.showThread(self.listThread.currentRow(),item.isSelected())

    def hideAllMsgNamedAsSelected(self):
        self.diagramView.hideAllMessageSelected()

    def addThreadList(self,threads):

        if not self.groupBoxThreadInfo:
            self.groupBoxThreadInfo = QGroupBox()
            self.threadInfo = QLabel("Thread Info.")
            self.groupBoxThreadInfo.setStyleSheet("QGroupBox {border: 1px solid gray; border-radius: 9px; margin-top: 0.5em} QGroupBox::title {subcontrol-origin: margin; left: 10px; padding: 0 3px 0 3px;")

        if not self.threadvbox:
            self.threadvbox = QVBoxLayout()

        if not self.listThread:
            self.listThread = QListWidget()
            
        self.listThread.setFixedWidth(200)
        self.listThread.setSelectionMode(QAbstractItemView.MultiSelection)
        QtCore.QObject.connect(self.listThread, QtCore.SIGNAL("itemClicked(QListWidgetItem *)"), self.toggleThreadDisplay)
        self.threadvbox.addWidget(self.threadInfo)
        self.threadvbox.addWidget(self.listThread)
        self.groupBoxThreadInfo.setLayout(self.threadvbox)
        self.addWidget(self.groupBoxThreadInfo)
        self.groupBoxThreadInfo.setSizePolicy(self.sizePolicy)

        for id in threads:
            item = QListWidgetItem(id)
            self.listThread.addItem(item)

    def connectController(self,controller):
        self.controller = controller
        self.connect(controller,QtCore.SIGNAL('setAvailable()'),self.setAvailable)
       
    def connectDiagramView(self,view):
        self.diagramView = view
 
    def disconnectMsgRcv(self,receiver):
        print("Implement this method !!! disconnectMsgRcv")

    def connectMsgRcv(self,receiver):
        self.msgRcv.append(receiver)

    def notifyHide(self):
        for rcv in self.msgRcv:
            rcv.activateHide(True)

    def showHiddenLifelines(self):
        response, selected_items = HiddenDialog.HiddenDialog.getSelectedItems(self.diagramView.getHiddenLifeLines())
        if response:
            self.diagramView.showLifelines(selected_items)

    def showHiddenMessages(self):
        response, selected_items = HiddenMessageDialog.HiddenMessageDialog.getSelectedItems(self.diagramView.getHiddenMessages(),self.diagramView.getHiddenLifeLines())
        if response:
            if selected_items[3] in self.diagramView.getHiddenLifeLines():
                confirmation = ShowLifeLineDialog.ShowLifeLineDialog.confirmToShowLifeLine(selected_items[3])
                if confirmation:
                    self.diagramView.showLifelines([selected_items[3]])
                    self.diagramView.showMessages(selected_items)
            else:
                self.diagramView.showMessages(selected_items)

    def notifyCapture(self):
        for rcv in self.msgRcv:
            rcv.activateCapture(True)
    
    def moveToPrev(self):
        for rcv in self.msgRcv:
            rcv.moveToPrev()
        
    def moveToNext(self):
        for rcv in self.msgRcv:
            rcv.moveToNext()

    def searchMsg(self):
        str = self.editTextSearch.toPlainText()
        for rcv in self.msgRcv:
            rcv.searchMessage(str)
Example #53
0
    def __init__(self):
        super().__init__()
        self.tl_layout = QGridLayout(self)
        rbtn_values = QGroupBox("Calibration Values", self)
        vbox = QVBoxLayout(rbtn_values)
        self.mode_btns = [
            QRadioButton(s, rbtn_values) for s in [
                "Idle", "Shifter neutral zone", "Shifter 135 zone",
                "Shifter 246R zone", "Shifter 12 zone", "Shifter 56 zone",
                "Gas pedal (if not auto-calibrated)",
                "Brake pedal (if not auto-calibrated)",
                "Clutch pedal (if not auto-calibrated)"
            ]
        ]
        self.mode_btns[0].setChecked(True)
        self.mode_cmds = [b"i", b"n", b"u", b"b", b"l", b"r", b"G", b"B", b"C"]
        self.help_cmds = [
            "First decide about the filtering needed (in middle panel). If there is a lot of noise in the signal, "
            "maybe because of old pots, you might want to use a multi-sample median filter. Note that this filter "
            "introduces some delay, so you want to keep the numbers reasonable low. Afterwards, iterate through "
            "the calibration values in the left panel.\n\n"
            "When you're done, you can save the calibration in the right panel to the EEPROM.",
            "Put the shifter in neutral position. Afterwards, keep the left red button pressed and move the "
            "shifter while still in neutral. When reaching the calibrated area, the gear will be set to neutral.",
            "Put the shifter in 3rd gear. Afterwards keep the left red button pressed and move the shifter "
            "while still in 3rd gear. When done, release the red button. Optionally repeat for gears 1st and 5th.",
            "Put the shifter in 4th gear. Afterwards keep the left red button pressed and move the shifter "
            "while still in 4th gear. When done, release the red button. Optionally repeat for gears 2nd and 6th.",
            "Put the shifter in 1st gear. Afterwards keep the left red button pressed and move the shifter "
            "while still in 1st gear. When done, release the red button. Optionally repeat for 2nd gear.",
            "Put the shifter in 5th gear. Afterwards keep the left red button pressed and move the shifter "
            "while still in 5th gear. When done, release the red button. Optionally repeat for 6th gear.",
            "Move the gas pedal multiple times between lowest and highest position.",
            "Move the brake pedal multiple times between lowest and highest position.",
            "Move the clutch pedal multiple times between lowest and highest position."
        ]
        for b in self.mode_btns:
            vbox.addWidget(b)
            b.toggled.connect(self.modeChanged)
        self.tl_layout.addWidget(rbtn_values, 0, 0, 1, 1)

        cbtn_options = QGroupBox("Options", self)
        grid = QGridLayout(cbtn_options)
        self.option_btns = [
            QCheckBox(s, cbtn_options) for s in [
                "Enable pedal auto-calibration", "Invert gas/throttle pedal",
                "Invert brake pedal", "Invert clutch pedal",
                "Use right red button for reverse instead pushing the gear",
                "Enable pedals", "Enable shifter"
            ]
        ] + [
            QComboBox(),
            QComboBox(),
            QComboBox(),
            QComboBox(),
            QComboBox(),
            QComboBox()
        ]
        self.option_cmds = [
            (b"p", b"P"),  #0
            (b"y", b"Y"),  #1
            (b"x", b"X"),  #2
            (b"z", b"Z"),  #3
            (b"q", b"Q"),  #4
            (b"e", b"E"),  #5
            (b"s", b"S"),  #6
            (b".", b"+", b"-"),  #7
            (b"[^", b"[!", b"[\"", b"[]", b"[$", b"[%", b"[&", b"[/"),
            (b"(^", b"(!", b"(\"", b"(]", b"($", b"(%", b"(&", b"(/"),
            (b")^", b")!", b")\"", b")]", b")$", b")%", b")&", b")/"),
            (b"0", b"3", b"5", b"7", b"9", b"f"),
            (b"1", b"2", b"4", b"6", b"8", b"F"),
        ]
        self.option_btns[-6].addItem("Do not combine clutch and gas")
        self.option_btns[-6].addItem(
            "Combine Clutch and Gas (Clutch = Gas - Clutch)")
        self.option_btns[-6].addItem(
            "Combine Clutch and Gas (Clutch = Clutch - Gas)")
        for (idx, name) in [(-5, "Gas"), (-4, "Brake"), (-3, "Clutch")]:
            for dz in [0, 2, 4, 6, 8, 10, 12, 14]:
                self.option_btns[idx].addItem("%s: %d%% dead zone" %
                                              (name, dz))
        for (idx, name) in [(-2, "pedals"), (-1, "shifter")]:
            for size in [0, 3, 5, 9, 15, 49]:
                self.option_btns[idx].addItem(
                    "off" if size == 0 else (str(size) + "-median"), size)
        for i, b in enumerate(self.option_btns):
            n_checkboxes = len(self.option_cmds) - 6
            if i < n_checkboxes:
                grid.addWidget(b, i, 0, 1, 2)
            else:
                names = {
                    n_checkboxes: "Combine",
                    n_checkboxes + 1: "Gas Dead Zone",
                    n_checkboxes + 2: "Brake Dead Zone",
                    n_checkboxes + 3: "Clutch Dead Zone",
                    n_checkboxes + 4: "Pedal filter",
                    n_checkboxes + 5: "Shifter filter"
                }
                grid.addWidget(QLabel(names[i], parent=self), i, 0)
                grid.addWidget(b, i, 1)
            if isinstance(b, QCheckBox):
                b.toggled.connect(self.optionChanged)
            else:
                b.currentIndexChanged.connect(self.optionChanged)
        self.tl_layout.addWidget(cbtn_options, 0, 1, 1, 1)

        cbtn_persistent = QGroupBox("Persistency")
        self.persistent_btns = [
            QPushButton(s, parent=self)
            for s in ["Save to EEPROM", "Load from EEPROM", "Defaults"]
        ]
        self.persistent_cmds = [b"w", b"U", b"c"]
        vbox = QVBoxLayout(cbtn_persistent)
        for i, b in enumerate(self.persistent_btns):
            vbox.addWidget(b)
            b.clicked.connect(self.persistent_cmd)
        self.tl_layout.addWidget(cbtn_persistent, 0, 2, 1, 1)

        self.helpArea = QLabel(self.help_cmds[0], self)
        self.helpArea.setWordWrap(True)
        f = self.helpArea.font()
        f.setBold(True)
        f.setPointSizeF(f.pointSizeF() * 1.5)
        self.helpArea.setFont(f)
        self.tl_layout.addWidget(self.helpArea, 0, 3, 1, 1)

        shifter_label = QLabel("Shifter")
        self.tl_layout.addWidget(shifter_label,
                                 1,
                                 2,
                                 1,
                                 2,
                                 alignment=Qt.AlignHCenter)
        shifter_plot = pg.PlotWidget(parent=self)
        shifter_plot.setMouseEnabled(x=False, y=False)
        self.tl_layout.addWidget(shifter_plot, 2, 2, 1, 2)
        shifter_plot.setRange(QRectF(0, 0, 1023, 1023), padding=0)
        pi = shifter_plot.getPlotItem()
        self.shifter_neutral_plot = pg.LinearRegionItem(
            values=(400, 600),
            orientation='horizontal',
            movable=False,
            brush=QBrush(QColor(200, 50, 50, 50)),
            pen=QPen(QColor(200, 50, 50)))
        shifter_plot.addItem(self.shifter_neutral_plot)
        self.shifter_135_plot = pg.LinearRegionItem(
            values=(800, 1024),
            orientation='horizontal',
            movable=False,
            brush=QBrush(QColor(50, 200, 50, 50)),
            pen=QPen(QColor(50, 200, 50)))
        shifter_plot.addItem(self.shifter_135_plot)
        self.shifter_246_plot = pg.LinearRegionItem(
            values=(0, 200),
            orientation='horizontal',
            movable=False,
            brush=QBrush(QColor(50, 50, 200, 50)),
            pen=QPen(QColor(50, 50, 200)))
        shifter_plot.addItem(self.shifter_246_plot)
        self.shifter_12_plot = pg.LinearRegionItem(
            values=(0, 200),
            orientation='vertical',
            movable=False,
            brush=QBrush(QColor(50, 200, 200, 50)),
            pen=QPen(QColor(50, 200, 200)))
        shifter_plot.addItem(self.shifter_12_plot)
        self.shifter_56_plot = pg.LinearRegionItem(
            values=(800, 1024),
            orientation='vertical',
            movable=False,
            brush=QBrush(QColor(200, 200, 50, 50)),
            pen=QPen(QColor(200, 200, 50)))
        shifter_plot.addItem(self.shifter_56_plot)
        self.shifter_pos_plot = pi.plot(x=[512], y=[512], symbol='+', pen=None)

        pedals_label = QLabel("Pedals")
        self.tl_layout.addWidget(pedals_label,
                                 1,
                                 0,
                                 1,
                                 2,
                                 alignment=Qt.AlignHCenter)
        pedals_plot = pg.PlotWidget(parent=self)
        pedals_plot.setMouseEnabled(x=False, y=False)
        pedals_plot.setRange(QRectF(-1, 0, 4, 1023), padding=0)
        pedals_plot.getAxis('bottom').setTicks([[(0.0, "Gas/Throttle"),
                                                 (1.0, "Brake"),
                                                 (2.0, "Clutch")], []])
        self.tl_layout.addWidget(pedals_plot, 2, 0, 1, 2)
        self.pedals_pos_plot = pg.BarGraphItem(x=np.arange(3),
                                               height=[512, 512, 512],
                                               width=0.5)
        self.pedals_gas_calib_plot = pedals_plot.getPlotItem().plot(
            x=[0],
            y=[0],
            pen=QPen(QColor(255, 0, 0), width=0.1),
            brush=QBrush(Qt.NoBrush))
        self.pedals_brake_calib_plot = pedals_plot.getPlotItem().plot(
            x=[0], y=[0], pen=QPen(QColor(0, 255, 0)))
        self.pedals_clutch_calib_plot = pedals_plot.getPlotItem().plot(
            x=[0], y=[0], pen=QPen(QColor(0, 0, 255)))
        self.pedals_pos_plot2 = pedals_plot.getPlotItem().plot(x=[],
                                                               y=[],
                                                               symbol='+',
                                                               pen=None)
        pedals_plot.addItem(self.pedals_pos_plot)

        self.status_line = QLabel(self)
        self.tl_layout.addWidget(self.status_line, 3, 0, 1, 2)
        self.status_line2 = QLabel(self)
        self.tl_layout.addWidget(self.status_line2, 3, 2, 1, 2)
        self.currentVals = Values()