def __addSinglesLine(self):
     """
     Private slot to add a line of entry widgets for single characters.
     """
     hbox = QWidget(self.singlesItemsBox)
     hboxLayout = QHBoxLayout(hbox)
     hboxLayout.setContentsMargins(0, 0, 0, 0)
     hboxLayout.setSpacing(6)
     hbox.setLayout(hboxLayout)
     cb1 = QComboBox(hbox)
     cb1.setEditable(False)
     cb1.addItems(self.comboItems)
     cb1.addItems(self.singleComboItems)
     hboxLayout.addWidget(cb1)
     le1 = QLineEdit(hbox)
     le1.setValidator(self.charValidator)
     hboxLayout.addWidget(le1)
     cb2 = QComboBox(hbox)
     cb2.setEditable(False)
     cb2.addItems(self.comboItems)
     cb2.addItems(self.singleComboItems)
     hboxLayout.addWidget(cb2)
     le2 = QLineEdit(hbox)
     le2.setValidator(self.charValidator)
     hboxLayout.addWidget(le2)
     self.singlesItemsBoxLayout.addWidget(hbox)
     
     cb1.activated[int].connect(self.__singlesCharTypeSelected)
     cb2.activated[int].connect(self.__singlesCharTypeSelected)
     hbox.show()
     
     self.singlesItemsBox.adjustSize()
     
     self.singlesEntries.append([cb1, le1])
     self.singlesEntries.append([cb2, le2])
示例#2
0
    def __init__(self, parent):
        super(SearchBar, self).__init__(parent)

        self._sit = None

        self._editor = SearchEdit(self)
        self._prevButton = QPushButton("<", self)
        self._nextButton = QPushButton(">", self)
        self._closeButton = QPushButton(QIcon.fromTheme("window-close"), "", self)

        layout = QHBoxLayout()
        layout.setAlignment(Qt.AlignLeft)
        layout.setSpacing(0)

        layout.addWidget(self._editor)
        layout.addWidget(self._prevButton)
        layout.addWidget(self._nextButton)
        layout.addWidget(self._closeButton)
        layout.setContentsMargins(1, 1, 1, 1)

        self.setLayout(layout)

        self._nextButton.clicked.connect(self.next)
        self._prevButton.clicked.connect(self.prev)
        self._closeButton.clicked.connect(self.hide)
        self._editor.textChanged.connect(self._reset)
        self._editor.returnPressed.connect(self.next)
        self._editor.escapePressed.connect(self.hide)
示例#3
0
    def initUI(self):
        self.graphicsView = GraphicsView(self)

        self.graphicsView.setDragMode(QGraphicsView.RubberBandDrag)
        self.graphicsView.setOptimizationFlags(QGraphicsView.DontSavePainterState)
        self.graphicsView.setViewportUpdateMode(QGraphicsView.SmartViewportUpdate)
        self.graphicsView.setTransformationAnchor(QGraphicsView.AnchorUnderMouse)
        self.graphicsView.setRenderHint(QPainter.Antialiasing, True)

        #Make a graphics scene
        self.scene = GraphicsScene()
        self.graphicsView.setScene(self.scene)

        #Create a graph that can contain nodes and edges
        self.graph = Graph(self, self.scene, self.graphicsView)
        self.tokensInScene = []

        # initial zoomlevel
        self.zoomLevel = 250

        #Final layout
        topLayout = QHBoxLayout()
        topLayout.setContentsMargins(0, 0, 0, 0)
        topLayout.setSpacing(0)
        topLayout.addWidget(self.graphicsView)
        self.setLayout(topLayout)
示例#4
0
    def initMainUi(self):
        role_names = self.parentApplet.dataSelectionApplet.topLevelOperator.DatasetRoles.value
        self.list_widgets = []
        
        # Create a tab for each role
        for role_index, role_name in enumerate(role_names):
            select_button = QPushButton("Select " + role_name + " Files...", 
                                        clicked=partial(self.select_files, role_index) )
            clear_button = QPushButton("Clear " + role_name + " Files",
                                       clicked=partial(self.clear_files, role_index) )
            button_layout = QHBoxLayout()
            button_layout.addWidget(select_button)
            button_layout.addSpacerItem( QSpacerItem(0,0,hPolicy=QSizePolicy.Expanding) )
            button_layout.addWidget(clear_button)
            button_layout.setContentsMargins(0, 0, 0, 0)
            
            button_layout_widget = QWidget()
            button_layout_widget.setLayout(button_layout)
            button_layout_widget.setSizePolicy( QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Maximum) )

            list_widget = QListWidget(parent=self)
            list_widget.setSizePolicy( QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) )
            self.list_widgets.append( list_widget )

            tab_layout = QVBoxLayout()
            tab_layout.setContentsMargins(0, 0, 0, 0)
            tab_layout.addWidget( button_layout_widget )
            tab_layout.addWidget( list_widget )
            
            layout_widget = QWidget(parent=self)
            layout_widget.setLayout(tab_layout)
            self.addTab(layout_widget, role_name)
示例#5
0
    def addMultiplierController(self):
        wid = QWidget()
        wid.setSizePolicy(QSizePolicy())
        layout = QHBoxLayout(wid)
        layout.setSpacing(0)
        layout.setContentsMargins(0,0,0,0)

        statcontrol = tightLineEdit()
        statcontrol.textEdited[str].connect(self.updateMultipliers)
        wid.control = statcontrol

        timeslabel = QLabel('\u00d7')
        timeslabel.setMargin(0)
        timeslabel.setIndent(0)
        timeslabel.setAlignment(Qt.AlignCenter)
        timeslabel.setContentsMargins(0,0,0,0)

        label = popupButton(['HP','ATK','RCV'])
        label.stateChanged.connect(self.updateMultipliers)
        wid.label = label

        layout.addWidget(statcontrol)
        layout.addWidget(timeslabel)
        layout.addWidget(label)

        self.layout.insertWidget(len(self.mcontrols),wid)
        self.mcontrols.append(wid)
        return wid
    def __init__(self, parent=None):
        super(CentralWidget, self).__init__(parent)
        self.parent = parent
        #This variables are used to save the splitter sizes before hide
        self.lateralPanel = LateralPanel()

        self._add_functions = {
            "central": self._insert_widget_inside,
            "lateral": self._insert_widget_base,
        }
        self._items = {}

        hbox = QHBoxLayout(self)
        hbox.setContentsMargins(0, 0, 0, 0)
        hbox.setSpacing(0)
        #Create Splitters to divide the UI 3 regions
        self._splitterBase = dynamic_splitter.DynamicSplitter(Qt.Horizontal)
        self._splitterBase.setOpaqueResize(True)
        self._splitterInside = dynamic_splitter.DynamicSplitter(Qt.Vertical)
        self._splitterInside.setOpaqueResize(True)
        self._splitterBase.addWidget(self._splitterInside)

        #Add to Main Layout
        hbox.addWidget(self._splitterBase)
        IDE.register_service('central_container', self)
示例#7
0
    def __make_cell(self, c, name, col_type, col_type_def):
        cell = QWidget(self.inner)
        rbtn = QRadioButton('', cell)
        rbtn.toggled.connect(lambda: self.rbtn_clicked(name + '_' + str(c)))
        hbl = QHBoxLayout(cell)
        hbl.addWidget(rbtn)
        hbl.setContentsMargins(0, 0, 0, 0)
        hbl.setAlignment(Qt.AlignCenter)
        cell.setLayout(hbl)
        if name == 'cat':
            if col_type == 'object':
                rbtn.setChecked(True)
            self.lst_cat.append(rbtn)
        elif name == 'num':
            if col_type != 'object':
                rbtn.setChecked(True)
            if col_type_def == 'object':
                rbtn.setEnabled(False)
            self.lst_num.append(rbtn)
        elif name == 'obj':
            if col_type == 'object' and self.params.task == 'Regression':
                rbtn.setEnabled(False)
            elif col_type != 'object' and self.params.task == 'Classification':
                rbtn.setEnabled(False)
            if self.params.columns[c] == self.params.objective:
                rbtn.setChecked(True)
            self.lst_obj.append(rbtn)

        return cell
示例#8
0
    def createBottomLeftTabWidget(self):
        self.bottomLeftTabWidget = QTabWidget()
        self.bottomLeftTabWidget.setSizePolicy(QSizePolicy.Preferred,
                QSizePolicy.Ignored)

        tab1 = QWidget()
        tableWidget = QTableWidget(10, 10)

        tab1hbox = QHBoxLayout()
        tab1hbox.setContentsMargins(5, 5, 5, 5)
        tab1hbox.addWidget(tableWidget)
        tab1.setLayout(tab1hbox)

        tab2 = QWidget()
        textEdit = QTextEdit()

        textEdit.setPlainText("Twinkle, twinkle, little star,\n"
                              "How I wonder what you are.\n" 
                              "Up above the world so high,\n"
                              "Like a diamond in the sky.\n"
                              "Twinkle, twinkle, little star,\n" 
                              "How I wonder what you are!\n")

        tab2hbox = QHBoxLayout()
        tab2hbox.setContentsMargins(5, 5, 5, 5)
        tab2hbox.addWidget(textEdit)
        tab2.setLayout(tab2hbox)

        self.bottomLeftTabWidget.addTab(tab1, "&Table")
        self.bottomLeftTabWidget.addTab(tab2, "Text &Edit")
示例#9
0
文件: ui.py 项目: leohazy/FeelUOwn
class CentralPanel(FFrame):
    def __init__(self, app, parent=None):
        super().__init__(parent)
        self._app = app

        self.left_panel_container = LeftPanel_Container(self._app, self)
        self.right_panel_container = RightPanel_Container(self._app, self)
        self.left_panel = self.left_panel_container.left_panel
        self.right_panel = self.right_panel_container.right_panel

        self._layout = QHBoxLayout(self)
        self.set_theme_style()
        self.setup_ui()

    def set_theme_style(self):
        style_str = '''
            #{0} {{
                background: transparent;
            }}
        '''.format(self.objectName())
        self.setStyleSheet(style_str)

    def setup_ui(self):
        self._layout.setContentsMargins(0, 0, 0, 0)
        self._layout.setSpacing(0)

        self._layout.addWidget(self.left_panel_container)
        self._layout.addWidget(self.right_panel_container)
示例#10
0
    def __init__(self, parentWidget, markerFmt, editWidget):
        QWidget.__init__(self, parentWidget)

        self.markerFormat = markerFmt
        self.textEdit = editWidget
        self.startPos = 0
        self.endPos = 0
        self.pattern = ''

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

        self.searchPattern = CancelAwareLineEdit(self)
        self.searchPattern.setPlaceholderText('Start typing to find in page')
        self.searchPattern.editingFinished.connect(self.hideWidget)
        self.searchPattern.textEdited.connect(self.doSearch)

        upAction = QAction(QIcon(':/icons/find-up.png'), "Find backwards (Shift-F3)", self)
        upAction.setShortcut(Qt.SHIFT + Qt.Key_F3);
        upAction.triggered.connect(self.findUpwards)
        self.upButton = QToolButton(self)
        self.upButton.setDefaultAction(upAction)

        downAction = QAction(QIcon(':/icons/find-down.png'), "Find next (F3)", self)
        downAction.setShortcut(Qt.Key_F3);
        downAction.triggered.connect(self.findDownwards)
        self.downButton = QToolButton(self)
        self.downButton.setDefaultAction(downAction)

        layout.addWidget(self.searchPattern)
        layout.addWidget(self.upButton)
        layout.addWidget(self.downButton)
示例#11
0
文件: ui.py 项目: leohazy/FeelUOwn
class TopPanel(FFrame):
    def __init__(self, app, parent=None):
        super().__init__(parent)
        self._app = app

        self._layout = QHBoxLayout(self)
        self.pc_panel = PlayerControlPanel(self._app, self)
        self.mo_panel = SongOperationPanel(self._app, self)

        self.setObjectName('top_panel')
        self.set_theme_style()
        self.setup_ui()

    def set_theme_style(self):
        theme = self._app.theme_manager.current_theme
        style_str = '''
            #{0} {{
                background: transparent;
                color: {1};
                border-bottom: 3px inset {3};
            }}
        '''.format(self.objectName(),
                   theme.foreground.name(),
                   theme.color0_light.name(),
                   theme.color0_light.name())
        self.setStyleSheet(style_str)

    def setup_ui(self):
        self._layout.setContentsMargins(0, 0, 0, 0)
        self._layout.setSpacing(0)
        self.setFixedHeight(50)
        self._layout.addSpacing(5)
        self._layout.addWidget(self.pc_panel)
        self._layout.addWidget(self.mo_panel)
示例#12
0
文件: ui.py 项目: leohazy/FeelUOwn
class RightPanel(FFrame):
    def __init__(self, app, parent=None):
        super().__init__(parent)
        self._app = app

        self.widget = None

        self._layout = QHBoxLayout(self)
        self.setLayout(self._layout)
        self.setObjectName('right_panel')
        self.set_theme_style()
        self.setup_ui()

    def set_theme_style(self):
        style_str = '''
            #{0} {{
                background: transparent;
            }}
        '''.format(self.objectName())
        self.setStyleSheet(style_str)

    def set_widget(self, widget):
        if self.widget and self.widget != widget:
            self._layout.removeWidget(self.widget)
            self.widget.hide()
            widget.show()
            self._layout.addWidget(widget)
        else:
            self._layout.addWidget(widget)
        self.widget = widget

    def setup_ui(self):
        self._layout.setContentsMargins(0, 0, 0, 0)
        self._layout.setSpacing(0)
示例#13
0
 def __init__(self, parent, name):
     QWidget.__init__(self, parent)
     self.setStyleSheet(get_stylesheet("ribbonPane"))
     horizontal_layout = QHBoxLayout()
     horizontal_layout.setSpacing(0)
     horizontal_layout.setContentsMargins(0, 0, 0, 0)
     self.setLayout(horizontal_layout)
     vertical_widget = QWidget(self)
     horizontal_layout.addWidget(vertical_widget)
     horizontal_layout.addWidget(RibbonSeparator(self))
     vertical_layout = QVBoxLayout()
     vertical_layout.setSpacing(0)
     vertical_layout.setContentsMargins(0, 0, 0, 0)
     vertical_widget.setLayout(vertical_layout)
     label = QLabel(name)
     label.setAlignment(Qt.AlignCenter)
     label.setStyleSheet("color:#666;")
     content_widget = QWidget(self)
     vertical_layout.addWidget(content_widget)
     vertical_layout.addWidget(label)
     content_layout = QHBoxLayout()
     content_layout.setAlignment(Qt.AlignLeft)
     content_layout.setSpacing(0)
     content_layout.setContentsMargins(0, 0, 0, 0)
     self.contentLayout = content_layout
     content_widget.setLayout(content_layout)
示例#14
0
class Prompt(QWidget):

    """The prompt widget shown in the statusbar.

    Attributes:
        txt: The TextBase instance (QLabel) used to display the prompt text.
        lineedit: The MinimalLineEdit instance (QLineEdit) used for the input.
        _hbox: The QHBoxLayout used to display the text and prompt.
    """

    def __init__(self, win_id, parent=None):
        super().__init__(parent)
        objreg.register('prompt', self, scope='window', window=win_id)
        self._hbox = QHBoxLayout(self)
        self._hbox.setContentsMargins(0, 0, 0, 0)
        self._hbox.setSpacing(5)

        self.txt = textbase.TextBase()
        self._hbox.addWidget(self.txt)

        self.lineedit = PromptLineEdit()
        self._hbox.addWidget(self.lineedit)

        prompter_obj = prompter.Prompter(win_id)
        objreg.register('prompter', prompter_obj, scope='window',
                        window=win_id)
        self.destroyed.connect(
            functools.partial(objreg.delete, 'prompter', scope='window',
                              window=win_id))

    def __repr__(self):
        return utils.get_repr(self)
 def __addRangesLine(self):
     """
     Private slot to add a line of entry widgets for character ranges.
     """
     hbox = QWidget(self.rangesItemsBox)
     hboxLayout = QHBoxLayout(hbox)
     hboxLayout.setContentsMargins(0, 0, 0, 0)
     hboxLayout.setSpacing(6)
     hbox.setLayout(hboxLayout)
     cb1 = QComboBox(hbox)
     cb1.setEditable(False)
     cb1.addItems(self.comboItems)
     hboxLayout.addWidget(cb1)
     l1 = QLabel(self.tr("Between:"), hbox)
     hboxLayout.addWidget(l1)
     le1 = QLineEdit(hbox)
     le1.setValidator(self.charValidator)
     hboxLayout.addWidget(le1)
     l2 = QLabel(self.tr("And:"), hbox)
     hboxLayout.addWidget(l2)
     le2 = QLineEdit(hbox)
     le2.setValidator(self.charValidator)
     hboxLayout.addWidget(le2)
     self.rangesItemsBoxLayout.addWidget(hbox)
     
     cb1.activated[int].connect(self.__rangesCharTypeSelected)
     
     hbox.show()
     
     self.rangesItemsBox.adjustSize()
     
     self.rangesEntries.append([cb1, le1, le2])
示例#16
0
    def __init__(self, parent=None):
        super(_s_CentralWidget, self).__init__(parent)
        self.parent = parent
        #This variables are used to save the splitter sizes before hide
        self._splitterMainSizes = None
        self._splitterAreaSizes = None
        self.lateralPanel = None

        hbox = QHBoxLayout(self)
        hbox.setContentsMargins(0, 0, 0, 0)
        hbox.setSpacing(0)
        #Create Splitters to divide the UI in: MainPanel, Explorer, Misc
        self._splitterArea = QSplitter(Qt.Horizontal)
        self._splitterMain = QSplitter(Qt.Vertical)

        #Create scrollbar for follow mode
        self.scrollBar = QScrollBar(Qt.Vertical, self)
        self.scrollBar.setFixedWidth(20)
        self.scrollBar.setToolTip('Follow Mode: Scroll the Editors together')
        self.scrollBar.hide()
        self.scrollBar.valueChanged[int].connect(self.move_follow_scrolls)

        #Add to Main Layout
        hbox.addWidget(self.scrollBar)
        hbox.addWidget(self._splitterArea)
示例#17
0
class PreviewWidget(QScrollArea):

    def __init__(self, parent=None):
        super(PreviewWidget, self).__init__(parent)
        self.setWidgetResizable(True)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        self.widget = QWidget()
        self.layout = QHBoxLayout()
        self.layout.addStretch(1)
        self.layout.setContentsMargins(0, 0, 0, 0)
        self.widget.setLayout(self.layout)
        self.setWidget(self.widget)

    def removeLast(self):
        item = self.layout.takeAt(0)
        if item:
            item.widget().deleteLater()

    def resizeEvent(self, event):
        self.widget.setFixedHeight(self.viewport().height())
        super(PreviewWidget, self).resizeEvent(event)

    def addPixmap(self, pixmap):
        label = ImageLabel(pixmap, self)
        self.layout.insertWidget(0, label)
示例#18
0
class LabelButtonGroup(QWidget):
    def __init__(self, label = '', buttons = {'UJ object reference value': 'Name to show'}):
        super(LabelButtonGroup, self).__init__()
        self.label = QLabel()
        self.label.setText(label)
        self.button_group = QButtonGroup()
        self.buttons = {}
        self.layout = QHBoxLayout()
        self.layout.setContentsMargins(0,0,0,0)
        self.layout.addWidget(self.label)
        for button_key in buttons.keys():
            self.buttons[button_key] = QRadioButton(buttons[button_key])
            self.button_group.addButton(self.buttons[button_key])
            self.layout.addWidget(self.buttons[button_key])

    def show(self):
        for button in self.buttons.values():
            button.show()
        self.label.show()

    def hide(self):
        for button in self.buttons.values():
            button.hide()
        self.label.hide()

    def set_text(self, key):
        if key != '':
            self.buttons[key].setChecked(1)

    def text(self):
        return self.button_group.checkedButton().text()

    def checked(self):
        return self.button_group.checkedButton()
class DateRangeSelectorView(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self._setupUi()

    def _setupUi(self):
        self.resize(259, 32)
        self.horizontalLayout = QHBoxLayout(self)
        self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
        self.prevButton = QPushButton(self)
        icon = QIcon()
        icon.addPixmap(QPixmap(":/nav_left_9"), QIcon.Normal, QIcon.Off)
        self.prevButton.setIcon(icon)
        self.horizontalLayout.addWidget(self.prevButton)
        self.typeButton = QPushButton("<date range>")
        sizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.typeButton.sizePolicy().hasHeightForWidth())
        self.typeButton.setSizePolicy(sizePolicy)
        self.typeButton.setMinimumSize(QSize(0, 0))
        self.typeButton.setMaximumSize(QSize(16777215, 16777215))
        self.typeButton.setIconSize(QSize(6, 6))
        self.horizontalLayout.addWidget(self.typeButton)
        self.nextButton = QPushButton(self)
        icon1 = QIcon()
        icon1.addPixmap(QPixmap(":/nav_right_9"), QIcon.Normal, QIcon.Off)
        self.nextButton.setIcon(icon1)
        self.horizontalLayout.addWidget(self.nextButton)
        self.horizontalLayout.setStretch(1, 1)
    def init(self, parent):
        layout = QHBoxLayout(parent)
        layout.setContentsMargins(0, 0, 0, 0)
        self.m_treeWidget = QtPropertyEditorView(parent)
        self.m_treeWidget.setEditorPrivate(self)
        self.m_treeWidget.setIconSize(QSize(18, 18))
        layout.addWidget(self.m_treeWidget)
        parent.setFocusProxy(self.m_treeWidget)

        self.m_treeWidget.setColumnCount(2)
        labels = QList()
        labels.append(QCoreApplication.translate("QtTreePropertyBrowser", "Property"))
        labels.append(QCoreApplication.translate("QtTreePropertyBrowser", "Value"))
        self.m_treeWidget.setHeaderLabels(labels)
        self.m_treeWidget.setAlternatingRowColors(True)
        self.m_treeWidget.setEditTriggers(QAbstractItemView.EditKeyPressed)
        self.m_delegate = QtPropertyEditorDelegate(parent)
        self.m_delegate.setEditorPrivate(self)
        self.m_treeWidget.setItemDelegate(self.m_delegate)
        self.m_treeWidget.header().setSectionsMovable(False)
        self.m_treeWidget.header().setSectionResizeMode(QHeaderView.Stretch)

        self.m_expandIcon = drawIndicatorIcon(self.q_ptr.palette(), self.q_ptr.style())

        self.m_treeWidget.collapsed.connect(self.slotCollapsed)
        self.m_treeWidget.expanded.connect(self.slotExpanded)
        self.m_treeWidget.currentItemChanged.connect(self.slotCurrentTreeItemChanged)
示例#21
0
class OffsetRow(QWidget):
    def __init__(self):
        super(OffsetRow, self).__init__()
        self.layout = QHBoxLayout()
        self.layout.setContentsMargins(0,0,0,0)
        self.sign = QComboBox()
        self.sign.addItems(['-', '+'])
        self.amount = QLineEdit()
        self.amount.setInputMask('99999999')
        self.unit = QComboBox()
        self.unit.addItems(['sec', 'min', 'hrs', 'day'])
        self.layout.addWidget(self.sign)
        self.layout.addWidget(self.amount, stretch = 1)
        self.layout.addWidget(self.unit)

    def show(self):
        self.sign.show()
        self.amount.show()
        self.unit.show()

    def hide(self):
        self.sign.hide()
        self.amount.hide()
        self.unit.hide()

    def set_values(self, sign, amount, unit):
        self.sign.setCurrentText(sign)
        self.amount.setText(str(amount))
        self.unit.setCurrentText(unit)
示例#22
0
class LabelCheckboxesGroup(QWidget):
    def __init__(self, label = '', boxes = ['name_to_show']):
        super(LabelCheckboxesGroup, self).__init__()
        self.label = QLabel()
        self.label.setText(label)
        self.button_group = QButtonGroup()
        self.box_key_order = boxes
        self.boxes = {}
        self.layout = QHBoxLayout()
        self.layout.setContentsMargins(0,0,0,0)
        self.layout.addWidget(self.label)
        for name in boxes:
            self.boxes[name] = QCheckBox(name)
            self.layout.addWidget(self.boxes[name])

    def show(self):
        self.label.show()
        for box in self.boxes.values():
            box.show()

    def hide(self):
        self.label.hide()
        for box in self.boxes.values():
            box.hide()

    def set_values(self, *checks):
        for key, value in zip(self.box_key_order, checks):
            # print('key', key, 'value', value)
            self.boxes[key].setChecked(value)

    def text(self):
        return { k:v.isChecked() for k, v in self.boxes.items() }
    def initUI(self, complete, back):
        self.completeButtonClick = complete
        self.backButtonClick = back

        main_layout = QHBoxLayout()

        self.photo_load_button = QPushButton("Load photo")
        self.complete_button = QPushButton("Complete")
        self.back_button = QPushButton("Back")

        self.photo_load_button.clicked.connect(self.loadPhotoDialog)

        if self.completeButtonClick is not None:
            self.complete_button.clicked.connect(self.nextState)
        if self.backButtonClick is not None:
            self.back_button.clicked.connect(self.backButtonClick)

        toolbar = QToolbar()
        toolbar.addWidgetToToolbar(self.photo_load_button)
        toolbar.addWidgetToToolbar(self.complete_button)
        toolbar.addWidgetToToolbar(self.back_button)
        toolbar.addStretch(1)

        self.viewer = QViewer()
        viewer_scroll = QScrollArea()
        viewer_scroll.setWidget(self.viewer)
        viewer_scroll.setWidgetResizable(True)

        main_layout.addWidget(toolbar)
        main_layout.addWidget(viewer_scroll)
        main_layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(main_layout)
示例#24
0
文件: prefs.py 项目: freeaks/filer
class QCustomQWidget (QWidget):

    def __init__(self, parent=None):
        super(QCustomQWidget, self).__init__(parent)
        self.textQVBoxLayout = QVBoxLayout()
        self.textQVBoxLayout.setContentsMargins(0, 0, 0, 0)
        self.textQVBoxLayout.setSpacing(0)

        self.textUpQLabel = QLabel()
        self.textDownQLabel = QLabel()
        self.textQVBoxLayout.addWidget(self.textUpQLabel)
        self.textQVBoxLayout.addWidget(self.textDownQLabel)
        self.allQHBoxLayout = QHBoxLayout()
        self.allQHBoxLayout.setContentsMargins(0, 0, 0, 0)
        self.allQHBoxLayout.setSpacing(3)
        self.iconQLabel = QLabel()
        self.allQHBoxLayout.addWidget(self.iconQLabel, 0)
        self.allQHBoxLayout.addLayout(self.textQVBoxLayout, 1)
        self.setLayout(self.allQHBoxLayout)
        # setStyleSheet
        self.textUpQLabel.setStyleSheet('''color: rgb(0, 0, 255);''')
        self.textDownQLabel.setStyleSheet('''color: rgb(0, 0, 0);''')

    def setTextUp(self, text):
        self.textUpQLabel.setText(text)

    def setTextDown(self, text):
        self.textDownQLabel.setText(text)

    def setIcon(self, imagePath):
        self.iconQLabel.setPixmap(QPixmap(imagePath))
