def setupUi(self):
     self.resize(500, 300)
     self.settingsWidget = QWidget()
     self.settingsWidget.setMinimumSize(900, 150)
     # Create the main widget as a container widget.
     self.mainWidget = QWidget(self)
     self.setWidget(self.mainWidget)
     mainLayout = QVBoxLayout(self.mainWidget)
     # Create 'Settings' dropdown button.
     self.settingsButton = QToolButton(self)
     self.settingsButton.setText("Settings")
     # Remove the menu indicator by applying a global style.
     self.settingsButton.setObjectName("noIndicator")
     # And replace it with a down arrow icon instead (which looks better).
     self.settingsButton.setArrowType(QtCore.Qt.DownArrow)
     self.settingsButton.setToolButtonStyle(
         QtCore.Qt.ToolButtonTextBesideIcon)
     # Set the popup that opens on button click.
     self.settingsButton.setPopupMode(QToolButton.InstantPopup)
     action = QWidgetAction(self.settingsButton)
     action.setDefaultWidget(self.settingsWidget)
     self.settingsButton.addAction(action)
     # Create a horizontal layout for the settings button.
     buttonLayout = QHBoxLayout()
     buttonLayout.addWidget(self.settingsButton)
     buttonLayout.addStretch()
     mainLayout.addLayout(buttonLayout)
     # Create the plotter widget.
     self.plotter = Qt5Plotter()
     self.plotter.setPlotterGUI(self)
     self.plotter.setMinimumSize(300, 200)
     self.plotter.plotLinear()
     mainLayout.addWidget(self.plotter)
     # Create the settings dialog.
     self.setupSettingsDialogUi()
     # Set keys that are plotted by default
     self.defaultKeys = {"TEST": ["loss"], "TRAIN": ["loss"]}
Esempio n. 2
0
    def __init__(self, *args, **kwargs):
        QWidget.__init__(self, *args, **kwargs)
        layout = QHBoxLayout()
        confirm = QToolButton()
        confirm.setText("OK")
        confirm.setToolTip("Apply the entered filter")
        self.field_entry = get_field_entry()

        # stack containing widgets for string, k/v, date, daterange
        self.str_cmp_entry = StringCmpWidget()
        self.kv_cmp_entry = StringKVWidget()
        self.inv_entry = QCheckBox("inv")
        # date
        # daterange

        self.entry_layout = QStackedLayout()
        self.entry_layout.setContentsMargins(0, 0, 0, 0)
        self.current_entry = 0
        self.entry_layout.addWidget(self.str_cmp_entry)
        self.entry_layout.addWidget(self.kv_cmp_entry)
        # add date # 2
        # add daterange # 3

        confirm.clicked.connect(self.confirm_entry)
        self.str_cmp_entry.returnPressed.connect(self.confirm_entry)
        self.kv_cmp_entry.returnPressed.connect(self.confirm_entry)
        self.field_entry.currentIndexChanged.connect(
            self._display_value_widget)

        layout.addWidget(confirm)
        layout.addWidget(self.inv_entry)
        layout.addWidget(self.field_entry)
        layout.addLayout(self.entry_layout)

        self.setLayout(layout)
        self.setContentsMargins(0, 0, 0, 0)
        self._display_value_widget()
Esempio n. 3
0
 def init_toolbar(self):
     toolbar = self.addToolBar('')
     toolbar.setAllowedAreas(Qt.TopToolBarArea)
     toolbar.setFloatable(False)
     toolbar.setMovable(False)
     toolbar.setContextMenuPolicy(Qt.PreventContextMenu)
     self.toolButton = []
     for item in [
             self.line_menu, self.polygon_menu, self.ellipse_act,
             self.curve_menu, self.translate_act, self.rotate_act,
             self.scale_act, self.clip_menu
     ]:
         button = QToolButton()
         button.setCheckable(True)
         button.toggled.connect(self.action_toggled)
         button.setFocusPolicy(Qt.NoFocus)
         if isinstance(item, QMenu):
             button.setMenu(item)
             button.setPopupMode(QToolButton.MenuButtonPopup)
         if item == self.translate_act:
             toolbar.addSeparator()
         toolbar.addWidget(button)
         self.toolButton.append(button)
     color = QPushButton()
     color.setFocusPolicy(Qt.NoFocus)
     color.setFixedSize(toolbar.iconSize())
     color.setFlat(True)
     # fix initial with empty color
     # FIXED: fix by setting background color at the beginning,
     #        and resetting background afterwards
     color.setStyleSheet("border:1px solid black; background-color: black")
     color.setAutoFillBackground(True)
     color.clicked.connect(lambda: self.set_pen_color(
     ) if not self.canvas_widget.selected_id else self.set_item_color())
     self.toolColor = color
     toolbar.addSeparator()
     toolbar.addWidget(color)
Esempio n. 4
0
    def __init__(self, img_path, parent=None):
        super(ImagePlayer, self).__init__(parent)
        if __name__ == '__main__':
            self.setWindowTitle("Viewer")
            self.setGeometry(0, 0, 640, 480)
            self.main = QWidget()
        else:
            self.setGeometry(0, 0, parent.width(), parent.height())
            self.main = parent

        self.vue = QGraphicsView()
        self.vue.setDragMode(QGraphicsView.ScrollHandDrag)
        self.vue.wheelEvent = self.wheel_event

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

        self.verticalLayout = QVBoxLayout()
        self.verticalLayout.addWidget(self.vue)
        self.verticalLayout.addWidget(self.statusBar)

        self.setPixmapView(img_path)

        self.statusBar.showMessage(img_path)

        if __name__ == '__main__':
            self.image_btn = QToolButton()
            self.image_btn.setText("Image")
            self.image_btn.setObjectName("image_btn")
            self.image_btn.clicked.connect(self.get_image)
            self.verticalLayout.addWidget(self.image_btn)

            self.setLayout(self.verticalLayout)
            self.show()
        else:
            self.main.setLayout(self.verticalLayout)