class widgetSpinBoxSpanSlider(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.span_slider = QxtSpanSlider()
        self.sbox_lower = QSpinBox()
        self.sbox_upper = QSpinBox()
        self.horizontal_layout = QHBoxLayout()
        self.horizontal_layout.setContentsMargins(5, 5, 5, 5)
        self.horizontal_layout.addWidget(self.sbox_lower)
        self.horizontal_layout.addWidget(self.span_slider)
        self.horizontal_layout.addWidget(self.sbox_upper)

        # Signal and slots
        self.sbox_lower.valueChanged.connect(self.slot_sbox_lower_value_changed)
        self.sbox_upper.valueChanged.connect(self.slot_sbox_upper_value_changed)
        self.span_slider.lowerPositionChanged.connect(self.slot_span_slider_lower_position_changed)
        self.span_slider.upperPositionChanged.connect(self.slot_span_slider_upper_position_changed)

        self.setLayout(self.horizontal_layout)

    def slot_sbox_lower_value_changed(self, value):
        value_sbox_upper = self.sbox_upper.value()
        value_sbox_lower = value

        if value_sbox_upper < value_sbox_lower:
            self.span_slider.swapControls()
            self.span_slider.setUpperValue(value_sbox_lower)
            self.span_slider.setUpperPosition(value_sbox_lower)
            self.span_slider.setLowerValue(value_sbox_upper)
            self.span_slider.setLowerPosition(value_sbox_upper)
            self.sbox_upper.setValue(value_sbox_lower)
            self.sbox_lower.setValue(value_sbox_upper)
            return

        self.span_slider.setLowerValue(value_sbox_lower)
        self.span_slider.setLowerPosition(value_sbox_lower)

    def slot_sbox_upper_value_changed(self, value):
        value_sbox_upper = value
        value_sbox_lower = self.sbox_lower.value()

        if value_sbox_upper < value_sbox_lower:
            self.span_slider.swapControls()
            self.span_slider.setUpperValue(value_sbox_lower)
            self.span_slider.setUpperPosition(value_sbox_lower)
            self.span_slider.setLowerValue(value_sbox_upper)
            self.span_slider.setLowerPosition(value_sbox_upper)
            self.sbox_upper.setValue(value_sbox_lower)
            self.sbox_lower.setValue(value_sbox_upper)
            return

        self.span_slider.setUpperValue(value_sbox_upper)
        self.span_slider.setUpperPosition(value_sbox_upper)

    def slot_span_slider_lower_position_changed(self, value):
        self.sbox_lower.setValue(value)

    def slot_span_slider_upper_position_changed(self, value):
        self.sbox_upper.setValue(value)
示例#26
0
    def __init__(self, parent=None):
        super(CentralWidget, self).__init__(parent)
        self.parent = parent
        main_container = QHBoxLayout(self)
        main_container.setContentsMargins(0, 0, 0, 0)
        main_container.setSpacing(0)
        # This variables are used to save the spliiter sizes
        self.lateral_panel = LateralPanel()

        self._add_functions = {
            "central": self._insert_widget_inside,
            "lateral": self._insert_widget_base
        }
        self._items = {}

        # Toolbar
        self._toolbar = ntoolbar.NToolBar(self)
        main_container.addWidget(self._toolbar)

        # Create Splitters to divide the UI 3 regions
        self._splitter_base = dynamic_splitter.DynamicSplitter(Qt.Horizontal)
        self._splitter_inside = dynamic_splitter.DynamicSplitter(Qt.Vertical)
        self._splitter_base.addWidget(self._splitter_inside)

        vbox = QVBoxLayout()
        vbox.setContentsMargins(0, 0, 0, 0)
        vbox.setSpacing(0)

        vbox.addWidget(self._splitter_base)
        tools_dock = IDE.get_service("tools_dock")
        vbox.addWidget(tools_dock.buttons_widget)
        main_container.addLayout(vbox)
        # main_container.addWidget(self._splitter_base)
        IDE.register_service("central_container", self)
示例#27
0
文件: charview.py 项目: B-Rich/PPQT2
 def _uic(self):
     mainLayout = QVBoxLayout()
     self.setLayout(mainLayout)
     topLayout = QHBoxLayout()
     topLayout.setContentsMargins(0,0,0,0)
     mainLayout.addLayout(topLayout,0)
     # Lay out the refresh button and filter popup
     self.refresh = QPushButton(
         _TR('Button to reload all data in char panel',
             'Refresh')
         )
     topLayout.addWidget(self.refresh,0)
     topLayout.addStretch(1) # push filters to the right
     self.popup = QComboBox()
     # Set choices in popup, must match to the lambdas
     # defined in CharFilter.set_filter()
     self.popup.addItem(
         _TR('char panel: show all characters',
             'All')
     )
     self.popup.addItem(
         _TR('char panel: show non-ascii characters',
             'not 7-bit')
     )
     self.popup.addItem(
         _TR('char panel: show non-latin-1',
             'not Latin-1')
     )
     topLayout.addWidget(self.popup,0)
     # Set up the table view, the actual visible table
     self.view = QTableView()
     self.view.setCornerButtonEnabled(False)
     self.view.setWordWrap(False)
     self.view.setAlternatingRowColors(True)
     mainLayout.addWidget(self.view,1) # give it all the stretch
示例#28
0
 def addTypeBar(self,types):
     typebar = QHBoxLayout();
     typebar.addStretch(1)
     for tp in types:
         if isinstance(tp,Type):
             icon = QIcon('types/%s.png' % tp)
         elif isinstance(tp,Orb):
             icon = QIcon('orbs/%s.png' % tp)
         button = QToolButton()
         button.setIcon(icon)
         button.setCheckable(True)
         button.setContentsMargins(0,0,0,0)
         button.setFixedSize(22,22)
         button.setChecked(tp in self.skill.scope)
         def buttonFuncMaker(x):
             def buttonFunc(y):
                 if y:
                     self.skill.scope.update((x,))
                 else:
                     self.skill.scope.difference_update((x,))
                 self.skillsChanged.emit()
             return buttonFunc
         button.toggled[bool].connect(buttonFuncMaker(tp))
         typebar.addWidget(button)
     typebar.addStretch(1)
     typebar.setSpacing(0)
     typebar.setContentsMargins(0,0,0,0)
     typebar.setAlignment(Qt.AlignCenter)
     self.layout.addLayout(typebar)
示例#29
0
    def __init__(self, main_window, items):
        super().__init__()

        vbox = QVBoxLayout()
        vbox.setSpacing(0)
        vbox.setContentsMargins(0, 0, 0, 0)
        self.setLayout(vbox)

        top_system_buttons = TopSystemButtons(main_window)
        vbox.addWidget(top_system_buttons)
        vbox.addStretch()
        hbox = QHBoxLayout()
        hbox.addSpacing(25)
        hbox.setSpacing(0)
        hbox.setContentsMargins(0, 0, 0, 0)
        vbox.addLayout(hbox)

        l = QLabel()
        hbox.addWidget(l)
        vbox.addStretch()
        vbox.addWidget(SelectMenu(main_window, items))

        main_window.communication.input_changed_signal.connect(l.setText)
        self.resizeEvent = functools.partial(main_window.resized, self,
                                             top_system_buttons)

        self.setGraphicsEffect(utils.get_shadow())
    def __init__(self, *args):
        # Invoke parent init
        QFrame.__init__(self, *args)
        self.item_id = None
        self.item_type = None

        # Get translation object
        _ = get_app()._tr

        # Widgets
        self.lblSelection = QLabel()
        self.lblSelection.setText("<strong>%s</strong>" % _("No Selection"))
        self.btnSelectionName = QPushButton()
        self.btnSelectionName.setVisible(False)
        self.btnSelectionName.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum)

        # Support rich text
        self.lblSelection.setTextFormat(Qt.RichText)

        hbox = QHBoxLayout()
        hbox.setContentsMargins(0,0,0,0)
        hbox.addWidget(self.lblSelection)
        hbox.addWidget(self.btnSelectionName)
        self.setLayout(hbox)

        # Connect signals
        get_app().window.propertyTableView.loadProperties.connect(self.select_item)
示例#31
0
	def initUI(self):

		self.setStyleSheet("background-color: white")

		#Layout Manager and Items
		self.chooseFile = QCheckBox("Audio File")
		self.chooseFile.setChecked(True)
		self.chooseFile.clicked.connect(self.audioSelected)
		#chooseFile.setAlignment(Qt.AlignCenter)
		filecheckbox = QHBoxLayout()
		filecheckbox.addWidget(self.chooseFile)
		filecheckbox.setAlignment(Qt.AlignCenter)

		self.fileLabel = QLineEdit("")
		openBtn = QPushButton("Open", self)
		openBtn.clicked.connect(self.openFileDialog)
		openBtn.resize(openBtn.sizeHint())
		filebox = QHBoxLayout()
		filebox.addWidget(self.fileLabel)
		filebox.addWidget(openBtn)
		filebox.setAlignment(Qt.AlignCenter)
		filebox.setContentsMargins(90, 0, 90, 0)

		self.chooseMic = QCheckBox("Microphone")
		self.chooseMic.clicked.connect(self.micSelected)
		miccheckbox = QHBoxLayout()
		miccheckbox.addWidget(self.chooseMic)
		miccheckbox.setAlignment(Qt.AlignCenter)

		startBtn = QPushButton("Start", self)
		startBtn.clicked.connect(self.hal)
		startBtn.resize(startBtn.sizeHint())
		hbox = QHBoxLayout()
		hbox.addWidget(startBtn)
		hbox.setAlignment(Qt.AlignCenter)

		self.commandBtn = QPushButton("Execute Command", self)
		self.commandBtn.clicked.connect(self.runCmd)
		self.commandBtn.setEnabled(False)
		self.commandBtn.resize(self.commandBtn.sizeHint())
		hbox4 = QHBoxLayout()
		hbox4.addWidget(self.commandBtn)
		hbox4.setAlignment(Qt.AlignCenter)

		closeBtn = QPushButton("Close", self)
		closeBtn.clicked.connect(QApplication.instance().quit)
		closeBtn.resize(closeBtn.sizeHint())
		hbox5 = QHBoxLayout()
		hbox5.addWidget(closeBtn)
		hbox5.setAlignment(Qt.AlignCenter)

		self.gif = QLabel("Loading GIF here.")
		self.gif.setPixmap(QPixmap("../../gui/stop.png"))
		hbox2 = QHBoxLayout()
		hbox2.addWidget(self.gif)
		hbox2.setAlignment(Qt.AlignCenter)

		self.resultLabel = QLabel("Click Start to begin detection...")
		hbox3 = QHBoxLayout()
		hbox3.setAlignment(Qt.AlignCenter)
		hbox3.addWidget(self.resultLabel)

		vbox = QVBoxLayout()
		vbox.addLayout(filecheckbox)
		vbox.addLayout(filebox)
		vbox.addLayout(miccheckbox)
		vbox.addLayout(hbox2)
		vbox.addLayout(hbox3)
		vbox.addLayout(hbox)
		vbox.addLayout(hbox4)
		vbox.addLayout(hbox5)

		self.setLayout(vbox)

		self.resize(600, 500)
		self.center()
		self.setWindowTitle('Word Recognizer')
		self.show()
示例#32
0
    def setup(self):
        # definition of all button

        TogOff = self.icon + 'Toggle_Off.png'
        TogOn = self.icon + 'Toggle_On.png'
        TogOff = pathlib.Path(TogOff)
        TogOff = pathlib.PurePosixPath(TogOff)
        TogOn = pathlib.Path(TogOn)
        TogOn = pathlib.PurePosixPath(TogOn)

        self.setStyleSheet("QCheckBox::indicator{width: 30px;height: 30px;}"
                           "QCheckBox::indicator:unchecked { image : url(%s);}"
                           "QCheckBox::indicator:checked { image:  url(%s);}"
                           "QCheckBox{font :10pt;}" % (TogOff, TogOn))

        vbox1 = QVBoxLayout()
        self.hbox0 = QHBoxLayout()
        vbox1.addLayout(self.hbox0)

        hbox1 = QHBoxLayout()
        self.checkBoxPlot = QCheckBox('CROSS', self)
        self.checkBoxPlot.setChecked(False)
        self.label_CrossValue = QLabel()
        self.label_CrossValue.setStyleSheet("font:13pt")
        hbox1.addWidget(self.checkBoxPlot)
        hbox1.addWidget(self.label_CrossValue)

        hbox2 = QHBoxLayout()
        self.label_Cross = QLabel()
        #self.label_Cross.setMaximumHeight(20)
        self.label_Cross.setMaximumWidth(170)
        self.label_Cross.setStyleSheet("font:12pt")
        hbox2.addWidget(self.label_Cross)

        vbox1.addLayout(hbox1)
        vbox1.addLayout(hbox2)

        self.ZoomLabel = QLabel('Zoom')
        vbox1.addWidget(self.ZoomLabel)
        self.checkBoxZoom = QSlider(Qt.Horizontal)
        self.checkBoxZoom.setMaximumWidth(250)
        self.checkBoxZoom.setMinimum(0)
        self.checkBoxZoom.setMaximum(200)
        self.checkBoxZoom.setValue(0)
        vbox1.addWidget(self.checkBoxZoom)

        self.checkBoxScale = QCheckBox('Auto Scale', self)
        self.checkBoxScale.setChecked(True)
        self.checkBoxScale.setMaximumWidth(100)

        self.checkBoxColor = QCheckBox('Color', self)
        self.checkBoxColor.setChecked(True)

        self.checkBoxHist = QCheckBox('Hist', self)
        self.checkBoxHist.setChecked(False)
        self.maxGraphBox = QCheckBox('Max', self)
        hbox3 = QHBoxLayout()
        grid_layout = QGridLayout()
        grid_layout.setVerticalSpacing(0)
        grid_layout.setHorizontalSpacing(10)
        grid_layout.addWidget(self.checkBoxScale, 0, 0)
        grid_layout.addWidget(self.checkBoxColor, 1, 0)
        grid_layout.addWidget(self.checkBoxHist, 0, 1)
        #grid_layout.addWidget(self.checkBoxZoom, 1, 0)
        grid_layout.addWidget(self.maxGraphBox, 1, 1)

        hbox3.addLayout(grid_layout)

        vbox1.addLayout(hbox3)

        hbox4 = QHBoxLayout()

        if self.meas == 'on':
            self.MeasButton = QPushButton('Meas.')
            hbox4.addWidget(self.MeasButton)

        vbox1.addLayout(hbox4)

        vbox1.addStretch(1)

        self.winImage = pg.GraphicsLayoutWidget()
        #self.winImage.setContentsMargins(1,1,1,1)
        self.winImage.setAspectLocked(True)
        self.winImage.setSizePolicy(QSizePolicy.Expanding,
                                    QSizePolicy.Expanding)
        #self.winImage.ci.setContentsMargins(1,1,1,1)

        vbox2 = QVBoxLayout()
        # self.dockImage=QDockWidget(self)

        # self.dockImage.setWidget(self.winImage)
        # self.dockImage.setFeatures(QDockWidget.DockWidgetFloatable)
        #vbox2.addWidget(self.dockImage)
        vbox2.addWidget(self.winImage)
        vbox2.setContentsMargins(0, 0, 0, 0)

        self.p1 = self.winImage.addPlot()
        self.imh = pg.ImageItem()
        self.axeX = self.p1.getAxis('bottom')
        self.axeY = self.p1.getAxis('left')
        self.p1.addItem(self.imh)
        self.p1.setMouseEnabled(x=False, y=False)
        self.p1.setContentsMargins(0, 0, 0, 0)

        self.p1.setAspectLocked(True, ratio=1)
        self.p1.showAxis('right', show=False)
        self.p1.showAxis('top', show=False)
        self.p1.showAxis('left', show=True)
        self.p1.showAxis('bottom', show=True)

        if self.bloqKeyboard == True:
            self.vLine = pg.InfiniteLine(angle=90, movable=False, pen='r')
            self.hLine = pg.InfiniteLine(angle=0, movable=False, pen='r')
        else:
            self.vLine = pg.InfiniteLine(angle=90, movable=False, pen='y')
            self.hLine = pg.InfiniteLine(angle=0, movable=False, pen='y')

        self.xc = int(self.conf.value(self.name + "/xc"))
        self.yc = int(self.conf.value(self.name + "/yc"))
        self.rx = int(self.conf.value(self.name + "/rx"))
        self.ry = int(self.conf.value(self.name + "/ry"))
        self.vLine.setPos(self.xc)
        self.hLine.setPos(self.yc)

        self.ro1 = pg.EllipseROI([self.xc, self.yc], [self.rx, self.ry],
                                 pen='y',
                                 movable=False,
                                 maxBounds=QtCore.QRectF(
                                     0, 0, self.rx, self.ry))
        self.ro1.setPos([self.xc - (self.rx / 2), self.yc - (self.ry / 2)])

        # text for fwhm on p1
        self.textX = pg.TextItem(angle=-90)
        self.textY = pg.TextItem()

        #histogram
        self.hist = pg.HistogramLUTItem()
        self.hist.setImageItem(self.imh)
        self.hist.autoHistogramRange()
        self.hist.gradient.loadPreset('flame')

        ##  XY  graph
        self.curve2 = pg.PlotCurveItem()
        self.curve3 = pg.PlotCurveItem()

        ## main layout
        hMainLayout = QHBoxLayout()
        if self.aff == 'right':
            hMainLayout.addLayout(vbox2)
            hMainLayout.addLayout(vbox1)
        else:
            hMainLayout.addLayout(vbox1)
            hMainLayout.addLayout(vbox2)

        hMainLayout.setContentsMargins(1, 1, 1, 1)
        hMainLayout.setSpacing(1)
        hMainLayout.setStretch(10, 1)

        self.setLayout(hMainLayout)
        self.setContentsMargins(1, 1, 1, 1)
示例#33
0
    def __init__(self, playlist, parent=None):
        super(Player, self).__init__(parent)

        self.colorDialog = None
        self.trackInfo = ""
        self.statusInfo = ""
        self.duration = 0

        self.player = QMediaPlayer()
        self.playlist = QMediaPlaylist()
        self.player.setPlaylist(self.playlist)

        self.player.durationChanged.connect(self.durationChanged)
        self.player.positionChanged.connect(self.positionChanged)
        self.player.metaDataChanged.connect(self.metaDataChanged)
        self.playlist.currentIndexChanged.connect(self.playlistPositionChanged)
        self.player.mediaStatusChanged.connect(self.statusChanged)
        self.player.bufferStatusChanged.connect(self.bufferingProgress)
        self.player.videoAvailableChanged.connect(self.videoAvailableChanged)
        self.player.error.connect(self.displayErrorMessage)

        self.videoWidget = VideoWidget()
        self.player.setVideoOutput(self.videoWidget)

        self.playlistModel = PlaylistModel()
        self.playlistModel.setPlaylist(self.playlist)

        self.playlistView = QListView()
        self.playlistView.setModel(self.playlistModel)
        self.playlistView.setCurrentIndex(
                self.playlistModel.index(self.playlist.currentIndex(), 0))

        self.playlistView.activated.connect(self.jump)

        self.slider = QSlider(Qt.Horizontal)
        self.slider.setRange(0, self.player.duration() / 1000)

        self.labelDuration = QLabel()
        self.slider.sliderMoved.connect(self.seek)


        openButton = QPushButton("Открыть файл", clicked=self.open)

        controls = PlayerControls()
        controls.setState(self.player.state())
        controls.setVolume(self.player.volume())

        controls.play.connect(self.player.play)
        controls.pause.connect(self.player.pause)
        controls.stop.connect(self.player.stop)
        controls.next.connect(self.playlist.next)
        controls.previous.connect(self.previousClicked)
        controls.changeVolume.connect(self.player.setVolume)
        controls.changeRate.connect(self.player.setPlaybackRate)
        controls.stop.connect(self.videoWidget.update)

        self.player.stateChanged.connect(controls.setState)
        self.player.volumeChanged.connect(controls.setVolume)

        self.fullScreenButton = QPushButton("Полный экран")
        self.fullScreenButton.setCheckable(True)

        displayLayout = QHBoxLayout()
        displayLayout.addWidget(self.videoWidget, 2)
        displayLayout.addWidget(self.playlistView)

        controlLayout = QHBoxLayout()
        controlLayout.setContentsMargins(0, 0, 0, 0)
        controlLayout.addWidget(openButton)
        controlLayout.addStretch(1)
        controlLayout.addWidget(controls)
        controlLayout.addStretch(1)
        controlLayout.addWidget(self.fullScreenButton)

        layout = QVBoxLayout()
        layout.addLayout(displayLayout)
        hLayout = QHBoxLayout()
        hLayout.addWidget(self.slider)
        hLayout.addWidget(self.labelDuration)
        layout.addLayout(hLayout)
        layout.addLayout(controlLayout)

        self.setLayout(layout)

        self.metaDataChanged()

        self.addToPlaylist(playlist)
示例#34
0
    def setup_ui(self):
        """ Setup Ui
        """
        main_wrap = QVBoxLayout()
        main_wrap.setContentsMargins(0, 0, 0, 0)

        # updatebar on top
        self.update_bar = UpdateBar(self)
        self.update_bar.onUpdateNowClicked.connect(self._update_dwarf)
        self.update_bar.setVisible(False)
        main_wrap.addWidget(self.update_bar)

        # main content
        h_box = QHBoxLayout()
        h_box.setContentsMargins(15, 15, 15, 15)
        wrapper = QVBoxLayout()
        head = QHBoxLayout()
        head.setContentsMargins(50, 10, 0, 10)
        # dwarf icon
        icon = QLabel()
        icon.setPixmap(QPixmap(utils.resource_path('assets/dwarf.svg')))
        icon.setAlignment(Qt.AlignCenter)
        icon.setMinimumSize(QSize(125, 125))
        icon.setMaximumSize(QSize(125, 125))
        head.addWidget(icon)

        # main title
        v_box = QVBoxLayout()
        title = QLabel('Dwarf')
        title.setContentsMargins(0, 0, 0, 0)
        font = QFont('Anton', 100, QFont.Bold)
        font.setPixelSize(120)
        title.setFont(font)
        title.setMaximumHeight(125)
        title.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum)
        title.setAlignment(Qt.AlignCenter)
        head.addWidget(title)

        sub_title_text = (self._pick_random_word(0) + ' ' +
                          self._pick_random_word(1) + ' ' +
                          self._pick_random_word(2) + ' ' +
                          self._pick_random_word(3) + ' ' +
                          self._pick_random_word(4))
        sub_title_text = sub_title_text[:1].upper() + sub_title_text[1:]
        self._sub_title = QLabel(sub_title_text)
        font = QFont('OpenSans', 16, QFont.Bold)
        font.setPixelSize(24)
        self._sub_title.setFont(font)
        font_metric = QFontMetrics(self._sub_title.font())
        self._char_width = font_metric.widthChar('#')
        self._sub_title.setAlignment(Qt.AlignCenter)
        self._sub_title.setContentsMargins(175, 0, 0, 20)
        self._sub_title.setSizePolicy(QSizePolicy.Expanding,
                                      QSizePolicy.Minimum)
        v_box.addLayout(head)
        v_box.addWidget(self._sub_title)

        wrapper.addLayout(v_box)

        recent = QLabel('Last saved Sessions')
        font = recent.font()
        font.setPixelSize(14)
        font.setBold(True)
        #font.setPointSize(10)
        recent.setFont(font)
        wrapper.addWidget(recent)
        wrapper.addWidget(self._recent_list)
        h_box.addLayout(wrapper, stretch=False)
        buttonSpacer = QSpacerItem(15, 100, QSizePolicy.Fixed,
                                   QSizePolicy.Minimum)
        h_box.addItem(buttonSpacer)
        wrapper = QVBoxLayout()

        btn = QPushButton()
        ico = QIcon(QPixmap(utils.resource_path('assets/android.svg')))
        btn.setIconSize(QSize(75, 75))
        btn.setIcon(ico)
        btn.setToolTip('New Android Session')
        btn.clicked.connect(self._on_android_button)
        wrapper.addWidget(btn)

        btn = QPushButton()
        ico = QIcon(QPixmap(utils.resource_path('assets/apple.svg')))
        btn.setIconSize(QSize(75, 75))
        btn.setIcon(ico)
        btn.setToolTip('New iOS Session')
        btn.clicked.connect(self._on_ios_button)
        wrapper.addWidget(btn)

        btn = QPushButton()
        ico = QIcon(QPixmap(utils.resource_path('assets/local.svg')))
        btn.setIconSize(QSize(75, 75))
        btn.setIcon(ico)
        btn.setToolTip('New Local Session')
        btn.clicked.connect(self._on_local_button)
        wrapper.addWidget(btn)

        btn = QPushButton()
        ico = QIcon(QPixmap(utils.resource_path('assets/remote.svg')))
        btn.setIconSize(QSize(75, 75))
        btn.setIcon(ico)
        btn.setToolTip('New Remote Session')
        btn.clicked.connect(self._on_remote_button)
        wrapper.addWidget(btn)

        session_history = self._prefs.get(prefs.RECENT_SESSIONS, default=[])
        invalid_session_files = []
        for recent_session_file in session_history:
            if os.path.exists(recent_session_file):
                with open(recent_session_file, 'r') as f:
                    exported_session = json.load(f)
                hooks = '0'
                watchers = '0'
                on_loads = 0
                bookmarks = '0'
                #have_user_script = False
                if 'hooks' in exported_session and exported_session[
                        'hooks'] is not None:
                    hooks = str(len(exported_session['hooks']))
                if 'watchers' in exported_session and exported_session[
                        'watchers'] is not None:
                    watchers = str(len(exported_session['watchers']))
                if 'nativeOnLoads' in exported_session and exported_session[
                        'nativeOnLoads'] is not None:
                    on_loads += len(exported_session['nativeOnLoads'])
                if 'javaOnLoads' in exported_session and exported_session[
                        'javaOnLoads'] is not None:
                    on_loads += len(exported_session['javaOnLoads'])
                if 'bookmarks' in exported_session and exported_session[
                        'bookmarks'] is not None:
                    bookmarks = str(len(exported_session['bookmarks']))
                if 'user_script' in exported_session and exported_session[
                        'user_script']:
                    have_user_script = exported_session['user_script'] != ''

                #user_script_item = QStandardItem()
                #if have_user_script:
                #user_script_item.setIcon(self._dot_icon)

                on_loads = str(on_loads)

                recent_session_file_item = QStandardItem(recent_session_file)
                recent_session_file_item.setData(exported_session,
                                                 Qt.UserRole + 2)

                item_1 = QStandardItem(exported_session['session'])
                item_1.setTextAlignment(Qt.AlignCenter)
                item_2 = QStandardItem(hooks)
                item_2.setTextAlignment(Qt.AlignCenter)
                item_3 = QStandardItem(watchers)
                item_3.setTextAlignment(Qt.AlignCenter)
                item_4 = QStandardItem(on_loads)
                item_4.setTextAlignment(Qt.AlignCenter)
                item_5 = QStandardItem(bookmarks)
                item_5.setTextAlignment(Qt.AlignCenter)
                #item_6 = QStandardItem(user_script_item)
                #item_6.setTextAlignment(Qt.AlignCenter)

                self._recent_list_model.insertRow(
                    self._recent_list_model.rowCount(), [
                        recent_session_file_item, item_1, item_2, item_3,
                        item_4, item_5
                    ])
            else:
                invalid_session_files.append(recent_session_file)
        for invalid in invalid_session_files:
            session_history.pop(session_history.index(invalid))
        self._prefs.put(prefs.RECENT_SESSIONS, session_history)

        h_box.addLayout(wrapper, stretch=False)
        main_wrap.addLayout(h_box)
        self.setLayout(main_wrap)
示例#35
0
    def create_fee_controls(self):

        self.size_e = TxSizeLabel()
        self.size_e.setAlignment(Qt.AlignCenter)
        self.size_e.setAmount(0)
        self.size_e.setStyleSheet(ColorScheme.DEFAULT.as_stylesheet())

        self.feerate_e = FeerateEdit(lambda: 0)
        self.feerate_e.setAmount(self.config.fee_per_byte())
        self.feerate_e.textEdited.connect(
            partial(self.on_fee_or_feerate, self.feerate_e, False))
        self.feerate_e.editingFinished.connect(
            partial(self.on_fee_or_feerate, self.feerate_e, True))

        self.fee_e = BTCAmountEdit(self.main_window.get_decimal_point)
        self.fee_e.textEdited.connect(
            partial(self.on_fee_or_feerate, self.fee_e, False))
        self.fee_e.editingFinished.connect(
            partial(self.on_fee_or_feerate, self.fee_e, True))

        self.fee_e.textChanged.connect(self.entry_changed)
        self.feerate_e.textChanged.connect(self.entry_changed)

        self.fee_slider = FeeSlider(self, self.config,
                                    self.fee_slider_callback)
        self.fee_combo = FeeComboBox(self.fee_slider)
        self.fee_slider.setFixedWidth(self.fee_e.width())

        def feerounding_onclick():
            text = (
                self.feerounding_text + '\n\n' +
                _('To somewhat protect your privacy, Electrum-CHI tries to create change with similar precision to other outputs.'
                  ) + ' ' +
                _('At most 100 swartz might be lost due to this rounding.') +
                ' ' + _("You can disable this setting in '{}'.").format(
                    _('Preferences')) + '\n' +
                _('Also, dust is not kept as change, but added to the fee.') +
                '\n' +
                _('Also, when batching RBF transactions, BIP 125 imposes a lower bound on the fee.'
                  ))
            self.show_message(title=_('Fee rounding'), msg=text)

        self.feerounding_icon = QPushButton(read_QIcon('info.png'), '')
        self.feerounding_icon.setFixedWidth(
            round(2.2 * char_width_in_lineedit()))
        self.feerounding_icon.setFlat(True)
        self.feerounding_icon.clicked.connect(feerounding_onclick)
        self.feerounding_icon.setVisible(False)

        self.feecontrol_fields = QWidget()
        hbox = QHBoxLayout(self.feecontrol_fields)
        hbox.setContentsMargins(0, 0, 0, 0)
        grid = QGridLayout()
        grid.addWidget(QLabel(_("Target fee:")), 0, 0)
        grid.addWidget(self.feerate_e, 0, 1)
        grid.addWidget(self.size_e, 0, 2)
        grid.addWidget(self.fee_e, 0, 3)
        grid.addWidget(self.feerounding_icon, 0, 4)
        grid.addWidget(self.fee_slider, 1, 1)
        grid.addWidget(self.fee_combo, 1, 2)
        hbox.addLayout(grid)
        hbox.addStretch(1)
示例#36
0
    def add_tx_stats(self, vbox):
        hbox_stats = QHBoxLayout()

        # left column
        vbox_left = QVBoxLayout()
        self.tx_desc = TxDetailLabel(word_wrap=True)
        vbox_left.addWidget(self.tx_desc)
        self.status_label = TxDetailLabel()
        vbox_left.addWidget(self.status_label)
        self.date_label = TxDetailLabel()
        vbox_left.addWidget(self.date_label)
        self.amount_label = TxDetailLabel()
        vbox_left.addWidget(self.amount_label)
        self.ln_amount_label = TxDetailLabel()
        vbox_left.addWidget(self.ln_amount_label)

        fee_hbox = QHBoxLayout()
        self.fee_label = TxDetailLabel()
        fee_hbox.addWidget(self.fee_label)
        self.fee_warning_icon = QLabel()
        pixmap = QPixmap(icon_path("warning"))
        pixmap_size = round(2 * char_width_in_lineedit())
        pixmap = pixmap.scaled(pixmap_size, pixmap_size, Qt.KeepAspectRatio,
                               Qt.SmoothTransformation)
        self.fee_warning_icon.setPixmap(pixmap)
        self.fee_warning_icon.setVisible(False)
        fee_hbox.addWidget(self.fee_warning_icon)
        fee_hbox.addStretch(1)
        vbox_left.addLayout(fee_hbox)

        name_fee_hbox = QHBoxLayout()
        self.name_fee_label = TxDetailLabel()
        name_fee_hbox.addWidget(self.name_fee_label)
        name_fee_hbox.addStretch(1)
        vbox_left.addLayout(name_fee_hbox)

        vbox_left.addStretch(1)
        hbox_stats.addLayout(vbox_left, 50)

        # vertical line separator
        line_separator = QFrame()
        line_separator.setFrameShape(QFrame.VLine)
        line_separator.setFrameShadow(QFrame.Sunken)
        line_separator.setLineWidth(1)
        hbox_stats.addWidget(line_separator)

        # right column
        vbox_right = QVBoxLayout()
        self.size_label = TxDetailLabel()
        vbox_right.addWidget(self.size_label)
        self.rbf_label = TxDetailLabel()
        vbox_right.addWidget(self.rbf_label)
        self.rbf_cb = QCheckBox(_('Replace by fee'))
        self.rbf_cb.setChecked(bool(self.config.get('use_rbf', True)))
        vbox_right.addWidget(self.rbf_cb)

        self.locktime_final_label = TxDetailLabel()
        vbox_right.addWidget(self.locktime_final_label)

        locktime_setter_hbox = QHBoxLayout()
        locktime_setter_hbox.setContentsMargins(0, 0, 0, 0)
        locktime_setter_hbox.setSpacing(0)
        locktime_setter_label = TxDetailLabel()
        locktime_setter_label.setText("LockTime: ")
        self.locktime_e = LockTimeEdit()
        locktime_setter_hbox.addWidget(locktime_setter_label)
        locktime_setter_hbox.addWidget(self.locktime_e)
        locktime_setter_hbox.addStretch(1)
        self.locktime_setter_widget = QWidget()
        self.locktime_setter_widget.setLayout(locktime_setter_hbox)
        vbox_right.addWidget(self.locktime_setter_widget)

        self.block_height_label = TxDetailLabel()
        vbox_right.addWidget(self.block_height_label)
        vbox_right.addStretch(1)
        hbox_stats.addLayout(vbox_right, 50)

        vbox.addLayout(hbox_stats)

        # below columns
        self.block_hash_label = TxDetailLabel(word_wrap=True)
        vbox.addWidget(self.block_hash_label)

        # set visibility after parenting can be determined by Qt
        self.rbf_label.setVisible(self.finalized)
        self.rbf_cb.setVisible(not self.finalized)
        self.locktime_final_label.setVisible(self.finalized)
        self.locktime_setter_widget.setVisible(not self.finalized)
示例#37
0
    def __init__(self, parent=None, show_progress_dlg=False):
        super(SearchPanel, self).__init__(parent=parent)
        self._app_window = parent

        if self._app_window.dwarf is None:
            print('SearchPanel created before Dwarf exists')
            return

        self._app_window.dwarf.onMemoryScanResult.connect(
            self._on_search_result)

        self._app_window.dwarf.onSetRanges.connect(self._on_setranges)

        self._ranges_model = None
        self._result_model = None

        self._blocking_search = show_progress_dlg
        self.progress = None
        self._pattern_length = 0

        self._search_results = []

        self.setContentsMargins(0, 0, 0, 0)

        main_wrap = QVBoxLayout()
        main_wrap.setContentsMargins(1, 1, 1, 1)

        wrapping_wdgt = QWidget()
        wrapping_wdgt.setContentsMargins(10, 10, 10, 10)
        v_box = QVBoxLayout(wrapping_wdgt)
        v_box.setContentsMargins(0, 0, 0, 0)
        self.input = QLineEdit()
        self.input.setPlaceholderText(
            'search for a sequence of bytes in hex format: deadbeef123456aabbccddeeff...'
        )
        v_box.addWidget(self.input)

        self.check_all_btn = QPushButton('check all')
        self.check_all_btn.clicked.connect(self._on_click_check_all)
        self.uncheck_all_btn = QPushButton('uncheck all')
        self.uncheck_all_btn.clicked.connect(self._on_click_uncheck_all)
        self.search_btn = QPushButton('search')
        self.search_btn.clicked.connect(self._on_click_search)

        h_box = QHBoxLayout()
        h_box.addWidget(self.check_all_btn)
        h_box.addWidget(self.uncheck_all_btn)
        h_box.addWidget(self.search_btn)
        v_box.addLayout(h_box)

        main_wrap.addWidget(wrapping_wdgt)

        self.ranges = DwarfListView(self)
        self.ranges.clicked.connect(self._on_show_results)
        self.results = DwarfListView(self)
        self.results.setVisible(False)

        h_box = QHBoxLayout()
        h_box.setContentsMargins(0, 0, 0, 0)
        h_box.addWidget(self.ranges)
        h_box.addWidget(self.results)
        main_wrap.addLayout(h_box)

        main_wrap.setSpacing(0)

        self.setLayout(main_wrap)

        self._setup_models()
        self._app_window.dwarf.dwarf_api('updateRanges')
示例#38
0
    def __init__(
        self,
        *,
        data,
        parent=None,
        title="",
        show_text=False,
        help_text=None,
        show_copy_text_btn=False,
        config: SimpleConfig,
    ):
        WindowModalDialog.__init__(self, parent, title)
        self.config = config

        vbox = QVBoxLayout()

        qrw = QRCodeWidget(data)
        qr_hbox = QHBoxLayout()
        qr_hbox.addWidget(qrw)
        qr_hbox.addStretch(1)
        vbox.addLayout(qr_hbox)

        help_text = data if show_text else help_text
        if help_text:
            qr_hbox.setContentsMargins(0, 0, 0, 44)
            text_label = WWLabel()
            text_label.setText(help_text)
            vbox.addWidget(text_label)
        hbox = QHBoxLayout()
        hbox.addStretch(1)

        def print_qr():
            filename = getSaveFileName(
                parent=self,
                title=_("Select where to save file"),
                filename="qrcode.png",
                config=self.config,
            )
            if not filename:
                return
            p = qrw.grab()
            p.save(filename, 'png')
            self.show_message(_("QR code saved to file") + " " + filename)

        def copy_image_to_clipboard():
            p = qrw.grab()
            QApplication.clipboard().setPixmap(p)
            self.show_message(_("QR code copied to clipboard"))

        def copy_text_to_clipboard():
            QApplication.clipboard().setText(data)
            self.show_message(_("Text copied to clipboard"))

        b = QPushButton(_("Copy Image"))
        hbox.addWidget(b)
        b.clicked.connect(copy_image_to_clipboard)

        if show_copy_text_btn:
            b = QPushButton(_("Copy Text"))
            hbox.addWidget(b)
            b.clicked.connect(copy_text_to_clipboard)

        b = QPushButton(_("Save"))
        hbox.addWidget(b)
        b.clicked.connect(print_qr)

        b = QPushButton(_("Close"))
        hbox.addWidget(b)
        b.clicked.connect(self.accept)
        b.setDefault(True)

        vbox.addLayout(hbox)
        self.setLayout(vbox)
示例#39
0
    def __init__(self, parent=None):
        super().__init__(parent)

        self.mThread = None

        self.layout = QVBoxLayout()

        # 最上层的文本框

        self.tbox_log = QTextEdit()
        self.tbox_log.setFontPointSize(10)
        # 按钮及下拉框
        line_1 = QHBoxLayout()

        self.serial_cb = QComboBox()

        self.baudRate_cb = QComboBox()
        self.baudRate_cb.addItem("9600")
        self.baudRate_cb.addItem("115200")
        self.baudRate_cb.addItem("500000")
        self.baudRate_cb.addItem("921600")

        btn_refresh_p = QPushButton("刷新串口")
        btn_recv_cnt = QPushButton("收")
        btn_send_cnt = QPushButton("发")
        btn_clean_scn = QPushButton("清除窗口")
        self.btn_Open = QPushButton("打开串口")

        btn_refresh_p.clicked.connect(self.refresh_p_fn)
        btn_clean_scn.clicked.connect(self.clean_screen_fn)
        self.btn_Open.clicked.connect(self.OpenSerial)

        line_1.addWidget(self.serial_cb)
        line_1.addWidget(btn_refresh_p)
        line_1.addWidget(self.baudRate_cb)
        line_1.addWidget(self.btn_Open)
        line_1.addWidget(btn_recv_cnt)
        line_1.addWidget(btn_send_cnt)
        line_1.addWidget(btn_clean_scn)

        line_1.setContentsMargins(0, 0, 0, 0)

        # 发送文本框及发送按钮
        line_2 = QHBoxLayout()

        self.cbox_sendData = QComboBox()
        self.cbox_sendData.setEditable(True)

        self.checkBox_Hex = QCheckBox("HEX发送")
        self.checkBox_Hex.setEnabled(False)

        self.checkBox_CF = QCheckBox("加回车换行")
        self.checkBox_CF.setChecked(True)

        btn_Send = QPushButton("发送数据")

        btn_Send.clicked.connect(lambda: self.send_btn_fn())

        line_2.addWidget(self.cbox_sendData)
        line_2.addWidget(self.checkBox_Hex)
        line_2.addWidget(self.checkBox_CF)
        line_2.addWidget(btn_Send)

        line_2.setStretch(0, 42)
        line_2.setStretch(1, 10)
        line_2.setStretch(2, 10)
        line_2.setStretch(3, 10)

        # 预定义的AT指令按键矩阵
        line_3 = QGridLayout()

        names = [
            'AT', 'AT+GMR', 'AT+RST', 'AT+SLEEP', 'AT+RESTORE', 'AT+SCAN',
            'AT+DISCONNECT', 'AT+NAME?', 'AT+BAUD?', 'AT+MAC?', 'AT+ADDR?',
            'AT+MODE?', 'AT+STATE?', 'AT+MESHNAME?'
        ]

        positions = [(i, j) for i in range(2) for j in range(7)]

        for name, position in zip(names, positions):

            if name == ' ':
                continue
            button = QPushButton(name)
            button.clicked.connect(lambda: self.grid_btn_fn())
            line_3.addWidget(button, *position)

        self.layout.addWidget(self.tbox_log)
        self.layout.addLayout(line_1)
        self.layout.addLayout(line_2)
        self.layout.addLayout(line_3)

        self.setLayout(self.layout)
        self.refresh_p_fn()
示例#40
0
    def __init__(self, dialog, contract):
        QGridLayout.__init__(self)
        self.setSpacing(8)
        self.setColumnStretch(3, 1)
        self.dialog = dialog
        self.contract = contract
        self.senders = self.dialog.parent().wallet.get_spendable_addresses()

        address_lb = QLabel(_("Address:"))
        self.address_e = ButtonsLineEdit()

        qr_show = lambda: dialog.parent().show_qrcode(str(self.address_e.text()), 'Address', parent=dialog)
        qr_icon = "qrcode_white.png" if ColorScheme.dark_scheme else "qrcode.png"
        self.address_e.addButton(qr_icon, qr_show, _("Show as QR code"))
        self.address_e.setText(self.contract['address'])
        self.address_e.setReadOnly(True)
        self.addWidget(address_lb, 1, 0)
        self.addWidget(self.address_e, 1, 1, 1, -1)

        abi_lb = QLabel(_('Function:'))
        self.abi_combo = QComboBox()

        self.abi_signatures = [(-1, "(00)"), ]
        for index, abi in enumerate(contract.get('interface', [])):
            if not abi.get('type') == 'function':
                continue
            signature = '{}({})'.format(
                abi.get('name', ''),
                ', '.join(['{} {}'.format(i.get('type'), i.get('name')) for i in abi.get('inputs', [])]))
            self.abi_signatures.append((index, signature))

        self.abi_combo.addItems([s[1] for s in self.abi_signatures])
        self.abi_combo.setFixedWidth(self.address_e.width())
        if len(self.senders) > 0:
            self.abi_combo.setCurrentIndex(0)
        self.addWidget(abi_lb, 2, 0)
        self.addWidget(self.abi_combo, 2, 1, 1, -1)
        self.abi_combo.currentIndexChanged.connect(self.update)

        args_lb = QLabel(_('Parameters:'))
        self.args_e = QLineEdit()
        self.addWidget(args_lb, 3, 0)
        self.addWidget(self.args_e, 3, 1, 1, -1)

        self.optional_lb = QLabel(_('Optional:'))
        self.addWidget(self.optional_lb, 4, 0)
        self.optional_widget = QWidget()

        optional_layout = QHBoxLayout()
        optional_layout.setContentsMargins(0, 0, 0, 0)
        optional_layout.setSpacing(0)

        gas_limit_lb = QLabel(_('gas limit: '))
        self.gas_limit_e = ButtonsLineEdit()
        self.gas_limit_e.setValidator(int_validator)
        self.gas_limit_e.setText('250000')
        gas_price_lb = QLabel(_('gas price: '))
        self.gas_price_e = ButtonsLineEdit()
        self.gas_price_e.setValidator(float_validator)
        self.gas_price_e.setText('0.00000040')
        amount_lb = QLabel(_('amount: '))
        self.amount_e = ButtonsLineEdit()
        self.amount_e.setValidator(float_validator)
        optional_layout.addWidget(gas_limit_lb)
        optional_layout.addWidget(self.gas_limit_e)
        optional_layout.addStretch(1)
        optional_layout.addWidget(gas_price_lb)
        optional_layout.addWidget(self.gas_price_e)
        optional_layout.addStretch(1)
        optional_layout.addWidget(amount_lb)
        optional_layout.addWidget(self.amount_e)
        optional_layout.addStretch(0)
        self.optional_widget.setLayout(optional_layout)
        self.addWidget(self.optional_widget, 4, 1, 1, -1)

        sender_lb = QLabel(_('Sender:'))
        self.addWidget(sender_lb, 5, 0)

        buttons = QHBoxLayout()
        self.sender_combo = QComboBox()
        self.sender_combo.setMinimumWidth(400)
        self.sender_combo.addItems(self.senders)
        buttons.addWidget(self.sender_combo)
        buttons.addStretch(1)
        self.call_button = EnterButton(_("Call"), self.do_call)
        self.sendto_button = EnterButton(_("Send to"), self.do_sendto)
        self.preview_btn = EnterButton(_("Preview"), self.do_preview)
        buttons.addWidget(self.call_button)
        buttons.addWidget(self.preview_btn)
        buttons.addWidget(self.sendto_button)
        buttons.addStretch()
        self.addLayout(buttons, 5, 1, 1, -1)

        self.update()
示例#41
0
class MainWindow(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)

        self.inputs = []

        self.setWindowIcon(QIcon(get_resource_path() + "icon.png"))
        self.setWindowTitle("Natural Password Generator v1.0.1")

        central_widget = QWidget(self)
        self.setCentralWidget(central_widget)

        self.grid_layout = QGridLayout()
        central_widget.setLayout(self.grid_layout)

        self.create_buttons()
        self.create_input()
        self.create_output()

        self.grid_layout.setRowStretch(0, 0)
        self.grid_layout.setRowStretch(1, 0)
        self.grid_layout.setRowStretch(2, 1)
        self.grid_layout.setRowStretch(3, 1)
        self.grid_layout.setRowStretch(4, 1)

        if os.path.isfile("input.current"):
            self.restore()
        else:
            self.create_default()

    def closeEvent(self, _):
        self.save()

    def create_buttons(self):
        generate_password_btn = QPushButton("Generate Password", self)
        help_btn = QPushButton("Help && Tips", self)
        clear_output_btn = QPushButton("Clear Output", self)
        add_words_btn = QPushButton("Add Words Field", self)
        add_digits_btn = QPushButton("Add Digit(s) Field", self)
        add_characters_btn = QPushButton("Add Character(s) Field", self)

        generate_password_btn.clicked.connect(self.generate_password)
        help_btn.clicked.connect(self.help)
        clear_output_btn.clicked.connect(self.clear_output)
        add_words_btn.clicked.connect(self.create_words_field)
        add_digits_btn.clicked.connect(self.create_digits_field)
        add_characters_btn.clicked.connect(self.create_characters_field)

        self.grid_layout.addWidget(generate_password_btn, 0, 0,
                                   QtCore.Qt.AlignTop)
        self.grid_layout.addWidget(help_btn, 0, 1, QtCore.Qt.AlignTop)
        self.grid_layout.addWidget(clear_output_btn, 0, 2, QtCore.Qt.AlignTop)
        self.grid_layout.addWidget(add_words_btn, 1, 0, QtCore.Qt.AlignTop)
        self.grid_layout.addWidget(add_digits_btn, 1, 1, QtCore.Qt.AlignTop)
        self.grid_layout.addWidget(add_characters_btn, 1, 2,
                                   QtCore.Qt.AlignTop)

    def create_output(self):
        group = QGroupBox("Output:", self)
        layout = QVBoxLayout()
        group.setLayout(layout)
        group.setMinimumWidth(200)

        self.output = QTextEdit(self)
        self.output.setReadOnly(True)
        layout.addWidget(self.output)

        self.grid_layout.addWidget(group, 0, 3, 8, 1)

    def create_input(self):
        widget = QWidget(self)
        self.input_widget = QHBoxLayout()
        self.input_widget.setContentsMargins(0, 0, 0, 0)
        widget.setLayout(self.input_widget)
        self.grid_layout.addWidget(widget, 2, 0, 6, 3)

    @pyqtSlot()
    def create_words_field(self):
        self.inputs.append(WordInput(self.input_widget))
        self.add_input_remove_btn()

    @pyqtSlot()
    def create_digits_field(self):
        self.inputs.append(DigitsInput(self.input_widget))
        self.add_input_remove_btn()

    @pyqtSlot()
    def create_characters_field(self):
        self.inputs.append(CharactersInput(self.input_widget))
        self.add_input_remove_btn()

    def add_input_remove_btn(self):
        remove_btn = QPushButton("Remove")
        input_field = self.inputs[-1]
        remove_btn.clicked.connect(lambda: self.remove_input(input_field))
        self.inputs[-1].layout().addWidget(remove_btn, QtCore.Qt.AlignBottom)

    @pyqtSlot()
    def remove_input(self, input_field):
        self.inputs.remove(input_field)
        input_field.deleteLater()

    @pyqtSlot()
    def generate_password(self):
        password = ""
        for i in self.inputs:
            password += i.generate()
        self.output.append(password)
        self.output.repaint()

    @pyqtSlot()
    def clear_output(self):
        self.output.clear()
        self.output.repaint()

    @pyqtSlot()
    def help(self):
        msg_box = QMessageBox()
        msg_box.setMinimumSize(500, 1000)
        msg_box.setWindowTitle("Natural Password Generator")
        msg_box.setText("<h2>Help & Tips</h2>")
        msg_box.setInformativeText("""
                <h3>Inputs:</h3>
                <h5>Words input</h5>
                Add one word per line. When generating a password - a random line from each field is selected.<br/>
                <h5>Digits input</h5>
                Set the number of digits to generate. 1 digit is 0 to 9.<br/>
                <h5>Character input</h5>
                Set the number of special characters ['!', '#', '*', '&', '%'] to generate.<br/>
                <h3>Save state</h3>
                The current input configuration is saved to a file when closing the application.<br/>
                The file 'input.current' is saved next to the executable. To clear the save state just delete that file.<br/>
                <h3>Tips</h3>
                To make a more memorable password it's suggested to make all but the last word field adjectives (Pink, Big, Small).
                The last word field should then be nouns (House, Apple, Shoe). So the password ends up being something along the lines of; BigHouse or SmallPinkShoe.<br/>
                <br/>
                Words should also be capitalized to increase security.<br/>
                <h3>Contact</h3>
                Please report issues at:
                <a href=\"https://github.com/timotii48/NaturalPasswordGenerator/issues\">Github/Issues</a><br/>
                For new releases check:
                <a href=\"https://github.com/timotii48/NaturalPasswordGenerator/releases\">Github/Releases</a><br/>
                For anything else email me at: <a href=\"[email protected]\">[email protected]</a>
            """)
        msg_box.setTextFormat(QtCore.Qt.RichText)
        msg_box.setStandardButtons(QMessageBox.Close)
        msg_box.setDefaultButton(QMessageBox.Close)
        msg_box.exec()

    def save(self):
        data = {}
        data['inputs'] = []
        for i in self.inputs:
            data['inputs'].append(i.serialize())
        with open(get_save_path() + 'input.current', 'w') as outfile:
            json.dump(data,
                      outfile,
                      sort_keys=False,
                      indent=4,
                      separators=(',', ': '))

    def restore(self):
        with open('input.current') as json_file:
            data = json.load(json_file)
            for i in data['inputs']:
                if i['type'] == "words":
                    self.create_words_field()
                elif i['type'] == "digits":
                    self.create_digits_field()
                elif i['type'] == "characters":
                    self.create_characters_field()
                self.inputs[-1].deserialize(i)

    def create_default(self):
        self.create_words_field()
        self.create_words_field()
        self.create_digits_field()
        self.create_characters_field()
示例#42
0
class MenuBar(QWidget):
    """A class responsible for providing the logic of standard drag-and-move window behaviour."""
    def __init__(self, window: QMainWindow, control, screens: list) -> None:
        super().__init__(parent=window)
        self.window = window
        self.control = control
        self.screens = screens
        self.layout = QHBoxLayout()
        self.layout.setAlignment(Qt.AlignTop)
        self.layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(self.layout)
        self.setStyleSheet("background-color:#141414;"
                           "color:#afafaf;"
                           "font-weight:bold;")

        self.logo = Icon(self.window, self.control, logo)
        self.logo.setFixedSize(30, 30)
        self.layout.addWidget(self.logo)
        self.title = QLabel("My player")
        self.title.setAlignment(Qt.AlignRight)
        self.title.setStyleSheet("font-size:18pt")
        self.layout.addWidget(self.title)
        self.layout.setSpacing(0)
        self._createButtons()
        self.start = QPoint(0, 0)
        self.mousePressed = False
        self.pressedForParent = False
        self.screenTops = {}
        for screen in self.screens:
            self.screenTops[(
                screen.geometry().x(), screen.geometry().x() +
                screen.geometry().width())] = screen.geometry().y()

    def _createButtons(self) -> None:
        self.buttonsLayout = QHBoxLayout()
        buttonSize = 35

        self.closeButton = QPushButton(chr(0x1f5d9))
        self.closeButton.clicked.connect(self.window.close)
        self.closeButton.setFixedSize(buttonSize, buttonSize)
        self.closeButton.setStyleSheet("QPushButton:!hover {"
                                       "    border-style: none;"
                                       "}"
                                       "QPushButton:hover {"
                                       "    background-color: #ba2d2d;"
                                       "}")

        self.minimizeButton = QPushButton(chr(0x1f5d5))
        self.minimizeButton.clicked.connect(self.window.showMinimized)
        self.minimizeButton.setFixedSize(buttonSize, buttonSize)
        self.minimizeButton.setStyleSheet(minMaxButtonStyle)

        self.maximizeButton = QPushButton(chr(0x1f5d6))
        self.maximizeButton.clicked.connect(self.maximizeButtonClick)
        self.maximizeButton.setFixedSize(buttonSize, buttonSize)
        self.maximizeButton.setStyleSheet(minMaxButtonStyle)

        self.layout.addLayout(self.buttonsLayout)

        self.buttonsLayout.addWidget(self.minimizeButton)
        self.buttonsLayout.addWidget(self.maximizeButton)
        self.buttonsLayout.addWidget(self.closeButton)
        self.buttonsLayout.setAlignment(Qt.AlignRight)

    def maximizeButtonClick(self) -> None:
        if not self.window.isMaximized():
            self.window.showMaximized()
            self.maximizeButton.setText(chr(0x1f5d7))
        elif self.window.isMaximized():
            self.maximizeButton.setText(chr(0x1f5d6))
            self.window.showNormal()

    def mousePressEvent(self, event: QMouseEvent) -> None:
        if event.pos().y() < 5:
            self.pressedForParent = True
            self.window.mousePressEvent(event)
        else:
            self.start = self.mapToGlobal(event.pos())
            self.mousePressed = True

    def mouseReleaseEvent(self, event: QMouseEvent) -> None:
        if self.pressedForParent:
            self.window.mouseReleaseEvent(event)
        self.mousePressed = self.pressedForParent = False

    def mouseDoubleClickEvent(self, event: QMouseEvent) -> None:
        if self.window.isMaximized():
            self.maximizeButton.setText(chr(0x1f5d6))
            self.window.showNormal()
        else:
            self.window.showMaximized()
            self.maximizeButton.setText(chr(0x1f5d7))

    def mouseMoveEvent(self, event: QMouseEvent) -> None:
        if self.pressedForParent:
            self.window.mouseMoveEvent(event)
        elif self.mousePressed:
            for screen in self.screenTops:
                if screen[0] < QCursor().pos().x() < screen[1]:
                    if QCursor().pos().y() == self.screenTops[screen]:
                        if not self.window.isMaximized():
                            self.window.showMaximized()
                            self.maximizeButton.setText(chr(0x1f5d7))
                    elif self.window.isMaximized():
                        self.maximizeButton.setText(chr(0x1f5d6))
                        self.window.showNormal()
                    else:
                        self.end = self.mapToGlobal(event.pos())
                        self.movement = self.end - self.start
                        self.window.setGeometry(
                            self.window.pos().x() + self.movement.x(),
                            self.window.pos().y() + self.movement.y(),
                            self.window.width(), self.window.height())
                        self.start = self.end
示例#43
0
class CoreWidget(QWidget):

    def get_net(self):
        net = set(self.graphWidget.netlistWidget.netlist.netlist().splitlines())
        return net
    net = property(get_net)

    def get_folder(self):
        return self.graphWidget.netlistWidget.netlist.folder
    folder = property(get_folder)

    def get_label(self):
        return self.titleWidget.label
    label = property(get_label)

    def get_status(self):
        return self.titleWidget.status
    status = property(get_status)

    def __init__(self, graphWidget, parent=None):

        super(CoreWidget, self).__init__(parent)

        self.parameters = {'reduce z': False,
                           'substitute': False}

        self.graphWidget = graphWidget

        self.initUI()

    def initUI(self):

        self.core = Core(self.graphWidget.label)

        self.statusSig = BoolSig()
        self.initSig= NoneSig()

        self.dimsLayout = QHBoxLayout()
        self.dimsLayout.setContentsMargins(0, 0, 0, 0)

        self.storageWidget = DescriptionWidget('Storages', '0', 'Dimension of the state vector')
        self.dissipationWidget = DescriptionWidget('Dissipations', '0', 'Dimension of the dissipation vector')
        self.sourceWidget = DescriptionWidget('Ports', '0', 'Dimension of the inpuut/output vectors')

        self.dimsLayout.addWidget(self.storageWidget)
        self.dimsLayout.addWidget(self.dissipationWidget)
        self.dimsLayout.addWidget(self.sourceWidget)
        self.dimsLayout.addStretch()
        self.dimsLayout.setContentsMargins(0, 0, 0, 0)

        self.dimsWidget = QWidget(self)
        self.dimsWidget.setLayout(self.dimsLayout)

        # ---------------------------------------------------------------------
        # Define Core Actions

        self.buttonsLayout = QHBoxLayout()
        self.buttonsLayout.setContentsMargins(0, 0, 0, 0)

        # Build Action
        build_icon = QIcon(os.path.join(iconspath, 'work.png'))
        self.buildAction = QAction(build_icon,
                                 '&Build PHS Core', self)
        self.buildAction.setShortcut('Ctrl+B')
        self.buildAction.setStatusTip('Build Port-Hamiltonian System equations')
        self.buildAction.triggered.connect(self._build)
        self.buildButton = QPushButton(build_icon, '')
        self.buildButton.setToolTip('Build Port-Hamiltonian System equations')
        self.buildButton.clicked.connect(self._build)
        self.buttonsLayout.addWidget(self.buildButton)

        # Latex export Action
        export_icon = QIcon(os.path.join(iconspath, 'latex.png'))
        self.exportAction = QAction(export_icon,
                                    '&Export LaTeX document', self)
        self.exportAction.setShortcut('Ctrl+L')
        self.exportAction.setStatusTip('Export a LaTeX document that describes the Port-Hamiltonian System')
        self.exportAction.triggered.connect(self._writelatex)
        self.exportButton = QPushButton(export_icon, '')
        self.exportButton.setToolTip('Export a LaTeX document')
        self.exportButton.clicked.connect(self._writelatex)
        self.buttonsLayout.addWidget(self.exportButton)

        # ---------------------------------------------------------------------
        # title widget

        title = 'CORE'

        self.labelWidget = QLineEdit(self.core.label)
        self.labelWidget.adjustSize()
        status_labels = {True: 'OK',
                         False: 'Not OK'}

        self.titleWidget = TitleWidget(title=title,
                                       labelWidget=self.labelWidget,
                                       status_labels=status_labels,
                                       buttonsLayout=self.buttonsLayout)

        # ---------------------------------------------------------------------
        # set parameters

        content = {}

        content['reduce z'] = {'desc': 'Reduce linear dissipations into the R-matrix.',
                               'label': 'Reduce z',
                               'value': self.parameters['reduce z'],
                               'type': 'bool'
                               }

        content['substitute'] = {'desc': 'Substitute all symbols by their numerical value.',
                                 'label': 'Substitute',
                                 'value': self.parameters['substitute'],
                                 'type': 'bool'
                                 }
        tooltip = 'Core parameters'

        self.parametersWidget = ParametersWidget('', content, tooltip)

        # ---------------------------------------------------------------------
        # signals
        self.graphWidget.initSig.sig.connect(self._netlist_init)
        self.graphWidget.statusSig.sig.connect(self._status_changed)
        self.parametersWidget.modifiedSig.sig.connect(self._update_parameters)
        self.titleWidget.labelSignal.sig.connect(self._update_label)

    def _update_parameters(self):
        if not self.parameters == self.parametersWidget.parameters:
            self.parameters.update(self.parametersWidget.parameters)
            self._change_status(False)

    def _update(self):
        self.storageWidget.desc.setText(str(self.core.dims.x()))
        self.dissipationWidget.desc.setText(str(self.core.dims.w()))
        self.sourceWidget.desc.setText(str(self.core.dims.y()))

    def _status_changed(self, s=False):
        if not s:
            self._change_status(s)

    def _change_status(self, s=False):
            self.titleWidget._change_status(s)
            self.statusSig.sig.emit(s)

    def _netlist_init(self):
        label = self.graphWidget.label
        self._update_label(label)
        self.initSig.sig.emit()

    def _update_label(self, label):
        if not self.core.label == label:
            self.graphWidget.graph.label = label
            self.core.label = label
            self.titleWidget._change_label(label)

    def _change_label(self, label):
        self.titleWidget._change_label(label)
        self._update_label(label)

    def _build(self):
        if not self.graphWidget.status:
            self.graphWidget._build()

        if self.graphWidget.status:
            self.core = self.graphWidget.graph.to_core(self.core.label)

            if self.parameters['reduce z']:
                self.core.reduce_z()

            if self.parameters['substitute']:
                self.core.substitute(selfall=True)

            self._update()
            self._change_status(True)

    def _writelatex(self):
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        dialog = QFileDialog()
        filename = os.path.join(self.folder, self.label + '.tex')
        dialog.selectFile(filename)
        fileName, _ = dialog.getSaveFileName(self,
                                             "Save LaTeX file as...",
                                             filename,
                                             "All Files (*);;Latex Files (*.tex)",
                                             "Latex Files (*.tex)",
                                             options=options)
        if not fileName == '':
            folder = filename[:filename.rfind(os.sep)]
            content = netlist2tex(self.graphWidget.netlistWidget.netlist)
            content += graphplot2tex(self.graphWidget.graph,
                                     folder=folder)
            content += core2tex(self.core)
            title = self.core.label
            texdocument(content, fileName, title)