Esempio n. 5
0
    def __init__(self, parent=None, title=''):
        QWidget.__init__(self, parent=parent)

        from PyQt5.QtWidgets import QFrame, QToolButton, QGridLayout, QSizePolicy
        self.content_area = c = QFrame()
        self.toggle_button = b = QToolButton()
        self.main_layout = layout = QGridLayout()

        from PyQt5.QtCore import Qt
        b.setStyleSheet("QToolButton { border: none; font: 14px; }")
        # TODO: Could not figure out a way to reduce left padding on disclosure arrow on Mac Qt 5.9
        #        b.setAttribute(Qt.WA_LayoutUsesWidgetRect)  # Avoid extra padding on Mac
        #        b.setStyleSheet("QToolButton { margin: 0; padding-left: 0px; border: none; font: 14px; }")
        #        b.setMaximumSize(20,10)
        #        b.setContentsMargins(0,0,0,0)
        b.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
        b.setArrowType(Qt.RightArrow)
        b.setText(str(title))
        b.setCheckable(True)
        b.setChecked(False)

        #        c.setStyleSheet("QFrame { background-color: white; border: none; }")
        c.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        # start out collapsed
        c.setMaximumHeight(0)
        c.setMinimumHeight(0)

        # don't waste space
        layout.setVerticalSpacing(0)
        layout.setContentsMargins(0, 0, 0, 0)
        row = 0
        layout.addWidget(b, row, 0, 1, 1, Qt.AlignLeft)
        row += 1
        layout.addWidget(c, row, 0, 1, 3)
        self.setLayout(layout)

        b.clicked.connect(self.toggle_panel_display)
Esempio n. 6
0
    def onPinStatusChanged(self, qname, path, statusInfo):
        nodesProcessed = statusInfo['status'].get('Progress', iUnknown())

        idx = self.getIndexFromPath(path)

        if not idx:
            # Register it
            btnCancel = QToolButton()
            btnCancel.setIcon(getIcon('cancel.png'))
            btnCancel.setText(iCancel())
            btnCancel.clicked.connect(partialEnsure(self.onCancel, qname,
                                                    path))
            btnCancel.setFixedWidth(140)

            displayPath = path
            if len(displayPath) > 64:
                displayPath = displayPath[0:64] + ' ..'

            itemTs = UneditableItem(str(statusInfo['ts_queued']))
            itemQ = UneditableItem(qname)
            itemP = UneditableItem(displayPath)
            itemP.setData(path, PinObjectPathRole)
            itemP.setToolTip(path)
            itemP.lastProgressUpdate = time.time()

            itemStatus = UneditableItem(iPinning())
            itemProgress = UneditableItem(str(nodesProcessed))

            itemC = UneditableItem('')

            self.model.invisibleRootItem().appendRow(
                [itemTs, itemQ, itemP, itemStatus, itemProgress, itemC])
            idx = self.model.indexFromItem(itemC)
            self.tree.setIndexWidget(idx, btnCancel)
            self.resort()
        else:
            self.updatePinStatus(path, iPinning(), str(nodesProcessed))
Esempio n. 7
0
    def addButton(self,
                  icon_name: str,
                  on_click: Callable[[], None],
                  tooltip: str,
                  insert: bool = False) -> None:
        button = QToolButton(self)
        button.setIcon(read_QIcon(icon_name))
        # Horizontal buttons are inside the edit widget and do not have borders.
        if self.buttons_mode == ButtonsMode.INTERNAL:
            button.setStyleSheet(
                "QToolButton { border: none; hover {border: 1px} "
                "pressed {border: 1px} padding: 0px; }")
        button.setVisible(True)
        button.setToolTip(tooltip)
        button.setCursor(QCursor(Qt.PointingHandCursor))
        button.clicked.connect(on_click)
        if insert:
            self.buttons.insert(0, button)
        else:
            self.buttons.append(button)

        # Vertical buttons are integrated into the widget, within a margin that moves the edge
        # of the edit widget over to make space.
        frame_width = self.style().pixelMetric(QStyle.PM_DefaultFrameWidth)
        if self.buttons_mode == ButtonsMode.TOOLBAR_RIGHT:
            self.button_padding = max(button.sizeHint().width()
                                      for button in self.buttons) + 4
            self.setStyleSheet(self.qt_css_class + " { margin-right: " +
                               str(self.button_padding) + "px; }" +
                               self.qt_css_extra)
        elif self.buttons_mode == ButtonsMode.TOOLBAR_BOTTOM:
            self.button_padding = max(button.sizeHint().height() for button in self.buttons) + \
                frame_width
            self.setStyleSheet(self.qt_css_class + " { margin-bottom: " +
                               str(self.button_padding) + "px; }" +
                               self.qt_css_extra)
        return button
Esempio n. 8
0
    def setRightPage(self):
        '''
        设置右边的元素
        '''

        self.friendsList = QTableWidget(1, 1)
        self.friendsList.horizontalHeader().setVisible(False)
        self.friendsList.verticalHeader().setVisible(False)
        self.friendsList.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.friendsList.setFocusPolicy(Qt.NoFocus)
        # self.friendsList.setColumnWidth(0, 150)
        self.friendsList.setShowGrid(False)
        self.friendsList.setFixedWidth(180)
        self.friendsList.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.friendsList.verticalScrollBar().setStyleSheet('''
            QScrollBar{background:transparent; width: 10px;}
            QScrollBar::handle{background:lightgray; border:2px solid transparent; border-radius:5px;}
            QScrollBar::handle:hover{background:gray;}
            QScrollBar::sub-line{background:transparent;}
            QScrollBar::add-line{background:transparent;}
        ''')

        self.friendHead = QToolButton()
        self.friendHead.setText('好友列表')
        self.friendHead.setFixedSize(180, 50)
        self.friendHead.clicked.connect(self.getFrineds)

        self.friendsList.setCellWidget(0, 0, self.friendHead)
        self.friendsList.setRowHeight(0, 50)

        self.rightPageLayout = QVBoxLayout()
        self.rightPageLayout.addWidget(self.friendsList)
        self.setMenuBar()

        self.rightPage.setFixedWidth(200)
        self.rightPage.setLayout(self.rightPageLayout)
Esempio n. 9
0
 def setSearchBar(self):
     self.selectBox = QComboBox()
     self.selectBox.addItems(['书号', '分类', '出版社', '作者', '书名'])
     self.selectBox.setFixedHeight(30)
     self.searchTitle = QLabel()
     self.searchTitle.setText('搜索书籍')
     self.searchInput = QLineEdit()
     self.searchInput.setText('')
     self.searchInput.setClearButtonEnabled(True)
     self.searchInput.setFixedSize(400, 40)
     self.searchButton = QToolButton()
     self.searchButton.setFixedSize(100, 40)
     self.searchButton.setText('搜索')
     self.searchButton.clicked.connect(self.searchFunction)
     searchLayout = QHBoxLayout()
     searchLayout.addStretch()
     searchLayout.addWidget(self.selectBox)
     searchLayout.addWidget(self.searchTitle)
     searchLayout.addWidget(self.searchInput)
     searchLayout.addWidget(self.searchButton)
     searchLayout.addStretch()
     self.searchWidget = QWidget()
     self.searchWidget.setLayout(searchLayout)
     self.body.addWidget(self.searchWidget)