示例#44
0
class PlayerControlPanel(QFrame):

    def __init__(self, app, parent=None):
        super().__init__(parent)
        self._app = app

        class IconButton(QPushButton):
            def __init__(self, *args, **kwargs):
                super().__init__(*args, **kwargs)

        self._playback_modes = list(PlaybackMode.__members__.values())
        self._pm_alias_map = {
            PlaybackMode.one_loop: '单曲循环',
            PlaybackMode.sequential: '顺序播放',
            PlaybackMode.loop: '循环播放',
            PlaybackMode.random: '随机播放',
        }
        self.lyric_window = LyricWindow()
        self.lyric_window.hide()

        # initialize sub widgets
        self._layout = QHBoxLayout(self)
        self.previous_btn = IconButton(self)
        self.pp_btn = IconButton(self)
        self.next_btn = IconButton(self)

        #: playback mode switch button
        self.pms_btn = TextButton(self)
        self.volume_btn = VolumeButton(self)
        self.playlist_btn = IconButton(parent=self)
        #: mark song as favorite button
        self.like_btn = LikeButton(self._app, self)
        self.mv_btn = TextButton('MV', self)
        self.toggle_lyric_btn = LyricButton(self._app, self)
        self.download_btn = QPushButton(self)
        self.toggle_watch_btn = WatchButton(self._app, self)
        self.toggle_video_btn = TextButton('△', self)
        # toggle picture-in-picture button
        self.toggle_pip_btn = TextButton('◲', self)

        self.previous_btn.setObjectName('previous_btn')
        self.pp_btn.setObjectName('pp_btn')
        self.next_btn.setObjectName('next_btn')
        self.playlist_btn.setObjectName('playlist_btn')
        self.volume_btn.setObjectName('volume_btn')
        self.pms_btn.setObjectName('pms_btn')
        self.download_btn.setObjectName('download_btn')
        self.like_btn.setObjectName('like_btn')
        self.mv_btn.setObjectName('mv_btn')
        self.toggle_lyric_btn.setObjectName('toggle_lyric_btn')
        self.toggle_video_btn.setObjectName('toggle_video_btn')
        self.toggle_pip_btn.setObjectName('toggle_pip_btn')

        self.progress_slider = ProgressSlider(app=app, parent=self)

        self.pms_btn.setToolTip('修改播放模式')
        self.volume_btn.setToolTip('调整音量')
        self.playlist_btn.setToolTip('显示当前播放列表')

        self.mv_btn.setToolTip('播放 MV')
        self.download_btn.setToolTip('下载歌曲(未实现,欢迎 PR)')
        self.pp_btn.setCheckable(True)
        self.download_btn.setCheckable(True)
        self.toggle_video_btn.hide()
        self.toggle_pip_btn.hide()

        self.song_title_label = SongBriefLabel(self._app)
        self.song_title_label.setAlignment(Qt.AlignCenter)
        self.song_source_label = SourceLabel(self._app, parent=self)

        self.duration_label = DurationLabel(app, parent=self)
        self.position_label = ProgressLabel(app, parent=self)

        # we should enable focus since we want to have shortcut keys
        self.setFocusPolicy(Qt.StrongFocus)
        self.song_source_label.setObjectName('song_source_label')

        self.next_btn.clicked.connect(self._app.playlist.next)
        self.previous_btn.clicked.connect(self._app.playlist.previous)
        self.pp_btn.clicked.connect(self._app.player.toggle)
        self.pms_btn.clicked.connect(self._switch_playback_mode)
        self.volume_btn.change_volume_needed.connect(
            lambda volume: setattr(self._app.player, 'volume', volume))

        player = self._app.player

        player.state_changed.connect(self._on_player_state_changed,
                                     aioqueue=True)
        player.playlist.playback_mode_changed.connect(
            self.on_playback_mode_changed, aioqueue=True)
        player.playlist.song_changed.connect(
            self.on_player_song_changed, aioqueue=True)
        player.media_changed.connect(
            self.on_player_media_changed, aioqueue=True)
        player.volume_changed.connect(self.volume_btn.on_volume_changed)
        self._app.live_lyric.sentence_changed.connect(
            self.lyric_window.set_sentence)
        self.lyric_window.play_previous_needed.connect(player.playlist.previous)
        self.lyric_window.play_next_needed.connect(player.playlist.next)

        self._update_pms_btn_text()
        self._setup_ui()

    def _setup_ui(self):
        # set widget layout
        self.song_source_label.setFixedHeight(20)
        self.progress_slider.setFixedHeight(20)  # half of parent height
        self.position_label.setFixedWidth(50)
        self.duration_label.setFixedWidth(50)
        # on macOS, we should set AlignVCenter flag
        self.position_label.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
        self.like_btn.setFixedSize(15, 15)
        self.download_btn.setFixedSize(15, 15)
        self.download_btn.hide()
        self.mv_btn.setFixedHeight(16)
        self.toggle_lyric_btn.setFixedHeight(16)
        self.toggle_watch_btn.setFixedHeight(16)

        self.progress_slider.setSizePolicy(QSizePolicy.Expanding,
                                           QSizePolicy.Preferred)
        self._sub_layout = QVBoxLayout()
        self._sub_top_layout = QHBoxLayout()

        # add space to make top layout align with progress slider
        self._sub_top_layout.addSpacing(3)
        self._sub_top_layout.addWidget(self.song_source_label)
        self._sub_top_layout.addSpacing(5)
        self._sub_top_layout.addWidget(self.song_title_label)
        self._sub_top_layout.addSpacing(5)
        self._sub_top_layout.addWidget(self.like_btn)
        self._sub_top_layout.addSpacing(8)
        self._sub_top_layout.addWidget(self.mv_btn)
        self._sub_top_layout.addSpacing(8)
        self._sub_top_layout.addWidget(self.toggle_lyric_btn)
        self._sub_top_layout.addSpacing(8)
        self._sub_top_layout.addWidget(self.toggle_watch_btn)
        # self._sub_top_layout.addSpacing(8)
        # self._sub_top_layout.addWidget(self.download_btn)
        self._sub_top_layout.addSpacing(3)

        self._sub_layout.addSpacing(3)
        self._sub_layout.addLayout(self._sub_top_layout)
        self._sub_layout.addWidget(self.progress_slider)

        self._layout.addSpacing(20)
        self._layout.addWidget(self.previous_btn)
        self._layout.addSpacing(8)
        self._layout.addWidget(self.pp_btn)
        self._layout.addSpacing(8)
        self._layout.addWidget(self.next_btn)
        self._layout.addSpacing(26)
        self._layout.addWidget(self.volume_btn)
        # 18 = 200(left_panel_width) - 4 * 30(btn) - 20 - 8 - 8 -26
        self._layout.addSpacing(18)
        self._layout.addStretch(0)
        self._layout.addWidget(self.position_label)
        self._layout.addSpacing(7)
        self._layout.addLayout(self._sub_layout)
        self._layout.setStretchFactor(self._sub_layout, 1)
        self._layout.addSpacing(7)
        self._layout.addWidget(self.duration_label)
        self._layout.addStretch(0)
        self._layout.addSpacing(18)
        self._layout.addWidget(self.pms_btn)
        self._layout.addSpacing(8)
        self._layout.addWidget(self.playlist_btn)
        self._layout.addSpacing(8)
        self._layout.addWidget(self.toggle_video_btn)
        self._layout.addSpacing(8)
        self._layout.addWidget(self.toggle_pip_btn)
        self._layout.addSpacing(18)
        self._layout.setSpacing(0)
        self._layout.setContentsMargins(0, 0, 0, 0)

    def _switch_playback_mode(self):
        playlist = self._app.player.playlist
        pm_total = len(self._playback_modes)
        pm_idx = self._playback_modes.index(playlist.playback_mode)
        if pm_idx < pm_total - 1:
            pm_idx += 1
        else:
            pm_idx = 0
        playlist.playback_mode = self._playback_modes[pm_idx]

    def on_playback_mode_changed(self, playback_mode):
        self._update_pms_btn_text()

    def _update_pms_btn_text(self):
        playback_mode = self._app.player.playlist.playback_mode
        alias = self._pm_alias_map[playback_mode]
        self.pms_btn.setText(alias)

    def on_player_song_changed(self, song):
        if song is None:
            self.song_source_label.setText('歌曲来源')
            self.song_title_label.setText('No song is playing.')
            return
        source_name_map = {p.identifier: p.name
                           for p in self._app.library.list()}
        text = '{} - {}'.format(song.title_display, song.artists_name_display)
        # width -> three button + source label + text <= progress slider
        # three button: 63, source label: 150
        source_name = source_name_map.get(song.source, song.source)
        self.song_source_label.setText(source_name)
        self.song_title_label.setText(text)
        task_spec = self._app.task_mgr.get_or_create('update-mv-btn-status')
        task_spec.bind_coro(self.update_mv_btn_status(song))

    def on_player_media_changed(self, media):
        if media is not None and media.type_ == MediaType.audio:
            metadata = media.metadata
            if metadata.bitrate:
                text = self.song_source_label.text()
                bitrate_text = str(metadata.bitrate) + 'kbps'
                self.song_source_label.setText(
                    '{} - {}'.format(text, bitrate_text))

    async def update_mv_btn_status(self, song):
        song = self._app.library.cast_model_to_v1(song)
        try:
            mv = await async_run(lambda: song.mv)
        except ProviderIOError:
            logger.exception('fetch song mv info failed')
            self.mv_btn.setEnabled(False)
        else:
            if mv:
                self.mv_btn.setToolTip(mv.name)
                self.mv_btn.setEnabled(True)
            else:
                self.mv_btn.setEnabled(False)

    def _on_player_state_changed(self, state):
        self.pp_btn.setChecked(state == State.playing)
示例#45
0
    def __init__(self):
        super(Main, self).__init__()
        self.setupUi(self)

        self.removeButton.clicked.connect(self.OnRemove)
        self.addButton.clicked.connect(lambda: self.OnAddButton())
        self.createSRTButton.clicked.connect(self.CreateSRT)
        self.actionOpen_Video.triggered.connect(self.OpenVideoFile)

        #Modes
        self.actionDark_Mode_2.triggered.connect(
            lambda: self.ToggleDarkMode(self.darkMode))
        self.actionLight_Mode.triggered.connect(self.ToggleLightMode)
        self.actionRed_Palette.triggered.connect(
            lambda: self.ToggleRedMode(self.redMode))
        self.actionBlue_Palette.triggered.connect(
            lambda: self.ToggleBlueMode(self.blueMode))

        #Video
        self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface)

        btnSize = QSize(16, 16)
        videoWidget = QVideoWidget()

        openButton = QPushButton("Abrir Video")
        openButton.setToolTip("Abrir Video")
        openButton.setStatusTip("Abrir Video")
        openButton.setFixedHeight(40)
        openButton.setIconSize(btnSize)
        openButton.setFont(QFont("Noto Sans", 15))
        openButton.setIcon(
            QIcon.fromTheme("document-open", QIcon("D:/_Qt/img/open.png")))
        openButton.clicked.connect(self.open)

        self.playButton = QPushButton()
        self.playButton.setEnabled(False)
        self.playButton.setFixedHeight(65)
        self.playButton.setFixedWidth(60)
        self.playButton.setIconSize(btnSize)
        self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
        self.playButton.clicked.connect(self.play)

        self.positionSlider = QSlider(Qt.Horizontal)
        self.positionSlider.setRange(0, 0)
        self.positionSlider.sliderMoved.connect(self.setPosition)

        self.statusBar = QStatusBar()
        self.statusBar.setFont(QFont("Noto Sans", 7))
        self.statusBar.setFixedHeight(14)

        controlLayout = QHBoxLayout()
        controlLayout.setContentsMargins(0, 0, 0, 0)
        controlLayout.addWidget(openButton)
        controlLayout.addWidget(self.playButton)
        controlLayout.addWidget(self.positionSlider)

        #self.QVideoBoxVLayout = QVBoxLayout()
        self.QVideoBoxVLayout.addWidget(videoWidget)
        self.QVideoBoxVLayout.addLayout(controlLayout)
        self.QVideoBoxVLayout.addWidget(self.statusBar)

        self.setLayout(self.QVideoBoxVLayout)

        self.mediaPlayer.setVideoOutput(videoWidget)
        self.mediaPlayer.stateChanged.connect(self.mediaStateChanged)
        self.mediaPlayer.positionChanged.connect(self.positionChanged)
        self.mediaPlayer.durationChanged.connect(self.durationChanged)
        self.mediaPlayer.error.connect(self.handleError)
        # Every 200 ms
        self.mediaPlayer.setNotifyInterval(200)
        self.translator = google_translator()
        self.statusBar.showMessage("Listo")

        # connect buttons playback
        self.fiveBack.clicked.connect(lambda: self.TimeSkip(5, False))
        self.tenBack.clicked.connect(lambda: self.TimeSkip(10, False))
        self.oneMBack.clicked.connect(lambda: self.TimeSkip(.1, False))
        self.fiveForward.clicked.connect(lambda: self.TimeSkip(5, True))
        self.tenForward.clicked.connect(lambda: self.TimeSkip(10, True))
        self.oneMForward.clicked.connect(lambda: self.TimeSkip(.1, True))

        #Import srt
        self.actionInportar_Subtitulos_srt.triggered.connect(self.ImportSRT)
示例#46
0
class SearchResultsDock(DockWidget):
    """Dock with search results
    """

    onResultsHandledByReplaceThread = pyqtSignal(str, list)

    def __init__(self, parent):
        DockWidget.__init__(self, parent, "&Search Results", QIcon(":/enkiicons/search.png"), "Alt+S")

        # actions
        widget = QWidget(self)

        self._model = searchresultsmodel.SearchResultsModel(self)
        self.onResultsHandledByReplaceThread.connect(self._model.onResultsHandledByReplaceThread)

        self._view = QTreeView(self)
        self._view.setHeaderHidden(True)
        self._view.setUniformRowHeights(True)
        self._view.setModel(self._model)
        self._delegate = HTMLDelegate()
        self._view.setItemDelegate(self._delegate)

        self._layout = QHBoxLayout(widget)
        self._layout.setContentsMargins(5, 5, 5, 5)
        self._layout.setSpacing(5)
        self._layout.addWidget(self._view)

        self.setWidget(widget)
        self.setFocusProxy(self._view)

        # connections
        self._model.firstResultsAvailable.connect(self.show)
        self._view.activated.connect(self._onResultActivated)

        core.actionManager().addAction("mView/aSearchResults", self.showAction())

        self._expandCollapseAll = ExpandCollapseAllButton(self.titleBarWidget(), self._view, self._model)
        self._checkUncheckAll = None

    def terminate(self):
        core.actionManager().removeAction("mView/aSearchResults")

    def _onResultActivated(self, index):
        """Item doubleclicked in the model, opening file
        """
        result = index.internalPointer()
        if isinstance(result, searchresultsmodel.Result):
            fileResults = index.parent().internalPointer()
            core.workspace().goTo(result.fileName,
                                  line=result.line,
                                  column=result.column,
                                  selectionLength=len(result.match.group(0)))
            core.mainWindow().statusBar().showMessage('Match %d of %d' %
                                                      (fileResults.results.index(result) + 1,
                                                       len(fileResults.results)), 3000)
            self.setFocus()

    def clear(self):
        """Clear themselves
        """
        self._model.clear()

    def appendResults(self, fileResultList):
        """Append results. Handler for signal from the search thread
        """
        self._model.appendResults(fileResultList)

    def getCheckedItems(self):
        """Get items, which must be replaced, as dictionary {file name : list of items}
        """
        items = {}

        for fileRes in self._model.fileResults:
            for row, result in enumerate(fileRes.results):
                if result.checkState == Qt.Checked:
                    if result.fileName not in items:
                        items[result.fileName] = []
                    items[result.fileName].append(result)
        return items

    def setReplaceMode(self, enabled):
        """When replace mode is enabled, dock shows checkbox near every item
        """
        self._model.setReplaceMode(enabled)
        if enabled:
            if self._checkUncheckAll is None:
                self._checkUncheckAll = CheckUncheckAllButton(self.titleBarWidget(), self._view, self._model)
            self._checkUncheckAll.show()
        else:
            if self._checkUncheckAll is not None:
                self._checkUncheckAll.hide()

    def matchesCount(self):
        """Get count of matches, stored by the model
        """
        return self._model.matchesCount()
示例#47
0
    def __init__(self, parent: 'ElectrumWindow', config: 'SimpleConfig'):
        WindowModalDialog.__init__(self, parent, _('Preferences'))
        self.config = config
        self.window = parent
        self.need_restart = False
        self.fx = self.window.fx
        self.wallet = self.window.wallet
        
        vbox = QVBoxLayout()
        tabs = QTabWidget()
        gui_widgets = []
        tx_widgets = []
        oa_widgets = []

        # language
        lang_help = _('Select which language is used in the GUI (after restart).')
        lang_label = HelpLabel(_('Language') + ':', lang_help)
        lang_combo = QComboBox()
        lang_combo.addItems(list(languages.values()))
        lang_keys = list(languages.keys())
        lang_cur_setting = self.config.get("language", '')
        try:
            index = lang_keys.index(lang_cur_setting)
        except ValueError:  # not in list
            index = 0
        lang_combo.setCurrentIndex(index)
        if not self.config.is_modifiable('language'):
            for w in [lang_combo, lang_label]: w.setEnabled(False)
        def on_lang(x):
            lang_request = list(languages.keys())[lang_combo.currentIndex()]
            if lang_request != self.config.get('language'):
                self.config.set_key("language", lang_request, True)
                self.need_restart = True
        lang_combo.currentIndexChanged.connect(on_lang)
        gui_widgets.append((lang_label, lang_combo))

        nz_help = _('Number of zeros displayed after the decimal point. For example, if this is set to 2, "1." will be displayed as "1.00"')
        nz_label = HelpLabel(_('Zeros after decimal point') + ':', nz_help)
        nz = QSpinBox()
        nz.setMinimum(0)
        nz.setMaximum(self.config.decimal_point)
        nz.setValue(self.config.num_zeros)
        if not self.config.is_modifiable('num_zeros'):
            for w in [nz, nz_label]: w.setEnabled(False)
        def on_nz():
            value = nz.value()
            if self.config.num_zeros != value:
                self.config.num_zeros = value
                self.config.set_key('num_zeros', value, True)
                self.window.history_list.update()
                self.window.address_list.update()
        nz.valueChanged.connect(on_nz)
        gui_widgets.append((nz_label, nz))

        use_rbf = bool(self.config.get('use_rbf', True))
        use_rbf_cb = QCheckBox(_('Use Replace-By-Fee'))
        use_rbf_cb.setChecked(use_rbf)
        use_rbf_cb.setToolTip(
            _('If you check this box, your transactions will be marked as non-final,') + '\n' + \
            _('and you will have the possibility, while they are unconfirmed, to replace them with transactions that pay higher fees.') + '\n' + \
            _('Note that some merchants do not accept non-final transactions until they are confirmed.'))
        def on_use_rbf(x):
            self.config.set_key('use_rbf', bool(x))
            batch_rbf_cb.setEnabled(bool(x))
        use_rbf_cb.stateChanged.connect(on_use_rbf)
        tx_widgets.append((use_rbf_cb, None))

        batch_rbf_cb = QCheckBox(_('Batch RBF transactions'))
        batch_rbf_cb.setChecked(bool(self.config.get('batch_rbf', False)))
        batch_rbf_cb.setEnabled(use_rbf)
        batch_rbf_cb.setToolTip(
            _('If you check this box, your unconfirmed transactions will be consolidated into a single transaction.') + '\n' + \
            _('This will save fees.'))
        def on_batch_rbf(x):
            self.config.set_key('batch_rbf', bool(x))
        batch_rbf_cb.stateChanged.connect(on_batch_rbf)
        tx_widgets.append((batch_rbf_cb, None))

        # lightning
        lightning_widgets = []

        if self.wallet.lnworker and self.wallet.lnworker.has_deterministic_node_id():
            help_recov = _(messages.MSG_RECOVERABLE_CHANNELS)
            recov_cb = QCheckBox(_("Create recoverable channels"))
            recov_cb.setToolTip(help_recov)
            recov_cb.setChecked(bool(self.config.get('use_recoverable_channels', True)))
            def on_recov_checked(x):
                self.config.set_key('use_recoverable_channels', bool(x))
            recov_cb.stateChanged.connect(on_recov_checked)
            recov_cb.setEnabled(not bool(self.config.get('lightning_listen')))
            lightning_widgets.append((recov_cb, None))

        help_gossip = _("""If this option is enabled, Electrum will download the network
channels graph and compute payment path locally, instead of using trampoline payments. """)
        gossip_cb = QCheckBox(_("Enable gossip (disable trampoline)"))
        gossip_cb.setToolTip(help_gossip)
        gossip_cb.setChecked(bool(self.config.get('use_gossip', False)))
        def on_gossip_checked(x):
            use_gossip = bool(x)
            self.config.set_key('use_gossip', use_gossip)
            if use_gossip:
                self.window.network.start_gossip()
            else:
                self.window.network.run_from_another_thread(
                    self.window.network.stop_gossip())
            util.trigger_callback('ln_gossip_sync_progress')
            # FIXME: update all wallet windows
            util.trigger_callback('channels_updated', self.wallet)
        gossip_cb.stateChanged.connect(on_gossip_checked)
        lightning_widgets.append((gossip_cb, None))

        help_local_wt = _("""If this option is checked, Electrum will
run a local watchtower and protect your channels even if your wallet is not
open. For this to work, your computer needs to be online regularly.""")
        local_wt_cb = QCheckBox(_("Run a local watchtower"))
        local_wt_cb.setToolTip(help_local_wt)
        local_wt_cb.setChecked(bool(self.config.get('run_local_watchtower', False)))
        def on_local_wt_checked(x):
            self.config.set_key('run_local_watchtower', bool(x))
        local_wt_cb.stateChanged.connect(on_local_wt_checked)
        lightning_widgets.append((local_wt_cb, None))

        help_persist = _("""If this option is checked, Electrum will persist after
you close all your wallet windows, and the Electrum icon will be visible in the taskbar.
Use this if you want your local watchtower to keep running after you close your wallet.""")
        persist_cb = QCheckBox(_("Persist after all windows are closed"))
        persist_cb.setToolTip(help_persist)
        persist_cb.setChecked(bool(self.config.get('persist_daemon', False)))
        def on_persist_checked(x):
            self.config.set_key('persist_daemon', bool(x))
        persist_cb.stateChanged.connect(on_persist_checked)
        lightning_widgets.append((persist_cb, None))

        help_remote_wt = _("""To use a remote watchtower, enter the corresponding URL here""")
        remote_wt_cb = QCheckBox(_("Use a remote watchtower"))
        remote_wt_cb.setToolTip(help_remote_wt)
        remote_wt_cb.setChecked(bool(self.config.get('use_watchtower', False)))
        def on_remote_wt_checked(x):
            self.config.set_key('use_watchtower', bool(x))
            self.watchtower_url_e.setEnabled(bool(x))
        remote_wt_cb.stateChanged.connect(on_remote_wt_checked)
        watchtower_url = self.config.get('watchtower_url')
        self.watchtower_url_e = QLineEdit(watchtower_url)
        self.watchtower_url_e.setEnabled(self.config.get('use_watchtower', False))
        def on_wt_url():
            url = self.watchtower_url_e.text() or None
            watchtower_url = self.config.set_key('watchtower_url', url)
        self.watchtower_url_e.editingFinished.connect(on_wt_url)
        lightning_widgets.append((remote_wt_cb, self.watchtower_url_e))

        msg = _('OpenAlias record, used to receive coins and to sign payment requests.') + '\n\n'\
              + _('The following alias providers are available:') + '\n'\
              + '\n'.join(['https://cryptoname.co/', 'http://xmr.link']) + '\n\n'\
              + 'For more information, see https://openalias.org'
        alias_label = HelpLabel(_('OpenAlias') + ':', msg)
        alias = self.config.get('alias','')
        self.alias_e = QLineEdit(alias)
        self.set_alias_color()
        self.alias_e.editingFinished.connect(self.on_alias_edit)
        oa_widgets.append((alias_label, self.alias_e))

        # units
        units = base_units_list
        msg = (_('Base unit of your wallet.')
               + '\n1 BTC = 1000 mBTC. 1 mBTC = 1000 bits. 1 bit = 100 sat.\n'
               + _('This setting affects the Send tab, and all balance related fields.'))
        unit_label = HelpLabel(_('Base unit') + ':', msg)
        unit_combo = QComboBox()
        unit_combo.addItems(units)
        unit_combo.setCurrentIndex(units.index(self.window.base_unit()))
        def on_unit(x, nz):
            unit_result = units[unit_combo.currentIndex()]
            if self.window.base_unit() == unit_result:
                return
            edits = self.window.amount_e, self.window.receive_amount_e
            amounts = [edit.get_amount() for edit in edits]
            self.config.set_base_unit(unit_result)
            nz.setMaximum(self.config.decimal_point)
            self.window.update_tabs()
            for edit, amount in zip(edits, amounts):
                edit.setAmount(amount)
            self.window.update_status()
        unit_combo.currentIndexChanged.connect(lambda x: on_unit(x, nz))
        gui_widgets.append((unit_label, unit_combo))

        system_cameras = qrscanner._find_system_cameras()
        qr_combo = QComboBox()
        qr_combo.addItem("Default","default")
        for camera, device in system_cameras.items():
            qr_combo.addItem(camera, device)
        #combo.addItem("Manually specify a device", config.get("video_device"))
        index = qr_combo.findData(self.config.get("video_device"))
        qr_combo.setCurrentIndex(index)
        msg = _("Install the zbar package to enable this.")
        qr_label = HelpLabel(_('Video Device') + ':', msg)
        qr_combo.setEnabled(qrscanner.libzbar is not None)
        on_video_device = lambda x: self.config.set_key("video_device", qr_combo.itemData(x), True)
        qr_combo.currentIndexChanged.connect(on_video_device)
        gui_widgets.append((qr_label, qr_combo))

        colortheme_combo = QComboBox()
        colortheme_combo.addItem(_('Light'), 'default')
        colortheme_combo.addItem(_('Dark'), 'dark')
        index = colortheme_combo.findData(self.config.get('qt_gui_color_theme', 'default'))
        colortheme_combo.setCurrentIndex(index)
        colortheme_label = QLabel(_('Color theme') + ':')
        def on_colortheme(x):
            self.config.set_key('qt_gui_color_theme', colortheme_combo.itemData(x), True)
            self.need_restart = True
        colortheme_combo.currentIndexChanged.connect(on_colortheme)
        gui_widgets.append((colortheme_label, colortheme_combo))

        updatecheck_cb = QCheckBox(_("Automatically check for software updates"))
        updatecheck_cb.setChecked(bool(self.config.get('check_updates', False)))
        def on_set_updatecheck(v):
            self.config.set_key('check_updates', v == Qt.Checked, save=True)
        updatecheck_cb.stateChanged.connect(on_set_updatecheck)
        gui_widgets.append((updatecheck_cb, None))

        filelogging_cb = QCheckBox(_("Write logs to file"))
        filelogging_cb.setChecked(bool(self.config.get('log_to_file', False)))
        def on_set_filelogging(v):
            self.config.set_key('log_to_file', v == Qt.Checked, save=True)
            self.need_restart = True
        filelogging_cb.stateChanged.connect(on_set_filelogging)
        filelogging_cb.setToolTip(_('Debug logs can be persisted to disk. These are useful for troubleshooting.'))
        gui_widgets.append((filelogging_cb, None))

        preview_cb = QCheckBox(_('Advanced preview'))
        preview_cb.setChecked(bool(self.config.get('advanced_preview', False)))
        preview_cb.setToolTip(_("Open advanced transaction preview dialog when 'Pay' is clicked."))
        def on_preview(x):
            self.config.set_key('advanced_preview', x == Qt.Checked)
        preview_cb.stateChanged.connect(on_preview)
        tx_widgets.append((preview_cb, None))

        usechange_cb = QCheckBox(_('Use change addresses'))
        usechange_cb.setChecked(self.window.wallet.use_change)
        if not self.config.is_modifiable('use_change'): usechange_cb.setEnabled(False)
        def on_usechange(x):
            usechange_result = x == Qt.Checked
            if self.window.wallet.use_change != usechange_result:
                self.window.wallet.use_change = usechange_result
                self.window.wallet.db.put('use_change', self.window.wallet.use_change)
                multiple_cb.setEnabled(self.window.wallet.use_change)
        usechange_cb.stateChanged.connect(on_usechange)
        usechange_cb.setToolTip(_('Using change addresses makes it more difficult for other people to track your transactions.'))
        tx_widgets.append((usechange_cb, None))

        def on_multiple(x):
            multiple = x == Qt.Checked
            if self.wallet.multiple_change != multiple:
                self.wallet.multiple_change = multiple
                self.wallet.db.put('multiple_change', multiple)
        multiple_change = self.wallet.multiple_change
        multiple_cb = QCheckBox(_('Use multiple change addresses'))
        multiple_cb.setEnabled(self.wallet.use_change)
        multiple_cb.setToolTip('\n'.join([
            _('In some cases, use up to 3 change addresses in order to break '
              'up large coin amounts and obfuscate the recipient address.'),
            _('This may result in higher transactions fees.')
        ]))
        multiple_cb.setChecked(multiple_change)
        multiple_cb.stateChanged.connect(on_multiple)
        tx_widgets.append((multiple_cb, None))

        def fmt_docs(key, klass):
            lines = [ln.lstrip(" ") for ln in klass.__doc__.split("\n")]
            return '\n'.join([key, "", " ".join(lines)])

        choosers = sorted(coinchooser.COIN_CHOOSERS.keys())
        if len(choosers) > 1:
            chooser_name = coinchooser.get_name(self.config)
            msg = _('Choose coin (UTXO) selection method.  The following are available:\n\n')
            msg += '\n\n'.join(fmt_docs(*item) for item in coinchooser.COIN_CHOOSERS.items())
            chooser_label = HelpLabel(_('Coin selection') + ':', msg)
            chooser_combo = QComboBox()
            chooser_combo.addItems(choosers)
            i = choosers.index(chooser_name) if chooser_name in choosers else 0
            chooser_combo.setCurrentIndex(i)
            def on_chooser(x):
                chooser_name = choosers[chooser_combo.currentIndex()]
                self.config.set_key('coin_chooser', chooser_name)
            chooser_combo.currentIndexChanged.connect(on_chooser)
            tx_widgets.append((chooser_label, chooser_combo))

        def on_unconf(x):
            self.config.set_key('confirmed_only', bool(x))
        conf_only = bool(self.config.get('confirmed_only', False))
        unconf_cb = QCheckBox(_('Spend only confirmed coins'))
        unconf_cb.setToolTip(_('Spend only confirmed inputs.'))
        unconf_cb.setChecked(conf_only)
        unconf_cb.stateChanged.connect(on_unconf)
        tx_widgets.append((unconf_cb, None))

        def on_outrounding(x):
            self.config.set_key('coin_chooser_output_rounding', bool(x))
        enable_outrounding = bool(self.config.get('coin_chooser_output_rounding', True))
        outrounding_cb = QCheckBox(_('Enable output value rounding'))
        outrounding_cb.setToolTip(
            _('Set the value of the change output so that it has similar precision to the other outputs.') + '\n' +
            _('This might improve your privacy somewhat.') + '\n' +
            _('If enabled, at most 100 satoshis might be lost due to this, per transaction.'))
        outrounding_cb.setChecked(enable_outrounding)
        outrounding_cb.stateChanged.connect(on_outrounding)
        tx_widgets.append((outrounding_cb, None))

        block_explorers = sorted(util.block_explorer_info().keys())
        BLOCK_EX_CUSTOM_ITEM = _("Custom URL")
        if BLOCK_EX_CUSTOM_ITEM in block_explorers:  # malicious translation?
            block_explorers.remove(BLOCK_EX_CUSTOM_ITEM)
        block_explorers.append(BLOCK_EX_CUSTOM_ITEM)
        msg = _('Choose which online block explorer to use for functions that open a web browser')
        block_ex_label = HelpLabel(_('Online Block Explorer') + ':', msg)
        block_ex_combo = QComboBox()
        block_ex_custom_e = QLineEdit(self.config.get('block_explorer_custom') or '')
        block_ex_combo.addItems(block_explorers)
        block_ex_combo.setCurrentIndex(
            block_ex_combo.findText(util.block_explorer(self.config) or BLOCK_EX_CUSTOM_ITEM))
        def showhide_block_ex_custom_e():
            block_ex_custom_e.setVisible(block_ex_combo.currentText() == BLOCK_EX_CUSTOM_ITEM)
        showhide_block_ex_custom_e()
        def on_be_combo(x):
            if block_ex_combo.currentText() == BLOCK_EX_CUSTOM_ITEM:
                on_be_edit()
            else:
                be_result = block_explorers[block_ex_combo.currentIndex()]
                self.config.set_key('block_explorer_custom', None, False)
                self.config.set_key('block_explorer', be_result, True)
            showhide_block_ex_custom_e()
        block_ex_combo.currentIndexChanged.connect(on_be_combo)
        def on_be_edit():
            val = block_ex_custom_e.text()
            try:
                val = ast.literal_eval(val)  # to also accept tuples
            except:
                pass
            self.config.set_key('block_explorer_custom', val)
        block_ex_custom_e.editingFinished.connect(on_be_edit)
        block_ex_hbox = QHBoxLayout()
        block_ex_hbox.setContentsMargins(0, 0, 0, 0)
        block_ex_hbox.setSpacing(0)
        block_ex_hbox.addWidget(block_ex_combo)
        block_ex_hbox.addWidget(block_ex_custom_e)
        block_ex_hbox_w = QWidget()
        block_ex_hbox_w.setLayout(block_ex_hbox)
        tx_widgets.append((block_ex_label, block_ex_hbox_w))

        # Fiat Currency
        hist_checkbox = QCheckBox()
        hist_capgains_checkbox = QCheckBox()
        fiat_address_checkbox = QCheckBox()
        ccy_combo = QComboBox()
        ex_combo = QComboBox()

        def update_currencies():
            if not self.window.fx: return
            currencies = sorted(self.fx.get_currencies(self.fx.get_history_config()))
            ccy_combo.clear()
            ccy_combo.addItems([_('None')] + currencies)
            if self.fx.is_enabled():
                ccy_combo.setCurrentIndex(ccy_combo.findText(self.fx.get_currency()))

        def update_history_cb():
            if not self.fx: return
            hist_checkbox.setChecked(self.fx.get_history_config())
            hist_checkbox.setEnabled(self.fx.is_enabled())

        def update_fiat_address_cb():
            if not self.fx: return
            fiat_address_checkbox.setChecked(self.fx.get_fiat_address_config())

        def update_history_capgains_cb():
            if not self.fx: return
            hist_capgains_checkbox.setChecked(self.fx.get_history_capital_gains_config())
            hist_capgains_checkbox.setEnabled(hist_checkbox.isChecked())

        def update_exchanges():
            if not self.fx: return
            b = self.fx.is_enabled()
            ex_combo.setEnabled(b)
            if b:
                h = self.fx.get_history_config()
                c = self.fx.get_currency()
                exchanges = self.fx.get_exchanges_by_ccy(c, h)
            else:
                exchanges = self.fx.get_exchanges_by_ccy('USD', False)
            ex_combo.blockSignals(True)
            ex_combo.clear()
            ex_combo.addItems(sorted(exchanges))
            ex_combo.setCurrentIndex(ex_combo.findText(self.fx.config_exchange()))
            ex_combo.blockSignals(False)

        def on_currency(hh):
            if not self.fx: return
            b = bool(ccy_combo.currentIndex())
            ccy = str(ccy_combo.currentText()) if b else None
            self.fx.set_enabled(b)
            if b and ccy != self.fx.ccy:
                self.fx.set_currency(ccy)
            update_history_cb()
            update_exchanges()
            self.window.update_fiat()

        def on_exchange(idx):
            exchange = str(ex_combo.currentText())
            if self.fx and self.fx.is_enabled() and exchange and exchange != self.fx.exchange.name():
                self.fx.set_exchange(exchange)

        def on_history(checked):
            if not self.fx: return
            self.fx.set_history_config(checked)
            update_exchanges()
            self.window.history_model.refresh('on_history')
            if self.fx.is_enabled() and checked:
                self.fx.trigger_update()
            update_history_capgains_cb()

        def on_history_capgains(checked):
            if not self.fx: return
            self.fx.set_history_capital_gains_config(checked)
            self.window.history_model.refresh('on_history_capgains')

        def on_fiat_address(checked):
            if not self.fx: return
            self.fx.set_fiat_address_config(checked)
            self.window.address_list.refresh_headers()
            self.window.address_list.update()

        update_currencies()
        update_history_cb()
        update_history_capgains_cb()
        update_fiat_address_cb()
        update_exchanges()
        ccy_combo.currentIndexChanged.connect(on_currency)
        hist_checkbox.stateChanged.connect(on_history)
        hist_capgains_checkbox.stateChanged.connect(on_history_capgains)
        fiat_address_checkbox.stateChanged.connect(on_fiat_address)
        ex_combo.currentIndexChanged.connect(on_exchange)

        fiat_widgets = []
        fiat_widgets.append((QLabel(_('Fiat currency')), ccy_combo))
        fiat_widgets.append((QLabel(_('Source')), ex_combo))
        fiat_widgets.append((QLabel(_('Show history rates')), hist_checkbox))
        fiat_widgets.append((QLabel(_('Show capital gains in history')), hist_capgains_checkbox))
        fiat_widgets.append((QLabel(_('Show Fiat balance for addresses')), fiat_address_checkbox))

        tabs_info = [
            (gui_widgets, _('General')),
            (tx_widgets, _('Transactions')),
            (lightning_widgets, _('Lightning')),
            (fiat_widgets, _('Fiat')),
            (oa_widgets, _('OpenAlias')),
        ]
        for widgets, name in tabs_info:
            tab = QWidget()
            tab_vbox = QVBoxLayout(tab)
            grid = QGridLayout()
            for a,b in widgets:
                i = grid.rowCount()
                if b:
                    if a:
                        grid.addWidget(a, i, 0)
                    grid.addWidget(b, i, 1)
                else:
                    grid.addWidget(a, i, 0, 1, 2)
            tab_vbox.addLayout(grid)
            tab_vbox.addStretch(1)
            tabs.addTab(tab, name)

        vbox.addWidget(tabs)
        vbox.addStretch(1)
        vbox.addLayout(Buttons(CloseButton(self)))
        self.setLayout(vbox)