Esempio n. 10
0
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)

        self.vert_layout = QVBoxLayout(self)
        self.grid_layout = QGridLayout()
        self.grid_layout.setSpacing(0)

        self.status_label = QLabel('no btn')

        c = 0
        for x in range(5):
            for y in range(5):
                button = (QToolButton(self))
                button.setText(str(c))
                button.setObjectName(str([x, y]))
                button.released.connect(self.button_released)
                self.grid_layout.addWidget(button, x, y)
                c = c + 1


#        [[self.grid_layout.addWidget(QToolButton(self), x, y) for x in range(5)] for y in range(5)]

        self.vert_layout.addItem(self.grid_layout)
        self.vert_layout.addWidget(self.status_label)
Esempio n. 11
0
File: _qt.py Progetto: aces/EEG2BIDS
    def _dock_add_button(
        self, name, callback, *, style='pushbutton', tooltip=None, layout=None
    ):
        _check_option(
            parameter='style',
            value=style,
            allowed_values=('toolbutton', 'pushbutton')
        )
        if style == 'toolbutton':
            widget = QToolButton()
            widget.setText(name)
        else:
            widget = QPushButton(name)
            # Don't change text color upon button press
            widget.setStyleSheet(
                'QPushButton:pressed {color: none;}'
            )

        _set_widget_tooltip(widget, tooltip)
        widget.clicked.connect(callback)

        layout = self._dock_layout if layout is None else layout
        self._layout_add_widget(layout, widget)
        return _QtWidget(widget)
Esempio n. 12
0
    def __init__(self, text=None, parent=None):
        QFrame.__init__(self, parent)
        self.layout = QHBoxLayout()
        self.layout.setContentsMargins(3, 0, 0, 0)
        self.layout.setSpacing(0)
        self.setMaximumHeight(parent.size().height() - 4)
        self.setLayout(self.layout)

        self.keyword = text

        label = QLabel(text, self)
        delete_button = QToolButton(self)
        icon_path = os.path.dirname(os.path.realpath(__file__))
        icon_path = os.path.join(icon_path, "images/remove.png")
        delete_button.setIcon(QIcon(icon_path))
        delete_button.setStyleSheet(
            "border: 0px; background-color: transparent; margin: 0px")
        delete_button.clicked.connect(self.delete_pressed)

        self.layout.addWidget(label)
        self.layout.addWidget(delete_button)

        self.setStyleSheet(
            "background-color:#CCCCCC;color:#000000; border-radius: 2px;")
Esempio n. 13
0
    def initUI(self):
        '''
        界面初始设置
        '''
        self.resize(400, 300)
        self.setWindowTitle('关注微信公众号:学点编程吧--工具按钮(QToolButton)')

        tb = QToolButton(self)
        tb.move(100, 100)
        tb.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)  # 文字出现在图标旁边
        # tb.setArrowType(Qt.DownArrow)# 设置按钮是否显示一个箭头,这里有好几种方式。
        tb.setPopupMode(QToolButton.InstantPopup)  # 按下工具按钮菜单显示
        tb.setText('支付方式')
        tb.setIcon(QIcon('icon/bank.ico'))
        tb.setAutoRaise(True)  # 启用自动浮起

        menu = QMenu(self)
        self.alipayAct = QAction(QIcon('icon/alipay.ico'), '支付宝支付',
                                 self)  # 带图标的菜单
        self.wechatAct = QAction(QIcon('icon/wechat.ico'), '微信支付', self)
        self.visaAct = QAction(QIcon('icon/visa.ico'), 'Visa卡支付', self)
        self.master_cardAct = QAction(QIcon('icon/master_card.ico'), '万事达卡支付',
                                      self)
        menu.addAction(self.alipayAct)
        menu.addAction(self.wechatAct)
        menu.addSeparator()
        menu.addAction(self.visaAct)
        menu.addAction(self.master_cardAct)

        tb.setMenu(menu)
        self.show()

        self.alipayAct.triggered.connect(self.on_click)  # 点击菜单后连接到相应的槽函数
        self.wechatAct.triggered.connect(self.on_click)
        self.visaAct.triggered.connect(self.on_click)
        self.master_cardAct.triggered.connect(self.on_click)
Esempio n. 14
0
    def __init__(self, canvas, parent ):
        NavigationToolbar2QT.__init__(self,canvas,parent)
        self.showLegend = False
        
        # Search through existing buttons
        # next use for placement of custom button
        next=None
        for c in self.findChildren(QToolButton):
            if next is None:
                next=c
            #Verwijder buttons die we niet willen
            if str(c.text()) in ('Home','Customize','Forward','Back','Subplots'):
                c.defaultAction().setVisible(False)
                continue
            # Need to keep track of pan and zoom buttons
            if str(c.text()) in ('Pan','Zoom'):
                next=None
        
        #Define legend button
        legendButton=QAction("Toggle legend",self)
        legendButton.setIcon(QApplication.style().standardIcon(QStyle.SP_MessageBoxInformation))
        legendButton.setCheckable(True)
        legendButton.setToolTip("Toggle legend")
        self.legendButton = legendButton
        button=QToolButton(self)
        button.setDefaultAction(self.legendButton)

        #Add it to the toolbar, and connect up event
        self.insertWidget(next.defaultAction(),button)
        legendButton.toggled.connect(self.legendToggled)
        
        #Send a signal when the zoom or pan button is pressed.
        self.release_zoom('button_release_event')
        self.canvas.mpl_connect('button_release_event', self.viewChange)
        self.release_pan('button_release_event')
        self.canvas.mpl_connect('button_release_event', self.viewChange)      
Esempio n. 15
0
	def __init__(self):
		ribbon_base.__init__(self)
		self.setMaximumHeight(130)
		#self.setStyleSheet("QWidget {	background-color:cyan; }")

		self.about = QToolButton(self)
		self.about.setText(_("About"))
		self.about.pressed.connect(self.callback_about_dialog)

		self.setCornerWidget(self.about)

		w=self.experiment()
		self.addTab(w,_("Experiment"))
		
		w=self.laser()
		self.addTab(w,_("Laser"))

		w=self.simulation()
		self.addTab(w,_("Simulation"))

		sheet=self.readStyleSheet(os.path.join(get_css_path(),"style.css"))
		if sheet!=None:
			sheet=str(sheet,'utf-8')
			self.setStyleSheet(sheet)
Esempio n. 16
0
    def __init__(self, parent = None):
        super().__init__(parent)

        self.mFilter = ''
        self.mErrorTextColor = Qt.red

        layout = QHBoxLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(0)
        self.mLineEdit = QLineEdit(self)
        self.mLineEdit.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred))
        self.mOkTextColor = self.mLineEdit.palette().color(QPalette.Active, QPalette.Text)
        button = QToolButton(self)
        button.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred))
        button.setFixedWidth(20)
        button.setText("...")
        layout.addWidget(self.mLineEdit)
        layout.addWidget(button)
        self.setFocusProxy(self.mLineEdit)
        self.setFocusPolicy(Qt.StrongFocus)
        self.setAttribute(Qt.WA_InputMethodEnabled)
        self.mLineEdit.textEdited.connect(self.filePathChanged)
        self.mLineEdit.textChanged.connect(self.validate)
        button.clicked.connect(self.buttonClicked)
Esempio n. 17
0
    def initUI(self):
        self.button = QToolButton()
        self.button.setText(self.text)

        # search for icon
        icon_path = self.get_icon(self.state)

        self.button.setIcon(QIcon(icon_path))
        self.button.setIconSize(QSize(128, 128))
        self.button.setStyleSheet("padding: 10px")

        # add event handler
        self.button.clicked.connect(self.handle_click)

        # build label
        self.label = QLabel()
        self.label.setText(self.text)

        # build button with text
        layout = QGridLayout()
        layout.addWidget(self.button, 0, 0, Qt.AlignHCenter)
        layout.addWidget(self.label, 1, 0, Qt.AlignCenter)

        self.setLayout(layout)
Esempio n. 18
0
    def initGui(self):
        """Create the menu entries and toolbar icons inside the QGIS GUI."""
        self.toolButton = QToolButton()
        self.toolButton.setMenu(QMenu())
        self.toolButton.setPopupMode(QToolButton.MenuButtonPopup)
        self.toolButton.setAutoRaise(True)
        
        self.toolBtnAdd = self.iface.addToolBarWidget(self.toolButton)

        self.fragment_action = QAction(QIcon(os.path.join(
                        self.plugin_dir, 'tools/fragmentPrint', 'icon.png')),
                                        u"Create layout with fragment map", 
                                        self.iface.mainWindow())
        self.iface.addPluginToMenu(u"&PrintMap", self.fragment_action)
        m = self.toolButton.menu()
        m.addAction(self.fragment_action)
        self.toolButton.setDefaultAction(self.fragment_action)
        self.fragment_action.triggered.connect(self.run_fragmentPrint)

        self.compPrint_action = QAction(QIcon(os.path.join(
                        self.plugin_dir, 'tools/comp_print', 'icon.png')),
                                        u"Create multipage layout",
                                        self.iface.mainWindow())
        self.iface.addPluginToMenu(u"&PrintMap", self.compPrint_action)
        m = self.toolButton.menu()
        m.addAction(self.compPrint_action)
        self.compPrint_action.triggered.connect(self.run_compPrint)

        self.legend_action = QAction(QIcon(os.path.join(
                        self.plugin_dir, 'tools/userLegend', 'icon.png')), 
                                        u"Add custom legend to Layout", 
                                        self.iface.mainWindow())
        self.iface.addPluginToMenu(u"&PrintMap", self.legend_action)
        m = self.toolButton.menu()
        m.addAction(self.legend_action)
        self.legend_action.triggered.connect(self.run_userLegend)
Esempio n. 19
0
    def __createSelectionPopMenu(self):  ##创建ToolButton的下拉菜单
        menuSelection = QMenu(self)  #下拉菜单
        menuSelection.addAction(self.ui.actSel_ALL)
        menuSelection.addAction(self.ui.actSel_None)
        menuSelection.addAction(self.ui.actSel_Invs)

        #listWidget上方的 btnSelectItem 按钮
        self.ui.btnSelectItem.setPopupMode(QToolButton.MenuButtonPopup)
        ##        self.ui.btnSelectItem.setPopupMode(QToolButton.InstantPopup)
        self.ui.btnSelectItem.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
        self.ui.btnSelectItem.setDefaultAction(self.ui.actSelPopMenu)
        self.ui.btnSelectItem.setMenu(menuSelection)  #设置下拉菜单

        ##工具栏上的下拉式菜单按钮
        toolBtn = QToolButton(self)
        toolBtn.setPopupMode(QToolButton.InstantPopup)
        toolBtn.setDefaultAction(self.ui.actSelPopMenu)
        toolBtn.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
        toolBtn.setMenu(menuSelection)  #设置下拉菜单
        self.ui.mainToolBar.addWidget(toolBtn)

        #工具栏添加分隔条,和“退出”按钮
        self.ui.mainToolBar.addSeparator()
        self.ui.mainToolBar.addAction(self.ui.actQuit)
Esempio n. 20
0
def createButton(label,
                 iconPath=None,
                 toolText=None,
                 func=None,
                 focusPolicy=None,
                 enabled=True,
                 tool=False):
    """Utility function creating a button. to save typing"""

    button = QPushButton(label)
    if tool:
        button = QToolButton()
        button.setText(label)
    if iconPath is not None:
        button.setIcon(QIcon(iconPath))
    if func is not None:
        button.clicked.connect(func)
    if focusPolicy is not None:
        button.setFocusPolicy(focusPolicy)
    if toolText is not None:
        button.setToolTip(toolText)
        button.setStatusTip(toolText)
    button.setEnabled(enabled)
    return button