示例#48
0
    def __init__(self, *args, **kwargs):
        super(TrendPage, self).__init__(*args, **kwargs)
        layout = QHBoxLayout(self)
        layout.setContentsMargins(QMargins(0, 0, 0, 1))
        layout.setSpacing(0)
        self.variety_folded = ScrollFoldedBox()
        self.variety_folded.left_mouse_clicked.connect(self.variety_clicked)
        layout.addWidget(self.variety_folded)
        # 右侧是QTableWidget用于显示数据表信息

        # tableinfo_layout.addWidget(self.data_table)
        # layout.addLayout(tableinfo_layout)
        # 右侧是webView
        r_layout = QVBoxLayout(self)
        self.table_lib_btn = QPushButton("数据库", self, objectName='libBtn')
        self.table_lib_btn.setToolTip("点击查看当前品种数据表")
        self.table_lib_btn.setCursor(Qt.PointingHandCursor)
        self.table_lib_btn.hide()
        self.table_lib_btn.clicked.connect(self.reverse_charts_and_table)
        r_layout.addWidget(self.table_lib_btn, alignment=Qt.AlignLeft)
        self.charts_loader = QWebEngineView(self)
        r_layout.addWidget(self.charts_loader)

        self.data_table = DataTableWidget(self)
        r_layout.addWidget(self.data_table)
        self.data_table.hide()

        layout.addLayout(r_layout)

        self.setLayout(layout)
        # 设置折叠窗的样式
        self.variety_folded.setFoldedStyleSheet("""
        QScrollArea{
            border: none;
        }
        #foldedBox{
            border-right: 1px solid rgb(180, 180, 180);
        }
        #foldedHead{
            background-color: rgb(145,202,182);
            border-bottom: 1px solid rgb(200,200,200);
            border-right: 1px solid rgb(180, 180, 180);
            max-height: 30px;
        }
        #headLabel{
            padding:8px 5px;
            font-weight: bold;
            font-size: 15px;
        }
        #foldedBody{
            background-color: rgb(240, 240, 240);
            border-right: 1px solid rgb(180, 180, 180);
        }
        /*折叠窗内滚动条样式*/
        #foldedBox QScrollBar:vertical{
            width: 5px;
            background: transparent;
        }
        #foldedBox QScrollBar::handle:vertical {
            background: rgba(0, 0, 0, 30);
            width: 5px;
            border-radius: 5px;
            border: none;
        }
        #foldedBox QScrollBar::handle:vertical:hover,QScrollBar::handle:horizontal:hover {
            background: rgba(0, 0, 0, 80);
        }
        """)
        self.setStyleSheet("""
        #libBtn{border:1px solid rgb(200,200,200);border-left:none;color:rgb(254,255,255);background-color:rgb(255,87,87);padding:5px 10px;font-size:14px;font-weight:bold;border-bottom-right-radius:5px}
        #libBtn:hover{color:rgb(15,67,146);font-weight:bold;background-color:rgb(74,247,198)}
        """)
        self.charts_loader.load(QUrl(settings.SERVER_ADDR + 'trend/charts/'))
示例#49
0
class GuiDocViewHeader(QWidget):
    def __init__(self, docViewer):
        QWidget.__init__(self, docViewer)

        logger.debug("Initialising GuiDocViewHeader ...")

        self.mainConf = nw.CONFIG
        self.docViewer = docViewer
        self.theParent = docViewer.theParent
        self.theProject = docViewer.theProject
        self.theTheme = docViewer.theTheme
        self.theHandle = None

        fPx = int(0.9 * self.theTheme.fontPixelSize)
        hSp = self.mainConf.pxInt(6)

        # Main Widget Settings
        self.setAutoFillBackground(True)

        # Title Label
        self.theTitle = QLabel()
        self.theTitle.setText("")
        self.theTitle.setIndent(0)
        self.theTitle.setMargin(0)
        self.theTitle.setContentsMargins(0, 0, 0, 0)
        self.theTitle.setAutoFillBackground(True)
        self.theTitle.setAlignment(Qt.AlignHCenter | Qt.AlignTop)
        self.theTitle.setFixedHeight(fPx)

        lblFont = self.theTitle.font()
        lblFont.setPointSizeF(0.9 * self.theTheme.fontPointSize)
        self.theTitle.setFont(lblFont)

        buttonStyle = (
            "QToolButton {{border: none; background: transparent;}} "
            "QToolButton:hover {{border: none; background: rgba({0},{1},{2},0.2);}}"
        ).format(*self.theTheme.colText)

        # Buttons
        self.backButton = QToolButton(self)
        self.backButton.setIcon(self.theTheme.getIcon("backward"))
        self.backButton.setContentsMargins(0, 0, 0, 0)
        self.backButton.setIconSize(QSize(fPx, fPx))
        self.backButton.setFixedSize(fPx, fPx)
        self.backButton.setStyleSheet(buttonStyle)
        self.backButton.setToolButtonStyle(Qt.ToolButtonIconOnly)
        self.backButton.setVisible(False)
        self.backButton.setToolTip("Go backward")
        self.backButton.clicked.connect(self.docViewer.navBackward)

        self.forwardButton = QToolButton(self)
        self.forwardButton.setIcon(self.theTheme.getIcon("forward"))
        self.forwardButton.setContentsMargins(0, 0, 0, 0)
        self.forwardButton.setIconSize(QSize(fPx, fPx))
        self.forwardButton.setFixedSize(fPx, fPx)
        self.forwardButton.setStyleSheet(buttonStyle)
        self.forwardButton.setToolButtonStyle(Qt.ToolButtonIconOnly)
        self.forwardButton.setVisible(False)
        self.forwardButton.setToolTip("Go forward")
        self.forwardButton.clicked.connect(self.docViewer.navForward)

        self.refreshButton = QToolButton(self)
        self.refreshButton.setIcon(self.theTheme.getIcon("refresh"))
        self.refreshButton.setContentsMargins(0, 0, 0, 0)
        self.refreshButton.setIconSize(QSize(fPx, fPx))
        self.refreshButton.setFixedSize(fPx, fPx)
        self.refreshButton.setStyleSheet(buttonStyle)
        self.refreshButton.setToolButtonStyle(Qt.ToolButtonIconOnly)
        self.refreshButton.setVisible(False)
        self.refreshButton.setToolTip("Reload the document")
        self.refreshButton.clicked.connect(self._refreshDocument)

        self.closeButton = QToolButton(self)
        self.closeButton.setIcon(self.theTheme.getIcon("close"))
        self.closeButton.setContentsMargins(0, 0, 0, 0)
        self.closeButton.setIconSize(QSize(fPx, fPx))
        self.closeButton.setFixedSize(fPx, fPx)
        self.closeButton.setStyleSheet(buttonStyle)
        self.closeButton.setToolButtonStyle(Qt.ToolButtonIconOnly)
        self.closeButton.setVisible(False)
        self.closeButton.setToolTip("Close the document")
        self.closeButton.clicked.connect(self._closeDocument)

        # Assemble Layout
        self.outerBox = QHBoxLayout()
        self.outerBox.setSpacing(hSp)
        self.outerBox.addWidget(self.backButton, 0)
        self.outerBox.addWidget(self.forwardButton, 0)
        self.outerBox.addWidget(self.theTitle, 1)
        self.outerBox.addWidget(self.refreshButton, 0)
        self.outerBox.addWidget(self.closeButton, 0)
        self.setLayout(self.outerBox)

        # Fix Margins and Size
        # This is needed for high DPI systems. See issue #499.
        cM = self.mainConf.pxInt(8)
        self.setContentsMargins(0, 0, 0, 0)
        self.outerBox.setContentsMargins(cM, cM, cM, cM)
        self.setMinimumHeight(fPx + 2 * cM)

        # Fix the Colours
        self.matchColours()

        logger.debug("GuiDocViewHeader initialisation complete")

        return

    ##
    #  Methods
    ##

    def matchColours(self):
        """Update the colours of the widget to match those of the syntax
        theme rather than the main GUI.
        """
        thePalette = QPalette()
        thePalette.setColor(QPalette.Window, QColor(*self.theTheme.colBack))
        thePalette.setColor(QPalette.WindowText,
                            QColor(*self.theTheme.colText))
        thePalette.setColor(QPalette.Text, QColor(*self.theTheme.colText))

        self.setPalette(thePalette)
        self.theTitle.setPalette(thePalette)

        return

    def setTitleFromHandle(self, tHandle):
        """Sets the document title from the handle, or alternatively,
        set the whole document path.
        """
        self.theHandle = tHandle
        if tHandle is None:
            self.theTitle.setText("")
            self.backButton.setVisible(False)
            self.forwardButton.setVisible(False)
            self.closeButton.setVisible(False)
            self.refreshButton.setVisible(False)
            return True

        if self.mainConf.showFullPath:
            tTitle = []
            tTree = self.theProject.projTree.getItemPath(tHandle)
            for aHandle in reversed(tTree):
                nwItem = self.theProject.projTree[aHandle]
                if nwItem is not None:
                    tTitle.append(nwItem.itemName)
            sSep = "  %s  " % nwUnicode.U_RSAQUO
            self.theTitle.setText(sSep.join(tTitle))
        else:
            nwItem = self.theProject.projTree[tHandle]
            if nwItem is None:
                return False
            self.theTitle.setText(nwItem.itemName)

        self.backButton.setVisible(True)
        self.forwardButton.setVisible(True)
        self.closeButton.setVisible(True)
        self.refreshButton.setVisible(True)

        return True

    def updateNavButtons(self, firstIdx, lastIdx, currIdx):
        """Enable and disable nav buttons based on index in history.
        """
        self.backButton.setEnabled(currIdx > firstIdx)
        self.forwardButton.setEnabled(currIdx < lastIdx)
        return

    ##
    #  Slots
    ##

    def _closeDocument(self):
        """Trigger the close editor/viewer on the main window.
        """
        self.theParent.closeDocViewer()
        return

    def _refreshDocument(self):
        """Reload the content of the document.
        """
        if self.docViewer.theHandle == self.theParent.docEditor.theHandle:
            self.theParent.saveDocument()
        self.docViewer.reloadText()
        return

    ##
    #  Events
    ##

    def mousePressEvent(self, theEvent):
        """Capture a click on the title and ensure that the item is
        selected in the project tree.
        """
        self.theParent.treeView.setSelectedHandle(self.theHandle,
                                                  doScroll=True)
        return
示例#50
0
class BlenderLauncher(QMainWindow, BaseWindow, Ui_MainWindow):
    show_signal = pyqtSignal()
    close_signal = pyqtSignal()

    def __init__(self, app):
        super().__init__()
        self.setupUi(self)
        self.setAcceptDrops(True)

        # Server
        self.server = QLocalServer()
        self.server.listen("blender-launcher-server")
        self.server.newConnection.connect(self.new_connection)

        # Global scope
        self.app = app
        self.favorite = None
        self.status = "None"
        self.app_state = AppState.IDLE
        self.cashed_builds = []
        self.notification_pool = []
        self.windows = [self]
        self.manager = PoolManager(200)
        self.timer = None
        self.started = True

        # Setup window
        self.setWindowTitle("Blender Launcher")
        self.app.setWindowIcon(
            QIcon(taskbar_icon_paths[get_taskbar_icon_color()]))

        # Setup font
        QFontDatabase.addApplicationFont(
            ":/resources/fonts/OpenSans-SemiBold.ttf")
        self.font = QFont("Open Sans SemiBold", 10)
        self.font.setHintingPreference(QFont.PreferNoHinting)
        self.app.setFont(self.font)

        # Setup style
        file = QFile(":/resources/styles/global.qss")
        file.open(QFile.ReadOnly | QFile.Text)
        self.style_sheet = QTextStream(file).readAll()
        self.app.setStyleSheet(self.style_sheet)

        # Check library folder
        if is_library_folder_valid() is False:
            self.dlg = DialogWindow(
                self,
                title="Information",
                text="First, choose where Blender\nbuilds will be stored",
                accept_text="Continue",
                cancel_text=None,
                icon=DialogIcon.INFO)
            self.dlg.accepted.connect(self.set_library_folder)
        else:
            self.draw()

    def set_library_folder(self):
        library_folder = Path.cwd().as_posix()
        new_library_folder = QFileDialog.getExistingDirectory(
            self,
            "Select Library Folder",
            library_folder,
            options=QFileDialog.DontUseNativeDialog | QFileDialog.ShowDirsOnly)

        if new_library_folder:
            set_library_folder(new_library_folder)
            self.draw()

    def draw(self):
        self.HeaderLayout = QHBoxLayout()
        self.HeaderLayout.setContentsMargins(1, 1, 1, 0)
        self.HeaderLayout.setSpacing(0)
        self.CentralLayout.addLayout(self.HeaderLayout)

        self.SettingsButton = \
            QPushButton(QIcon(":resources/icons/settings.svg"), "")
        self.SettingsButton.setIconSize(QSize(20, 20))
        self.SettingsButton.setFixedSize(36, 32)
        self.WikiButton = \
            QPushButton(QIcon(":resources/icons/wiki.svg"), "")
        self.WikiButton.setIconSize(QSize(20, 20))
        self.WikiButton.setFixedSize(36, 32)
        self.MinimizeButton = \
            QPushButton(QIcon(":resources/icons/minimize.svg"), "")
        self.MinimizeButton.setIconSize(QSize(20, 20))
        self.MinimizeButton.setFixedSize(36, 32)
        self.CloseButton = \
            QPushButton(QIcon(":resources/icons/close.svg"), "")
        self.CloseButton.setIconSize(QSize(20, 20))
        self.CloseButton.setFixedSize(36, 32)
        self.HeaderLabel = QLabel("Blender Launcher")
        self.HeaderLabel.setAlignment(Qt.AlignCenter)

        self.HeaderLayout.addWidget(self.SettingsButton, 0, Qt.AlignLeft)
        self.HeaderLayout.addWidget(self.WikiButton, 0, Qt.AlignLeft)
        self.HeaderLayout.addWidget(self.HeaderLabel, 1)
        self.HeaderLayout.addWidget(self.MinimizeButton, 0, Qt.AlignRight)
        self.HeaderLayout.addWidget(self.CloseButton, 0, Qt.AlignRight)

        self.SettingsButton.setProperty("HeaderButton", True)
        self.WikiButton.setProperty("HeaderButton", True)
        self.MinimizeButton.setProperty("HeaderButton", True)
        self.CloseButton.setProperty("HeaderButton", True)
        self.CloseButton.setProperty("CloseButton", True)

        # Tab layout
        self.TabWidget = QTabWidget()
        self.CentralLayout.addWidget(self.TabWidget)

        self.LibraryTab = QWidget()
        self.LibraryTabLayout = QVBoxLayout()
        self.LibraryTabLayout.setContentsMargins(0, 0, 0, 0)
        self.LibraryTab.setLayout(self.LibraryTabLayout)
        self.TabWidget.addTab(self.LibraryTab, "Library")

        self.DownloadsTab = QWidget()
        self.DownloadsTabLayout = QVBoxLayout()
        self.DownloadsTabLayout.setContentsMargins(0, 0, 0, 0)
        self.DownloadsTab.setLayout(self.DownloadsTabLayout)
        self.TabWidget.addTab(self.DownloadsTab, "Downloads")

        self.LibraryToolBox = BaseToolBoxWidget(self)

        self.LibraryStableListWidget = \
            self.LibraryToolBox.add_list_widget(
                "Stable Releases", "Nothing to show yet")
        self.LibraryDailyListWidget = \
            self.LibraryToolBox.add_list_widget(
                "Daily Builds", "Nothing to show yet")
        self.LibraryExperimentalListWidget = \
            self.LibraryToolBox.add_list_widget(
                "Experimental Branches", "Nothing to show yet")
        self.LibraryCustomListWidget = \
            self.LibraryToolBox.add_list_widget(
                "Custom Builds", "Nothing to show yet")
        self.LibraryTab.layout().addWidget(self.LibraryToolBox)

        self.DownloadsToolBox = BaseToolBoxWidget(self)

        self.DownloadsStableListWidget = \
            self.DownloadsToolBox.add_list_widget(
                "Stable Releases", "No new builds available", False)
        self.DownloadsDailyListWidget = \
            self.DownloadsToolBox.add_list_widget(
                "Daily Builds", "No new builds available")
        self.DownloadsExperimentalListWidget = \
            self.DownloadsToolBox.add_list_widget(
                "Experimental Branches", "No new builds available")
        self.DownloadsTab.layout().addWidget(self.DownloadsToolBox)

        self.LibraryToolBox.setCurrentIndex(get_default_library_page())

        # Connect buttons
        self.SettingsButton.clicked.connect(self.show_settings_window)
        self.WikiButton.clicked.connect(lambda: webbrowser.open(
            "https://github.com/DotBow/Blender-Launcher/wiki"))
        self.MinimizeButton.clicked.connect(self.showMinimized)
        self.CloseButton.clicked.connect(self.close)

        self.StatusBar.setFont(self.font)
        self.statusbarLabel = QLabel()
        self.statusbarLabel.setIndent(8)
        self.NewVersionButton = QPushButton()
        self.NewVersionButton.hide()
        self.NewVersionButton.clicked.connect(lambda: webbrowser.open(
            "https://github.com/DotBow/Blender-Launcher/releases/latest"))
        self.statusbarVersion = QLabel(self.app.applicationVersion())
        self.StatusBar.addPermanentWidget(self.statusbarLabel, 1)
        self.StatusBar.addPermanentWidget(self.NewVersionButton)
        self.StatusBar.addPermanentWidget(self.statusbarVersion)

        # Draw library
        self.draw_library()

        # Setup tray icon context Menu
        quit_action = QAction("Quit", self)
        quit_action.triggered.connect(self.quit)
        hide_action = QAction("Hide", self)
        hide_action.triggered.connect(self.close)
        show_action = QAction("Show", self)
        show_action.triggered.connect(self._show)
        launch_favorite_action = QAction(
            QIcon(":resources/icons/favorite.svg"), "Blender", self)
        launch_favorite_action.triggered.connect(self.launch_favorite)

        tray_menu = QMenu()
        tray_menu.setFont(self.font)
        tray_menu.addAction(launch_favorite_action)
        tray_menu.addAction(show_action)
        tray_menu.addAction(hide_action)
        tray_menu.addAction(quit_action)

        # Setup tray icon
        self.tray_icon = QSystemTrayIcon(self)
        self.tray_icon.setIcon(
            QIcon(taskbar_icon_paths[get_taskbar_icon_color()]))
        self.tray_icon.setToolTip("Blender Launcher")
        self.tray_icon.activated.connect(self.tray_icon_activated)
        self.tray_icon.setContextMenu(tray_menu)
        self.tray_icon.messageClicked.connect(self._show)
        self.tray_icon.show()

        # Forse style update
        self.style().unpolish(self.app)
        self.style().polish(self.app)

        # Show window
        if get_launch_minimized_to_tray() is False:
            self._show()

    def _show(self):
        self.activateWindow()
        self.show()
        self.set_status()
        self.show_signal.emit()

    def show_message(self, message, value=None):
        if value not in self.notification_pool:
            if value is not None:
                self.notification_pool.append(value)
            self.tray_icon.showMessage(
                "Blender Launcher", message,
                QIcon(taskbar_icon_paths[get_taskbar_icon_color()]), 10000)

    def launch_favorite(self):
        try:
            self.favorite.launch()
        except Exception:
            self.dlg = DialogWindow(self,
                                    text="Favorite build not found!",
                                    accept_text="OK",
                                    cancel_text=None)

    def tray_icon_activated(self, reason):
        if reason == QSystemTrayIcon.Trigger:
            self._show()
        elif reason == QSystemTrayIcon.MiddleClick:
            self.launch_favorite()

    def quit(self):
        download_widgets = []

        download_widgets.extend(self.DownloadsStableListWidget.items())
        download_widgets.extend(self.DownloadsDailyListWidget.items())
        download_widgets.extend(self.DownloadsExperimentalListWidget.items())

        for widget in download_widgets:
            if widget.state == DownloadState.DOWNLOADING:
                self.dlg = DialogWindow(self,
                                        title="Warning",
                                        text="Download task in progress!<br>\
                    Are you sure you want to quit?",
                                        accept_text="Yes",
                                        cancel_text="No",
                                        icon=DialogIcon.WARNING)

                self.dlg.accepted.connect(self.destroy)
                return

        self.destroy()

    def destroy(self):
        if self.timer is not None:
            self.timer.cancel()

        self.tray_icon.hide()
        self.app.quit()

    def draw_library(self, clear=False):
        self.set_status("Reading local builds")

        if clear:
            self.timer.cancel()
            self.scraper.quit()
            self.DownloadsStableListWidget.clear()
            self.DownloadsDailyListWidget.clear()
            self.DownloadsExperimentalListWidget.clear()
            self.started = True

        self.favorite = None

        self.LibraryStableListWidget.clear()
        self.LibraryDailyListWidget.clear()
        self.LibraryExperimentalListWidget.clear()

        self.library_drawer = LibraryDrawer(self)
        self.library_drawer.build_found.connect(self.draw_to_library)
        self.library_drawer.finished.connect(self.draw_downloads)
        self.library_drawer.start()

    def draw_downloads(self):
        for page in self.DownloadsToolBox.pages:
            page.set_info_label_text("Checking for new builds")

        self.app_state = AppState.CHECKINGBUILDS
        self.set_status("Checking for new builds")
        self.scraper = Scraper(self, self.manager)
        self.scraper.links.connect(self.draw_new_builds)
        self.scraper.new_bl_version.connect(self.set_version)
        self.scraper.error.connect(self.connection_error)
        self.scraper.start()

    def connection_error(self):
        set_locale()
        utcnow = strftime(('%H:%M'), localtime())
        self.set_status("Connection Error at " + utcnow)
        self.app_state = AppState.IDLE

        self.timer = threading.Timer(600.0, self.draw_downloads)
        self.timer.start()

    def draw_new_builds(self, builds):
        self.cashed_builds.clear()
        self.cashed_builds.extend(builds)

        library_widgets = []
        download_widgets = []

        library_widgets.extend(self.LibraryStableListWidget.items())
        library_widgets.extend(self.LibraryDailyListWidget.items())
        library_widgets.extend(self.LibraryExperimentalListWidget.items())

        download_widgets.extend(self.DownloadsStableListWidget.items())
        download_widgets.extend(self.DownloadsDailyListWidget.items())
        download_widgets.extend(self.DownloadsExperimentalListWidget.items())

        for widget in download_widgets:
            if widget.build_info in builds:
                builds.remove(widget.build_info)
            elif widget.state != DownloadState.DOWNLOADING:
                widget.destroy()

        for widget in library_widgets:
            if widget.build_info in builds:
                builds.remove(widget.build_info)

        for build_info in builds:
            self.draw_to_downloads(build_info, not self.started)

        if (len(builds) > 0) and (not self.started):
            self.show_message("New builds of Blender is available!")

        set_locale()
        utcnow = strftime(('%H:%M'), localtime())
        self.set_status("Last check at " + utcnow)
        self.app_state = AppState.IDLE

        for page in self.DownloadsToolBox.pages:
            page.set_info_label_text("No new builds available")

        self.timer = threading.Timer(600.0, self.draw_downloads)
        self.timer.start()
        self.started = False

    def draw_from_cashed(self, build_info):
        if self.app_state == AppState.IDLE:
            if build_info in self.cashed_builds:
                i = self.cashed_builds.index(build_info)
                self.draw_to_downloads(self.cashed_builds[i])

    def draw_to_downloads(self, build_info, show_new=False):
        branch = build_info.branch

        if branch == 'stable':
            list_widget = self.DownloadsStableListWidget
        elif branch == 'daily':
            list_widget = self.DownloadsDailyListWidget
        else:
            list_widget = self.DownloadsExperimentalListWidget

        item = BaseListWidgetItem(build_info.commit_time)
        widget = DownloadWidget(self, list_widget, item, build_info, show_new)
        list_widget.add_item(item, widget)

    def draw_to_library(self, path, show_new=False):
        category = Path(path).parent.name

        if category == 'stable':
            list_widget = self.LibraryStableListWidget
        elif category == 'daily':
            list_widget = self.LibraryDailyListWidget
        elif category == 'experimental':
            list_widget = self.LibraryExperimentalListWidget
        elif category == 'custom':
            list_widget = self.LibraryCustomListWidget
        else:
            return

        item = BaseListWidgetItem()
        widget = LibraryWidget(self, item, path, list_widget, show_new)
        list_widget.insert_item(item, widget)

    def set_status(self, status=None):
        if status is not None:
            self.status = status

        self.statusbarLabel.setText("Status: {0}".format(self.status))

    def set_version(self, latest_tag):
        current_tag = self.app.applicationVersion()
        latest_ver = re.sub(r'\D', '', latest_tag)
        current_ver = re.sub(r'\D', '', current_tag)

        if int(latest_ver) > int(current_ver):
            if latest_tag not in self.notification_pool:
                self.NewVersionButton.setText(
                    "New version {0} is available".format(
                        latest_tag.replace('v', '')))
                self.NewVersionButton.show()
                self.show_message(
                    "New version of Blender Launcher is available!",
                    latest_tag)

    def show_settings_window(self):
        self.settings_window = SettingsWindow(self)

    def clear_temp(self):
        temp_folder = Path(get_library_folder()) / ".temp"
        self.remover = Remover(temp_folder)
        self.remover.start()

    def closeEvent(self, event):
        event.ignore()
        self.hide()
        self.close_signal.emit()

    def new_connection(self):
        self._show()

    def dragEnterEvent(self, e):
        if e.mimeData().hasFormat('text/plain'):
            e.accept()
        else:
            e.ignore()

    def dropEvent(self, e):
        print(e.mimeData().text())