Esempio n. 21
0
 def __init__(self, parent: QWidget = None):
     # Constructs a frame widget with frame style NoFrame and a 1-pixel frame width.
     super(CollapsibleFrame, self).__init__(parent)
     # possible values are:
     #   QFrame.NoFrame, QFrame.Box, QFrame.Panel, QFrame.StyledPanel,
     #   QFrame.HLine, QFrame.VLine, QFrame.WinPanel
     self.setFrameShape(QFrame.StyledPanel)
     # possible values are:  QFrame.Plain, QFrame.Raised, QFrame.Sunken
     self.setFrameShadow(QFrame.Plain)
     # layout
     self._layout = QVBoxLayout()
     self._layout.setContentsMargins(0, 0, 0, 0)
     self._layout.setSpacing(0)
     self.setLayout(self._layout)
     # button
     self._button = QToolButton(self)
     self._button.setArrowType(Qt.RightArrow)
     self._button.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
     self._button.setAutoRaise(False)
     self._button.setText('CollapsibleFrame')
     self._button.setSizePolicy(QSizePolicy.MinimumExpanding,
                                QSizePolicy.Fixed)
     self._layout.addWidget(self._button, 0)
     self._button.setVisible(True)
     # group box
     self._panel = QWidget(self)
     self._layout.addWidget(self._panel)
     self._panel.setVisible(False)
     self._panel_layout = QVBoxLayout()
     self._panel_layout.setContentsMargins(1, 1, 1, 1)
     self._panel_layout.setSpacing(2)
     self._panel.setLayout(self._panel_layout)
     # connect signals
     self._button.clicked.connect(self.on_button_click)
     # private state variables
     self._is_collapsed = True
Esempio n. 22
0
    def __init__(self, icon: QIcon, action, i18n: I18n, background: str = None, align: int = Qt.AlignCenter, tooltip: str = None, expanding: bool = False):
        super(IconButton, self).__init__()
        self.bt = QToolButton()
        self.bt.setCursor(QCursor(Qt.PointingHandCursor))
        self.bt.setIcon(icon)
        self.bt.clicked.connect(action)
        self.i18n = i18n
        self.default_tootip = tooltip
        self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
        self.bt.setSizePolicy(QSizePolicy.Expanding if expanding else QSizePolicy.Minimum, QSizePolicy.Minimum)

        if background:
            style = 'QToolButton { color: white; background: ' + background + '} '
            style += 'QToolButton:disabled { color: white; background: blue }'
            self.bt.setStyleSheet(style)

        if tooltip:
            self.bt.setToolTip(tooltip)

        layout = QHBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setAlignment(align)
        layout.addWidget(self.bt)
        self.setLayout(layout)
Esempio n. 23
0
    def create_button(self, index, button_text, _):
        button = QToolButton(self.dialog_widget)
        button.setText(button_text)
        button.setFixedHeight(26)
        button.setCursor(QCursor(Qt.PointingHandCursor))
        self.buttons.append(button)

        button.setStyleSheet("""
        QToolButton {
            border: 1px solid #B5B5B5;
            border-radius: 13px;
            color: white;
            padding-left: 4px;
            padding-right: 4px;
        }

        QToolButton::hover {
            border: 1px solid white;
            color: white;
        }
        """)

        self.dialog_widget.dialog_button_container.layout().addWidget(button)
        button.clicked.connect(lambda: self.button_clicked.emit(index))
Esempio n. 24
0
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.mqtw = mqtw(self)
        self.mqtw.showSearchOptions(True)
        self.mqtw.showSearchCloseButton(False)
        self.mqtw.setGenericContextMenu()
        self.mqtwSelected = mqtw(self)
        self.mqtwSelected.showSearchOptions(True)
        self.mqtwSelected.showSearchCloseButton(False)
        self.mqtwSelected.setGenericContextMenu()

        self.laybuttons = QVBoxLayout()
        self.cmdLeft = QToolButton(self)
        self.cmdLeft.setText("<")
        self.cmdLeftAll = QToolButton(self)
        self.cmdLeftAll.setText("<<")
        self.cmdRight = QToolButton(self)
        self.cmdRight.setText(">")
        self.cmdRightAll = QToolButton(self)
        self.cmdRightAll.setText(">>")
        self.cmdDown = QToolButton(self)
        self.cmdUp = QToolButton(self)
        self.laybuttons.addWidget(self.cmdUp)
        self.laybuttons.addWidget(self.cmdRightAll)
        self.laybuttons.addWidget(self.cmdRight)
        self.laybuttons.addWidget(self.cmdLeft)
        self.laybuttons.addWidget(self.cmdLeftAll)
        self.laybuttons.addWidget(self.cmdDown)
        self.laybuttons.setAlignment(Qt.AlignVCenter)

        self.cmdDown.hide()
        self.cmdUp.hide()

        self.lay = QHBoxLayout(self)
        self.lay.addWidget(self.mqtw)
        self.lay.addLayout(self.laybuttons)
        self.lay.addWidget(self.mqtwSelected)
        self._showObjectIcons = True
        self._showObjectCallingByName = "name"
Esempio n. 25
0
    def __init__(self, *args):
        QMainWindow.__init__(self, *args)
        self.d_plot = Plot(self)
        margin = 5
        self.d_plot.setContentsMargins(margin, margin, margin, 0)

        self.setContextMenuPolicy(Qt.NoContextMenu)

        self.d_zoomer = [None, None]
        self.d_zoomer[0] = Zoomer(Qwt.QwtPlot.xBottom, Qwt.QwtPlot.yLeft,
                                  self.d_plot.canvas())
        self.d_zoomer[0].setRubberBand(Qwt.QwtPicker.RectRubberBand)
        self.d_zoomer[0].setRubberBandPen(QColor(Qt.green))
        self.d_zoomer[0].setTrackerMode(Qwt.QwtPicker.ActiveOnly)
        self.d_zoomer[0].setTrackerPen(QColor(Qt.white))

        self.d_zoomer[1] = Zoomer(Qwt.QwtPlot.xTop, Qwt.QwtPlot.yRight,
                                  self.d_plot.canvas())
        self.d_panner = Qwt.QwtPlotPanner(self.d_plot.canvas())
        self.d_panner.setMouseButton(Qt.MidButton)

        self.d_picker = Qwt.QwtPlotPicker(Qwt.QwtPlot.xBottom,
                                          Qwt.QwtPlot.yLeft,
                                          Qwt.QwtPlotPicker.CrossRubberBand,
                                          Qwt.QwtPicker.AlwaysOn,
                                          self.d_plot.canvas())
        self.d_picker.setStateMachine(Qwt.QwtPickerDragPointMachine())
        self.d_picker.setRubberBandPen(QColor(Qt.green))
        self.d_picker.setRubberBand(Qwt.QwtPicker.CrossRubberBand)
        self.d_picker.setTrackerPen(QColor(Qt.white))

        self.setCentralWidget(self.d_plot)

        self.toolBar = QToolBar(self)

        self.btnZoom = QToolButton(self.toolBar)
        self.btnZoom.setText("Zoom")
        self.btnZoom.setIcon(QIcon(QPixmap(zoom_xpm)))
        self.btnZoom.setCheckable(True)
        self.btnZoom.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
        self.toolBar.addWidget(self.btnZoom)
        self.btnZoom.toggled.connect(self.enableZoomMode)

        self.btnPrint = QToolButton(self.toolBar)
        self.btnPrint.setText("Print")
        self.btnPrint.setIcon(QIcon(QPixmap(print_xpm)))
        self.btnPrint.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
        self.toolBar.addWidget(self.btnPrint)
        self.btnPrint.clicked.connect(self.mprint)

        self.btnExport = QToolButton(self.toolBar)
        self.btnExport.setText("Export")
        self.btnExport.setIcon(QIcon(QPixmap(print_xpm)))
        self.btnExport.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
        self.toolBar.addWidget(self.btnExport)
        self.btnExport.clicked.connect(self.exportDocument)

        self.toolBar.addSeparator()

        hBox = QWidget(self.toolBar)

        self.layout = QHBoxLayout(hBox)
        self.layout.setSpacing(0)
        self.layout.addWidget(QWidget(hBox), 10)  # spacer
        self.layout.addWidget(QLabel("Damping Factor", hBox), 0)
        self.layout.addSpacing(10)

        self.cntDamp = Qwt.QwtCounter(hBox)
        self.cntDamp.setRange(0.0, 5.0)
        self.cntDamp.setSingleStep(0.01)
        self.cntDamp.setValue(0.0)

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

        self.toolBar.addWidget(hBox)

        self.addToolBar(self.toolBar)
        self.statusBar()
        self.enableZoomMode(False)
        self.showInfo()

        self.cntDamp.valueChanged['double'].connect(self.d_plot.setDamp)
        self.d_picker.moved.connect(self.moved)
    def __init__(self,
                 *,
                 parent: 'ElectrumWindow',
                 desc,
                 prompt_if_unsaved,
                 finalized: bool,
                 external_keypairs=None):
        '''Transactions in the wallet will show their description.
        Pass desc to give a description for txs not yet in the wallet.
        '''
        # We want to be a top-level window
        QDialog.__init__(self, parent=None)
        self.tx = None  # type: Optional[Transaction]
        self.external_keypairs = external_keypairs
        self.finalized = finalized
        self.main_window = parent
        self.config = parent.config
        self.wallet = parent.wallet
        self.prompt_if_unsaved = prompt_if_unsaved
        self.saved = False
        self.desc = desc
        self.external_keypairs = None
        self.setMinimumWidth(950)
        self.set_title()

        self.psbt_only_widgets = []  # type: List[QWidget]

        vbox = QVBoxLayout()
        self.setLayout(vbox)

        vbox.addWidget(QLabel(_("Transaction ID:")))
        self.tx_hash_e = ButtonsLineEdit()
        qr_show = lambda: parent.show_qrcode(
            str(self.tx_hash_e.text()), 'Transaction ID', parent=self)
        qr_icon = "qrcode_white.png" if ColorScheme.dark_scheme else "qrcode.png"
        self.tx_hash_e.addButton(qr_icon, qr_show, _("Show as QR code"))
        self.tx_hash_e.setReadOnly(True)
        vbox.addWidget(self.tx_hash_e)

        self.add_tx_stats(vbox)

        vbox.addSpacing(10)

        self.inputs_header = QLabel()
        vbox.addWidget(self.inputs_header)
        self.inputs_textedit = QTextEditWithDefaultSize()
        vbox.addWidget(self.inputs_textedit)
        self.outputs_header = QLabel()
        vbox.addWidget(self.outputs_header)
        self.outputs_textedit = QTextEditWithDefaultSize()
        vbox.addWidget(self.outputs_textedit)
        self.sign_button = b = QPushButton(_("Sign"))
        b.clicked.connect(self.sign)

        self.broadcast_button = b = QPushButton(_("Broadcast"))
        b.clicked.connect(self.do_broadcast)

        self.save_button = b = QPushButton(_("Save"))
        b.clicked.connect(self.save)

        self.cancel_button = b = QPushButton(_("Close"))
        b.clicked.connect(self.close)
        b.setDefault(True)

        self.export_actions_menu = export_actions_menu = QMenu()
        self.add_export_actions_to_menu(export_actions_menu)
        export_actions_menu.addSeparator()
        export_submenu = export_actions_menu.addMenu(
            _("For CoinJoin; strip privates"))
        self.add_export_actions_to_menu(export_submenu,
                                        gettx=self._gettx_for_coinjoin)
        self.psbt_only_widgets.append(export_submenu)
        export_submenu = export_actions_menu.addMenu(
            _("For hardware device; include xpubs"))
        self.add_export_actions_to_menu(export_submenu,
                                        gettx=self._gettx_for_hardware_device)
        self.psbt_only_widgets.append(export_submenu)

        self.export_actions_button = QToolButton()
        self.export_actions_button.setText(_("Export"))
        self.export_actions_button.setMenu(export_actions_menu)
        self.export_actions_button.setPopupMode(QToolButton.InstantPopup)

        self.finalize_button = QPushButton(_('Finalize'))
        self.finalize_button.clicked.connect(self.on_finalize)

        partial_tx_actions_menu = QMenu()
        ptx_merge_sigs_action = QAction(_("Merge signatures from"), self)
        ptx_merge_sigs_action.triggered.connect(self.merge_sigs)
        partial_tx_actions_menu.addAction(ptx_merge_sigs_action)
        ptx_join_txs_action = QAction(_("Join inputs/outputs"), self)
        ptx_join_txs_action.triggered.connect(self.join_tx_with_another)
        partial_tx_actions_menu.addAction(ptx_join_txs_action)
        self.partial_tx_actions_button = QToolButton()
        self.partial_tx_actions_button.setText(_("Combine"))
        self.partial_tx_actions_button.setMenu(partial_tx_actions_menu)
        self.partial_tx_actions_button.setPopupMode(QToolButton.InstantPopup)
        self.psbt_only_widgets.append(self.partial_tx_actions_button)

        # Action buttons
        self.buttons = [
            self.partial_tx_actions_button, self.sign_button,
            self.broadcast_button, self.cancel_button
        ]
        # Transaction sharing buttons
        self.sharing_buttons = [
            self.finalize_button, self.export_actions_button, self.save_button
        ]
        run_hook('transaction_dialog', self)
        if not self.finalized:
            self.create_fee_controls()
            vbox.addWidget(self.feecontrol_fields)
        self.hbox = hbox = QHBoxLayout()
        hbox.addLayout(Buttons(*self.sharing_buttons))
        hbox.addStretch(1)
        hbox.addLayout(Buttons(*self.buttons))
        vbox.addLayout(hbox)
        self.set_buttons_visibility()

        dialogs.append(self)
    def __init__(self, compare_frame_controller: CompareFrameController,
                 generator_tab_controller: GeneratorTabController,
                 project_manager: ProjectManager, parent):
        super().__init__(parent)

        self.project_manager = project_manager
        self.compare_frame_controller = compare_frame_controller
        self.generator_tab_controller = generator_tab_controller
        self.proto_analyzer = compare_frame_controller.proto_analyzer

        self.simulator_config = SimulatorConfiguration(self.project_manager)
        self.sim_expression_parser = SimulatorExpressionParser(
            self.simulator_config)
        SimulatorItem.simulator_config = self.simulator_config
        SimulatorItem.expression_parser = self.sim_expression_parser

        self.ui = Ui_SimulatorTab()
        self.ui.setupUi(self)
        util.set_splitter_stylesheet(self.ui.splitter)
        util.set_splitter_stylesheet(self.ui.splitterLeftRight)

        self.ui.splitter.setSizes([self.width() / 0.7, self.width() / 0.3])

        self.ui.treeProtocols.setHeaderHidden(True)
        self.tree_model = self.generator_tab_controller.tree_model
        self.ui.treeProtocols.setModel(self.tree_model)

        self.participant_table_model = ParticipantTableModel(
            project_manager.participants)
        self.ui.tableViewParticipants.setModel(self.participant_table_model)
        self.participant_table_model.update()

        self.simulator_message_field_model = SimulatorMessageFieldModel(self)
        self.ui.tblViewFieldValues.setModel(self.simulator_message_field_model)
        self.ui.tblViewFieldValues.setItemDelegateForColumn(
            1,
            ComboBoxDelegate(ProtocolLabel.DISPLAY_FORMATS,
                             parent=self.ui.tblViewFieldValues))
        self.ui.tblViewFieldValues.setItemDelegateForColumn(
            2,
            ComboBoxDelegate(SimulatorProtocolLabel.VALUE_TYPES,
                             parent=self.ui.tblViewFieldValues))
        self.ui.tblViewFieldValues.setItemDelegateForColumn(
            3,
            ProtocolValueDelegate(controller=self,
                                  parent=self.ui.tblViewFieldValues))
        self.project_manager.reload_field_types()
        self.update_field_name_column()

        self.simulator_message_table_model = SimulatorMessageTableModel(
            self.project_manager, self)
        self.ui.tblViewMessage.setModel(self.simulator_message_table_model)

        self.ui.ruleCondLineEdit.setValidator(
            RuleExpressionValidator(self.sim_expression_parser,
                                    is_formula=False))
        self.completer_model = QStringListModel([])
        self.ui.ruleCondLineEdit.setCompleter(
            QCompleter(self.completer_model, self.ui.ruleCondLineEdit))
        self.ui.ruleCondLineEdit.setToolTip(
            self.sim_expression_parser.rule_condition_help)

        self.simulator_scene = SimulatorScene(
            mode=0, simulator_config=self.simulator_config)
        self.simulator_scene.tree_root_item = compare_frame_controller.proto_tree_model.rootItem
        self.ui.gvSimulator.setScene(self.simulator_scene)
        self.ui.gvSimulator.setAlignment(Qt.AlignLeft | Qt.AlignTop)
        self.ui.gvSimulator.proto_analyzer = compare_frame_controller.proto_analyzer

        self.__active_item = None

        self.ui.listViewSimulate.setModel(
            SimulatorParticipantListModel(self.simulator_config))
        self.ui.spinBoxNRepeat.setValue(
            self.project_manager.simulator_num_repeat)
        self.ui.spinBoxTimeout.setValue(
            self.project_manager.simulator_timeout_ms)
        self.ui.spinBoxRetries.setValue(self.project_manager.simulator_retries)
        self.ui.comboBoxError.setCurrentIndex(
            self.project_manager.simulator_error_handling_index)

        # place save/load button at corner of tab widget
        frame = QFrame(parent=self)
        frame.setLayout(QHBoxLayout())
        frame.setFrameStyle(frame.NoFrame)
        self.ui.btnSave = QToolButton(self.ui.tab)
        self.ui.btnSave.setIcon(QIcon.fromTheme("document-save"))
        frame.layout().addWidget(self.ui.btnSave)

        self.ui.btnLoad = QToolButton(self.ui.tab)
        self.ui.btnLoad.setIcon(QIcon.fromTheme("document-open"))
        frame.layout().addWidget(self.ui.btnLoad)
        frame.layout().setContentsMargins(0, 0, 0, 0)
        self.ui.tabWidget.setCornerWidget(frame)

        self.ui.splitterLeftRight.setSizes(
            [0.2 * self.width(), 0.8 * self.width()])

        self.create_connects()