示例#51
0
class MainWidget(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent=parent, flags=Qt.WindowFlags())
        self.parent = parent
        self.icon = parent.icon

        self.main_layout = QVBoxLayout()

        self.header_layout = QHBoxLayout()
        self.header_left_layout = QVBoxLayout()
        self.icon_layout = QVBoxLayout()
        self.icon_label = QLabel()
        self.header_right_layout = QVBoxLayout()
        self.app_name = QLabel(__name__.title())
        self.app_version = QLabel(__version__)
        self.author_name = QLabel(f'(c)2018 by {__author__}')

        self.choose_mode = LabeledComboBox(values=('Find and delete orphan files',
                                                   'Delete orphan files'),
                                           label='Choose mode:',
                                           vertical=True)
        self.load_defaults_button = QPushButton('Fill in default values')

        self.specific_layout = QVBoxLayout()
        self.specific_area_stack = QStackedWidget(self)
        self.find_orphans = FindOrphans()
        self.delete_orphans = DeleteOrphans()
        self.variable_area_widgets = (
            self.find_orphans,
            self.delete_orphans,
        )

        self.buttons_layout = QHBoxLayout()
        self.about_button = QPushButton('About...')
        self.cancel_button = QPushButton('Cancel')
        self.ok_button = QPushButton('OK')

        self.init_ui()

    def init_ui(self):
        self.choose_mode.input_widget.currentIndexChanged.connect(self.action_changed)
        self.load_defaults_button.clicked.connect(self.fill_in_default_values)
        self.about_button.clicked.connect(self.open_about)
        self.cancel_button.clicked.connect(self.quit_action)
        self.ok_button.clicked.connect(self.run_action)

        self.main_layout.setContentsMargins(15, 10, 15, 10)
        self.main_layout.addLayout(self.header_layout, 0)
        self.main_layout.addLayout(self.specific_layout, 0)
        self.main_layout.addLayout(self.buttons_layout, 0)
        self.main_layout.addStretch(2)

        self.header_layout.setSpacing(10)
        self.header_layout.addLayout(self.header_left_layout, 2)
        self.header_layout.addLayout(self.icon_layout, 0)
        self.header_layout.addLayout(self.header_right_layout, 0)

        self.header_left_layout.addWidget(self.choose_mode, 0, Qt.AlignBottom)
        self.header_left_layout.addWidget(self.load_defaults_button, 0, Qt.AlignBottom)

        self.icon_layout.setContentsMargins(0, 15, 0, 0)
        self.icon_layout.addWidget(self.icon_label, 0, Qt.AlignBottom)
        self.icon_label.setPixmap(self.icon)
        self.icon_label.setAlignment(Qt.AlignCenter)
        self.icon_label.setFixedWidth(100)
        self.icon_label.setFixedHeight(85)
        self.icon_label.setContentsMargins(75, 75, 75, 150)

        self.header_right_layout.addWidget(self.app_name, 0, Qt.AlignBottom)
        self.header_right_layout.addWidget(self.app_version, 0, Qt.AlignBottom)
        self.header_right_layout.addWidget(self.author_name, 0, Qt.AlignBottom)
        self.app_name.setAlignment(Qt.AlignCenter)
        font = QFont()
        font.setBold(True)
        font.setPointSize(20)
        self.app_name.setFont(font)
        self.app_version.setAlignment(Qt.AlignCenter)
        self.author_name.setAlignment(Qt.AlignCenter)

        self.load_defaults_button.setMinimumWidth(250)
        self.load_defaults_button.setMinimumHeight(40)
        self.load_defaults_button.setStyleSheet("background-color: darkseagreen")

        self.specific_layout.setContentsMargins(0, 0, 0, 0)
        self.specific_layout.setSpacing(0)
        self.specific_layout.addWidget(self.specific_area_stack, Qt.AlignBottom)

        for widget in self.variable_area_widgets:
            self.specific_area_stack.addWidget(widget)

        self.buttons_layout.setContentsMargins(0, 10, 0, 0)
        self.buttons_layout.addStretch(2)
        self.buttons_layout.addWidget(self.about_button, 0, Qt.AlignBottom)
        self.buttons_layout.addWidget(self.cancel_button, 0, Qt.AlignBottom)
        self.buttons_layout.addWidget(self.ok_button, 0, Qt.AlignBottom)

        self.setLayout(self.main_layout)

    def action_changed(self, index):
        self.specific_area_stack.setCurrentIndex(index)
        self.change_defaults_button_status(index)

    def change_defaults_button_status(self, index):
        if index == 1:
            self.load_defaults_button.setEnabled(False)
        else:
            self.load_defaults_button.setEnabled(True)

    def fill_in_default_values(self):
        path_to_prefs_file = zotler.get_prefs_file(silent=True)
        self.find_orphans.path_to_prefs_file.text = path_to_prefs_file

        zotero_home_dir = os.path.join(str(Path.home()), 'Zotero')
        self.find_orphans.path_to_database_file.text = os.path.join(zotero_home_dir,
                                                                    'zotero.sqlite')

    def open_about(self):
        self.parent.about_dialog.show()

    def run_action(self):
        if self.choose_mode.text == 'Find and delete orphan files':
            zotero_prefs = self.find_orphans.path_to_prefs_file.text
            zotero_dbase = self.find_orphans.path_to_database_file.text
            path_to_output_file = self.find_orphans.path_to_output_file.text.strip()

            error_messages = (
                i
                for i in (self.validate_path(zotero_prefs),
                          self.validate_path(zotero_dbase))
                if i is not None
            )

            joined_messages = '\n'.join(error_messages)
            if len(joined_messages) > 0:
                self.show_error_dialog(joined_messages)
            else:
                self.find_orphans_action(zotero_prefs, zotero_dbase, path_to_output_file)

        elif self.choose_mode.text == 'Delete orphan files':
            path_to_orphans_file = self.delete_orphans.path_to_list_of_orphans.text.strip()

            error_message = self.validate_path(path_to_orphans_file)
            if error_message is None:
                self.delete_orphans_action(path_to_orphans_file)
            else:
                self.show_error_dialog(error_message)
        else:
            raise InvalidModeError('Invalid mode\'s been chosen.')

    def find_orphans_action(self, zotero_prefs, zotero_dbase, path_to_output_file):
        orphan_files = zotler.create_set_of_orphans(zotero_dbase, zotero_prefs)

        if path_to_output_file == '':
            _, path_to_output_file = tempfile.mkstemp(prefix='zotler_gui-')

        with open(path_to_output_file, 'w') as output_file:
            print('\n'.join(orphan_files), file=output_file)

        self.delete_orphans_action(path_to_output_file)

    def delete_orphans_action(self, path_to_orphans_file):
        text_dialog = ShowStdinDialog(self, file_path=path_to_orphans_file)
        is_accepted = text_dialog.exec()
        if is_accepted:
            with open(path_to_orphans_file, 'r') as file:
                zotler.remove_files(file.readlines())

        self.quit_action()

    @staticmethod
    def show_error_dialog(joined_messages):
        msg = QMessageBox()
        msg.setIcon(QMessageBox.Critical)
        msg.setWindowTitle('Error')
        msg.setText(joined_messages)
        msg.exec_()

    @staticmethod
    def validate_path(path, is_directory=False, is_existing=True):
        message = None
        if is_existing:
            if not os.path.exists(path):
                message = f'{path} doesn\'t exist'
            elif is_directory and not os.path.isdir(path):
                message = f'{path} is not a directory'
            elif not is_directory and not os.path.isfile(path):
                message = f'{path} is not a file'

        return message

    @staticmethod
    def quit_action():
        QCoreApplication.instance().quit()
示例#52
0
class GuiDocViewFooter(QWidget):
    def __init__(self, docViewer):
        QWidget.__init__(self, docViewer)

        logger.debug("Initialising GuiDocViewFooter ...")

        self.mainConf = nw.CONFIG
        self.docViewer = docViewer
        self.theParent = docViewer.theParent
        self.theTheme = docViewer.theTheme
        self.viewMeta = docViewer.theParent.viewMeta
        self.theHandle = None

        fPx = int(0.9 * self.theTheme.fontPixelSize)
        bSp = self.mainConf.pxInt(2)
        hSp = self.mainConf.pxInt(8)

        # Icons
        stickyOn = self.theTheme.getPixmap("sticky-on", (fPx, fPx))
        stickyOff = self.theTheme.getPixmap("sticky-off", (fPx, fPx))
        stickyIcon = QIcon()
        stickyIcon.addPixmap(stickyOn, QIcon.Normal, QIcon.On)
        stickyIcon.addPixmap(stickyOff, QIcon.Normal, QIcon.Off)

        bulletOn = self.theTheme.getPixmap("bullet-on", (fPx, fPx))
        bulletOff = self.theTheme.getPixmap("bullet-off", (fPx, fPx))
        bulletIcon = QIcon()
        bulletIcon.addPixmap(bulletOn, QIcon.Normal, QIcon.On)
        bulletIcon.addPixmap(bulletOff, QIcon.Normal, QIcon.Off)

        # Main Widget Settings
        self.setContentsMargins(0, 0, 0, 0)
        self.setAutoFillBackground(True)

        buttonStyle = (
            "QToolButton {{border: none; background: transparent;}} "
            "QToolButton:hover {{border: none; background: rgba({0},{1},{2},0.2);}}"
        ).format(*self.theTheme.colText)

        # Show/Hide Details
        self.showHide = QToolButton(self)
        self.showHide.setToolButtonStyle(Qt.ToolButtonIconOnly)
        self.showHide.setStyleSheet(buttonStyle)
        self.showHide.setIcon(self.theTheme.getIcon("reference"))
        self.showHide.setIconSize(QSize(fPx, fPx))
        self.showHide.setFixedSize(QSize(fPx, fPx))
        self.showHide.clicked.connect(self._doShowHide)
        self.showHide.setToolTip("Show/hide the references panel")

        # Sticky Button
        self.stickyRefs = QToolButton(self)
        self.stickyRefs.setCheckable(True)
        self.stickyRefs.setToolButtonStyle(Qt.ToolButtonIconOnly)
        self.stickyRefs.setStyleSheet(buttonStyle)
        self.stickyRefs.setIcon(stickyIcon)
        self.stickyRefs.setIconSize(QSize(fPx, fPx))
        self.stickyRefs.setFixedSize(QSize(fPx, fPx))
        self.stickyRefs.toggled.connect(self._doToggleSticky)
        self.stickyRefs.setToolTip(
            "Activate to freeze the content of the references panel when changing document"
        )

        # Show Comments
        self.showComments = QToolButton(self)
        self.showComments.setCheckable(True)
        self.showComments.setChecked(self.mainConf.viewComments)
        self.showComments.setToolButtonStyle(Qt.ToolButtonIconOnly)
        self.showComments.setStyleSheet(buttonStyle)
        self.showComments.setIcon(bulletIcon)
        self.showComments.setIconSize(QSize(fPx, fPx))
        self.showComments.setFixedSize(QSize(fPx, fPx))
        self.showComments.toggled.connect(self._doToggleComments)
        self.showComments.setToolTip("Show comments")

        # Show Synopsis
        self.showSynopsis = QToolButton(self)
        self.showSynopsis.setCheckable(True)
        self.showSynopsis.setChecked(self.mainConf.viewSynopsis)
        self.showSynopsis.setToolButtonStyle(Qt.ToolButtonIconOnly)
        self.showSynopsis.setStyleSheet(buttonStyle)
        self.showSynopsis.setIcon(bulletIcon)
        self.showSynopsis.setIconSize(QSize(fPx, fPx))
        self.showSynopsis.setFixedSize(QSize(fPx, fPx))
        self.showSynopsis.toggled.connect(self._doToggleSynopsis)
        self.showSynopsis.setToolTip("Show synopsis comments")

        # Labels
        self.lblRefs = QLabel("References")
        self.lblRefs.setBuddy(self.showHide)
        self.lblRefs.setIndent(0)
        self.lblRefs.setMargin(0)
        self.lblRefs.setContentsMargins(0, 0, 0, 0)
        self.lblRefs.setAutoFillBackground(True)
        self.lblRefs.setFixedHeight(fPx)
        self.lblRefs.setAlignment(Qt.AlignLeft | Qt.AlignTop)

        self.lblSticky = QLabel("Sticky")
        self.lblSticky.setBuddy(self.stickyRefs)
        self.lblSticky.setIndent(0)
        self.lblSticky.setMargin(0)
        self.lblSticky.setContentsMargins(0, 0, 0, 0)
        self.lblSticky.setAutoFillBackground(True)
        self.lblSticky.setFixedHeight(fPx)
        self.lblSticky.setAlignment(Qt.AlignLeft | Qt.AlignTop)

        self.lblComments = QLabel("Comments")
        self.lblComments.setBuddy(self.showComments)
        self.lblComments.setIndent(0)
        self.lblComments.setMargin(0)
        self.lblComments.setContentsMargins(0, 0, 0, 0)
        self.lblComments.setAutoFillBackground(True)
        self.lblComments.setFixedHeight(fPx)
        self.lblComments.setAlignment(Qt.AlignLeft | Qt.AlignTop)

        self.lblSynopsis = QLabel("Synopsis")
        self.lblSynopsis.setBuddy(self.showSynopsis)
        self.lblSynopsis.setIndent(0)
        self.lblSynopsis.setMargin(0)
        self.lblSynopsis.setContentsMargins(0, 0, 0, 0)
        self.lblSynopsis.setAutoFillBackground(True)
        self.lblSynopsis.setFixedHeight(fPx)
        self.lblSynopsis.setAlignment(Qt.AlignLeft | Qt.AlignTop)

        lblFont = self.font()
        lblFont.setPointSizeF(0.9 * self.theTheme.fontPointSize)
        self.lblRefs.setFont(lblFont)
        self.lblSticky.setFont(lblFont)
        self.lblComments.setFont(lblFont)
        self.lblSynopsis.setFont(lblFont)

        # Assemble Layout
        self.outerBox = QHBoxLayout()
        self.outerBox.setSpacing(bSp)
        self.outerBox.addWidget(self.showHide, 0)
        self.outerBox.addWidget(self.lblRefs, 0)
        self.outerBox.addSpacing(hSp)
        self.outerBox.addWidget(self.stickyRefs, 0)
        self.outerBox.addWidget(self.lblSticky, 0)
        self.outerBox.addStretch(1)
        self.outerBox.addWidget(self.showComments, 0)
        self.outerBox.addWidget(self.lblComments, 0)
        self.outerBox.addSpacing(hSp)
        self.outerBox.addWidget(self.showSynopsis, 0)
        self.outerBox.addWidget(self.lblSynopsis, 0)
        self.setLayout(self.outerBox)

        # Fix Margins and Size
        # This is needed for high DPI systems. See issue #499.
        cM = self.mainConf.pxInt(8)
        self.setContentsMargins(0, 0, 0, 0)
        self.outerBox.setContentsMargins(cM, cM, cM, cM)
        self.setMinimumHeight(fPx + 2 * cM)

        # Fix the Colours
        self.matchColours()

        logger.debug("GuiDocViewFooter initialisation complete")

        return

    ##
    #  Methods
    ##

    def matchColours(self):
        """Update the colours of the widget to match those of the syntax
        theme rather than the main GUI.
        """
        thePalette = QPalette()
        thePalette.setColor(QPalette.Window, QColor(*self.theTheme.colBack))
        thePalette.setColor(QPalette.WindowText,
                            QColor(*self.theTheme.colText))
        thePalette.setColor(QPalette.Text, QColor(*self.theTheme.colText))

        self.setPalette(thePalette)
        self.lblRefs.setPalette(thePalette)
        self.lblSticky.setPalette(thePalette)
        self.lblComments.setPalette(thePalette)
        self.lblSynopsis.setPalette(thePalette)

        return

    ##
    #  Slots
    ##

    def _doShowHide(self):
        """Toggle the expand/collapse of the panel.
        """
        isVisible = self.viewMeta.isVisible()
        self.viewMeta.setVisible(not isVisible)
        return

    def _doToggleSticky(self, theState):
        """Toggle the sticky flag for the reference panel.
        """
        logger.verbose("Reference sticky is %s" % str(theState))
        self.docViewer.stickyRef = theState
        if not theState and self.docViewer.theHandle is not None:
            self.viewMeta.refreshReferences(self.docViewer.theHandle)
        return

    def _doToggleComments(self, theState):
        """Toggle the view comment button and reload the document.
        """
        self.mainConf.setViewComments(theState)
        self.docViewer.reloadText()
        return

    def _doToggleSynopsis(self, theState):
        """Toggle the view synopsis button and reload the document.
        """
        self.mainConf.setViewSynopsis(theState)
        self.docViewer.reloadText()
        return
示例#53
0
class SettingsWidget(QWidget):
    """Widget to set settings. Capturing/LEDs are live updated"""
    UVLEDSettingsUpdatedSignal    = pyqtSignal()
    ColorLEDSettingsUpdatedSignal = pyqtSignal()
    showSettingsUpdatedSignal     = pyqtSignal()
    captureSettingsUpdatedSignal  = pyqtSignal(str)
    resetSignal                   = pyqtSignal()

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


        self.mainLayout = QVBoxLayout(self)
        self.mainLayout.setContentsMargins(0,0,0,0)

        self.resetting = False #flag to avoid double emission of signals during reset. @TODO find better solution


        ################ buttons ################
        self.buttonsWidget = QWidget(self)
        self.buttonsLayout = QHBoxLayout(self.buttonsWidget)
        self.buttonsLayout.setContentsMargins(0,0,0,0)

        # reset button
        self.resetButton = QPushButton("&Reset")
        self.resetButton.clicked.connect(self.reset)

        # save as default button
        self.saveAsDefaultButton = QPushButton("&Save")
        self.saveAsDefaultButton.clicked.connect(util.saveSettings)

        #OK button
        self.OKButton = QPushButton("&OK")
        self.OKButton.setDefault(True)


        self.buttonsLayout.addWidget(self.saveAsDefaultButton)
        self.buttonsLayout.addWidget(self.resetButton)
        self.buttonsLayout.addWidget(self.OKButton)


        ###################### tabs ################
        self.tabs = QTabWidget(self)
        self.tabs.setStyleSheet(f"QTabWidget::tab-bar {{alignment: center;}} .QTabBar::tab {{height: 50px; width: {int(320/3)}px;}}")

        #######--------> Color <--------#######
        self.ColorTab = QWidget(self.tabs)
        self.tabs.addTab(self.ColorTab, "Color")
        self.ColorLayout = QGridLayout(self.ColorTab)

        # sliders and labels#
        self.ColorSliders = {}
        self.ColorLabels  = {}
        #### LED #####
        for i, name in enumerate(["Red", "Green", "Blue", "Brigh"]):
            slid  = QSlider(Qt.Vertical)

            slid.setMaximum(255)
            slid.setValue(constants.settings["Color"][f"LED_{name}"])
            slid.valueChanged.connect(self.updateLEDColors)

            label = QLabel(f"{name}\n{slid.value()}"  , alignment = Qt.AlignCenter)

            self.ColorLayout.addWidget(label, 0, i)
            self.ColorLayout.addWidget(slid , 1, i)

            self.ColorSliders[name] = slid
            self.ColorLabels [name] = label

        #### capture #####
        slid  = util.IntervalSlider(Qt.Vertical, maxValue = 1000, interval = 25)
        slid.setValue(constants.settings["Color"]["exposureTime"])
        label = QLabel(f"Exp\n{slid.value()}"  , alignment = Qt.AlignCenter)
        slid.valueChanged.connect(lambda val, label = label: label.setText(f"Exp\n{val}"))
        slid.sliderReleased.connect(lambda : self.updateExposure("Color"))

        self.ColorLayout.addWidget(label, 0, len(self.ColorSliders))
        self.ColorLayout.addWidget(slid , 1, len(self.ColorSliders))

        self.ColorSliders["Exp"] = slid
        self.ColorLabels ["Exp"] = label

        #######--------> UV <--------#######
        self.UVTab = QWidget(self.tabs)
        self.tabs.addTab(self.UVTab, "UV")
        self.UVLayout = QGridLayout(self.UVTab)

        # sliders and labels#
        self.UVSliders = {}
        self.UVLabels  = {}
        #### LED #####
        slid  = QSlider(Qt.Vertical)

        slid.setMaximum(100)
        slid.setValue(constants.settings["Color"]["LED_Brigh"])
        slid.valueChanged.connect(self.updateLEDUV)

        label = QLabel(f"Brigh\n{slid.value()}"  , alignment = Qt.AlignCenter)

        self.UVLayout.addWidget(label, 0, 0)
        self.UVLayout.addWidget(slid , 1, 0)

        self.UVSliders["Brigh"] = slid
        self.UVLabels ["Brigh"] = label

        #### capture #####
        slid  = util.IntervalSlider(Qt.Vertical, maxValue = 6000, interval = 100)
        slid.setValue(constants.settings["UV"]["exposureTime"])
        label = QLabel(f"Exp\n{slid.value()}"  , alignment = Qt.AlignCenter)
        slid.valueChanged.connect(lambda val, label = label: label.setText(f"Exp\n{val}"))
        slid.sliderReleased.connect(lambda : self.updateExposure("UV"))

        self.UVLayout.addWidget(label, 0, 1)
        self.UVLayout.addWidget(slid , 1, 1)

        self.UVSliders["Exp"] = slid
        self.UVLabels ["Exp"] = label

        #######--------> show <--------#######
        self.showTab = QWidget(self.tabs)
        self.tabs.addTab(self.showTab, "Show")
        self.showLayout = QVBoxLayout(self.showTab)

        self.showColorCheckboxes = {}
        for i, name in enumerate(["Red", "Green", "Blue"]):
            widget = QWidget(self.showTab)
            layout = QHBoxLayout(widget)
            layout.setContentsMargins(0,0,0,0)

            label = QLabel(f"Show {name}", widget)
            # label.setFixedWidth(150)
            layout.addWidget(label)

            checkbox = QCheckBox(widget)
            checkbox.setChecked(constants.settings["show"][name])
            checkbox.setStyleSheet("QCheckBox::indicator { width:50px; height: 50px;}")
            checkbox.stateChanged.connect(self.updateShow)
            layout.addWidget(checkbox)

            self.showLayout.addWidget(widget)
            self.showColorCheckboxes[name] = checkbox

        self.showLayout.addStretch()

        #@TODO move up
        self.mainLayout.addWidget(self.tabs)
        self.mainLayout.addWidget(self.buttonsWidget)



    def reset(self):
        """Reset settings."""
        util.loadSettings()

        # block signals while resetting gui buttons to avoid double emission of signals
        self.resetting = True
        # self.blockSignals(True)

        #reset slider, labels and checkboxes
        for name in ["Red", "Green", "Blue", "Brigh"]:
            self.ColorSliders[name].setValue(constants.settings["Color"][f"LED_{name}"])
            self.ColorLabels [name].setText(f"{name}\n{constants.settings['Color'][f'LED_{name}']}")
        self.ColorSliders["Exp"].setValue(constants.settings["Color"]["exposureTime"])
        self.ColorLabels ["Exp"].setText(f"Exp\n{constants.settings['Color']['exposureTime']}")

        self.UVSliders["Brigh"].setValue(constants.settings["UV"]["LED_Brigh"])
        self.UVLabels ["Brigh"].setText(f"Brigh\n{constants.settings['UV']['LED_Brigh']}")
        self.UVSliders["Exp"].setValue(constants.settings["UV"]["exposureTime"])
        self.UVLabels ["Exp"].setText(f"Exp\n{constants.settings['UV']['exposureTime']}")

        for name, checkbox in self.showColorCheckboxes.items():
            checkbox.setChecked(constants.settings["show"][name])

        # self.blockSignals(False)
        self.resetting = False
        self.resetSignal.emit()

    def updateLEDColors(self):
        if self.resetting: return
        for name in ["Red", "Green", "Blue", "Brigh"]:
            constants.settings["Color"][f"LED_{name}"] = self.ColorSliders[name].value()
            self.ColorLabels[name].setText(f"{name}\n{constants.settings['Color'][f'LED_{name}']}")
        self.ColorLEDSettingsUpdatedSignal.emit()

    def updateLEDUV(self):
        if self.resetting: return
        constants.settings["UV"]["LED_Brigh"] = self.UVSliders["Brigh"].value()
        self.UVLabels ["Brigh"].setText(f"Brigh\n{constants.settings['UV']['LED_Brigh']}")
        self.UVLEDSettingsUpdatedSignal.emit()

    def updateExposure(self, name):
        """:param str name: Color or UV """
        if self.resetting: return
        if   name == "Color":     constants.settings[name]["exposureTime"] = self.ColorSliders["Exp"].value()
        elif name == "UV":        constants.settings[name]["exposureTime"] = self.UVSliders   ["Exp"].value()
        self.captureSettingsUpdatedSignal.emit(name)

    def updateShow(self):
        """Show mode updated"""
        if self.resetting: return
        for name, checkbox in self.showColorCheckboxes.items():
            constants.settings["show"][name] = checkbox.isChecked()
        self.showSettingsUpdatedSignal.emit()
class QRangeSlider(QWidget, Ui_Form):
    """
    The QRangeSlider class implements a horizontal range slider widget.
    Inherits QWidget.
    Methods
        * __init__ (self, QWidget parent = None)
        * bool drawValues (self)
        * int end (self)
        * (int, int) getRange (self)
        * int max (self)
        * int min (self)
        * int start (self)
        * setBackgroundStyle (self, QString styleSheet)
        * setDrawValues (self, bool draw)
        * setEnd (self, int end)
        * setStart (self, int start)
        * setRange (self, int start, int end)
        * setSpanStyle (self, QString styleSheet)
    Signals
        * endValueChanged (int)
        * maxValueChanged (int)
        * minValueChanged (int)
        * startValueChanged (int)
    Customizing QRangeSlider
    You can style the range slider as below:
    ::
        QRangeSlider * {
            border: 0px;
            padding: 0px;
        }
        QRangeSlider #Head {
            background: #222;
        }
        QRangeSlider #Span {
            background: #393;
        }
        QRangeSlider #Span:active {
            background: #282;
        }
        QRangeSlider #Tail {
            background: #222;
        }
    Styling the range slider handles follows QSplitter options:
    ::
        QRangeSlider > QSplitter::handle {
            background: #393;
        }
        QRangeSlider > QSplitter::handle:vertical {
            height: 4px;
        }
        QRangeSlider > QSplitter::handle:pressed {
            background: #ca5;
        }
    """
    endValueChanged = QtCore.pyqtSignal(int)
    maxValueChanged = QtCore.pyqtSignal(int)
    minValueChanged = QtCore.pyqtSignal(int)
    startValueChanged = QtCore.pyqtSignal(int)

    # define splitter indices
    _SPLIT_START = 1
    _SPLIT_END = 2

    def __init__(self,
                 parent=None,
                 currentRowCount=currentRowCount,
                 current_frame=current_frame,
                 total_frame=total_frame):
        """Create a new QRangeSlider instance.
            :param parent: QWidget parent
            :return: New QRangeSlider instance.
        """
        super(QRangeSlider, self).__init__(parent)
        self.setupUi(self)
        self.setMouseTracking(False)

        self._splitter.splitterMoved.connect(self._handleMoveSplitter)

        # head layout
        self._head_layout = QHBoxLayout()
        self._head_layout.setSpacing(0)
        self._head_layout.setContentsMargins(0, 0, 0, 0)
        self._head.setLayout(self._head_layout)
        self.head = Head(self._head, main=self)
        self._head_layout.addWidget(self.head)

        # handle layout
        self._handle_layout = QHBoxLayout()
        self._handle_layout.setSpacing(0)
        self._handle_layout.setContentsMargins(0, 0, 0, 0)
        self._handle.setLayout(self._handle_layout)
        self.handle = Handle(self._handle, main=self)
        self.handle.setTextColor((150, 255, 150))
        self._handle_layout.addWidget(self.handle)

        # tail layout
        self._tail_layout = QHBoxLayout()
        self._tail_layout.setSpacing(0)
        self._tail_layout.setContentsMargins(0, 0, 0, 0)
        self._tail.setLayout(self._tail_layout)
        self.tail = Tail(self._tail, main=self)
        self._tail_layout.addWidget(self.tail)

        # defaults
        self.setMin(0)
        self.setMax(total_frame)
        self.setStart(current_frame)
        self.setEnd(current_frame + 30)
        # Enabling the text of current frame in _splitters
        self.setDrawValues(True)

        # undo list
        self.commandList = UndoList.getInstance()

    def min(self):
        """:return: minimum value"""
        return getattr(self, '__min', None)

    def max(self):
        """:return: maximum value"""
        return getattr(self, '__max', None)

    def setMin(self, value):
        """sets minimum value"""
        assert type(value) is int
        setattr(self, '__min', value)
        self.minValueChanged.emit(value)
        # print("setMin", value)

    def setMax(self, value):
        """sets maximum value"""
        assert type(value) is int
        setattr(self, '__max', value)
        self.maxValueChanged.emit(value)
        # print("setMax", value)

    def start(self):
        """:return: range slider start value"""
        return getattr(self, '__start', None)

    def end(self):
        """:return: range slider end value"""
        return getattr(self, '__end', None)

    def _setStart(self, value):
        """stores the start value only"""
        setattr(self, '__start', value)
        self.startValueChanged.emit(value)

    def setStart(self, value):
        """sets the range slider start value"""
        assert type(value) is int
        v = self._valueToPos(value)
        self._splitter.splitterMoved.disconnect()
        self._splitter.moveSplitter(v, self._SPLIT_START)
        self._splitter.splitterMoved.connect(self._handleMoveSplitter)
        self._setStart(value)

    def _setEnd(self, value):
        """stores the end value only"""
        setattr(self, '__end', value)
        self.endValueChanged.emit(value)
        # print("_setEnd", value)

    def setEnd(self, value):
        """set the range slider end value"""
        assert type(value) is int
        v = self._valueToPos(value)
        self._splitter.splitterMoved.disconnect()
        self._splitter.moveSplitter(v, self._SPLIT_END)
        self._splitter.splitterMoved.connect(self._handleMoveSplitter)
        self._setEnd(value)

    def drawValues(self):
        """:return: True if slider values will be drawn"""
        return getattr(self, '__drawValues', None)

    def setDrawValues(self, draw):
        """sets draw values boolean to draw slider values"""
        assert type(draw) is bool
        setattr(self, '__drawValues', draw)

    def getRange(self):
        """:return: the start and end values as a tuple"""
        return (self.start(), self.end())

    def setRange(self, start, end):
        """set the start and end values"""
        self.setStart(start)
        self.setEnd(end)

    def setBackgroundStyle(self, style):
        """sets background style"""
        self._tail.setStyleSheet(style)
        self._head.setStyleSheet(style)

    def setSpanStyle(self, style):
        """sets range span handle style"""
        self._handle.setStyleSheet(style)

    def _valueToPos(self, value):
        """converts slider value to local pixel x coord"""
        # print("valtopos")
        return scale(value, (self.min(), self.max()), (0, self.width()))

    def _posToValue(self, xpos):
        """converts local pixel x coord to slider value"""
        # print("postoval",self.width())
        return scale(xpos, (0, self.width()), (self.min(), self.max()))

    def _handleMoveSplitter(self, xpos, index):
        """private method for handling moving splitter handles"""
        hw = self._splitter.handleWidth()

        # print(hw)

        def _lockWidth(widget):
            width = widget.size().width()
            widget.setMinimumWidth(width)
            widget.setMaximumWidth(width)
            # print("_lockWidth",width)

        def _unlockWidth(widget):
            widget.setMinimumWidth(0)
            widget.setMaximumWidth(16777215)

        v = self._posToValue(xpos)

        if index == self._SPLIT_START:
            _lockWidth(self._tail)
            if v >= self.end():
                return

            offset = -20
            w = xpos + offset
            last = self.start()
            self._setStart(v)
            self.commandList.stack.push(
                TrackActionCommand(last, self.end(), self.start(), self))

        elif index == self._SPLIT_END:
            _lockWidth(self._head)
            if v <= self.start():
                return

            offset = -40
            w = self.width() - xpos + offset
            last = self.end()
            self._setEnd(v)
            self.commandList.stack.push(
                TrackActionCommand(last, self.end(), self.start(), self))

        _unlockWidth(self._tail)
        _unlockWidth(self._head)
        _unlockWidth(self._handle)