Esempio n. 28
0
    def _create_effect_controls(self, zone, effect_options):
        """
        Groups all options with the "effect" type and present them as larger buttons.
        """
        widgets = []
        self.btn_grps[zone] = QButtonGroup()

        for effect in effect_options:
            fx_id = effect["id"]
            fx_params = effect["parameters"]
            fx_string = effect["label"]
            fx_active = effect["active"]
            fx_colours = effect["colours"]

            button = QToolButton()
            button.setText(fx_string)
            button.setCheckable(True)
            button.setIconSize(QSize(40, 40))
            button.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
            button.setIcon(QIcon(common.get_icon("options", fx_id)))
            button.setMinimumHeight(70)
            button.setMinimumWidth(70)
            button.effect = effect
            button.zone = zone
            self.btn_grps[zone].addButton(button)

            if fx_active:
                button.setChecked(True)

            widgets.append(button)

        def _clicked_effect_button(button):
            effect = button.effect
            zone = button.zone
            param_count = len(effect["parameters"])
            option_id = effect["id"]
            option_data = None
            colour_hex = []

            # Use saved colour, if available for this effect
            if len(effect["parameters"]) == 0:
                colour_hex = effect["colours"]

            # For effects with parameters, the second one will be used as the first may be 'random' or 'off'.
            if param_count > 0:
                if param_count == 1:
                    param = effect["parameters"][0]
                elif param_count >= 2:
                    param = effect["parameters"][1]

                option_data = param["data"]
                colour_hex = param["colours"]

            self.dbg.stdout("Setting effect {0} (data: {1}) on {2} device {3} (zone: {4}, colours: {5})".format(option_id, str(option_data), self.current_backend, self.current_uid, zone, str(colour_hex)), self.dbg.action, 1)
            response = self.middleman.set_device_state(self.current_backend, self.current_uid, self.current_serial, zone, option_id, option_data, colour_hex)
            self._event_check_response(response)
            self.reload_device()

        self.btn_grps[zone].buttonClicked.connect(_clicked_effect_button)

        if not widgets:
            return None

        return self.widgets.create_row_widget(self._("Effect"), widgets, wrap=True)