示例#55
0
文件: Polo.py 项目: JamesWrigley/Polo
    def __init__(self):
        """
        Constructor for the main application class. Creates the GUI and sets up
        the initial state.
        """
        super().__init__()

        self.player_thread = threading.Thread()
        self.output_screen_size = 32

        # Center master window
        self.resize(400, 200)
        self.center_widget(self, 0)

        # Create widgets
        self.display_widget = DisplayWidget()
        self.media_preview_stack = QStackedWidget()
        open_button = QPushButton("Open")
        clear_button = QPushButton("Clear")
        next_button = QPushButton(QIcon("next.svg"), "")
        previous_button = QPushButton(QIcon("previous.svg"), "")
        preview_label = QLabel()

        self.nav_widget = QWidget()
        self.size_widget = QWidget()
        self.size_checkbox = QCheckBox("Autosize")
        size_lineedit = QLineEdit(str(self.output_screen_size))

        # Configure
        preview_label.setScaledContents(True)
        preview_label.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored)
        open_button.setToolTip("Choose a media file to display")
        clear_button.setToolTip(
            "Clear the current media and turn off the display")
        size_lineedit.setInputMask("D0 \\i\\n")
        self.nav_widget.setEnabled(False)
        self.media_preview_stack.addWidget(QSvgWidget("blank.svg"))
        self.media_preview_stack.addWidget(preview_label)
        self.display_widget.setScaledContents(True)
        self.display_widget.setStyleSheet("background-color: rgb(20, 20, 20);")
        self.display_widget.closed.connect(self.close)
        self.size_checkbox.setChecked(True)
        self.size_checkbox.setEnabled(False)
        self.size_checkbox.setToolTip(
            "Use automatic screen dimensions for drawing")

        # Set up connections
        open_button.clicked.connect(self.choose_media)
        clear_button.clicked.connect(self.clear_media)
        next_button.clicked.connect(lambda: self.advance_media(1))
        previous_button.clicked.connect(lambda: self.advance_media(-1))
        size_lineedit.editingFinished.connect(self.size_changed)
        self.size_checkbox.stateChanged.connect(self.set_dimensions_visibility)

        # Set shortcuts
        makeShortcut = lambda hotkey: QShortcut(
            QKeySequence(hotkey), self, context=Qt.ApplicationShortcut)
        open_shortcut = makeShortcut("O")
        clear_shortcut = makeShortcut("C")
        close_shortcut = makeShortcut("Ctrl+Q")
        self.next_shortcut = makeShortcut("N")
        self.previous_shortcut = makeShortcut("P")
        self.dimensions_shortcut = makeShortcut("A")
        self.next_shortcut.setEnabled(False)
        self.previous_shortcut.setEnabled(False)
        self.dimensions_shortcut.setEnabled(False)

        open_shortcut.activated.connect(self.choose_media)
        clear_shortcut.activated.connect(self.clear_media)
        close_shortcut.activated.connect(self.close)
        self.next_shortcut.activated.connect(lambda: self.advance_media(1))
        self.previous_shortcut.activated.connect(
            lambda: self.advance_media(-1))
        self.dimensions_shortcut.activated.connect(self.size_checkbox.toggle)

        # Pack layouts
        vbox = QVBoxLayout()
        hbox = QHBoxLayout()
        nav_hbox = QHBoxLayout()
        size_hbox = QHBoxLayout()

        nav_hbox.addWidget(previous_button)
        nav_hbox.addWidget(next_button)

        size_hbox.addWidget(QLabel("Size:"))
        size_hbox.addWidget(size_lineedit)

        vbox.addWidget(open_button)
        vbox.addWidget(clear_button)
        vbox.addWidget(self.nav_widget)
        vbox.addWidget(self.size_checkbox)
        vbox.addWidget(self.size_widget)
        vbox.addStretch()

        hbox.addLayout(vbox)
        hbox.addWidget(self.media_preview_stack)

        hbox.setSpacing(20)
        hbox.setContentsMargins(20, 20, 20, 20)
        vbox.setSpacing(10)

        nav_hbox.setContentsMargins(0, 0, 0, 0)
        size_hbox.setContentsMargins(0, 0, 0, 0)
        self.nav_widget.setLayout(nav_hbox)
        self.size_widget.setLayout(size_hbox)

        # Create slave window
        desktop_widget = QDesktopWidget()
        if desktop_widget.screenCount() != 2:
            QMessageBox.warning(self, "Warning", "Cannot find a second screen, " \
                                                 "display will be on primary screen.")
            self.display_widget.showMaximized()
        else:
            self.center_widget(self.display_widget, 1)
            self.display_widget.showFullScreen()

        # Set default values in the screen dimension widgets
        display_geometry = desktop_widget.screenGeometry(self.display_widget)
        self.size_widget.hide()

        self.display_widget.setWindowTitle("Polo - Display")

        self.setLayout(hbox)
        self.setWindowTitle("Polo")
        self.show()
示例#56
0
    def __init__(self, parent = None):
        super(SettingsWidget, self).__init__(parent)


        self.mainLayout = QVBoxLayout(self)
        self.mainLayout.setContentsMargins(0,0,0,0)

        self.resetting = False #flag to avoid double emission of signals during reset. @TODO find better solution


        ################ buttons ################
        self.buttonsWidget = QWidget(self)
        self.buttonsLayout = QHBoxLayout(self.buttonsWidget)
        self.buttonsLayout.setContentsMargins(0,0,0,0)

        # reset button
        self.resetButton = QPushButton("&Reset")
        self.resetButton.clicked.connect(self.reset)

        # save as default button
        self.saveAsDefaultButton = QPushButton("&Save")
        self.saveAsDefaultButton.clicked.connect(util.saveSettings)

        #OK button
        self.OKButton = QPushButton("&OK")
        self.OKButton.setDefault(True)


        self.buttonsLayout.addWidget(self.saveAsDefaultButton)
        self.buttonsLayout.addWidget(self.resetButton)
        self.buttonsLayout.addWidget(self.OKButton)


        ###################### tabs ################
        self.tabs = QTabWidget(self)
        self.tabs.setStyleSheet(f"QTabWidget::tab-bar {{alignment: center;}} .QTabBar::tab {{height: 50px; width: {int(320/3)}px;}}")

        #######--------> Color <--------#######
        self.ColorTab = QWidget(self.tabs)
        self.tabs.addTab(self.ColorTab, "Color")
        self.ColorLayout = QGridLayout(self.ColorTab)

        # sliders and labels#
        self.ColorSliders = {}
        self.ColorLabels  = {}
        #### LED #####
        for i, name in enumerate(["Red", "Green", "Blue", "Brigh"]):
            slid  = QSlider(Qt.Vertical)

            slid.setMaximum(255)
            slid.setValue(constants.settings["Color"][f"LED_{name}"])
            slid.valueChanged.connect(self.updateLEDColors)

            label = QLabel(f"{name}\n{slid.value()}"  , alignment = Qt.AlignCenter)

            self.ColorLayout.addWidget(label, 0, i)
            self.ColorLayout.addWidget(slid , 1, i)

            self.ColorSliders[name] = slid
            self.ColorLabels [name] = label

        #### capture #####
        slid  = util.IntervalSlider(Qt.Vertical, maxValue = 1000, interval = 25)
        slid.setValue(constants.settings["Color"]["exposureTime"])
        label = QLabel(f"Exp\n{slid.value()}"  , alignment = Qt.AlignCenter)
        slid.valueChanged.connect(lambda val, label = label: label.setText(f"Exp\n{val}"))
        slid.sliderReleased.connect(lambda : self.updateExposure("Color"))

        self.ColorLayout.addWidget(label, 0, len(self.ColorSliders))
        self.ColorLayout.addWidget(slid , 1, len(self.ColorSliders))

        self.ColorSliders["Exp"] = slid
        self.ColorLabels ["Exp"] = label

        #######--------> UV <--------#######
        self.UVTab = QWidget(self.tabs)
        self.tabs.addTab(self.UVTab, "UV")
        self.UVLayout = QGridLayout(self.UVTab)

        # sliders and labels#
        self.UVSliders = {}
        self.UVLabels  = {}
        #### LED #####
        slid  = QSlider(Qt.Vertical)

        slid.setMaximum(100)
        slid.setValue(constants.settings["Color"]["LED_Brigh"])
        slid.valueChanged.connect(self.updateLEDUV)

        label = QLabel(f"Brigh\n{slid.value()}"  , alignment = Qt.AlignCenter)

        self.UVLayout.addWidget(label, 0, 0)
        self.UVLayout.addWidget(slid , 1, 0)

        self.UVSliders["Brigh"] = slid
        self.UVLabels ["Brigh"] = label

        #### capture #####
        slid  = util.IntervalSlider(Qt.Vertical, maxValue = 6000, interval = 100)
        slid.setValue(constants.settings["UV"]["exposureTime"])
        label = QLabel(f"Exp\n{slid.value()}"  , alignment = Qt.AlignCenter)
        slid.valueChanged.connect(lambda val, label = label: label.setText(f"Exp\n{val}"))
        slid.sliderReleased.connect(lambda : self.updateExposure("UV"))

        self.UVLayout.addWidget(label, 0, 1)
        self.UVLayout.addWidget(slid , 1, 1)

        self.UVSliders["Exp"] = slid
        self.UVLabels ["Exp"] = label

        #######--------> show <--------#######
        self.showTab = QWidget(self.tabs)
        self.tabs.addTab(self.showTab, "Show")
        self.showLayout = QVBoxLayout(self.showTab)

        self.showColorCheckboxes = {}
        for i, name in enumerate(["Red", "Green", "Blue"]):
            widget = QWidget(self.showTab)
            layout = QHBoxLayout(widget)
            layout.setContentsMargins(0,0,0,0)

            label = QLabel(f"Show {name}", widget)
            # label.setFixedWidth(150)
            layout.addWidget(label)

            checkbox = QCheckBox(widget)
            checkbox.setChecked(constants.settings["show"][name])
            checkbox.setStyleSheet("QCheckBox::indicator { width:50px; height: 50px;}")
            checkbox.stateChanged.connect(self.updateShow)
            layout.addWidget(checkbox)

            self.showLayout.addWidget(widget)
            self.showColorCheckboxes[name] = checkbox

        self.showLayout.addStretch()

        #@TODO move up
        self.mainLayout.addWidget(self.tabs)
        self.mainLayout.addWidget(self.buttonsWidget)
示例#57
0
    def __init__(self, parent):
        super(VidCutter, self).__init__(parent)
        self.novideoWidget = QWidget(self, autoFillBackground=True)
        self.parent = parent
        self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface)
        self.videoWidget = VideoWidget(self)
        self.videoService = VideoService(self)

        QFontDatabase.addApplicationFont(
            MainWindow.get_path('fonts/DroidSansMono.ttf'))
        QFontDatabase.addApplicationFont(
            MainWindow.get_path('fonts/OpenSans.ttf'))

        fontSize = 12 if sys.platform == 'darwin' else 10
        appFont = QFont('Open Sans', fontSize, 300)
        qApp.setFont(appFont)

        self.clipTimes = []
        self.inCut = False
        self.movieFilename = ''
        self.movieLoaded = False
        self.timeformat = 'hh:mm:ss'
        self.finalFilename = ''
        self.totalRuntime = 0

        self.initIcons()
        self.initActions()

        self.toolbar = QToolBar(floatable=False,
                                movable=False,
                                iconSize=QSize(40, 36))
        self.toolbar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
        self.toolbar.setStyleSheet('''QToolBar { spacing:10px; }
            QToolBar QToolButton { border:1px solid transparent; min-width:95px; font-size:11pt; font-weight:400;
                border-radius:5px; padding:1px 2px; color:#444; }
            QToolBar QToolButton:hover { border:1px inset #6A4572; color:#6A4572; background-color:rgba(255, 255, 255, 0.85); }
            QToolBar QToolButton:pressed { border:1px inset #6A4572; color:#6A4572; background-color:rgba(255, 255, 255, 0.25); }
            QToolBar QToolButton:disabled { color:#999; }''')
        self.initToolbar()

        self.appMenu, self.cliplistMenu = QMenu(), QMenu()
        self.initMenus()

        self.seekSlider = VideoSlider(parent=self,
                                      sliderMoved=self.setPosition)

        self.initNoVideo()

        self.cliplist = QListWidget(
            sizePolicy=QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Expanding),
            contextMenuPolicy=Qt.CustomContextMenu,
            uniformItemSizes=True,
            iconSize=QSize(100, 700),
            dragDropMode=QAbstractItemView.InternalMove,
            alternatingRowColors=True,
            customContextMenuRequested=self.itemMenu,
            dragEnabled=True)
        self.cliplist.setStyleSheet(
            'QListView { border-radius:0; border:none; border-left:1px solid #B9B9B9; '
            +
            'border-right:1px solid #B9B9B9; } QListView::item { padding:10px 0; }'
        )
        self.cliplist.setFixedWidth(185)
        self.cliplist.model().rowsMoved.connect(self.syncClipList)

        listHeader = QLabel(pixmap=QPixmap(
            MainWindow.get_path('images/clipindex.png'), 'PNG'),
                            alignment=Qt.AlignCenter)
        listHeader.setStyleSheet(
            '''padding:5px; padding-top:8px; border:1px solid #b9b9b9;
                                    background-color:qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FFF,
                                    stop: 0.5 #EAEAEA, stop: 0.6 #EAEAEA stop:1 #FFF);'''
        )

        self.runtimeLabel = QLabel('<div align="right">00:00:00</div>',
                                   textFormat=Qt.RichText)
        self.runtimeLabel.setStyleSheet(
            '''font-family:Droid Sans Mono; font-size:10pt; color:#FFF;
                                           background:rgb(106, 69, 114) url(:images/runtime.png)
                                           no-repeat left center; padding:2px; padding-right:8px;
                                           border:1px solid #B9B9B9;''')

        self.clipindexLayout = QVBoxLayout(spacing=0)
        self.clipindexLayout.setContentsMargins(0, 0, 0, 0)
        self.clipindexLayout.addWidget(listHeader)
        self.clipindexLayout.addWidget(self.cliplist)
        self.clipindexLayout.addWidget(self.runtimeLabel)

        self.videoLayout = QHBoxLayout()
        self.videoLayout.setContentsMargins(0, 0, 0, 0)
        self.videoLayout.addWidget(self.novideoWidget)
        self.videoLayout.addLayout(self.clipindexLayout)

        self.timeCounter = QLabel('00:00:00 / 00:00:00',
                                  autoFillBackground=True,
                                  alignment=Qt.AlignCenter,
                                  sizePolicy=QSizePolicy(
                                      QSizePolicy.Expanding,
                                      QSizePolicy.Fixed))
        self.timeCounter.setStyleSheet(
            'color:#FFF; background:#000; font-family:Droid Sans Mono; font-size:10.5pt; padding:4px;'
        )

        videoplayerLayout = QVBoxLayout(spacing=0)
        videoplayerLayout.setContentsMargins(0, 0, 0, 0)
        videoplayerLayout.addWidget(self.videoWidget)
        videoplayerLayout.addWidget(self.timeCounter)

        self.videoplayerWidget = QWidget(self, visible=False)
        self.videoplayerWidget.setLayout(videoplayerLayout)

        self.muteButton = QPushButton(icon=self.unmuteIcon,
                                      flat=True,
                                      toolTip='Mute',
                                      statusTip='Toggle audio mute',
                                      iconSize=QSize(16, 16),
                                      cursor=Qt.PointingHandCursor,
                                      clicked=self.muteAudio)

        self.volumeSlider = QSlider(Qt.Horizontal,
                                    toolTip='Volume',
                                    statusTip='Adjust volume level',
                                    cursor=Qt.PointingHandCursor,
                                    value=50,
                                    minimum=0,
                                    maximum=100,
                                    sliderMoved=self.setVolume)

        self.menuButton = QPushButton(
            icon=self.menuIcon,
            flat=True,
            toolTip='Menu',
            statusTip='Media + application information',
            iconSize=QSize(24, 24),
            cursor=Qt.PointingHandCursor)
        self.menuButton.setMenu(self.appMenu)

        toolbarLayout = QHBoxLayout()
        toolbarLayout.addWidget(self.toolbar)
        toolbarLayout.setContentsMargins(2, 2, 2, 2)

        toolbarGroup = QGroupBox()
        toolbarGroup.setFlat(False)
        toolbarGroup.setCursor(Qt.PointingHandCursor)
        toolbarGroup.setLayout(toolbarLayout)

        toolbarGroup.setStyleSheet(
            '''QGroupBox { background-color:rgba(0, 0, 0, 0.1);
            border:1px inset #888; border-radius:5px; }''')

        controlsLayout = QHBoxLayout(spacing=0)
        controlsLayout.addStretch(1)
        controlsLayout.addWidget(toolbarGroup)
        controlsLayout.addStretch(1)
        controlsLayout.addWidget(self.muteButton)
        controlsLayout.addWidget(self.volumeSlider)
        controlsLayout.addSpacing(1)
        controlsLayout.addWidget(self.menuButton)

        layout = QVBoxLayout()
        layout.setContentsMargins(10, 10, 10, 4)
        layout.addLayout(self.videoLayout)
        layout.addWidget(self.seekSlider)
        layout.addSpacing(5)
        layout.addLayout(controlsLayout)
        layout.addSpacing(2)

        self.setLayout(layout)

        self.mediaPlayer.setVideoOutput(self.videoWidget)
        self.mediaPlayer.stateChanged.connect(self.mediaStateChanged)
        self.mediaPlayer.positionChanged.connect(self.positionChanged)
        self.mediaPlayer.durationChanged.connect(self.durationChanged)
        self.mediaPlayer.error.connect(self.handleError)
示例#58
0
    def __init__(self, variables, parent=None):
        """
        Constructor
        
        @param variables list of template variable names (list of strings)
        @param parent parent widget of this dialog (QWidget)
        """
        super(TemplateMultipleVariablesDialog, self).__init__(parent)

        self.TemplateMultipleVariablesDialogLayout = QVBoxLayout(self)
        self.TemplateMultipleVariablesDialogLayout.setContentsMargins(
            6, 6, 6, 6)
        self.TemplateMultipleVariablesDialogLayout.setSpacing(6)
        self.TemplateMultipleVariablesDialogLayout.setObjectName(
            "TemplateMultipleVariablesDialogLayout")
        self.setLayout(self.TemplateMultipleVariablesDialogLayout)

        # generate the scrollarea
        self.variablesView = QScrollArea(self)
        self.variablesView.setObjectName("variablesView")
        self.TemplateMultipleVariablesDialogLayout.addWidget(
            self.variablesView)

        self.variablesView.setWidgetResizable(True)
        self.variablesView.setFrameStyle(QFrame.NoFrame)

        self.top = QWidget(self)
        self.variablesView.setWidget(self.top)
        self.grid = QGridLayout(self.top)
        self.grid.setContentsMargins(0, 0, 0, 0)
        self.grid.setSpacing(6)
        self.top.setLayout(self.grid)

        # populate the scrollarea with labels and text edits
        self.variablesEntries = {}
        row = 0
        for var in variables:
            label = QLabel("{0}:".format(var), self.top)
            self.grid.addWidget(label, row, 0, Qt.Alignment(Qt.AlignTop))
            if var.find(":") >= 0:
                formatStr = var[1:-1].split(":")[1]
                if formatStr in ["ml", "rl"]:
                    t = QTextEdit(self.top)
                    t.setTabChangesFocus(True)
                else:
                    t = QLineEdit(self.top)
            else:
                t = QLineEdit(self.top)
            self.grid.addWidget(t, row, 1)
            self.variablesEntries[var] = t
            row += 1
        # add a spacer to make the entries aligned at the top
        spacer = QSpacerItem(20, 40, QSizePolicy.Minimum,
                             QSizePolicy.Expanding)
        self.grid.addItem(spacer, row, 1)
        self.variablesEntries[variables[0]].setFocus()
        self.top.adjustSize()

        # generate the buttons
        layout1 = QHBoxLayout()
        layout1.setContentsMargins(0, 0, 0, 0)
        layout1.setSpacing(6)
        layout1.setObjectName("layout1")

        spacer1 = QSpacerItem(40, 20, QSizePolicy.Expanding,
                              QSizePolicy.Minimum)
        layout1.addItem(spacer1)

        self.okButton = QPushButton(self)
        self.okButton.setObjectName("okButton")
        self.okButton.setDefault(True)
        layout1.addWidget(self.okButton)

        self.cancelButton = QPushButton(self)
        self.cancelButton.setObjectName("cancelButton")
        layout1.addWidget(self.cancelButton)

        spacer2 = QSpacerItem(40, 20, QSizePolicy.Expanding,
                              QSizePolicy.Minimum)
        layout1.addItem(spacer2)

        self.TemplateMultipleVariablesDialogLayout.addLayout(layout1)

        # set the texts of the standard widgets
        self.setWindowTitle(self.tr("Enter Template Variables"))
        self.okButton.setText(self.tr("&OK"))
        self.cancelButton.setText(self.tr("&Cancel"))

        # polish up the dialog
        self.resize(QSize(400, 480).expandedTo(self.minimumSizeHint()))

        self.okButton.clicked.connect(self.accept)
        self.cancelButton.clicked.connect(self.reject)
示例#59
0
class VidCutter(QWidget):
    def __init__(self, parent):
        super(VidCutter, self).__init__(parent)
        self.novideoWidget = QWidget(self, autoFillBackground=True)
        self.parent = parent
        self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface)
        self.videoWidget = VideoWidget(self)
        self.videoService = VideoService(self)

        QFontDatabase.addApplicationFont(
            MainWindow.get_path('fonts/DroidSansMono.ttf'))
        QFontDatabase.addApplicationFont(
            MainWindow.get_path('fonts/OpenSans.ttf'))

        fontSize = 12 if sys.platform == 'darwin' else 10
        appFont = QFont('Open Sans', fontSize, 300)
        qApp.setFont(appFont)

        self.clipTimes = []
        self.inCut = False
        self.movieFilename = ''
        self.movieLoaded = False
        self.timeformat = 'hh:mm:ss'
        self.finalFilename = ''
        self.totalRuntime = 0

        self.initIcons()
        self.initActions()

        self.toolbar = QToolBar(floatable=False,
                                movable=False,
                                iconSize=QSize(40, 36))
        self.toolbar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
        self.toolbar.setStyleSheet('''QToolBar { spacing:10px; }
            QToolBar QToolButton { border:1px solid transparent; min-width:95px; font-size:11pt; font-weight:400;
                border-radius:5px; padding:1px 2px; color:#444; }
            QToolBar QToolButton:hover { border:1px inset #6A4572; color:#6A4572; background-color:rgba(255, 255, 255, 0.85); }
            QToolBar QToolButton:pressed { border:1px inset #6A4572; color:#6A4572; background-color:rgba(255, 255, 255, 0.25); }
            QToolBar QToolButton:disabled { color:#999; }''')
        self.initToolbar()

        self.appMenu, self.cliplistMenu = QMenu(), QMenu()
        self.initMenus()

        self.seekSlider = VideoSlider(parent=self,
                                      sliderMoved=self.setPosition)

        self.initNoVideo()

        self.cliplist = QListWidget(
            sizePolicy=QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Expanding),
            contextMenuPolicy=Qt.CustomContextMenu,
            uniformItemSizes=True,
            iconSize=QSize(100, 700),
            dragDropMode=QAbstractItemView.InternalMove,
            alternatingRowColors=True,
            customContextMenuRequested=self.itemMenu,
            dragEnabled=True)
        self.cliplist.setStyleSheet(
            'QListView { border-radius:0; border:none; border-left:1px solid #B9B9B9; '
            +
            'border-right:1px solid #B9B9B9; } QListView::item { padding:10px 0; }'
        )
        self.cliplist.setFixedWidth(185)
        self.cliplist.model().rowsMoved.connect(self.syncClipList)

        listHeader = QLabel(pixmap=QPixmap(
            MainWindow.get_path('images/clipindex.png'), 'PNG'),
                            alignment=Qt.AlignCenter)
        listHeader.setStyleSheet(
            '''padding:5px; padding-top:8px; border:1px solid #b9b9b9;
                                    background-color:qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FFF,
                                    stop: 0.5 #EAEAEA, stop: 0.6 #EAEAEA stop:1 #FFF);'''
        )

        self.runtimeLabel = QLabel('<div align="right">00:00:00</div>',
                                   textFormat=Qt.RichText)
        self.runtimeLabel.setStyleSheet(
            '''font-family:Droid Sans Mono; font-size:10pt; color:#FFF;
                                           background:rgb(106, 69, 114) url(:images/runtime.png)
                                           no-repeat left center; padding:2px; padding-right:8px;
                                           border:1px solid #B9B9B9;''')

        self.clipindexLayout = QVBoxLayout(spacing=0)
        self.clipindexLayout.setContentsMargins(0, 0, 0, 0)
        self.clipindexLayout.addWidget(listHeader)
        self.clipindexLayout.addWidget(self.cliplist)
        self.clipindexLayout.addWidget(self.runtimeLabel)

        self.videoLayout = QHBoxLayout()
        self.videoLayout.setContentsMargins(0, 0, 0, 0)
        self.videoLayout.addWidget(self.novideoWidget)
        self.videoLayout.addLayout(self.clipindexLayout)

        self.timeCounter = QLabel('00:00:00 / 00:00:00',
                                  autoFillBackground=True,
                                  alignment=Qt.AlignCenter,
                                  sizePolicy=QSizePolicy(
                                      QSizePolicy.Expanding,
                                      QSizePolicy.Fixed))
        self.timeCounter.setStyleSheet(
            'color:#FFF; background:#000; font-family:Droid Sans Mono; font-size:10.5pt; padding:4px;'
        )

        videoplayerLayout = QVBoxLayout(spacing=0)
        videoplayerLayout.setContentsMargins(0, 0, 0, 0)
        videoplayerLayout.addWidget(self.videoWidget)
        videoplayerLayout.addWidget(self.timeCounter)

        self.videoplayerWidget = QWidget(self, visible=False)
        self.videoplayerWidget.setLayout(videoplayerLayout)

        self.muteButton = QPushButton(icon=self.unmuteIcon,
                                      flat=True,
                                      toolTip='Mute',
                                      statusTip='Toggle audio mute',
                                      iconSize=QSize(16, 16),
                                      cursor=Qt.PointingHandCursor,
                                      clicked=self.muteAudio)

        self.volumeSlider = QSlider(Qt.Horizontal,
                                    toolTip='Volume',
                                    statusTip='Adjust volume level',
                                    cursor=Qt.PointingHandCursor,
                                    value=50,
                                    minimum=0,
                                    maximum=100,
                                    sliderMoved=self.setVolume)

        self.menuButton = QPushButton(
            icon=self.menuIcon,
            flat=True,
            toolTip='Menu',
            statusTip='Media + application information',
            iconSize=QSize(24, 24),
            cursor=Qt.PointingHandCursor)
        self.menuButton.setMenu(self.appMenu)

        toolbarLayout = QHBoxLayout()
        toolbarLayout.addWidget(self.toolbar)
        toolbarLayout.setContentsMargins(2, 2, 2, 2)

        toolbarGroup = QGroupBox()
        toolbarGroup.setFlat(False)
        toolbarGroup.setCursor(Qt.PointingHandCursor)
        toolbarGroup.setLayout(toolbarLayout)

        toolbarGroup.setStyleSheet(
            '''QGroupBox { background-color:rgba(0, 0, 0, 0.1);
            border:1px inset #888; border-radius:5px; }''')

        controlsLayout = QHBoxLayout(spacing=0)
        controlsLayout.addStretch(1)
        controlsLayout.addWidget(toolbarGroup)
        controlsLayout.addStretch(1)
        controlsLayout.addWidget(self.muteButton)
        controlsLayout.addWidget(self.volumeSlider)
        controlsLayout.addSpacing(1)
        controlsLayout.addWidget(self.menuButton)

        layout = QVBoxLayout()
        layout.setContentsMargins(10, 10, 10, 4)
        layout.addLayout(self.videoLayout)
        layout.addWidget(self.seekSlider)
        layout.addSpacing(5)
        layout.addLayout(controlsLayout)
        layout.addSpacing(2)

        self.setLayout(layout)

        self.mediaPlayer.setVideoOutput(self.videoWidget)
        self.mediaPlayer.stateChanged.connect(self.mediaStateChanged)
        self.mediaPlayer.positionChanged.connect(self.positionChanged)
        self.mediaPlayer.durationChanged.connect(self.durationChanged)
        self.mediaPlayer.error.connect(self.handleError)

    def initNoVideo(self) -> None:
        novideoImage = QLabel(
            alignment=Qt.AlignCenter,
            autoFillBackground=False,
            pixmap=QPixmap(MainWindow.get_path('images/novideo.png'), 'PNG'),
            sizePolicy=QSizePolicy(QSizePolicy.Expanding,
                                   QSizePolicy.MinimumExpanding))
        novideoImage.setBackgroundRole(QPalette.Dark)
        novideoImage.setContentsMargins(0, 20, 0, 20)
        self.novideoLabel = QLabel(alignment=Qt.AlignCenter,
                                   autoFillBackground=True,
                                   sizePolicy=QSizePolicy(
                                       QSizePolicy.Expanding,
                                       QSizePolicy.Minimum))
        self.novideoLabel.setBackgroundRole(QPalette.Dark)
        self.novideoLabel.setContentsMargins(0, 20, 15, 60)
        novideoLayout = QVBoxLayout(spacing=0)
        novideoLayout.addWidget(novideoImage)
        novideoLayout.addWidget(self.novideoLabel, alignment=Qt.AlignTop)
        self.novideoMovie = QMovie(
            MainWindow.get_path('images/novideotext.gif'))
        self.novideoMovie.frameChanged.connect(self.setNoVideoText)
        self.novideoMovie.start()
        self.novideoWidget.setBackgroundRole(QPalette.Dark)
        self.novideoWidget.setLayout(novideoLayout)

    def initIcons(self) -> None:
        self.appIcon = QIcon(MainWindow.get_path('images/vidcutter.png'))
        self.openIcon = icon('fa.film',
                             color='#444',
                             color_active='#6A4572',
                             scale_factor=0.9)
        self.playIcon = icon('fa.play-circle-o',
                             color='#444',
                             color_active='#6A4572',
                             scale_factor=1.1)
        self.pauseIcon = icon('fa.pause-circle-o',
                              color='#444',
                              color_active='#6A4572',
                              scale_factor=1.1)
        self.cutStartIcon = icon('fa.scissors',
                                 scale_factor=1.15,
                                 color='#444',
                                 color_active='#6A4572')
        endicon_normal = icon('fa.scissors', scale_factor=1.15,
                              color='#444').pixmap(QSize(36, 36)).toImage()
        endicon_active = icon('fa.scissors',
                              scale_factor=1.15,
                              color='#6A4572').pixmap(QSize(36, 36)).toImage()
        self.cutEndIcon = QIcon()
        self.cutEndIcon.addPixmap(
            QPixmap.fromImage(
                endicon_normal.mirrored(horizontal=True, vertical=False)),
            QIcon.Normal, QIcon.Off)
        self.cutEndIcon.addPixmap(
            QPixmap.fromImage(
                endicon_active.mirrored(horizontal=True, vertical=False)),
            QIcon.Active, QIcon.Off)
        self.saveIcon = icon('fa.video-camera',
                             color='#6A4572',
                             color_active='#6A4572')
        self.muteIcon = QIcon(MainWindow.get_path('images/muted.png'))
        self.unmuteIcon = QIcon(MainWindow.get_path('images/unmuted.png'))
        self.upIcon = icon('ei.caret-up', color='#444')
        self.downIcon = icon('ei.caret-down', color='#444')
        self.removeIcon = icon('ei.remove', color='#B41D1D')
        self.removeAllIcon = icon('ei.trash', color='#B41D1D')
        self.successIcon = QIcon(MainWindow.get_path('images/success.png'))
        self.menuIcon = icon('fa.cog', color='#444', scale_factor=1.15)
        self.completePlayIcon = icon('fa.play', color='#444')
        self.completeOpenIcon = icon('fa.folder-open', color='#444')
        self.completeRestartIcon = icon('fa.retweet', color='#444')
        self.completeExitIcon = icon('fa.sign-out', color='#444')
        self.mediaInfoIcon = icon('fa.info-circle', color='#444')
        self.updateCheckIcon = icon('fa.cloud-download', color='#444')

    def initActions(self) -> None:
        self.openAction = QAction(self.openIcon,
                                  'Open',
                                  self,
                                  statusTip='Open media file',
                                  triggered=self.openMedia)
        self.playAction = QAction(self.playIcon,
                                  'Play',
                                  self,
                                  statusTip='Play media file',
                                  triggered=self.playMedia,
                                  enabled=False)
        self.cutStartAction = QAction(self.cutStartIcon,
                                      ' Start',
                                      self,
                                      toolTip='Start',
                                      statusTip='Set clip start marker',
                                      triggered=self.setCutStart,
                                      enabled=False)
        self.cutEndAction = QAction(self.cutEndIcon,
                                    ' End',
                                    self,
                                    toolTip='End',
                                    statusTip='Set clip end marker',
                                    triggered=self.setCutEnd,
                                    enabled=False)
        self.saveAction = QAction(self.saveIcon,
                                  'Save',
                                  self,
                                  statusTip='Save clips to a new video file',
                                  triggered=self.cutVideo,
                                  enabled=False)
        self.moveItemUpAction = QAction(
            self.upIcon,
            'Move up',
            self,
            statusTip='Move clip position up in list',
            triggered=self.moveItemUp,
            enabled=False)
        self.moveItemDownAction = QAction(
            self.downIcon,
            'Move down',
            self,
            statusTip='Move clip position down in list',
            triggered=self.moveItemDown,
            enabled=False)
        self.removeItemAction = QAction(
            self.removeIcon,
            'Remove clip',
            self,
            statusTip='Remove selected clip from list',
            triggered=self.removeItem,
            enabled=False)
        self.removeAllAction = QAction(self.removeAllIcon,
                                       'Clear list',
                                       self,
                                       statusTip='Clear all clips from list',
                                       triggered=self.clearList,
                                       enabled=False)
        self.mediaInfoAction = QAction(
            self.mediaInfoIcon,
            'Media information',
            self,
            statusTip='View current media file information',
            triggered=self.mediaInfo,
            enabled=False)
        self.updateCheckAction = QAction(
            self.updateCheckIcon,
            'Check for updates...',
            self,
            statusTip='Check for application updates',
            triggered=self.updateCheck)
        self.aboutQtAction = QAction('About Qt',
                                     self,
                                     statusTip='About Qt',
                                     triggered=qApp.aboutQt)
        self.aboutAction = QAction('About %s' % qApp.applicationName(),
                                   self,
                                   statusTip='Credits and licensing',
                                   triggered=self.aboutInfo)

    def initToolbar(self) -> None:
        self.toolbar.addAction(self.openAction)
        self.toolbar.addAction(self.playAction)
        self.toolbar.addAction(self.cutStartAction)
        self.toolbar.addAction(self.cutEndAction)
        self.toolbar.addAction(self.saveAction)

    def initMenus(self) -> None:
        self.appMenu.addAction(self.mediaInfoAction)
        self.appMenu.addAction(self.updateCheckAction)
        self.appMenu.addSeparator()
        self.appMenu.addAction(self.aboutQtAction)
        self.appMenu.addAction(self.aboutAction)

        self.cliplistMenu.addAction(self.moveItemUpAction)
        self.cliplistMenu.addAction(self.moveItemDownAction)
        self.cliplistMenu.addSeparator()
        self.cliplistMenu.addAction(self.removeItemAction)
        self.cliplistMenu.addAction(self.removeAllAction)

    @staticmethod
    def getSpacer() -> QWidget:
        spacer = QWidget()
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
        return spacer

    def setRunningTime(self, runtime: str) -> None:
        self.runtimeLabel.setText('<div align="right">%s</div>' % runtime)

    @pyqtSlot(int)
    def setNoVideoText(self) -> None:
        self.novideoLabel.setPixmap(self.novideoMovie.currentPixmap())

    def itemMenu(self, pos: QPoint) -> None:
        globalPos = self.cliplist.mapToGlobal(pos)
        self.moveItemUpAction.setEnabled(False)
        self.moveItemDownAction.setEnabled(False)
        self.removeItemAction.setEnabled(False)
        self.removeAllAction.setEnabled(False)
        index = self.cliplist.currentRow()
        if index != -1:
            if not self.inCut:
                if index > 0:
                    self.moveItemUpAction.setEnabled(True)
                if index < self.cliplist.count() - 1:
                    self.moveItemDownAction.setEnabled(True)
            if self.cliplist.count() > 0:
                self.removeItemAction.setEnabled(True)
        if self.cliplist.count() > 0:
            self.removeAllAction.setEnabled(True)
        self.cliplistMenu.exec_(globalPos)

    def moveItemUp(self) -> None:
        index = self.cliplist.currentRow()
        tmpItem = self.clipTimes[index]
        del self.clipTimes[index]
        self.clipTimes.insert(index - 1, tmpItem)
        self.renderTimes()

    def moveItemDown(self) -> None:
        index = self.cliplist.currentRow()
        tmpItem = self.clipTimes[index]
        del self.clipTimes[index]
        self.clipTimes.insert(index + 1, tmpItem)
        self.renderTimes()

    def removeItem(self) -> None:
        index = self.cliplist.currentRow()
        del self.clipTimes[index]
        if self.inCut and index == self.cliplist.count() - 1:
            self.inCut = False
            self.initMediaControls()
        self.renderTimes()

    def clearList(self) -> None:
        self.clipTimes.clear()
        self.cliplist.clear()
        self.inCut = False
        self.renderTimes()
        self.initMediaControls()

    def mediaInfo(self) -> None:
        if self.mediaPlayer.isMetaDataAvailable():
            content = '<table cellpadding="4">'
            for key in self.mediaPlayer.availableMetaData():
                val = self.mediaPlayer.metaData(key)
                if type(val) is QSize:
                    val = '%s x %s' % (val.width(), val.height())
                content += '<tr><td align="right"><b>%s:</b></td><td>%s</td></tr>\n' % (
                    key, val)
            content += '</table>'
            mbox = QMessageBox(windowTitle='Media Information',
                               windowIcon=self.parent.windowIcon(),
                               textFormat=Qt.RichText)
            mbox.setText('<b>%s</b>' % os.path.basename(
                self.mediaPlayer.currentMedia().canonicalUrl().toLocalFile()))
            mbox.setInformativeText(content)
            mbox.exec_()
        else:
            QMessageBox.critical(
                self.parent, 'MEDIA ERROR',
                '<h3>Could not probe media file.</h3>' +
                '<p>An error occurred while analyzing the media file for its metadata details.'
                +
                '<br/><br/><b>This DOES NOT mean there is a problem with the file and you should '
                + 'be able to continue using it.</b></p>')

    def aboutInfo(self) -> None:
        about_html = '''<style>
    a { color:#441d4e; text-decoration:none; font-weight:bold; }
    a:hover { text-decoration:underline; }
</style>
<div style="min-width:650px;">
<p style="font-size:26pt; font-weight:bold; color:#6A4572;">%s</p>
<p>
    <span style="font-size:13pt;"><b>Version: %s</b></span>
    <span style="font-size:10pt;position:relative;left:5px;">( %s )</span>
</p>
<p style="font-size:13px;">
    Copyright &copy; 2016 <a href="mailto:[email protected]">Pete Alexandrou</a>
    <br/>
    Website: <a href="%s">%s</a>
</p>
<p style="font-size:13px;">
    Thanks to the folks behind the <b>Qt</b>, <b>PyQt</b> and <b>FFmpeg</b>
    projects for all their hard and much appreciated work.
</p>
<p style="font-size:11px;">
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.
</p>
<p style="font-size:11px;">
    This software uses libraries from the <a href="https://www.ffmpeg.org">FFmpeg</a> project under the
    <a href="https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html">LGPLv2.1</a>
</p></div>''' % (qApp.applicationName(), qApp.applicationVersion(),
                 platform.architecture()[0], qApp.organizationDomain(),
                 qApp.organizationDomain())
        QMessageBox.about(self.parent, 'About %s' % qApp.applicationName(),
                          about_html)

    def openMedia(self) -> None:
        filename, _ = QFileDialog.getOpenFileName(self.parent,
                                                  caption='Select video',
                                                  directory=QDir.homePath())
        if filename != '':
            self.loadFile(filename)

    def loadFile(self, filename: str) -> None:
        self.movieFilename = filename
        if not os.path.exists(filename):
            return
        self.mediaPlayer.setMedia(QMediaContent(QUrl.fromLocalFile(filename)))
        self.initMediaControls(True)
        self.cliplist.clear()
        self.clipTimes = []
        self.parent.setWindowTitle(
            '%s - %s' % (qApp.applicationName(), os.path.basename(filename)))
        if not self.movieLoaded:
            self.videoLayout.replaceWidget(self.novideoWidget,
                                           self.videoplayerWidget)
            self.novideoMovie.stop()
            self.novideoMovie.deleteLater()
            self.novideoWidget.deleteLater()
            self.videoplayerWidget.show()
            self.videoWidget.show()
            self.movieLoaded = True
        if self.mediaPlayer.isVideoAvailable():
            self.mediaPlayer.setPosition(1)
        self.mediaPlayer.play()
        self.mediaPlayer.pause()

    def playMedia(self) -> None:
        if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
            self.mediaPlayer.pause()
            self.playAction.setText('Play')
        else:
            self.mediaPlayer.play()
            self.playAction.setText('Pause')

    def initMediaControls(self, flag: bool = True) -> None:
        self.playAction.setEnabled(flag)
        self.saveAction.setEnabled(False)
        self.cutStartAction.setEnabled(flag)
        self.cutEndAction.setEnabled(False)
        self.mediaInfoAction.setEnabled(flag)
        if flag:
            self.seekSlider.setRestrictValue(0)

    def setPosition(self, position: int) -> None:
        self.mediaPlayer.setPosition(position)

    def positionChanged(self, progress: int) -> None:
        self.seekSlider.setValue(progress)
        currentTime = self.deltaToQTime(progress)
        totalTime = self.deltaToQTime(self.mediaPlayer.duration())
        self.timeCounter.setText('%s / %s' % (currentTime.toString(
            self.timeformat), totalTime.toString(self.timeformat)))

    @pyqtSlot()
    def mediaStateChanged(self) -> None:
        if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
            self.playAction.setIcon(self.pauseIcon)
        else:
            self.playAction.setIcon(self.playIcon)

    def durationChanged(self, duration: int) -> None:
        self.seekSlider.setRange(0, duration)

    def muteAudio(self) -> None:
        if self.mediaPlayer.isMuted():
            self.muteButton.setIcon(self.unmuteIcon)
            self.muteButton.setToolTip('Mute')
        else:
            self.muteButton.setIcon(self.muteIcon)
            self.muteButton.setToolTip('Unmute')
        self.mediaPlayer.setMuted(not self.mediaPlayer.isMuted())

    def setVolume(self, volume: int) -> None:
        self.mediaPlayer.setVolume(volume)

    def toggleFullscreen(self) -> None:
        self.videoWidget.setFullScreen(not self.videoWidget.isFullScreen())

    def setCutStart(self) -> None:
        self.clipTimes.append([
            self.deltaToQTime(self.mediaPlayer.position()), '',
            self.captureImage()
        ])
        self.cutStartAction.setDisabled(True)
        self.cutEndAction.setEnabled(True)
        self.seekSlider.setRestrictValue(self.seekSlider.value(), True)
        self.inCut = True
        self.renderTimes()

    def setCutEnd(self) -> None:
        item = self.clipTimes[len(self.clipTimes) - 1]
        selected = self.deltaToQTime(self.mediaPlayer.position())
        if selected.__lt__(item[0]):
            QMessageBox.critical(
                self.parent, 'Invalid END Time',
                'The clip end time must come AFTER it\'s start time. Please try again.'
            )
            return
        item[1] = selected
        self.cutStartAction.setEnabled(True)
        self.cutEndAction.setDisabled(True)
        self.seekSlider.setRestrictValue(0, False)
        self.inCut = False
        self.renderTimes()

    @pyqtSlot(QModelIndex, int, int, QModelIndex, int)
    def syncClipList(self, parent: QModelIndex, start: int, end: int,
                     destination: QModelIndex, row: int) -> None:
        if start < row:
            index = row - 1
        else:
            index = row
        clip = self.clipTimes.pop(start)
        self.clipTimes.insert(index, clip)

    def renderTimes(self) -> None:
        self.cliplist.clear()
        if len(self.clipTimes) > 4:
            self.cliplist.setFixedWidth(200)
        else:
            self.cliplist.setFixedWidth(185)
        self.totalRuntime = 0
        for item in self.clipTimes:
            endItem = ''
            if type(item[1]) is QTime:
                endItem = item[1].toString(self.timeformat)
                self.totalRuntime += item[0].msecsTo(item[1])
            listitem = QListWidgetItem()
            listitem.setTextAlignment(Qt.AlignVCenter)
            if type(item[2]) is QPixmap:
                listitem.setIcon(QIcon(item[2]))
            self.cliplist.addItem(listitem)
            marker = QLabel(
                '''<style>b { font-size:7pt; } p { margin:2px 5px; }</style>
                            <p><b>START</b><br/>%s<br/><b>END</b><br/>%s</p>'''
                % (item[0].toString(self.timeformat), endItem))
            marker.setStyleSheet('border:none;')
            self.cliplist.setItemWidget(listitem, marker)
            listitem.setFlags(Qt.ItemIsSelectable | Qt.ItemIsDragEnabled
                              | Qt.ItemIsEnabled)
        if len(self.clipTimes) and not self.inCut:
            self.saveAction.setEnabled(True)
        if self.inCut or len(self.clipTimes) == 0 or not type(
                self.clipTimes[0][1]) is QTime:
            self.saveAction.setEnabled(False)
        self.setRunningTime(
            self.deltaToQTime(self.totalRuntime).toString(self.timeformat))

    @staticmethod
    def deltaToQTime(millisecs: int) -> QTime:
        secs = millisecs / 1000
        return QTime((secs / 3600) % 60, (secs / 60) % 60, secs % 60,
                     (secs * 1000) % 1000)

    def captureImage(self) -> QPixmap:
        frametime = self.deltaToQTime(self.mediaPlayer.position()).toString(
            self.timeformat)
        inputfile = self.mediaPlayer.currentMedia().canonicalUrl().toLocalFile(
        )
        imagecap = self.videoService.capture(inputfile, frametime)
        if type(imagecap) is QPixmap:
            return imagecap

    def cutVideo(self) -> bool:
        clips = len(self.clipTimes)
        filename, filelist = '', []
        source = self.mediaPlayer.currentMedia().canonicalUrl().toLocalFile()
        _, sourceext = os.path.splitext(source)
        if clips > 0:
            self.finalFilename, _ = QFileDialog.getSaveFileName(
                self.parent, 'Save video', source,
                'Video files (*%s)' % sourceext)
            if self.finalFilename == '':
                return False
            qApp.setOverrideCursor(Qt.BusyCursor)
            self.saveAction.setDisabled(True)
            self.showProgress(clips)
            file, ext = os.path.splitext(self.finalFilename)
            index = 1
            self.progress.setLabelText('Cutting media files...')
            qApp.processEvents()
            for clip in self.clipTimes:
                duration = self.deltaToQTime(clip[0].msecsTo(
                    clip[1])).toString(self.timeformat)
                filename = '%s_%s%s' % (file, '{0:0>2}'.format(index), ext)
                filelist.append(filename)
                self.videoService.cut(source, filename,
                                      clip[0].toString(self.timeformat),
                                      duration)
                index += 1
            if len(filelist) > 1:
                self.joinVideos(filelist, self.finalFilename)
            else:
                QFile.remove(self.finalFilename)
                QFile.rename(filename, self.finalFilename)
            self.progress.setLabelText('Complete...')
            self.progress.setValue(100)
            qApp.processEvents()
            self.progress.close()
            self.progress.deleteLater()
            qApp.restoreOverrideCursor()
            self.complete()
            return True
        return False

    def joinVideos(self, joinlist: list, filename: str) -> None:
        listfile = os.path.normpath(
            os.path.join(os.path.dirname(joinlist[0]), '.vidcutter.list'))
        fobj = open(listfile, 'w')
        for file in joinlist:
            fobj.write('file \'%s\'\n' % file.replace("'", "\\'"))
        fobj.close()
        self.videoService.join(listfile, filename)
        QFile.remove(listfile)
        for file in joinlist:
            if os.path.isfile(file):
                QFile.remove(file)

    def updateCheck(self) -> None:
        self.updater = Updater()
        self.updater.updateAvailable.connect(self.updateHandler)
        self.updater.start()

    def updateHandler(self, updateExists: bool, version: str = None):
        if updateExists:
            if Updater.notify_update(self, version) == QMessageBox.AcceptRole:
                self.updater.install_update(self)
        else:
            Updater.notify_no_update(self)

    def showProgress(self,
                     steps: int,
                     label: str = 'Analyzing media...') -> None:
        self.progress = QProgressDialog(label,
                                        None,
                                        0,
                                        steps,
                                        self.parent,
                                        windowModality=Qt.ApplicationModal,
                                        windowIcon=self.parent.windowIcon(),
                                        minimumDuration=0,
                                        minimumWidth=500)
        self.progress.show()
        for i in range(steps):
            self.progress.setValue(i)
            qApp.processEvents()
            time.sleep(1)

    def complete(self) -> None:
        info = QFileInfo(self.finalFilename)
        mbox = QMessageBox(windowTitle='VIDEO PROCESSING COMPLETE',
                           minimumWidth=500,
                           textFormat=Qt.RichText)
        mbox.setText(
            '''
    <style>
        table.info { margin:6px; padding:4px 15px; }
        td.label { font-weight:bold; font-size:10.5pt; text-align:right; }
        td.value { font-size:10.5pt; }
    </style>
    <table class="info" cellpadding="4" cellspacing="0">
        <tr>
            <td class="label"><b>File:</b></td>
            <td class="value" nowrap>%s</td>
        </tr>
        <tr>
            <td class="label"><b>Size:</b></td>
            <td class="value">%s</td>
        </tr>
        <tr>
            <td class="label"><b>Length:</b></td>
            <td class="value">%s</td>
        </tr>
    </table><br/>''' %
            (QDir.toNativeSeparators(
                self.finalFilename), self.sizeof_fmt(int(info.size())),
             self.deltaToQTime(self.totalRuntime).toString(self.timeformat)))
        play = mbox.addButton('Play', QMessageBox.AcceptRole)
        play.setIcon(self.completePlayIcon)
        play.clicked.connect(self.openResult)
        fileman = mbox.addButton('Open', QMessageBox.AcceptRole)
        fileman.setIcon(self.completeOpenIcon)
        fileman.clicked.connect(self.openFolder)
        end = mbox.addButton('Exit', QMessageBox.AcceptRole)
        end.setIcon(self.completeExitIcon)
        end.clicked.connect(self.close)
        new = mbox.addButton('Restart', QMessageBox.AcceptRole)
        new.setIcon(self.completeRestartIcon)
        new.clicked.connect(self.parent.restart)
        mbox.setDefaultButton(new)
        mbox.setEscapeButton(new)
        mbox.adjustSize()
        mbox.exec_()

    def sizeof_fmt(self, num: float, suffix: chr = 'B') -> str:
        for unit in ['', 'K', 'M', 'G', 'T', 'P', 'E', 'Z']:
            if abs(num) < 1024.0:
                return "%3.1f%s%s" % (num, unit, suffix)
            num /= 1024.0
        return "%.1f%s%s" % (num, 'Y', suffix)

    @pyqtSlot()
    def openFolder(self) -> None:
        self.openResult(pathonly=True)

    @pyqtSlot(bool)
    def openResult(self, pathonly: bool = False) -> None:
        self.parent.restart()
        if len(self.finalFilename) and os.path.exists(self.finalFilename):
            target = self.finalFilename if not pathonly else os.path.dirname(
                self.finalFilename)
            QDesktopServices.openUrl(QUrl.fromLocalFile(target))

    @pyqtSlot()
    def startNew(self) -> None:
        qApp.restoreOverrideCursor()
        self.clearList()
        self.seekSlider.setValue(0)
        self.seekSlider.setRange(0, 0)
        self.mediaPlayer.setMedia(QMediaContent())
        self.initNoVideo()
        self.videoLayout.replaceWidget(self.videoplayerWidget,
                                       self.novideoWidget)
        self.initMediaControls(False)
        self.parent.setWindowTitle('%s' % qApp.applicationName())

    def wheelEvent(self, event: QWheelEvent) -> None:
        if self.mediaPlayer.isVideoAvailable(
        ) or self.mediaPlayer.isAudioAvailable():
            if event.angleDelta().y() > 0:
                newval = self.seekSlider.value() - 1000
            else:
                newval = self.seekSlider.value() + 1000
            self.seekSlider.setValue(newval)
            self.seekSlider.setSliderPosition(newval)
            self.mediaPlayer.setPosition(newval)
        event.accept()

    def keyPressEvent(self, event: QKeyEvent) -> None:
        if self.mediaPlayer.isVideoAvailable(
        ) or self.mediaPlayer.isAudioAvailable():
            addtime = 0
            if event.key() == Qt.Key_Left:
                addtime = -1000
            elif event.key() == Qt.Key_PageUp or event.key() == Qt.Key_Up:
                addtime = -10000
            elif event.key() == Qt.Key_Right:
                addtime = 1000
            elif event.key() == Qt.Key_PageDown or event.key() == Qt.Key_Down:
                addtime = 10000
            elif event.key() == Qt.Key_Enter:
                self.toggleFullscreen()
            elif event.key(
            ) == Qt.Key_Escape and self.videoWidget.isFullScreen():
                self.videoWidget.setFullScreen(False)
            if addtime != 0:
                newval = self.seekSlider.value() + addtime
                self.seekSlider.setValue(newval)
                self.seekSlider.setSliderPosition(newval)
                self.mediaPlayer.setPosition(newval)
        event.accept()

    def mousePressEvent(self, event: QMouseEvent) -> None:
        if event.button() == Qt.BackButton and self.cutStartAction.isEnabled():
            self.setCutStart()
            event.accept()
        elif event.button(
        ) == Qt.ForwardButton and self.cutEndAction.isEnabled():
            self.setCutEnd()
            event.accept()
        else:
            super(VidCutter, self).mousePressEvent(event)

    @pyqtSlot(QMediaPlayer.Error)
    def handleError(self, error: QMediaPlayer.Error) -> None:
        qApp.restoreOverrideCursor()
        self.startNew()
        if error == QMediaPlayer.ResourceError:
            QMessageBox.critical(
                self.parent, 'INVALID MEDIA',
                'Invalid media file detected at:<br/><br/><b>%s</b><br/><br/>%s'
                % (self.movieFilename, self.mediaPlayer.errorString()))
        else:
            QMessageBox.critical(self.parent, 'ERROR NOTIFICATION',
                                 self.mediaPlayer.errorString())

    def closeEvent(self, event: QCloseEvent) -> None:
        self.parent.closeEvent(event)
示例#60
0
class MenuBar(QTabWidget):
    ExpandHeight = 125
    HiddenHeight = 30

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

        tabbar = TabBar(parent)
        self.setTabBar(tabbar)
        self._init_ui()
        self.setMinimumHeight(125)
        self.setMouseTracking(True)
        self.tabBarClicked.connect(self._tab_clicked)

    def _set_height(self, height):
        self.setFixedHeight(height)

    _height = pyqtProperty(int, fset=_set_height)

    def _init_ui(self):
        font = QFont('Webdings')

        self._drop = False
        self._corner = CornerButton('5')
        self._corner.setObjectName('BUttonCorner')
        self._corner.setFont(font)
        self.setCornerWidget(self._corner, Qt.TopRightCorner)
        self._corner.clicked.connect(self._corner_clicked)
        self.currentChanged.connect(self._current_changed)

    def expand(self):
        self._corner.setText('5')
        self._drop = False
        self._set_height(self.ExpandHeight)

    def shrink(self):
        self._corner.setText('6')
        self._drop = True
        self._set_height(self.HiddenHeight)

    def _corner_clicked(self):
        # self._ani = QPropertyAnimation(self, b'_height')
        # self._ani.setDuration(100)

        if self._drop:  # 当前是否展开的状况
            self.expand()
        else:
            self.shrink()
        # self._ani.start()

    def _tab_clicked(self):
        if self._drop:
            self.expand()

    def _current_changed(self, index):
        pass
        # tab_text = self.tabText(index)
        # menu = self.findChild(MenuWidget, tab_text)
        # self._ani1 = QPropertyAnimation(menu, b'_height')
        # self._ani1.setDuration(500)
        # self._ani1.setStartValue(0)
        # self._ani1.setEndValue(95)
        # self._ani1.start()

    def add_menu(self, p_str) -> MenuWidget:
        p_str = f"  {p_str}  "
        menu = MenuWidget()
        menu.setObjectName(p_str)
        self.addTab(menu, p_str)
        self._hl = QHBoxLayout(menu)
        self._hl.setObjectName(p_str)
        self._hl.setContentsMargins(0, 0, 0, 0)
        self._hl.setSpacing(0)
        hs = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
        self._hl.addItem(hs)
        return menu

    def add_group(self, p_str, menu, *, use_corner=False) -> 'GroupWidget':
        group = GroupWidget(p_str, menu, useConer=use_corner)
        group.setObjectName('group')
        insert_index = len(menu.findChildren(GroupWidget, 'group')) - 1
        self._hl.insertWidget(insert_index, group)
        return group