Esempio n. 29
0
    def __init__(self, *args, **kwargs):
        url = "http://127.0.0.1:43110/1HeLLo4uzjaLetFx6NH3PMwFP3qbRbTf3D/"
        if "url" in kwargs:
            url = kwargs["url"]
            del kwargs["url"]

        if "zeronet_path" in kwargs:
            self.zeronet_path = kwargs["zeronet_path"]
            del kwargs["zeronet_path"]

        super(MainWindow, self).__init__(*args, **kwargs)

        # Tabs
        self.tabs = QTabWidget()
        self.tabs.setTabsClosable(True)
        self.tabs.tabCloseRequested.connect(self.close_tab)

        # New tab button
        #self.tab_add_button_index = self.tabs.addTab(QWidget(), '+')
        self.add_tab_button = QToolButton()
        self.add_tab_button.setText('+')
        self.add_tab_button.setStyleSheet(
            'QToolButton {border: none; margin: 4px 20px 4px 0px; height: 480px; border-left: 1px solid lightgrey; padding: 0px 4px 0px 4px; font-weight: bold; color: #5d5b59}'
            'QToolButton:hover { background-color: lightgrey }'
            'QToolButton:pressed { background-color: grey }')
        self.add_tab_button.clicked.connect(self.new_tab_clicked)
        self.tabs.setCornerWidget(self.add_tab_button)

        # Navigation bar
        self.navigation = NavigationBar()
        self.navigation.url_bar.returnPressed.connect(self.navigate_to_url)

        # Back
        self.navigation.back_btn.triggered.connect(
            lambda: self.tabs.currentWidget().back())

        # Next
        self.navigation.next_btn.triggered.connect(
            lambda: self.tabs.currentWidget().forward())

        # Reload
        self.navigation.reload_btn.triggered.connect(
            lambda: self.tabs.currentWidget().reload())
        self.navigation.shortcut_reload.activated.connect(
            lambda: self.tabs.currentWidget().reload())
        self.navigation.shortcut_reload_f5.activated.connect(
            lambda: self.tabs.currentWidget().reload())

        # Home
        self.navigation.home_btn.triggered.connect(self.go_home)

        # Menu: Edit config action
        self.navigation.edit_config_action.triggered.connect(
            self.edit_zeronet_config_file)

        # Add new tab
        self.add_new_tab(url, "Home")

        # Get everything fitting in the main window
        self.addToolBar(self.navigation)
        self.setCentralWidget(self.tabs)
        self.show()
        self.setWindowTitle("ZeroNet Browser")
        self.setWindowIcon(QIcon("icons/zeronet-logo.svg"))
        self.showMaximized()
Esempio n. 30
0
    def __init__(self):
        super().__init__()

        self.settings = QSettings("Vial", "Vial")
        themes.set_theme(self.get_theme())

        self.current_device = None
        self.devices = []
        # create empty VIA definitions. Easier than setting it to none and handling a bunch of exceptions
        self.via_stack_json = {"definitions": {}}
        self.sideload_json = None
        self.sideload_vid = self.sideload_pid = -1

        self.combobox_devices = QComboBox()
        self.combobox_devices.currentIndexChanged.connect(
            self.on_device_selected)

        self.btn_refresh_devices = QToolButton()
        self.btn_refresh_devices.setToolButtonStyle(Qt.ToolButtonTextOnly)
        self.btn_refresh_devices.setText(tr("MainWindow", "Refresh"))
        self.btn_refresh_devices.clicked.connect(self.on_click_refresh)

        layout_combobox = QHBoxLayout()
        layout_combobox.addWidget(self.combobox_devices)
        layout_combobox.addWidget(self.btn_refresh_devices)

        self.layout_editor = LayoutEditor()
        self.keymap_editor = KeymapEditor(self.layout_editor)
        self.firmware_flasher = FirmwareFlasher(self)
        self.macro_recorder = MacroRecorder()
        self.matrix_tester = MatrixTest(self.layout_editor)

        self.editors = [(self.keymap_editor, "Keymap"),
                        (self.layout_editor, "Layout"),
                        (self.macro_recorder, "Macros"),
                        (self.matrix_tester, "Matrix tester"),
                        (self.firmware_flasher, "Firmware updater")]
        Unlocker.global_layout_editor = self.layout_editor

        self.tabs = QTabWidget()
        self.refresh_tabs()

        self.lbl_no_devices = QLabel(
            tr(
                "MainWindow",
                'No devices detected. Connect a Vial-compatible device and press '
                '"Refresh"\n'
                'or select "File" → "Download VIA definitions" in order to enable'
                ' support for VIA keyboards.'))
        self.lbl_no_devices.setAlignment(Qt.AlignCenter)

        layout = QVBoxLayout()
        layout.addLayout(layout_combobox)
        layout.addWidget(self.tabs)
        layout.addWidget(self.lbl_no_devices)
        layout.setAlignment(self.lbl_no_devices, Qt.AlignHCenter)
        w = QWidget()
        w.setLayout(layout)
        self.setCentralWidget(w)

        self.init_menu()

        # cache for via definition files
        self.cache_path = QStandardPaths.writableLocation(
            QStandardPaths.CacheLocation)
        if not os.path.exists(self.cache_path):
            os.makedirs(self.cache_path)
        # check if the via defitions already exist
        if os.path.isfile(os.path.join(self.cache_path, "via_keyboards.json")):
            with open(os.path.join(self.cache_path,
                                   "via_keyboards.json")) as vf:
                self.via_stack_json = json.load(vf)
                vf.close()

        # make sure initial state is valid
        self.on_click_refresh()