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])
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)
class PlayerControlPanel(FFrame): def __init__(self, app, parent=None): super().__init__(parent) self._app = app self._layout = QHBoxLayout(self) self.previous_btn = PlayerControlButton(self._app, '上一首', self) self.pp_btn = PlayerControlButton(self._app, '播放', self) self.next_btn = PlayerControlButton(self._app, '下一首', self) self.progress_slider = ProgressSlider(self._app, self) self.volume_slider = VolumeSlider(self._app, self) self.progress_label = ProgressLabel(self._app, '00:00/00:00', self) self._btn_container = FFrame(self) self._slider_container = FFrame(self) self._bc_layout = QHBoxLayout(self._btn_container) self._sc_layout = QHBoxLayout(self._slider_container) self.setObjectName('pc_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}; }} '''.format(self.objectName(), theme.foreground.name(), theme.color0.name()) self.setStyleSheet(style_str) def setup_ui(self): self._btn_container.setFixedWidth(140) self._slider_container.setMinimumWidth(700) self.progress_label.setFixedWidth(90) self._layout.setSpacing(0) self._layout.setContentsMargins(0, 0, 0, 0) self._bc_layout.setSpacing(0) self._bc_layout.setContentsMargins(0, 0, 0, 0) self._bc_layout.addWidget(self.previous_btn) self._bc_layout.addStretch(1) self._bc_layout.addWidget(self.pp_btn) self._bc_layout.addStretch(1) self._bc_layout.addWidget(self.next_btn) self._sc_layout.addWidget(self.progress_slider) self._sc_layout.addSpacing(2) self._sc_layout.addWidget(self.progress_label) self._sc_layout.addSpacing(5) self._sc_layout.addWidget(self.volume_slider) self._layout.addWidget(self._btn_container) self._layout.addSpacing(10) self._layout.addWidget(self._slider_container)
def __init__(self, main_window, items): """ Connects to menu_btn_clicked signal and also emits it when button is clicked. """ super().__init__() self.hide() hbox = QHBoxLayout() hbox.setSpacing(0) hbox.setContentsMargins(0, 0, 0, 0) self.setLayout(hbox) hbox.addSpacing(25) main_window.communication.user_selected.connect(self._show) main_window.communication.menu_btn_clicked.connect(self._item_selected) self.buttons = [] labels = [each['sys'] for each in options.CONTROL_BUTTONS_LABELS] for i, text in enumerate(labels): btn = QPushButton(_(text)) self.buttons.append(btn) if i == 0: btn.setStyleSheet(self.BUTTON_SELECTED_QSS) btn.clicked.connect(functools.partial(main_window.communication.menu_btn_clicked.emit, i)) hbox.addWidget(btn) SelectItemMenu(main_window, self, items) self.buttons[0].setText(_(main_window.items[0].name)) self.buttons[0].setFixedWidth(int(main_window.width() / 5)) hbox.addStretch()
class Ui(object): def __init__(self, app): super().__init__() self._app = app self.login_dialog = LoginDialog(self._app, self._app) self.login_btn = LoginButton(self._app) self._lb_container = FFrame() self.songs_table_container = SongsTable_Container(self._app) self._lbc_layout = QHBoxLayout(self._lb_container) self.setup() def setup(self): self._lbc_layout.setContentsMargins(0, 0, 0, 0) self._lbc_layout.setSpacing(0) self._lbc_layout.addWidget(self.login_btn) self.login_btn.setFixedSize(30, 30) self._lbc_layout.addSpacing(10) tp_layout = self._app.ui.top_panel.layout() tp_layout.addWidget(self._lb_container)
def __init__(self, parent=None): super(Login, self).__init__(parent) usr = QLabel(u"用户:") pwd = QLabel(u"密码:") self.usrLineEdit = QLineEdit() self.pwdLineEdit = QLineEdit() self.pwdLineEdit.setEchoMode(QLineEdit.Password) gridLayout = QGridLayout() gridLayout.addWidget(usr, 0, 0, 1, 1) gridLayout.addWidget(pwd, 1, 0, 1, 1) gridLayout.addWidget(self.usrLineEdit, 0, 1, 1, 3); gridLayout.addWidget(self.pwdLineEdit, 1, 1, 1, 3); okBtn = QPushButton(u"确定") cancelBtn = QPushButton(u"取消") btnLayout = QHBoxLayout() btnLayout.setSpacing(60) btnLayout.addWidget(okBtn) btnLayout.addWidget(cancelBtn) dlgLayout = QVBoxLayout() dlgLayout.setContentsMargins(40, 40, 40, 40) dlgLayout.addLayout(gridLayout) dlgLayout.addStretch(40) dlgLayout.addLayout(btnLayout) self.setLayout(dlgLayout) okBtn.clicked.connect(self.accept) cancelBtn.clicked.connect(self.reject) self.setWindowTitle(u"登录") self.resize(300, 200)
class OUi(object): def __init__(self, app): self._app = app self.songs_table_container = SongsTableContainer(self._app) self._lb_container = MFrame() self.login_dialog = LoginDialog(self._app, self._app) self.playlist_dialog = PlaylistDialog(self._app, self._app) self.login_btn = LoginButton(self._app) self.music_database_item = LPGroupItem(self._app, '音乐库') self.music_database_item.set_img_text('Ω') self._lbc_layout = QHBoxLayout(self._lb_container) self.setup() def setup(self): self._lbc_layout.setContentsMargins(0, 0, 0, 0) self._lbc_layout.setSpacing(0) self._lbc_layout.addWidget(self.login_btn) self.login_btn.setFixedSize(30, 30) self._lbc_layout.addSpacing(10) # TODO: connect with Main APP tp_layout = self._app.ui.top_panel.layout() tp_layout.addWidget(self._lb_container) library_panel = self._app.ui.central_panel.left_panel.library_panel library_panel.add_item(self.music_database_item) # action in OO.py
class LoginDialog(MDialog): def __init__(self, app, parent=None): super().__init__(parent) self._app = app self.username_input = LineInput(self) self.password_input = LineInput(self) self.password_input.setEchoMode(MQLineEdit.Password) self.login_btn = MButton('登录', self) self.register_btn = MButton('注册', self) self._login_frame = MFrame() self._login_layout = QHBoxLayout(self._login_frame) self._layout = QVBoxLayout(self) self.username_input.setPlaceholderText('用户名或管理员backdoor登录') self.password_input.setPlaceholderText('密码') self.setObjectName('login_dialog') self.set_theme_style() self.setup_ui() def setup_ui(self): self.setFixedWidth(200) self._login_layout.setContentsMargins(0, 0, 0, 0) self._login_layout.setSpacing(1) self._login_layout.addWidget(self.login_btn) self._login_layout.addWidget(self.register_btn) self._layout.setContentsMargins(0, 0, 0, 0) self._layout.setSpacing(0) self._layout.addWidget(self.username_input) self._layout.addWidget(self.password_input) self._layout.addWidget(self._login_frame)
def _get_controls_layout(self, layout): """ Return buttons layout """ hbox = QHBoxLayout() hbox.addStretch() hbox.setContentsMargins(0, 0, 0, 0) hbox.setSpacing(10) args = ((' Сохранить', ' Закрыть'), ('save', 'close'), ('save_w.png', 'close.png'), (self._save, self._close)) for l, n, i, f in zip(*args): b = QPushButton(l) b.clicked.connect(f) b.setObjectName(n) b.setIcon(QIcon(os.path.join(options.STATIC_DIR, 'icons', i))) b.setGraphicsEffect(utils.get_shadow()) hbox.addWidget(b) if self.item: b = QPushButton('Удалить') b.setObjectName('delete') b.clicked.connect(self._delete) b.setGraphicsEffect(utils.get_shadow()) hbox.addWidget(b) return hbox
def _get_combobox(self, column, relations, main_window): """ Return combobox for foreign fields. """ label = column.name if label.endswith('_id'): label = label[:-3] foreign_model = relations.get(label).mapper.class_ items = list(db.SESSION.query(foreign_model).filter(foreign_model.deleted == False)) self.foreigns[column.name] = items items_labels = [str(i) for i in items] widget = QWidget() widget.setStyleSheet('margin:0;') combo_box = QComboBox() combo_box.addItems(items_labels) combo_box.currentIndexChanged.connect(self._check_input) combo_box.setObjectName(column.name) hbox = QHBoxLayout() hbox.setContentsMargins(0, 0, 0, 0) hbox.setSpacing(0) hbox.addWidget(combo_box, stretch=95) for icon, new in zip(('pencil_g.png', 'plus.png'), (False, True)): b = QPushButton() b.setObjectName('icon') b.setIcon(QIcon(os.path.join(options.STATIC_DIR, 'icons', icon))) b.clicked.connect(functools.partial( self.open_crud, main_window, foreign_model, new, combo_box)) hbox.addWidget(b, stretch=2) widget.setLayout(hbox) return label, widget
def buildWidget(self): layout = QHBoxLayout(self) layout.setContentsMargins(0,0,0,0) SettingMenu = QMenu() exitButton = QAction(QIcon('exit24.png'), 'Set As High', self) exitButton.triggered.connect(self.setHigh) SettingMenu.addAction(exitButton) setlowButton = QAction(QIcon('exit24.png'), 'Set As Low', self) setlowButton.triggered.connect(self.setLow) SettingMenu.addAction(setlowButton) self.tb_down = QToolButton() self.tb_down.pressed.connect(self.on_click_down) self.tb_down.released.connect(self.on_released) self.tb_down.setArrowType(Qt.LeftArrow) self.tb_up = QToolButton() self.tb_up.pressed.connect(self.on_click_up) self.tb_up.released.connect(self.on_released) self.tb_up.setArrowType(Qt.RightArrow) if self.showToggleButton: tb_set = QToolButton() tb_set.clicked.connect(self.on_click_set_value) tb_set.setText('<>') if self.showSettingMenu: tb_set.setMenu(SettingMenu) tb_set.setPopupMode(QToolButton.DelayedPopup) layout.addWidget(self.tb_down) layout.addWidget(self.bar) layout.addWidget(self.tb_up) if self.showToggleButton: layout.addWidget(tb_set) layout.setSpacing(0)
def initUI(self, windowType): self.setStyleSheet(""" #cmdLine, #bar, #bar > * { border: 0px; background: #070707; font-family: "Pro Font"; font-size: 10px; color: white; min-height: 17px } """) self.setWindowTitle('shower') self.setAttribute(Qt.WA_DeleteOnClose) vbox = QVBoxLayout() self.setLayout(vbox) vbox.setContentsMargins(0, 0, 0, 0) vbox.setSpacing(0) bar = QWidget() bar.setObjectName('bar') hbox = QHBoxLayout() hbox.setContentsMargins(2, 0, 0, 0) hbox.setSpacing(0) bar.setLayout(hbox) vbox.addWidget(bar) self.urlLabel = QLabel() self.urlLabel.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Preferred) self.urlLabel.setTextFormat(Qt.RichText) hbox.addWidget(self.urlLabel) hbox.setStretch(0, 1) self.progressLabel = QLabel() self.progressLabel.setTextFormat(Qt.RichText) hbox.addWidget(self.progressLabel) self.cmdLine = QLineEdit() self.cmdLine.setObjectName('cmdLine') vbox.addWidget(self.cmdLine) self.webView = QWebEngineView() self.webView.setPage(BrowserPage(self)) vbox.addWidget(self.webView) self.cmdLine.returnPressed.connect(self.handleCommand) self.webView.page().linkHovered.connect(self.onLinkHovered) self.webView.page().urlChanged.connect(self.urlChanged) self.webView.page().titleChanged.connect(self.onTitleChanged) self.webView.page().loadProgress.connect(self.onLoadProgress) self.webView.page().loadStarted.connect(self.onLoadStarted) self.webView.page().loadFinished.connect(self.onLoadFinished) self.urlChanged.connect(self.onUrlChanged) self.addShortcut("Alt+Left", lambda: self.webView.page().triggerAction(QWebEnginePage.Back)) self.addShortcut("Alt+Right", lambda: self.webView.page().triggerAction(QWebEnginePage.Forward)) self.addShortcut("Ctrl+R", lambda: self.webView.page().triggerAction(QWebEnginePage.Reload)) self.addShortcut("Ctrl+Shift+R", lambda: self.webView.page().triggerAction(QWebEnginePage.ReloadAndBypassCache)) self.stopShortcut = self.addShortcut("Esc", lambda: self.webView.page().triggerAction(QWebEnginePage.Stop)) self.addShortcut("Ctrl+W", lambda: self.close()) self.addShortcut("Ctrl+L", lambda: self.beginEnteringCommand(None)) self.addShortcut("Ctrl+K", lambda: self.beginEnteringCommand('? ')) self.addShortcut("Ctrl+/", lambda: self.beginEnteringCommand('/ ')) self.addShortcut("Ctrl+U", lambda: self.toggleSource())
def initUI(self): """Creates parts of layout that account for sizes. Notable is that the boardScene squares will be a multiple of 8.""" screens = [QDesktopWidget().availableGeometry(i) for i in range(QDesktopWidget().screenCount())] assert screens maxWidth = max(min(s.width(), s.height()) for s in screens) sceneWidth = int(maxWidth / 8) * 8 self.boardScene.initSquares(sceneWidth / 8) self.boardScene.setSceneRect(0, 0, sceneWidth, sceneWidth) self.boardSceneView.initUI(sceneWidth) """Creates layout without accounting for sizes""" pal = QPalette(self.palette()) pal.setColor(QPalette.Background, Qt.green) self.setAutoFillBackground(True) self.setPalette(pal) self.vertLayout = QVBoxLayout(self) self.vertLayout.setSpacing(0) self.vertLayout.setContentsMargins(0, 0, 0, 0) self.vertLayout.addWidget(self.moveTreeView) self.vertLayout.addWidget(self.engineWidget) self.vertWidget = QWidget(self) self.vertWidget.setLayout(self.vertLayout) horiLayout = QHBoxLayout(self) horiLayout.setSpacing(0) horiLayout.setContentsMargins(0, 0, 0, 0) horiLayout.addWidget(self.boardSceneView) horiLayout.addWidget(self.vertWidget) self.setLayout(horiLayout)
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)
def __init__(self, parent=None): super().__init__(parent) # Register signals connections layout = QHBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) self.__buttons = [] self.__action_number = 1 self.__buttons_visibility = {} self.__current_widget = None self.__last_index = -1 self._stack_widgets = QStackedWidget() layout.addWidget(self._stack_widgets) # Buttons Widget self.buttons_widget = QWidget() self.buttons_widget.setObjectName("tools_dock") self.buttons_widget.setFixedHeight(26) self.buttons_widget.setLayout(QHBoxLayout()) self.buttons_widget.layout().setContentsMargins(2, 2, 5, 2) self.buttons_widget.layout().setSpacing(10) IDE.register_service("tools_dock", self) _ToolsDock.__created = True
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)
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)
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)
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)
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])
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)
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))
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, 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)
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)
def addStatControl(self,i,label=None): statbox = QHBoxLayout() statbox.addSpacing(1) statbox.setSpacing(0) statbox.setAlignment(Qt.AlignCenter) statlabel = QLabel(self.stats[i] if label is None else label) statlabel.setContentsMargins(0,0,0,0) statlabel.setAlignment(Qt.AlignCenter) statlabel.setFixedWidth(20) statbox.addWidget(statlabel) statcontrol = QLineEdit() statcontrol.setAlignment(Qt.AlignCenter) statcontrol.setFixedWidth(40) statcontrol.setText(str(self.skill.multipliers[i])) v = QDoubleValidator(0,99,3,statcontrol) v.setNotation(QDoubleValidator.StandardNotation) #v.setRange(0,100,decimals=3) statcontrol.setValidator(v) #print(v.top()) def statFuncMaker(j): def statFunc(newValue): self.skill.multipliers[j] = float(newValue) self.skillsChanged.emit() return statFunc statcontrol.textChanged[str].connect(statFuncMaker(i)) statbox.addWidget(statcontrol) statbox.addSpacing(1) self.layout.addLayout(statbox)
def setup_ui(self): self.setObjectName('searchBox') self.searchButton = QToolButton(clicked = self.search_musics) self.searchButton.setFocusPolicy(Qt.NoFocus) self.searchButton.setIconSize(QSize(21, 21)) self.searchButton.setIcon(QIcon(IconsHub.Search)) self.searchButton.setCursor(Qt.ArrowCursor) self.searchCombo = QComboBox() self.searchCombo.setObjectName('searchCombo') musicIcon = QIcon(IconsHub.SearchMusictitle) artistIcon = QIcon(IconsHub.SearchArtist) albumIcon = QIcon(IconsHub.SearchAlbum) self.searchCombo.setIconSize(QSize(20, 20)) self.searchCombo.insertItem(0, musicIcon, "歌曲") self.searchCombo.insertItem(1, artistIcon, "歌手") self.searchCombo.insertItem(2, albumIcon, "专辑") self.searchCombo.setFixedSize(90, 26) self.searchCombo.setCursor(Qt.ArrowCursor) self.searchCombo.setCurrentIndex(0) searchLayout = QHBoxLayout(self) searchLayout.addWidget(self.searchCombo) searchLayout.addStretch() searchLayout.addWidget(self.searchButton) searchLayout.setSpacing(0) searchLayout.setContentsMargins(0, 0, 2, 0) self.setTextMargins(95, 0, 25, 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 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)
class MainWindow(QWidget): log_level = logging.INFO formatter = logging.Formatter(fmt='%(asctime)s - %(levelname)s - %(message)s', datefmt='%H:%M:%S') number_of_grids = 5 def __init__(self, app): super(MainWindow, self).__init__() self.app = app self.threadpool = QThreadPool() self.initUI() self.setAttribute(Qt.WA_DeleteOnClose) mp.set_start_method('spawn') def initUI(self): #start geometrie self.width = 1200 self.height = 800 self.desktop = QApplication.desktop() self.desktop_size = QRect() self.desktop_size = self.desktop.screenGeometry() self.logger = logging.getLogger() self.logger.setLevel(self.log_level) self.log_date = datetime.datetime.now() self.mod_path = os.path.dirname(Pythonic.__file__) log_date_str = self.log_date.strftime('%Y_%m_%d') month = self.log_date.strftime('%b') year = self.log_date.strftime('%Y') home_dict = str(Path.home()) file_path = '{}/Pythonic_{}/{}/log_{}.txt'.format(home_dict, year, month, log_date_str) self.ensure_file_path(file_path) file_handler = logging.FileHandler(file_path) file_handler.setLevel(self.log_level) file_handler.setFormatter(self.formatter) self.logger.addHandler(file_handler) # init language ! self.translator = QTranslator(self.app) #self.translator.load('translations/spanish_es') self.translator.load(join(self.mod_path, 'translations/english_en.qm')) self.app.installTranslator(self.translator) #QC.installTranslator(self.translator) logging.debug('Translation: {}'.format(QC.translate('', 'Save'))) # setup the default language here #self.changeTranslator('german_de.qm') self.x_position = self.desktop_size.width() / 2 - self.width / 2 self.y_position = self.desktop_size.height() / 2 - self.height / 2 self.setAcceptDrops(True) self.layout_v = QVBoxLayout() # main_layout contains the workingarea and the toolbox self.main_layout = QVBoxLayout() self.main_layout.setSpacing(0) self.main_layout.setContentsMargins(0, 0, 0, 0) self.bottom_border_layout = QHBoxLayout() self.bottom_border_layout.setSpacing(0) self.setContentsMargins(0, 0, 0, 0) # create class objects #self.exceptwindow = ExceptWindow(self) self.wrk_area_arr = [] self.wrk_tabs_arr = [] self.grd_ops_arr = [] self.working_tabs = QTabWidget() self.working_tabs.setMinimumSize(300, 300) for i in range(self.number_of_grids): self.wrk_area_arr.append(WorkingArea()) self.wrk_tabs_arr.append(QScrollArea()) self.wrk_tabs_arr[i].setWidget(self.wrk_area_arr[i]) self.wrk_tabs_arr[i].setWidgetResizable(True) #self.working_tabs.addTab(self.wrk_area_arr[i], QC.translate('', 'Grid {}'.format(i))) self.working_tabs.addTab(self.wrk_tabs_arr[i], QC.translate('', 'Grid {}'.format(i + 1))) self.grd_ops_arr.append(GridOperator(self.wrk_area_arr[i].grid, i)) # init reference for the current grid which is in focus self.focus_grid = self.wrk_area_arr[0] self.wrk_tab_index = 0 #self.working_area = WorkingArea() self.storagebar = StorageBar(self) self.menubar = MenuBar() self.toolbox_tab = QTabWidget() self.toolbox_tab.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred) self.topMenuBar = topMenuBar() self.settings = Settings() self.infoWindow = InfoWindow() #self.gridoperator = GridOperator(self) self.toolbox_basics = BasicTools(self) self.toolbox_binance = BinanceTools(self) self.toolbox_connectivity = ConnectivityTools(self) self.toolbox_ml = MLTools(self) # add Tabs to the toolbox self.toolbox_tab.addTab(self.toolbox_basics, QC.translate('', 'Basic')) self.toolbox_tab.addTab(self.toolbox_binance, QC.translate('', 'Binance')) self.toolbox_tab.addTab(self.toolbox_connectivity, QC.translate('', 'Connectivity')) self.toolbox_tab.addTab(self.toolbox_ml, QC.translate('', 'Machine Learning')) # signals and slots self.menubar.set_info_text.connect(self.setInfoText) self.menubar.start_debug.connect(self.startDebug) self.menubar.start_exec.connect(self.startExec) #self.menubar.clear_grid.connect(self.working_area.setupDefault) #self.menubar.stop_exec.connect(self.gridoperator.stop_execution) #self.menubar.kill_proc.connect(self.gridoperator.kill_proc) #self.menubar.kill_proc.connect(self.working_area.allStop) #self.gridoperator.update_logger.connect(self.update_logfile) self.topMenuBar.switch_language.connect(self.changeTranslator) self.topMenuBar.close_signal.connect(self.closeEvent) self.topMenuBar.open_action.triggered.connect(self.menubar.openFileNameDialog) self.topMenuBar.save_action.triggered.connect(self.menubar.simpleSave) self.topMenuBar.save_as_action.triggered.connect(self.menubar.saveFileDialog) self.topMenuBar.new_action.triggered.connect(self.menubar.saveQuestion) self.topMenuBar.settings_action.triggered.connect(self.settings.show) self.topMenuBar.info_action.triggered.connect(self.showInfo) self.working_tabs.currentChanged.connect(self.wrkIndexChanged) #self.toolbox_binance.reg_tool.connect(self.working_area.regType) #self.toolbox_connectivity.reg_tool.connect(self.working_area.regType) #self.toolbox_basics.reg_tool.connect(self.working_area.regType) #self.storagebar.forward_config.connect(self.working_area.receiveConfig) #self.working_area.finish_dropbox.connect(self.storagebar.finishDropBox) self.menubar.stop_exec.connect(self.stopExecution) self.menubar.kill_proc.connect(self.killProcesses) self.menubar.load_file.connect(self.loadGrid) self.menubar.save_file.connect(self.saveGrid) self.menubar.clear_grid.connect(self.setupDefault) for i in range(self.number_of_grids): self.toolbox_binance.reg_tool.connect(self.wrk_area_arr[i].regType) self.toolbox_connectivity.reg_tool.connect(self.wrk_area_arr[i].regType) self.toolbox_ml.reg_tool.connect(self.wrk_area_arr[i].regType) self.toolbox_basics.reg_tool.connect(self.wrk_area_arr[i].regType) # hier auch noch anpassen self.storagebar.forward_config.connect(self.wrk_area_arr[i].receiveConfig) self.wrk_area_arr[i].finish_dropbox.connect(self.storagebar.finishDropBox) self.grd_ops_arr[i].update_logger.connect(self.update_logfile) self.grd_ops_arr[i].switch_grid.connect(self.receiveTarget) self.wrk_area_arr[i].query_grid_config_wrk.connect(self.queryGridConfiguration) # register tools self.toolbox_binance.register_tools() self.toolbox_basics.register_tools() self.toolbox_connectivity.register_tools() self.toolbox_ml.register_tools() self.scrollArea = QScrollArea() #self.scrollArea.setWidget(self.working_area) self.scrollArea.setWidget(self.working_tabs) self.scrollArea.setWidgetResizable(True) self.scrollArea.setMinimumSize(300, 300) self.scroll_dropBox = QScrollArea() self.scroll_dropBox.setWidget(self.storagebar) self.scroll_dropBox.setWidgetResizable(True) self.scroll_dropBox.setMaximumWidth(270) self.bottom_area = QWidget() self.bottom_area_layout = QHBoxLayout(self.bottom_area) self.bottom_area_layout.addWidget(self.scrollArea) self.bottom_area_layout.addWidget(self.scroll_dropBox) self.layout_v.addWidget(self.topMenuBar) self.layout_v.addWidget(self.menubar) self.layout_v.addWidget(self.toolbox_tab) self.layout_v.addWidget(self.bottom_area) self.main_widget = QWidget() self.main_widget.setLayout(self.layout_v) # add main widget to main layout self.main_layout.addWidget(self.main_widget, 0) self.main_layout.setSpacing(0) # resize button self.sizeGrip = QSizeGrip(self.main_widget) # bottom info text self.infoText = QLabel() self.infoText.setText('') # define the bottom border line self.bottom_border_layout.addWidget(self.infoText) self.bottom_border_layout.setSpacing(0) # left, top, right, bottom self.bottom_border_layout.setContentsMargins(5, 0, 5, 5) self.bottom_border_layout.addWidget(self.sizeGrip, 0, Qt.AlignRight) self.bottom_border = QWidget() self.bottom_border.setLayout(self.bottom_border_layout) self.main_layout.addWidget(self.bottom_border) self.setLayout(self.main_layout) self.setGeometry(self.x_position, self.y_position, self.width, self.height) def receiveTarget(self, data): prg_return, fastpath = data grid, *pos = prg_return.target_0 logging.debug('MainWorker::receiveTarget() called from pos: {} goto grid: {}'.format(pos, grid)) logging.debug('MainWindow::receiveTarget() called fp {}'.format(fastpath)) # go to goNext() in the target grid # set fastpath variable self.grd_ops_arr[grid].stop_flag = False self.grd_ops_arr[grid].fastpath = fastpath # remove grid from target_0 prg_return.target_0 = pos if fastpath: self.grd_ops_arr[grid].delay = 0 else: self.grd_ops_arr[grid].delay = self.settings.delay / 1000 self.grd_ops_arr[grid].goNext(prg_return) def queryGridConfiguration(self): logging.debug('MainWindow::queryGridConfiguration() called') result = [] for wrk_area in self.wrk_area_arr: result.append(wrk_area.returnCurrentElements()) self.focus_grid.receiveGridConfiguration(result) def wrkIndexChanged(self, index): logging.debug('MainWindow::wrkIndexChanged() called with index {}'.format(index)) self.wrk_tab_index = index self.focus_grid = self.wrk_area_arr[index] def loadGrid(self, filename): logging.debug('MainWindow::loadGrid() called') grid_data_list = [] try: with ZipFile(filename, 'r') as archive: for zipped_grid in archive.namelist(): pickled_grid = archive.read(zipped_grid) element_list = pickle.loads(pickled_grid) # first char repesents the grid number self.wrk_area_arr[int(zipped_grid[0])].loadGrid(pickle.loads(pickled_grid)) archive.close() except Exception as e: err_msg = QMessageBox() err_msg.setIcon(QMessageBox.Critical) err_msg.setWindowTitle(QC.translate('', 'File Error')) err_msg.setText(QC.translate('', 'File can\'t be read')) err_msg.setAttribute(Qt.WA_DeleteOnClose) err_msg.exec() def saveGrid(self, filename): logging.debug('MainWindow::saveGrid() called') with ZipFile(filename, 'w') as save_file: for i in range(self.number_of_grids): tmp_file = (self.wrk_area_arr[i].saveGrid()) save_file.writestr('{}_grid'.format(str(i)), tmp_file) save_file.close() def setupDefault(self): logging.debug('MainWindow::setupDefault() called') self.wrk_area_arr[self.wrk_tab_index].setupDefault() def stopExecution(self): logging.debug('MainWindow::stopExecution() called') self.grd_ops_arr[self.wrk_tab_index].stop_execution() def killProcesses(self): logging.debug('MainWindow::killProcesses() called') self.grd_ops_arr[self.wrk_tab_index].kill_proc() self.wrk_area_arr[self.wrk_tab_index].allStop() def changeTranslator(self, fileName): #QC.removeTranslator(self.translator) self.app.removeTranslator(self.translator) logging.debug('changeTranslator() called with file: {}'.format(fileName)) self.translator.load(join(self.mod_path, 'translations/') + fileName) #QC.installTranslator(self.translator) self.app.installTranslator(self.translator) logging.debug('Translation: {}'.format(QC.translate('', 'Save'))) """ defaultLocale =QLocale.system().name() """ #defaultLocale.truncate(defaultLocale.lastIndexOf('''')) #logging.debug('Locale: {}'.format()) def setInfoText(self, text): #self.infoText.setText(QC.translate('', text)) self.infoText.setText(text) def startDebug(self): logging.debug('MainWindow::startDebug() called') target = (0, 0) self.grd_ops_arr[self.wrk_tab_index].stop_flag = False self.grd_ops_arr[self.wrk_tab_index].fastpath = False self.grd_ops_arr[self.wrk_tab_index].delay = self.settings.delay / 1000 self.grd_ops_arr[self.wrk_tab_index].startExec(target) def startExec(self): logging.debug('MainWindow::startExec() called') target = (0, 0) self.grd_ops_arr[self.wrk_tab_index].stop_flag = False self.grd_ops_arr[self.wrk_tab_index].delay = 0 self.grd_ops_arr[self.wrk_tab_index].fastpath = True self.grd_ops_arr[self.wrk_tab_index].startExec(target) def changeEvent(self, event): if event.type() == QEvent.LanguageChange: logging.debug('changeEvent() called MainWindow') self.setWindowTitle(QC.translate('', 'Pythonic - 0.18')) def showInfo(self, event): logging.debug('showInfo called') self.infoWindow.show() def update_logfile(self): now = datetime.datetime.now().date() if (now != self.log_date.date()): self.logger.removeHandler(self.logger.handlers[0]) log_date_str = now.strftime('%Y_%m_%d') month = now.strftime('%b') year = now.strftime('%Y') home_dict = str(Path.home()) file_path = '{}/Pythonic_{}/{}/log_{}.txt'.format(home_dict, year, month, log_date_str) self.ensure_file_path(file_path) file_handler = logging.FileHandler(file_path) file_handler.setLevel(self.log_level) file_handler.setFormatter(self.formatter) self.logger.addHandler(file_handler) self.log_date = datetime.datetime.now() def ensure_file_path(self, file_path): directory = os.path.dirname(file_path) if not os.path.exists(directory): os.makedirs(directory) def closeEvent(self, event): logging.debug('closeEvent() called') messageBox = QMessageBox() messageBox.setAttribute(Qt.WA_DeleteOnClose) messageBox.setIcon(QMessageBox.Warning) messageBox.setWindowTitle(QC.translate('', 'Close?')) messageBox.setText(QC.translate('', 'Warning: Execution of all tasks will be stopped!')) messageBox.setStandardButtons(QMessageBox.No | QMessageBox.Yes) messageBox.setDefaultButton(QMessageBox.No) ret = messageBox.exec() if ret == QMessageBox.No : logging.debug('closeEvent() No clicked') event.ignore() else: logging.debug('closeEvent() Yes clicked') event.accept() sys.exit(0)
class BaseLineEdit(QLineEdit): editSig = pyqtSignal() def __init__(self, *args, leftWidget=None, rightWidget=None, **kwargs): super(BaseLineEdit, self).__init__(*args, **kwargs) self.textSelectionEnabled = True self.leftRightLayout = None self.leftWidget = leftWidget self.rightWidget = rightWidget if self.leftWidget or self.rightWidget: # 对行编辑框内的部件进行布局 self.leftRightLayout = QHBoxLayout(self) self.leftRightLayout.setContentsMargins(2, 2, 2, 2) self.leftRightLayout.setSpacing(0) if self.leftWidget: self.leftRightLayout.addWidget(leftWidget) self.leftRightLayout.addStretch() if self.rightWidget: self.leftRightLayout.addWidget(rightWidget) def emitEditSig(self): ''' @brief: 主动发射编辑信号editSig() 因为Qt4中signals是protected权限,无法类外调用,所以这里设置一个public权限接口,实现在类外 调用主动发射编辑信号 @author: 缪庆瑞 @date: 2020.05.26 ''' self.setFocus() self.editSig.emit() def setLeftRightLayoutMargin(self, left=0, right=0, top=0, bottom=0): ''' *@brief: 设置行编辑框左右布局margin,主要为了方便调整左右侧部件的位置 *@author: 缪庆瑞 *@date: 2020.04.11 *@param: left:左边间距 right:右边间距 *@param: top:上边间距 bottom:下边间距 默认0,一般不需要调整 ''' if self.leftRightLayout: self.leftRightLayout.setContentsMargins(left, top, right, bottom) ''' 在编辑框显示之前左右部件的大小如果没有fixed,那么默认将采用部件自身的推荐大小。所以 这里只在部件显示(内部已完成布局)的情况下才自动调整文本的margin,避免按照部件推荐大小 设置margin导致编辑框的大小策略受到不良影响。 ''' if self.isVisible(): self.autoAdjustTextMargins() def mouseMoveEvent(self, event): ''' *@brief: 鼠标移动事件处理 *@author: 缪庆瑞 *@date: 2020.05.20 *@param: event:鼠标事件 ''' if self.textSelectionEnabled: QLineEdit.mouseMoveEvent(self, event) def mouseReleaseEvent(self, event): ''' *@brief: 鼠标释放事件处理 *@author: 缪庆瑞 *@date: 2020.04.11 *@param: event:鼠标事件 ''' # 左键释放并且非只读模式 if event.button() == Qt.LeftButton and not self.isReadOnly(): self.editSig.emit() # 发射编辑信号 QLineEdit.mouseReleaseEvent(self, event) def mouseDoubleClickEvent(self, event): ''' *@brief: 鼠标双击事件处理 *@author: 缪庆瑞 *@date: 2020.05.20 *@param: event:鼠标事件 ''' if self.textSelectionEnabled: QLineEdit.mouseDoubleClickEvent(self, event) def resizeEvent(self, event): ''' *@brief: 部件大小调整事件处理 (用来自动调整编辑框文本的margins) *@author: 缪庆瑞 *@date: 2020.04.11 *@param: event:大小事件 ''' QLineEdit.resizeEvent(self, event) self.autoAdjustTextMargins() def autoAdjustTextMargins(self): ''' *@brief: 根据布局的边距和部件的宽度,自动调整编辑框文本的margins *@author: 缪庆瑞 *@date: 2020.04.11 ''' if self.leftRightLayout: leftMargin = self.leftWidget.width() if self.leftWidget else 0 rightMargin = self.rightWidget.width() if self.rightWidget else 0 leftMargin += self.leftRightLayout.contentsMargins().left() rightMargin += self.leftRightLayout.contentsMargins().right() # 设置编辑框的margin 确保文本不会被部件遮挡 self.setTextMargins(leftMargin, 0, rightMargin, 0)
class StatusBar(QWidget): """The statusbar at the bottom of the mainwindow. Attributes: txt: The Text widget in the statusbar. keystring: The KeyString widget in the statusbar. percentage: The Percentage widget in the statusbar. url: The UrlText widget in the statusbar. prog: The Progress widget in the statusbar. cmd: The Command widget in the statusbar. _hbox: The main QHBoxLayout. _stack: The QStackedLayout with cmd/txt widgets. _win_id: The window ID the statusbar is associated with. Signals: resized: Emitted when the statusbar has resized, so the completion widget can adjust its size to it. arg: The new size. moved: Emitted when the statusbar has moved, so the completion widget can move to the right position. arg: The new position. """ resized = pyqtSignal('QRect') moved = pyqtSignal('QPoint') STYLESHEET = _generate_stylesheet() def __init__(self, *, win_id, private, parent=None): super().__init__(parent) self.setObjectName(self.__class__.__name__) self.setAttribute(Qt.WA_StyledBackground) stylesheet.set_register(self) self.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Fixed) self._win_id = win_id self._color_flags = ColorFlags() self._color_flags.private = private self._hbox = QHBoxLayout(self) self._set_hbox_padding() self._hbox.setSpacing(5) self._stack = QStackedLayout() self._hbox.addLayout(self._stack) self._stack.setContentsMargins(0, 0, 0, 0) self.cmd = command.Command(private=private, win_id=win_id) self._stack.addWidget(self.cmd) objreg.register('status-command', self.cmd, scope='window', window=win_id) self.txt = textbase.TextBase() self._stack.addWidget(self.txt) self.cmd.show_cmd.connect(self._show_cmd_widget) self.cmd.hide_cmd.connect(self._hide_cmd_widget) self._hide_cmd_widget() self.url = url.UrlText() self.percentage = percentage.Percentage() self.backforward = backforward.Backforward() self.tabindex = tabindex.TabIndex() self.keystring = keystring.KeyString() self.prog = progress.Progress(self) self._draw_widgets() config.instance.changed.connect(self._on_config_changed) QTimer.singleShot(0, self.maybe_hide) def __repr__(self): return utils.get_repr(self) @pyqtSlot(str) def _on_config_changed(self, option): if option == 'statusbar.show': self.maybe_hide() elif option == 'statusbar.padding': self._set_hbox_padding() elif option == 'statusbar.widgets': self._draw_widgets() def _draw_widgets(self): """Draw statusbar widgets.""" # Start with widgets hidden and show them when needed for widget in [ self.url, self.percentage, self.backforward, self.tabindex, self.keystring, self.prog ]: assert isinstance(widget, QWidget) widget.hide() self._hbox.removeWidget(widget) tab = self._current_tab() # Read the list and set widgets accordingly for segment in config.val.statusbar.widgets: if segment == 'url': self._hbox.addWidget(self.url) self.url.show() elif segment == 'scroll': self._hbox.addWidget(self.percentage) self.percentage.show() elif segment == 'scroll_raw': self._hbox.addWidget(self.percentage) self.percentage.set_raw() self.percentage.show() elif segment == 'history': self._hbox.addWidget(self.backforward) self.backforward.enabled = True if tab: self.backforward.on_tab_changed(tab) elif segment == 'tabs': self._hbox.addWidget(self.tabindex) self.tabindex.show() elif segment == 'keypress': self._hbox.addWidget(self.keystring) self.keystring.show() elif segment == 'progress': self._hbox.addWidget(self.prog) self.prog.enabled = True if tab: self.prog.on_tab_changed(tab) @pyqtSlot() def maybe_hide(self): """Hide the statusbar if it's configured to do so.""" strategy = config.val.statusbar.show tab = self._current_tab() if tab is not None and tab.data.fullscreen: self.hide() elif strategy == 'never': self.hide() elif strategy == 'in-mode': try: mode_manager = modeman.instance(self._win_id) except modeman.UnavailableError: self.hide() else: if mode_manager.mode == usertypes.KeyMode.normal: self.hide() else: self.show() elif strategy == 'always': self.show() else: raise utils.Unreachable def _set_hbox_padding(self): padding = config.val.statusbar.padding self._hbox.setContentsMargins(padding.left, 0, padding.right, 0) @pyqtProperty('QStringList') def color_flags(self): """Getter for self.color_flags, so it can be used as Qt property.""" return self._color_flags.to_stringlist() def _current_tab(self): """Get the currently displayed tab.""" window = objreg.get('tabbed-browser', scope='window', window=self._win_id) return window.widget.currentWidget() def set_mode_active(self, mode, val): """Setter for self.{insert,command,caret}_active. Re-set the stylesheet after setting the value, so everything gets updated by Qt properly. """ if mode == usertypes.KeyMode.insert: log.statusbar.debug("Setting insert flag to {}".format(val)) self._color_flags.insert = val if mode == usertypes.KeyMode.passthrough: log.statusbar.debug("Setting passthrough flag to {}".format(val)) self._color_flags.passthrough = val if mode == usertypes.KeyMode.command: log.statusbar.debug("Setting command flag to {}".format(val)) self._color_flags.command = val elif mode in [usertypes.KeyMode.prompt, usertypes.KeyMode.yesno]: log.statusbar.debug("Setting prompt flag to {}".format(val)) self._color_flags.prompt = val elif mode == usertypes.KeyMode.caret: if not val: # Turning on is handled in on_current_caret_selection_toggled log.statusbar.debug("Setting caret mode off") self._color_flags.caret = ColorFlags.CaretMode.off stylesheet.set_register(self, update=False) def _set_mode_text(self, mode): """Set the mode text.""" if mode == 'passthrough': key_instance = config.key_instance all_bindings = key_instance.get_reverse_bindings_for('passthrough') bindings = all_bindings.get('leave-mode') if bindings: suffix = ' ({} to leave)'.format(' or '.join(bindings)) else: suffix = '' else: suffix = '' text = "-- {} MODE --{}".format(mode.upper(), suffix) self.txt.setText(text) def _show_cmd_widget(self): """Show command widget instead of temporary text.""" self._stack.setCurrentWidget(self.cmd) self.show() def _hide_cmd_widget(self): """Show temporary text instead of command widget.""" log.statusbar.debug("Hiding cmd widget") self._stack.setCurrentWidget(self.txt) self.maybe_hide() @pyqtSlot(str) def set_text(self, text): """Set a normal (persistent) text in the status bar.""" log.message.debug(text) self.txt.setText(text) @pyqtSlot(usertypes.KeyMode) def on_mode_entered(self, mode): """Mark certain modes in the commandline.""" mode_manager = modeman.instance(self._win_id) if config.val.statusbar.show == 'in-mode': self.show() if mode_manager.parsers[mode].passthrough: self._set_mode_text(mode.name) if mode in [ usertypes.KeyMode.insert, usertypes.KeyMode.command, usertypes.KeyMode.caret, usertypes.KeyMode.prompt, usertypes.KeyMode.yesno, usertypes.KeyMode.passthrough ]: self.set_mode_active(mode, True) @pyqtSlot(usertypes.KeyMode, usertypes.KeyMode) def on_mode_left(self, old_mode, new_mode): """Clear marked mode.""" mode_manager = modeman.instance(self._win_id) if config.val.statusbar.show == 'in-mode': self.hide() if mode_manager.parsers[old_mode].passthrough: if mode_manager.parsers[new_mode].passthrough: self._set_mode_text(new_mode.name) else: self.txt.setText('') if old_mode in [ usertypes.KeyMode.insert, usertypes.KeyMode.command, usertypes.KeyMode.caret, usertypes.KeyMode.prompt, usertypes.KeyMode.yesno, usertypes.KeyMode.passthrough ]: self.set_mode_active(old_mode, False) @pyqtSlot(browsertab.AbstractTab) def on_tab_changed(self, tab): """Notify sub-widgets when the tab has been changed.""" self.url.on_tab_changed(tab) self.prog.on_tab_changed(tab) self.percentage.on_tab_changed(tab) self.backforward.on_tab_changed(tab) self.maybe_hide() assert tab.is_private == self._color_flags.private @pyqtSlot(browsertab.SelectionState) def on_caret_selection_toggled(self, selection_state): """Update the statusbar when entering/leaving caret selection mode.""" log.statusbar.debug( "Setting caret selection {}".format(selection_state)) if selection_state is browsertab.SelectionState.normal: self._set_mode_text("caret selection") self._color_flags.caret = ColorFlags.CaretMode.selection elif selection_state is browsertab.SelectionState.line: self._set_mode_text("caret line selection") self._color_flags.caret = ColorFlags.CaretMode.selection else: self._set_mode_text("caret") self._color_flags.caret = ColorFlags.CaretMode.on stylesheet.set_register(self, update=False) def resizeEvent(self, e): """Extend resizeEvent of QWidget to emit a resized signal afterwards. Args: e: The QResizeEvent. """ super().resizeEvent(e) self.resized.emit(self.geometry()) def moveEvent(self, e): """Extend moveEvent of QWidget to emit a moved signal afterwards. Args: e: The QMoveEvent. """ super().moveEvent(e) self.moved.emit(e.pos()) def minimumSizeHint(self): """Set the minimum height to the text height plus some padding.""" padding = config.cache['statusbar.padding'] width = super().minimumSizeHint().width() height = self.fontMetrics().height() + padding.top + padding.bottom return QSize(width, height)
def __init__(self, dialog, dele: 'Delegation', mode: str): """ :type dialog: QDialog :type callback: func """ QGridLayout.__init__(self) self.setSpacing(8) self.setColumnStretch(3, 1) self.dialog = dialog self.dele = dele self.mode = mode if dele and dele.addr: self.addresses = [dele.addr] else: self.addresses = [''] delegations = self.dialog.parent().wallet.db.list_delegations() for addr in self.dialog.parent().wallet.get_addresses_sort_by_balance(): if addr in delegations: continue addr_type, __ = b58_address_to_hash160(addr) if addr_type == constants.net.ADDRTYPE_P2PKH: self.addresses.append(addr) address_lb = QLabel(_("Address:")) self.address_combo = QComboBox() self.address_combo.setMinimumWidth(300) self.address_combo.addItems(self.addresses) self.addWidget(address_lb, 1, 0) self.addWidget(self.address_combo, 1, 1, 1, -1) self.address_combo.currentIndexChanged.connect(self.on_address) staker_lb = QLabel(_("Staker:")) self.staker_e = ButtonsLineEdit() self.addWidget(staker_lb, 2, 0) self.addWidget(self.staker_e, 2, 1, 1, -1) fee_lb = QLabel(_('Fee Percent:')) self.fee_e = QLineEdit() self.addWidget(fee_lb, 3, 0) self.addWidget(self.fee_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 = AmountEdit(lambda: '', True, None, 0, 0) self.gas_limit_e.setText('2250000') gas_price_lb = QLabel(_('gas price: ')) self.gas_price_e = AmountEdit(lambda: '', False, None, 8, 0) self.gas_price_e.setText('0.00000040') 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(0) self.optional_widget.setLayout(optional_layout) self.addWidget(self.optional_widget, 4, 1, 1, -1) self.cancel_btn = CancelButton(dialog) self.do_btn = QPushButton(self.mode[0].upper() + self.mode[1:]) self.do_btn.clicked.connect(self.do) buttons = Buttons(*[self.cancel_btn, self.do_btn]) buttons.addStretch() self.addLayout(buttons, 5, 2, 2, -1) self.update()
def __init__(self, session, tool_name): self._default_color = (255, 153, 204, 128) # Transparent pink self._max_slider_value = 1000 # QSlider only handles integer values self._max_slider_radius = 100.0 # Float maximum radius value, scene units self._block_text_update = False # Avoid radius slider and text continuous updating each other. self._block_slider_update = False # Avoid radius slider and text continuous updating each other. b = session.main_view.drawing_bounds() vradius = 100 if b is None else b.radius() self._max_slider_radius = vradius center = b.center() if b else (0, 0, 0) self._sphere_model = SphereModel('eraser sphere', session, self._default_color, center, 0.2 * vradius) ToolInstance.__init__(self, session, tool_name) self.display_name = 'Map Eraser' from chimerax.ui import MainToolWindow tw = MainToolWindow(self) self.tool_window = tw parent = tw.ui_area from PyQt5.QtWidgets import QVBoxLayout, QHBoxLayout, QFrame, QCheckBox, QLabel, QPushButton, QLineEdit, QSlider from PyQt5.QtCore import Qt layout = QVBoxLayout(parent) layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) parent.setLayout(layout) sf = QFrame(parent) layout.addWidget(sf) slayout = QHBoxLayout(sf) slayout.setContentsMargins(0, 0, 0, 0) slayout.setSpacing(10) self._show_eraser = se = QCheckBox('Show map eraser sphere', sf) se.setCheckState(Qt.Checked) se.stateChanged.connect(self._show_eraser_cb) slayout.addWidget(se) from chimerax.ui.widgets import ColorButton self._sphere_color = sc = ColorButton(sf, max_size=(16, 16), has_alpha_channel=True) sc.color = self._default_color sc.color_changed.connect(self._change_color_cb) slayout.addWidget(sc) slayout.addStretch(1) # Extra space at end rf = QFrame(parent) layout.addWidget(rf) rlayout = QHBoxLayout(rf) rlayout.setContentsMargins(0, 0, 0, 0) rlayout.setSpacing(4) rl = QLabel('Radius', rf) rlayout.addWidget(rl) self._radius_entry = rv = QLineEdit('', rf) rv.setMaximumWidth(40) rv.returnPressed.connect(self._radius_changed_cb) rlayout.addWidget(rv) self._radius_slider = rs = QSlider(Qt.Horizontal, rf) smax = self._max_slider_value rs.setRange(0, smax) rs.valueChanged.connect(self._radius_slider_moved_cb) rlayout.addWidget(rs) rv.setText('%.4g' % self._sphere_model.radius) self._radius_changed_cb() ef = QFrame(parent) layout.addWidget(ef) elayout = QHBoxLayout(ef) elayout.setContentsMargins(0, 0, 0, 0) elayout.setSpacing(30) eb = QPushButton('Erase inside sphere', ef) eb.clicked.connect(self._erase_in_sphere) elayout.addWidget(eb) eo = QPushButton('Erase outside sphere', ef) eo.clicked.connect(self._erase_outside_sphere) elayout.addWidget(eo) rb = QPushButton('Reduce map bounds', ef) rb.clicked.connect(self._crop_map) elayout.addWidget(rb) elayout.addStretch(1) # Extra space at end layout.addStretch(1) # Extra space at end tw.manage(placement="side") # When displayed models change update radius slider range. from chimerax.core.models import MODEL_DISPLAY_CHANGED h = session.triggers.add_handler(MODEL_DISPLAY_CHANGED, self._model_display_change) self._model_display_change_handler = h
def __init__(self): super(Window, self).__init__() self.setGeometry(50, 50, 800, 500) self.setMinimumSize(600, 450) self.setWindowModified(False) self.setWindowTitle("QC v" + appVersion) self.setStyleSheet(GUI_Style.mainWindow) # This builds the main widget for the GUI window to hold main_widget = QWidget() self.setCentralWidget(main_widget) # Create Threads self.Compiler_Thread = QCompilerThread() self.Progress_Bar_Thread = QProgressBarThread() self.Timer_Thread = QTimeThread() self.monitor_Thread = QMonitorThread() self.network_Thread = QNetworkThread() # Start all threads self.Compiler_Thread.start() self.Progress_Bar_Thread.start() self.Timer_Thread.start() self.monitor_Thread.start() self.network_Thread.start() self.Compiler_Thread.signalThreadSet.connect( self.Progress_Bar_Thread.setPBar) # Start monitoring folder self.monitor_Thread.setCheckFolder(True) self.network_Thread.setCheckFolder(True) # Instantiate GUI Objects self.MainTitle() self.inputFolderName() self.outputFolderName() self.folder_drop() self.Folder_select_GUI() self.Output_select_GUI() self.CreateProgressBar() self.StatusBar() self.ElapsedTime() self.AppliedLogo() self.Start_Btn_GUI() self.setStatusBar(self.statusBar) # Add title and logo to horizontal layout horizontal_title_layout = QHBoxLayout() horizontal_title_layout.addWidget(self.Logo) horizontal_title_layout.addWidget(self.UpperText) horizontal_title_layout.setSpacing(0) horizontal_title_layout.setContentsMargins(0, 0, 0, 0) # Create layout for folder names self.label_V = QVBoxLayout() self.label_V.addWidget(self.InputLabel) self.label_V.addWidget(self.OutputLabel) # Create layout for folder icon buttons self.select_V = QVBoxLayout() self.select_V.addWidget(self.folder_sel) self.select_V.addWidget(self.out_folder_sel) # Add buttons to horizontal layout horizontal_button_layout = QHBoxLayout() horizontal_button_layout.addLayout(self.label_V) horizontal_button_layout.addLayout(self.select_V) horizontal_button_layout.addWidget(self.strt_btn) horizontal_button_layout.setAlignment(Qt.AlignCenter) horizontal_button_layout.setSpacing(50) horizontal_button_layout.setContentsMargins(0, 0, 0, 0) # Add horizontal button layout to vertical layout verticalGUILayout = QVBoxLayout() verticalGUILayout.addLayout(horizontal_title_layout) verticalGUILayout.addLayout(horizontal_button_layout) verticalGUILayout.addWidget(self.drop_location) verticalGUILayout.addWidget(self.progress_bar) verticalGUILayout.setSpacing(20) verticalGUILayout.setContentsMargins(20, 15, 20, 20) # Set Main window layout to GUI central Widget self.centralWidget().setLayout(verticalGUILayout) self.centralWidget().isWindow() self.show()
class IterationTable(QWidget): """Widget that handles pipeline iteration. .. Methods: - add_tag: adds a tag to visualize in the iteration table - emit_iteration_table_updated: emits a signal when the iteration scans have been updated - fill_values: fill values_list depending on the visualized tags - refresh_layout: updates the layout of the widget - remove_tag: removes a tag to visualize in the iteration table - select_iterated_tag: opens a pop-up to let the user select on which tag to iterate - select_visualized_tag: opens a pop-up to let the user select which tag to visualize in the iteration table - update_iterated_tag: updates the widget - update_table: updates the iteration table - update_selected_tag: updates the selected tag for current pipeline manager tab """ iteration_table_updated = pyqtSignal(list, list) def __init__(self, project, scan_list, main_window): """ Initialization of the IterationTable widget. :param project: current project in the software :param scan_list: list of the selected database files :param main_window: software's main_window """ QWidget.__init__(self) # Necessary for using MIA bricks ProcessMIA.project = project self.project = project if not scan_list: self.scan_list = self.project.session.get_documents_names( COLLECTION_CURRENT) else: self.scan_list = scan_list self.main_window = main_window # values_list will contain the different values of each selected tag self.values_list = [[], []] self.all_tag_values = [] # Checkbox to choose to iterate the pipeline or not self.check_box_iterate = QCheckBox("Iterate pipeline") self.check_box_iterate.stateChanged.connect( self.emit_iteration_table_updated) # Label "Iterate over:" self.label_iterate = QLabel("Iterate over:") # Label that displays the name of the selected tag self.iterated_tag_label = QLabel("Select a tag") # Push button to select the tag to iterate self.iterated_tag_push_button = QPushButton("Select") self.iterated_tag_push_button.clicked.connect( self.select_iteration_tag) # QComboBox self.combo_box = QComboBox() self.combo_box.currentIndexChanged.connect(self.update_table) # filter self.filter_button = QPushButton("Filter") self.filter_button.clicked.connect(self.filter_values) # QTableWidget self.iteration_table = QTableWidget() # Label tag self.label_tags = QLabel("Tags to visualize:") # Each push button will allow the user to visualize a tag in # the iteration browser push_button_tag_1 = QPushButton() push_button_tag_1.setText("SequenceName") push_button_tag_1.clicked.connect( lambda: self.select_visualized_tag(0)) push_button_tag_2 = QPushButton() push_button_tag_2.setText("AcquisitionDate") push_button_tag_2.clicked.connect( lambda: self.select_visualized_tag(1)) # The list of all the push buttons # (the user can add as many as he or she wants) self.push_buttons = [] self.push_buttons.insert(0, push_button_tag_1) self.push_buttons.insert(1, push_button_tag_2) # Labels to add/remove a tag (a push button) self.add_tag_label = ClickableLabel() self.add_tag_label.setObjectName('plus') sources_images_dir = Config().getSourceImageDir() add_tag_picture = QPixmap( os.path.relpath(os.path.join(sources_images_dir, "green_plus.png"))) add_tag_picture = add_tag_picture.scaledToHeight(15) self.add_tag_label.setPixmap(add_tag_picture) self.add_tag_label.clicked.connect(self.add_tag) self.remove_tag_label = ClickableLabel() remove_tag_picture = QPixmap( os.path.relpath(os.path.join(sources_images_dir, "red_minus.png"))) remove_tag_picture = remove_tag_picture.scaledToHeight(20) self.remove_tag_label.setPixmap(remove_tag_picture) self.remove_tag_label.clicked.connect(self.remove_tag) # Layout self.v_layout = QVBoxLayout() self.setLayout(self.v_layout) self.refresh_layout() def add_tag(self): """Add a tag to visualize in the iteration table. Used only for tests """ idx = len(self.push_buttons) push_button = QPushButton() push_button.setText('Tag n°' + str(len(self.push_buttons) + 1)) push_button.clicked.connect(lambda: self.select_visualized_tag(idx)) self.push_buttons.insert(len(self.push_buttons), push_button) self.refresh_layout() def emit_iteration_table_updated(self): """Emit a signal when the iteration scans have been updated.""" if self.check_box_iterate.checkState(): if hasattr(self, 'scans'): self.iteration_table_updated.emit(self.iteration_scans, self.all_iterations_scans) else: self.iteration_table_updated.emit(self.scan_list, [self.scan_list]) else: self.iteration_table_updated.emit(self.scan_list, [self.scan_list]) def fill_values(self, idx): """ Fill values_list depending on the visualized tags :param idx: Index of the tag """ tag_name = self.push_buttons[idx].text() values = [] for scan in self.project.session.get_documents_names( COLLECTION_CURRENT): current_value = self.project.session.get_value( COLLECTION_CURRENT, scan, tag_name) if current_value is not None: values.append(current_value) idx_to_fill = len(self.values_list) while len(self.values_list) <= idx: self.values_list.insert(idx_to_fill, []) idx_to_fill += 1 if self.values_list[idx] is not None: self.values_list[idx] = [] for value in values: if value not in self.values_list[idx]: self.values_list[idx].append(value) def refresh_layout(self): """Update the layout of the widget. Called in widget's initialization and when a tag push button is added or removed. """ first_v_layout = QVBoxLayout() first_v_layout.addWidget(self.check_box_iterate) second_v_layout = QVBoxLayout() second_v_layout.addWidget(self.label_iterate) second_v_layout.addWidget(self.iterated_tag_label) third_v_layout = QVBoxLayout() third_v_layout.addWidget(self.iterated_tag_push_button) hbox = QHBoxLayout() hbox.addWidget(self.combo_box) hbox.addWidget(self.filter_button) third_v_layout.addLayout(hbox) top_layout = QHBoxLayout() top_layout.addLayout(first_v_layout) top_layout.addLayout(second_v_layout) top_layout.addLayout(third_v_layout) self.v_layout.addLayout(top_layout) self.v_layout.addWidget(self.iteration_table) self.h_box = QHBoxLayout() self.h_box.setSpacing(10) self.h_box.addWidget(self.label_tags) for tag_label in self.push_buttons: self.h_box.addWidget(tag_label) self.h_box.addWidget(self.add_tag_label) self.h_box.addWidget(self.remove_tag_label) self.h_box.addStretch(1) self.v_layout.addLayout(self.h_box) def remove_tag(self): """Remove a tag to visualize in the iteration table. """ if len(self.push_buttons) >= 1: push_button = self.push_buttons[-1] push_button.deleteLater() push_button = None del self.push_buttons[-1] del self.values_list[-1] self.refresh_layout() self.update_table() def select_iteration_tag(self): """Open a pop-up to let the user select on which tag to iterate.""" ui_select = PopUpSelectTagCountTable( self.project, self.project.session.get_fields_names(COLLECTION_CURRENT), self.main_window.pipeline_manager.pipelineEditorTabs. get_current_editor().iterated_tag) if ui_select.exec_(): if self.main_window.pipeline_manager.pipelineEditorTabs.get_current_editor().iterated_tag is None \ and ui_select.selected_tag is None: pass else: self.main_window.pipeline_manager.pipelineEditorTabs.get_current_editor().iterated_tag = \ ui_select.selected_tag # Retrieve tag values self.update_selected_tag(ui_select.selected_tag) def filter_values(self): iterated_tag = self.main_window.pipeline_manager.pipelineEditorTabs.get_current_editor( ).iterated_tag tag_values = self.main_window.pipeline_manager.pipelineEditorTabs.get_current_editor( ).all_tag_values_list ui_iteration = PopUpSelectIteration(iterated_tag, tag_values) if ui_iteration.exec_(): tag_values_list = [ t.replace('&', '') for t in ui_iteration.final_values ] self.main_window.pipeline_manager.pipelineEditorTabs.get_current_editor().tag_values_list\ = tag_values_list self.combo_box.clear() self.combo_box.addItems(tag_values_list) self.update_table() def select_visualized_tag(self, idx): """Open a pop-up to let the user select which tag to visualize in the iteration table. :param idx: index of the clicked push button """ popUp = PopUpSelectTagCountTable( self.project, self.project.session.get_fields_names(COLLECTION_CURRENT), self.push_buttons[idx].text()) if popUp.exec_() and popUp.selected_tag is not None: self.push_buttons[idx].setText(popUp.selected_tag) self.fill_values(idx) self.update_table() def update_iterated_tag(self, tag_name=None): """ Update the widget when the iterated tag is modified. :param tag_name: name of the iterated tag """ if len(self.main_window.pipeline_manager.scan_list) > 0: self.scan_list = self.main_window.pipeline_manager.scan_list else: self.scan_list = self.project.session.get_documents_names( COLLECTION_CURRENT) self.combo_box.clear() if tag_name is None: self.iterated_tag_push_button.setText("Select") self.iterated_tag_label.setText("Select a tag") self.iteration_table.clear() self.iteration_table.setColumnCount(len(self.push_buttons)) else: self.iterated_tag_push_button.setText(tag_name) self.iterated_tag_label.setText(tag_name + ":") # duplicate the values list to have the initial, unfiltered, one self.all_tag_values =\ list(self.main_window.pipeline_manager.pipelineEditorTabs.get_current_editor().all_tag_values_list) self.combo_box.\ addItems(self.main_window.pipeline_manager.pipelineEditorTabs.get_current_editor().tag_values_list) self.update_table() def update_table(self): """ Update the iteration table. """ # Updating the scan list if not self.scan_list: self.scan_list = self.project.session.get_documents_names( COLLECTION_CURRENT) # Clearing the table and preparing its columns self.iteration_table.clear() self.iteration_table.setColumnCount(len(self.push_buttons)) if self.main_window.pipeline_manager.pipelineEditorTabs.get_current_editor( ).iterated_tag is not None: # Headers for idx in range(len(self.push_buttons)): # FIXME should not use GUI text values !! header_name = self.push_buttons[idx].text().replace('&', '') if header_name not in self.project.session.get_fields_names( COLLECTION_CURRENT): print("{0} not in the project's tags".format(header_name)) return item = QTableWidgetItem() item.setText(header_name) self.iteration_table.setHorizontalHeaderItem(idx, item) # Searching the database scans that correspond to iterated tag value filter_query = "({" + \ str(self.main_window.pipeline_manager.pipelineEditorTabs.get_current_editor().iterated_tag) + \ "} " + "==" + " \"" + \ str(self.combo_box.currentText()).replace('&', '') + "\")" scans_list = self.project.session.filter_documents( COLLECTION_CURRENT, filter_query) scans_res = [ getattr(document, TAG_FILENAME) for document in scans_list ] # Taking the intersection between the found database scans and the # user selection in the data_browser self.iteration_scans = list( set(scans_res).intersection(self.scan_list)) self.iteration_table.setRowCount(len(self.iteration_scans)) # Filling the table cells row = -1 for scan_name in self.iteration_scans: row += 1 for idx in range(len(self.push_buttons)): tag_name = self.push_buttons[idx].text().replace('&', '') item = QTableWidgetItem() item.setText( str( self.project.session.get_value( COLLECTION_CURRENT, scan_name, tag_name))) self.iteration_table.setItem(row, idx, item) all_iterations_scans = [] for tag_value in self.main_window.pipeline_manager.pipelineEditorTabs.get_current_editor( ).tag_values_list: # Searching the database scans that correspond to iterated tag value filter_query = "({" + \ str(self.main_window.pipeline_manager.pipelineEditorTabs. get_current_editor().iterated_tag) + \ "} " + "==" \ + " \"" + str(tag_value) + "\")" scans_list = self.project.session.filter_documents( COLLECTION_CURRENT, filter_query) scans_res = [ getattr(document, TAG_FILENAME) for document in scans_list ] all_iterations_scans.append( list(set(scans_res).intersection(self.scan_list))) self.all_iterations_scans = all_iterations_scans #self.scans = True # This will change the scans list in the current Pipeline Manager tab self.iteration_table_updated.emit(self.iteration_scans, self.all_iterations_scans) def update_selected_tag(self, selected_tag): tag_values_list = [] scans_names = self.project.session.get_documents_names( COLLECTION_CURRENT) if not self.scan_list: self.scan_list = scans_names scans_names = list(set(scans_names).intersection(self.scan_list)) for scan_name in scans_names: tag_value = self.project.session.get_value(COLLECTION_CURRENT, scan_name, selected_tag) if str(tag_value) not in tag_values_list: tag_values_list.append(str(tag_value)) self.main_window.pipeline_manager.pipelineEditorTabs.get_current_editor().tag_values_list = \ tag_values_list self.main_window.pipeline_manager.pipelineEditorTabs.get_current_editor().all_tag_values_list = \ tag_values_list self.update_iterated_tag(selected_tag)
class TableMetaWidget(QWidget): toggle_full_window_needed = pyqtSignal([bool]) class getset_property: def __init__(self, name, set_cb): self.name = name self.name_real = '_' + name self.set_cb = set_cb def __get__(self, instance, owner): if hasattr(instance, self.name_real): return getattr(instance, self.name_real) return None def __set__(self, instance, value): setattr(instance, self.name_real, value) if self.set_cb is not None: self.set_cb(instance) def __init__(self, parent=None): super().__init__(parent=parent) self.title_label = QLabel(self) self.cover_label = QLabel(self) self.meta_label = QLabel(self) self.desc_container = DescriptionContainer(parent=self) self.toolbar = SongsTableToolbar(parent=self) self.title_label.setTextFormat(Qt.RichText) self.meta_label.setTextFormat(Qt.RichText) self._is_fullwindow = False self._setup_ui() self._refresh() self.desc_container.space_pressed.connect(self.toggle_full_window) def _setup_ui(self): self.cover_label.setMinimumWidth(200) self.setMaximumHeight(180) self.title_label.setAlignment(Qt.AlignTop) self.meta_label.setAlignment(Qt.AlignTop) self._v_layout = QVBoxLayout(self) self._h_layout = QHBoxLayout() self._right_layout = QVBoxLayout() self._right_layout.addWidget(self.title_label) self._right_layout.addWidget(self.meta_label) self._right_layout.addWidget(self.desc_container) self._right_layout.addWidget(self.toolbar) self._right_layout.setAlignment(self.toolbar, Qt.AlignBottom) self._h_layout.addWidget(self.cover_label) self._h_layout.setAlignment(self.cover_label, Qt.AlignTop) self._h_layout.addLayout(self._right_layout) self._v_layout.addLayout(self._h_layout) self._h_layout.setContentsMargins(10, 10, 10, 10) self._h_layout.setSpacing(20) self._right_layout.setContentsMargins(0, 0, 0, 0) self._right_layout.setSpacing(5) self.layout().setContentsMargins(0, 0, 0, 0) self.layout().setSpacing(0) def _refresh(self): self._refresh_title() self._refresh_meta_label() self._refresh_desc() self._refresh_cover() def _refresh_title(self): if self.title: self.title_label.show() self.title_label.setText('<h2>{}</h2>'.format(self.title)) else: self.title_label.hide() def _refresh_meta_label(self): creator = self.creator creator_part = '👤 <a href="fuo://local/users/{}">{}</a>'\ .format(creator, creator) if creator else '' if self.updated_at: updated_at = datetime.fromtimestamp(self.updated_at) updated_part = '🕒 更新于 <code style="font-size: small">{}</code>'\ .format(updated_at.strftime('%Y-%m-%d')) else: updated_part = '' if self.created_at: created_at = datetime.fromtimestamp(self.created_at) created_part = '🕛 创建于 <code style="font-size: small">{}</code>'\ .format(created_at.strftime('%Y-%m-%d')) else: created_part = '' if creator_part or updated_part or created_part: parts = [creator_part, created_part, updated_part] valid_parts = [p for p in parts if p] content = ' | '.join(valid_parts) text = '<span style="color: grey">{}</span>'.format(content) # TODO: add linkActivated callback for meta_label self.meta_label.setText(text) self.meta_label.show() else: self.meta_label.hide() def _refresh_desc(self): if self.desc: self.desc_container.show() self.desc_container.label.setText(self.desc) else: self.desc_container.hide() def _refresh_cover(self): if not self.cover: self.cover_label.hide() def _refresh_toolbar(self): if self.is_artist: self.toolbar.artist_mode() else: self.toolbar.songs_mode() def clear(self): self.title = None self.subtitle = None self.desc = None self.cover = None self.created_at = None self.updated_at = None self.creator = None self.is_artist = False def set_cover_pixmap(self, pixmap): self.cover_label.show() self.cover_label.setPixmap( pixmap.scaledToWidth(self.cover_label.width(), mode=Qt.SmoothTransformation)) title = getset_property('title', _refresh_title) subtitle = getset_property('subtitle', _refresh_title) desc = getset_property('desc', _refresh_desc) cover = getset_property('cover', _refresh_cover) created_at = getset_property('created_at', _refresh_meta_label) updated_at = getset_property('updated_at', _refresh_meta_label) creator = getset_property('creator', _refresh_meta_label) is_artist = getset_property('is_artist', _refresh_toolbar) def toggle_full_window(self): if self._is_fullwindow: self.toggle_full_window_needed.emit(False) self.setMaximumHeight(180) else: # generally, display height will be less than 4000px self.toggle_full_window_needed.emit(True) self.setMaximumHeight(4000) self._is_fullwindow = not self._is_fullwindow
def set_widgets(self): self.canvas = Static3DCanvasForPointCloud() ## TODO canvasRegionLable = QLabel("点云拟合三维可视化") qFont = QFont() qFont.setPointSize(12) canvasRegionLable.setFont(qFont) # 左半部分中部布局 leftMiddleLayout = QVBoxLayout() leftMiddleLayout.setSpacing(10) leftMiddleLayout.addWidget(canvasRegionLable) leftMiddleLayout.addWidget(self.canvas) self.prevButton = PreviousButton() quitButton = QuitButton() # 左半部分底部布局 leftBottomLayout = QHBoxLayout() leftBottomLayout.addStretch() leftBottomLayout.setSpacing(60) leftBottomLayout.addWidget(self.prevButton) leftBottomLayout.addWidget(quitButton) # 左半部分布局 leftLayout = QVBoxLayout() leftLayout.setSpacing(23) leftLayout.addLayout(leftMiddleLayout) leftLayout.addLayout(leftBottomLayout) tableRegionLable = QLabel("误差曲线显示区域") tableRegionLable.setFont(qFont) self.canvas01 = StaticCanvasForErrorCurve01() self.canvas02 = StaticCanvasForErrorCurve02() self.canvas03 = StaticCanvasForErrorCurve03() self.canvas04 = StaticCanvasForErrorCurve04() self.canvas05 = StaticCanvasForErrorCurve05() self.canvas06 = StaticCanvasForErrorCurve06() dataShowLayout = QGridLayout() dataShowLayout.setHorizontalSpacing(2) dataShowLayout.setVerticalSpacing(2) dataShowLayout.addWidget(self.canvas01, 0, 0) dataShowLayout.addWidget(self.canvas02, 0, 1) dataShowLayout.addWidget(self.canvas03, 0, 2) dataShowLayout.addWidget(self.canvas04, 1, 0) dataShowLayout.addWidget(self.canvas05, 1, 1) dataShowLayout.addWidget(self.canvas06, 1, 2) # 右半部分顶部布局 rightTopLayout = QVBoxLayout() rightTopLayout.addWidget(tableRegionLable) rightTopLayout.addLayout(dataShowLayout) XStartLable = QLabel("起点X坐标") XStartLable.setFont(qFont) self.XStartLineEdit = QLineEdit() YStartLable = QLabel("起点Y坐标") YStartLable.setFont(qFont) self.YStartLineEdit = QLineEdit() XEndLable = QLabel("终点X坐标") XEndLable.setFont(qFont) self.XEndLineEdit = QLineEdit() YEndLable = QLabel("终点Y坐标") YEndLable.setFont(qFont) self.YEndLineEdit = QLineEdit() # 右半部分中部布局 rightMiddleLayout = QGridLayout() rightMiddleLayout.addWidget(XStartLable, 0, 0) rightMiddleLayout.addWidget(self.XStartLineEdit, 0, 1) rightMiddleLayout.addWidget(YStartLable, 0, 2) rightMiddleLayout.addWidget(self.YStartLineEdit, 0, 3) rightMiddleLayout.addWidget(XEndLable, 1, 0) rightMiddleLayout.addWidget(self.XEndLineEdit, 1, 1) rightMiddleLayout.addWidget(YEndLable, 1, 2) rightMiddleLayout.addWidget(self.YEndLineEdit, 1, 3) confirmButton = ConfirmButton() confirmButton.clicked.connect( self.between_two_arbitrary_point_error_curve) self.enlargeButton = EnlargeButton() # 右半部分底部布局 rightBottomLayout = QHBoxLayout() rightBottomLayout.addStretch() rightBottomLayout.setSpacing(60) rightBottomLayout.addWidget(confirmButton) rightBottomLayout.addWidget(self.enlargeButton) # 右半部分布局 rightLayout = QVBoxLayout() rightLayout.setSpacing(30) rightLayout.addLayout(rightTopLayout) rightLayout.addLayout(rightMiddleLayout) rightLayout.addLayout(rightBottomLayout) # 全局布局 self.widgetLayout = QHBoxLayout() self.widgetLayout.setContentsMargins(40, 40, 40, 40) self.widgetLayout.setSpacing(20) self.widgetLayout.addLayout(leftLayout) self.widgetLayout.addLayout(rightLayout)
class LaserQtFourthWindow(QWidget): def __init__(self): super(LaserQtFourthWindow, self).__init__() self.create_main_window() def create_main_window(self): self.setWindowTitle("复杂曲率板加工系统") self.setWindowIcon(QIcon('LaserQt_Ui/logo.png')) self.width, self.height = get_current_screen_size() self.setMinimumSize(self.width, self.height) self.setMaximumSize(self.width, self.height) self.set_widgets() self.setLayout(self.widgetLayout) def set_widgets(self): self.canvas = Static3DCanvasForPointCloud() ## TODO canvasRegionLable = QLabel("点云拟合三维可视化") qFont = QFont() qFont.setPointSize(12) canvasRegionLable.setFont(qFont) # 左半部分中部布局 leftMiddleLayout = QVBoxLayout() leftMiddleLayout.setSpacing(10) leftMiddleLayout.addWidget(canvasRegionLable) leftMiddleLayout.addWidget(self.canvas) self.prevButton = PreviousButton() quitButton = QuitButton() # 左半部分底部布局 leftBottomLayout = QHBoxLayout() leftBottomLayout.addStretch() leftBottomLayout.setSpacing(60) leftBottomLayout.addWidget(self.prevButton) leftBottomLayout.addWidget(quitButton) # 左半部分布局 leftLayout = QVBoxLayout() leftLayout.setSpacing(23) leftLayout.addLayout(leftMiddleLayout) leftLayout.addLayout(leftBottomLayout) tableRegionLable = QLabel("误差曲线显示区域") tableRegionLable.setFont(qFont) self.canvas01 = StaticCanvasForErrorCurve01() self.canvas02 = StaticCanvasForErrorCurve02() self.canvas03 = StaticCanvasForErrorCurve03() self.canvas04 = StaticCanvasForErrorCurve04() self.canvas05 = StaticCanvasForErrorCurve05() self.canvas06 = StaticCanvasForErrorCurve06() dataShowLayout = QGridLayout() dataShowLayout.setHorizontalSpacing(2) dataShowLayout.setVerticalSpacing(2) dataShowLayout.addWidget(self.canvas01, 0, 0) dataShowLayout.addWidget(self.canvas02, 0, 1) dataShowLayout.addWidget(self.canvas03, 0, 2) dataShowLayout.addWidget(self.canvas04, 1, 0) dataShowLayout.addWidget(self.canvas05, 1, 1) dataShowLayout.addWidget(self.canvas06, 1, 2) # 右半部分顶部布局 rightTopLayout = QVBoxLayout() rightTopLayout.addWidget(tableRegionLable) rightTopLayout.addLayout(dataShowLayout) XStartLable = QLabel("起点X坐标") XStartLable.setFont(qFont) self.XStartLineEdit = QLineEdit() YStartLable = QLabel("起点Y坐标") YStartLable.setFont(qFont) self.YStartLineEdit = QLineEdit() XEndLable = QLabel("终点X坐标") XEndLable.setFont(qFont) self.XEndLineEdit = QLineEdit() YEndLable = QLabel("终点Y坐标") YEndLable.setFont(qFont) self.YEndLineEdit = QLineEdit() # 右半部分中部布局 rightMiddleLayout = QGridLayout() rightMiddleLayout.addWidget(XStartLable, 0, 0) rightMiddleLayout.addWidget(self.XStartLineEdit, 0, 1) rightMiddleLayout.addWidget(YStartLable, 0, 2) rightMiddleLayout.addWidget(self.YStartLineEdit, 0, 3) rightMiddleLayout.addWidget(XEndLable, 1, 0) rightMiddleLayout.addWidget(self.XEndLineEdit, 1, 1) rightMiddleLayout.addWidget(YEndLable, 1, 2) rightMiddleLayout.addWidget(self.YEndLineEdit, 1, 3) confirmButton = ConfirmButton() confirmButton.clicked.connect( self.between_two_arbitrary_point_error_curve) self.enlargeButton = EnlargeButton() # 右半部分底部布局 rightBottomLayout = QHBoxLayout() rightBottomLayout.addStretch() rightBottomLayout.setSpacing(60) rightBottomLayout.addWidget(confirmButton) rightBottomLayout.addWidget(self.enlargeButton) # 右半部分布局 rightLayout = QVBoxLayout() rightLayout.setSpacing(30) rightLayout.addLayout(rightTopLayout) rightLayout.addLayout(rightMiddleLayout) rightLayout.addLayout(rightBottomLayout) # 全局布局 self.widgetLayout = QHBoxLayout() self.widgetLayout.setContentsMargins(40, 40, 40, 40) self.widgetLayout.setSpacing(20) self.widgetLayout.addLayout(leftLayout) self.widgetLayout.addLayout(rightLayout) # 类方法重载 -- 关闭窗口事件 def closeEvent(self, event): messageDialog = MessageDialog() reply = messageDialog.question(self, "消息提示对话框", "您要退出系统吗?", messageDialog.Yes | messageDialog.No, messageDialog.No) if reply == messageDialog.Yes: event.accept() else: event.ignore() def init_the_canvas(self): self.canvas.axes.plot([0], [0]) self.canvas.axes.hold(True) self.canvas.axes.set_xlim([0, 100]) self.canvas.axes.set_xticks(np.arange(0, 101, 10)) self.canvas.axes.set_ylim([0, 100]) self.canvas.axes.set_yticks(np.arange(0, 101, 10)) self.canvas.axes.set_zticks([]) self.canvas.axes.set_xlabel("加工板水平方向", fontproperties=FONT, fontsize=9) self.canvas.axes.set_ylabel("加工板垂直方向", fontproperties=FONT, fontsize=9) self.canvas.axes.grid(True, which="both") X = [] Y = [] # X, Y的取值介于1~100? X = [[_] * 100 for _ in range(1, 101)] Y = [_ for _ in range(1, 101)] * 100 # myLaserQtSub02.Z1 和 myLaserQtSub02.Z2 哪个是被减数 哪个是减数 self.canvas.axes.scatter(X, Y, self.Z1, c='red') self.canvas.axes.scatter(X, Y, self.Z2, c='black') self.canvas.draw() self.canvas.axes.hold(False) if os.path.exists("LaserQt_Temp"): shutil.rmtree("LaserQt_Temp") os.mkdir("LaserQt_Temp") self.horizontal_direction_1_3_error_curve() self.horizontal_direction_1_2_error_curve() self.horizontal_direction_2_3_error_curve() self.vertical_direction_1_3_error_curve() self.vertical_direction_2_3_error_curve() def horizontal_direction_1_3_error_curve(self): from matplotlib.pyplot import savefig error = [] for i in range(1, 101): error.append(self.Z1[100 * 32 + i] - self.Z2[100 * 32 + i]) self.canvas01.axes.plot() self.canvas01.axes.hold(True) self.canvas01.axes.set_xlim([0, 100]) self.canvas01.axes.set_xticks(np.arange(0, 101, 10)) self.canvas01.axes.set_title("加工板水平方向1/3处误差曲线图", fontproperties=FONT, fontsize=14) self.canvas01.axes.grid(True, which="both") self.canvas01.axes.plot(range(1, 101), error, 'r') self.canvas01.print_figure( "LaserQt_Temp/horizontal_direction_1_3_error_curve.png") self.canvas01.draw() self.canvas01.axes.hold(False) def horizontal_direction_1_2_error_curve(self): error = [] for i in range(1, 101): error.append(self.Z1[100 * 49 + i] - self.Z2[100 * 49 + i]) self.canvas02.axes.plot() self.canvas02.axes.hold(True) self.canvas02.axes.set_xlim([0, 100]) self.canvas02.axes.set_xticks(np.arange(0, 101, 10)) self.canvas02.axes.set_title("加工板水平方向1/2处误差曲线图", fontproperties=FONT, fontsize=14) self.canvas02.axes.grid(True, which="both") self.canvas02.axes.plot(range(1, 101), error, 'r') self.canvas02.print_figure( "LaserQt_Temp/horizontal_direction_1_2_error_curve.png") self.canvas02.draw() self.canvas02.axes.hold(False) def horizontal_direction_2_3_error_curve(self): error = [] for i in range(1, 101): error.append(self.Z1[100 * 65 + i] - self.Z2[100 * 65 + i]) self.canvas03.axes.plot() self.canvas03.axes.hold(True) self.canvas03.axes.set_xlim([0, 100]) self.canvas03.axes.set_xticks(np.arange(0, 101, 10)) self.canvas03.axes.set_title("加工板水平方向2/3处误差曲线图", fontproperties=FONT, fontsize=14) self.canvas03.axes.grid(True, which="both") self.canvas03.axes.plot(range(1, 101), error, 'r') self.canvas03.print_figure( "LaserQt_Temp/horizontal_direction_2_3_error_curve.png") self.canvas03.draw() self.canvas03.axes.hold(False) def vertical_direction_1_3_error_curve(self): error = [] for i in range(100): error.append(self.Z1[100 * i + 33] - self.Z2[100 * i + 33]) self.canvas04.axes.plot() self.canvas04.axes.hold(True) self.canvas04.axes.set_xlim([0, 100]) self.canvas04.axes.set_xticks(np.arange(0, 101, 10)) self.canvas04.axes.set_title("加工板垂直方向1/3处误差曲线图", fontproperties=FONT, fontsize=14) self.canvas04.axes.grid(True, which="both") self.canvas04.axes.plot(range(1, 101), error, 'r') self.canvas04.print_figure( "LaserQt_Temp/vertical_direction_1_3_error_curve.png") self.canvas04.draw() self.canvas04.axes.hold(False) def vertical_direction_2_3_error_curve(self): error = [] for i in range(100): error.append(self.Z1[100 * i + 66] - self.Z2[100 * i + 66]) self.canvas05.axes.plot() self.canvas05.axes.hold(True) self.canvas05.axes.set_xlim([0, 100]) self.canvas05.axes.set_xticks(np.arange(0, 101, 10)) self.canvas05.axes.set_title("加工板垂直方向2/3处误差曲线图", fontproperties=FONT, fontsize=14) self.canvas05.axes.grid(True, which="both") self.canvas05.axes.plot(range(1, 101), error, 'r') self.canvas05.print_figure( "LaserQt_Temp/vertical_direction_2_3_error_curve.png") self.canvas05.draw() self.canvas05.axes.hold(False) def between_two_arbitrary_point_error_curve(self): x1 = int(self.XStartLineEdit.text().strip()) y1 = int(self.YStartLineEdit.text().strip()) x2 = int(self.XEndLineEdit.text().strip()) y2 = int(self.YEndLineEdit.text().strip()) k = (y2 - y1) / (x2 - x1) # 两点连线的斜率 dots_index = [] if x1 < x2: if y1 < y2: while x1 <= x2 and y1 <= y2: pass else: while x1 <= x2 and y1 >= y2: pass else: if y1 < y2: while x1 <= x2 and y1 <= y2: pass else: while x1 <= x2 and y1 >= y2: pass
class GuiProjectLoad(QDialog): NONE_STATE = 0 NEW_STATE = 1 OPEN_STATE = 2 C_NAME = 0 C_COUNT = 1 C_TIME = 2 def __init__(self, theParent): QDialog.__init__(self, theParent) logger.debug("Initialising GuiProjectLoad ...") self.setObjectName("GuiProjectLoad") self.mainConf = nw.CONFIG self.theParent = theParent self.theTheme = theParent.theTheme self.openState = self.NONE_STATE self.openPath = None sPx = self.mainConf.pxInt(16) nPx = self.mainConf.pxInt(96) iPx = self.theTheme.baseIconSize self.outerBox = QVBoxLayout() self.innerBox = QHBoxLayout() self.outerBox.setSpacing(sPx) self.innerBox.setSpacing(sPx) self.setWindowTitle("Open Project") self.setMinimumWidth(self.mainConf.pxInt(650)) self.setMinimumHeight(self.mainConf.pxInt(400)) self.setModal(True) self.nwIcon = QLabel() self.nwIcon.setPixmap( self.theParent.theTheme.getPixmap("novelwriter", (nPx, nPx))) self.innerBox.addWidget(self.nwIcon, 0, Qt.AlignTop) self.projectForm = QGridLayout() self.projectForm.setContentsMargins(0, 0, 0, 0) self.listBox = QTreeWidget() self.listBox.setSelectionMode(QAbstractItemView.SingleSelection) self.listBox.setDragDropMode(QAbstractItemView.NoDragDrop) self.listBox.setColumnCount(3) self.listBox.setHeaderLabels(["Working Title", "Words", "Last Opened"]) self.listBox.setRootIsDecorated(False) self.listBox.itemSelectionChanged.connect(self._doSelectRecent) self.listBox.itemDoubleClicked.connect(self._doOpenRecent) self.listBox.setIconSize(QSize(iPx, iPx)) treeHead = self.listBox.headerItem() treeHead.setTextAlignment(self.C_COUNT, Qt.AlignRight) treeHead.setTextAlignment(self.C_TIME, Qt.AlignRight) self.lblRecent = QLabel("<b>Recently Opened Projects</b>") self.lblPath = QLabel("<b>Path</b>") self.selPath = QLineEdit("") self.selPath.setReadOnly(True) self.browseButton = QPushButton("...") self.browseButton.setMaximumWidth( int(2.5 * self.theTheme.getTextWidth("..."))) self.browseButton.clicked.connect(self._doBrowse) self.projectForm.addWidget(self.lblRecent, 0, 0, 1, 3) self.projectForm.addWidget(self.listBox, 1, 0, 1, 3) self.projectForm.addWidget(self.lblPath, 2, 0, 1, 1) self.projectForm.addWidget(self.selPath, 2, 1, 1, 1) self.projectForm.addWidget(self.browseButton, 2, 2, 1, 1) self.projectForm.setColumnStretch(0, 0) self.projectForm.setColumnStretch(1, 1) self.projectForm.setColumnStretch(2, 0) self.projectForm.setVerticalSpacing(self.mainConf.pxInt(4)) self.projectForm.setHorizontalSpacing(self.mainConf.pxInt(8)) self.innerBox.addLayout(self.projectForm) self.buttonBox = QDialogButtonBox(QDialogButtonBox.Open | QDialogButtonBox.Cancel) self.buttonBox.accepted.connect(self._doOpenRecent) self.buttonBox.rejected.connect(self._doCancel) self.newButton = self.buttonBox.addButton("New", QDialogButtonBox.ActionRole) self.newButton.clicked.connect(self._doNewProject) self.outerBox.addLayout(self.innerBox) self.outerBox.addWidget(self.buttonBox) self.setLayout(self.outerBox) self._populateList() self._doSelectRecent() keyDelete = QShortcut(self.listBox) keyDelete.setKey(QKeySequence(Qt.Key_Delete)) keyDelete.activated.connect(self._keyPressDelete) logger.debug("GuiProjectLoad initialisation complete") return ## # Buttons ## def _doOpenRecent(self): """Close the dialog window with a recent project selected. """ logger.verbose("GuiProjectLoad open button clicked") self._saveSettings() self.openPath = None self.openState = self.NONE_STATE selItems = self.listBox.selectedItems() if selItems: self.openPath = selItems[0].data(self.C_NAME, Qt.UserRole) self.openState = self.OPEN_STATE self.accept() return def _doSelectRecent(self): """A recent item has been selected. """ selList = self.listBox.selectedItems() if selList: self.selPath.setText(selList[0].data(self.C_NAME, Qt.UserRole)) return def _doBrowse(self): """Browse for a folder path. """ logger.verbose("GuiProjectLoad browse button clicked") dlgOpt = QFileDialog.Options() dlgOpt |= QFileDialog.DontUseNativeDialog projFile, _ = QFileDialog.getOpenFileName( self, "Open novelWriter Project", "", "novelWriter Project File (%s);;All Files (*)" % nwFiles.PROJ_FILE, options=dlgOpt) if projFile: thePath = os.path.abspath(os.path.dirname(projFile)) self.selPath.setText(thePath) self.openPath = thePath self.openState = self.OPEN_STATE self.accept() return def _doCancel(self): """Close the dialog window without doing anything. """ logger.verbose("GuiProjectLoad close button clicked") self.openPath = None self.openState = self.NONE_STATE self.close() return def _doNewProject(self): """Create a new project. """ logger.verbose("GuiProjectLoad new project button clicked") self._saveSettings() self.openPath = None self.openState = self.NEW_STATE self.accept() return def _keyPressDelete(self): """Remove an entry from the recent projects list. """ selList = self.listBox.selectedItems() if selList: msgYes = self.theParent.askQuestion( "Remove Entry", "Remove the selected entry from the recent projects list?") if msgYes: self.mainConf.removeFromRecentCache(selList[0].data( self.C_NAME, Qt.UserRole)) self._populateList() return ## # Events ## def closeEvent(self, theEvent): """Capture the user closing the dialog so we can save settings. """ self._saveSettings() theEvent.accept() return ## # Internal Functions ## def _saveSettings(self): """Save the changes made to the dialog. """ colWidths = [0, 0, 0] colWidths[self.C_NAME] = self.listBox.columnWidth(self.C_NAME) colWidths[self.C_COUNT] = self.listBox.columnWidth(self.C_COUNT) colWidths[self.C_TIME] = self.listBox.columnWidth(self.C_TIME) self.mainConf.setProjColWidths(colWidths) return def _populateList(self): """Populate the list box with recent project data. """ dataList = [] for projPath in self.mainConf.recentProj: theEntry = self.mainConf.recentProj[projPath] theTitle = theEntry.get("title", "") theTime = theEntry.get("time", 0) theWords = theEntry.get("words", 0) dataList.append([theTitle, theTime, theWords, projPath]) self.listBox.clear() sortList = sorted(dataList, key=lambda x: x[1], reverse=True) for theTitle, theTime, theWords, projPath in sortList: newItem = QTreeWidgetItem([""] * 4) newItem.setIcon(self.C_NAME, self.theParent.theTheme.getIcon("proj_nwx")) newItem.setText(self.C_NAME, theTitle) newItem.setData(self.C_NAME, Qt.UserRole, projPath) newItem.setText(self.C_COUNT, formatInt(theWords)) newItem.setText(self.C_TIME, datetime.fromtimestamp(theTime).strftime("%x %X")) newItem.setTextAlignment(self.C_NAME, Qt.AlignLeft | Qt.AlignVCenter) newItem.setTextAlignment(self.C_COUNT, Qt.AlignRight | Qt.AlignVCenter) newItem.setTextAlignment(self.C_TIME, Qt.AlignRight | Qt.AlignVCenter) newItem.setFont(self.C_TIME, self.theTheme.guiFontFixed) self.listBox.addTopLevelItem(newItem) if self.listBox.topLevelItemCount() > 0: self.listBox.topLevelItem(0).setSelected(True) projColWidth = self.mainConf.getProjColWidths() if len(projColWidth) == 3: self.listBox.setColumnWidth(self.C_NAME, projColWidth[self.C_NAME]) self.listBox.setColumnWidth(self.C_COUNT, projColWidth[self.C_COUNT]) self.listBox.setColumnWidth(self.C_TIME, projColWidth[self.C_TIME]) return
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() else: self.app.quit() 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", "LibraryStableListWidget", "Nothing to show yet") self.LibraryDailyListWidget = \ self.LibraryToolBox.add_list_widget( "Daily Builds", "LibraryDailyListWidget", "Nothing to show yet") self.LibraryExperimentalListWidget = \ self.LibraryToolBox.add_list_widget( "Experimental Branches", "LibraryExperimentalListWidget", "Nothing to show yet") self.LibraryCustomListWidget = \ self.LibraryToolBox.add_list_widget( "Custom Builds", "LibraryCustomListWidget", "Nothing to show yet") self.LibraryTab.layout().addWidget(self.LibraryToolBox) self.DownloadsToolBox = BaseToolBoxWidget(self) self.DownloadsStableListWidget = \ self.DownloadsToolBox.add_list_widget( "Stable Releases", "DownloadsStableListWidget", "No new builds available", False) self.DownloadsDailyListWidget = \ self.DownloadsToolBox.add_list_widget( "Daily Builds", "DownloadsDailyListWidget", "No new builds available") self.DownloadsExperimentalListWidget = \ self.DownloadsToolBox.add_list_widget( "Experimental Branches", "DownloadsExperimentalListWidget", "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.LibraryCustomListWidget.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())
class IconData(QWidget): """ Visualizes a numeric value with an icon related to what the data's value mean, and it shows whether the value has been increasing or decreasing from previous samples. """ value = proxy_property('value_widget', ValueWidget, 'value') label = proxy_property('value_widget', ValueWidget, 'label') text_font = proxy_property('value_widget', ValueWidget, 'text_font') up_brush = proxy_property('arrow_widget', ArrowWidget, 'up_brush') down_brush = proxy_property('arrow_widget', ArrowWidget, 'down_brush') icon = proxy_property('icon_widget', IconWidget, 'icon') def __init__(self, parent=None): super(IconData, self).__init__(parent) self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) # Setting up the widget self.icon_widget = IconWidget() self.value_widget = ValueWidget() self.arrow_widget = ArrowWidget() # Setting up the layouts self.data_layout = QVBoxLayout() self.data_layout.setSpacing(0) self.data_layout.addWidget(self.icon_widget, alignment=Qt.AlignHCenter) self.data_layout.addWidget(self.value_widget, alignment=Qt.AlignHCenter) self.arrow_layout = QVBoxLayout() self.arrow_layout.setSpacing(0) self.arrow_layout.addWidget(self.arrow_widget, alignment=Qt.AlignVCenter) self.main_layout = QHBoxLayout(self) self.main_layout.setSpacing(5) self.main_layout.addLayout(self.data_layout) self.main_layout.addLayout(self.arrow_layout) self.setLayout(self.main_layout) # Default settings self.value = 12.0 self.label = 'V' self.text_font = QFont('Rockwell', 15) self.icon = QIcon( path.join(getcwd(), '..', '..', 'assets', 'battery', 'battery.png')) @pyqtSlot(name='onUpdate') def update(self): super(IconData, self).update() self.icon_widget.update() self.value_widget.update() self.arrow_widget.update() self.updateGeometry() @pyqtSlot(int, name='setValue') @pyqtSlot(float, name='setValue') def set_value(self, value): self.value_widget.set_value(value) @pyqtSlot(name='setIncreasing') def set_increasing(self): self.arrow_widget.set_increasing() @pyqtSlot(name='setDecreasing') def set_decreasing(self): self.arrow_widget.set_decreasing() @pyqtSlot(name='setSteady') def set_steady(self): self.arrow_widget.set_steady()
class Add1x2Container(QFrame): ''' QFrame container for the "add 1x2" buttons ''' def __init__(self, parent): super(Add1x2Container, self).__init__() # Initialize parent, geometry, layout self.parent = parent self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.setProperty('_pc', None) self.layout = QVBoxLayout(self) self.layout.setSpacing(4) self.layout.setContentsMargins(6, 6, 6, 6) # Put/Call toggle buttons self.pcToggle = QWidget(self) self.pcToggleLayout = QHBoxLayout(self.pcToggle) self.pcToggleLayout.setSpacing(2) self.pcToggleLayout.setContentsMargins(4, 4, 4, 4) self.pcToggle.setFixedHeight(30) self.put = ToggleButton(self, 'put') self.put.setText('Put') self.put.textField.setAlignment(Qt.AlignVCenter | Qt.AlignHCenter) self.call = ToggleButton(self, 'call') self.call.setText('Call') self.call.textField.setAlignment(Qt.AlignVCenter | Qt.AlignHCenter) self.pcToggleLayout.addWidget(self.put) self.pcToggleLayout.addWidget(self.call) # 1 x 2 lines self.bounds = QWidget(self) self.bounds.setObjectName('bounds') self.boundsLayout = QHBoxLayout(self.bounds) self.boundsLayout.setSpacing(6) self.boundsLayout.setContentsMargins(4, 4, 4, 4) self.bounds.setMinimumSize(80, 30) fontSize = QFont() fontSize.setPointSize(10) self.bound1 = QWidget(self.bounds) self.bound1Layout = QHBoxLayout(self.bound1) self.bound1Layout.setSpacing(2) self.bound1Layout.setContentsMargins(0, 0, 0, 0) self.bound1Label = QLabel(self.bound1) self.bound1Label.setObjectName('bound1Label') self.bound1Label.setText('1 @ $') self.bound1Label.setFont(fontSize) self.bound1Line = QLineEdit(self.bound1) self.bound1Line.setObjectName('bound1Line') self.bound1Line.setFixedSize(45, 20) self.bound1Layout.addWidget(self.bound1Label) self.bound1Layout.addWidget(self.bound1Line) self.x = QLabel(self.bounds) self.x.setObjectName('x') self.x.setText('x') self.bound2 = QWidget(self.bounds) self.bound2Layout = QHBoxLayout(self.bound2) self.bound2Layout.setSpacing(2) self.bound2Layout.setContentsMargins(0, 0, 0, 0) self.bound2Label = QLabel(self.bound2) self.bound2Label.setObjectName('bound2Label') self.bound2Label.setText('2 @ $') self.bound2Label.setFont(fontSize) self.bound2Line = QLineEdit(self.bound2) self.bound2Line.setObjectName('bound2Line') self.bound2Line.setFixedSize(45, 20) self.bound2Layout.addWidget(self.bound2Label) self.bound2Layout.addWidget(self.bound2Line) self.boundsLayout.addWidget(self.bound1, 0, Qt.AlignHCenter) self.boundsLayout.addWidget(self.x, 0, Qt.AlignHCenter) self.boundsLayout.addWidget(self.bound2, 0, Qt.AlignHCenter) # Add 1x2 button self.add = QPushButton('Add new 1x2') self.add.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.add.clicked.connect(lambda: self.add1x2()) # Add to layout (with stretch) self.layout.addWidget(self.bounds, 0, Qt.AlignHCenter) self.layout.addWidget(self.pcToggle) self.layout.addWidget(self.add) self.layout.addStretch(1) def add1x2(self): ''' Adds 1x2 to model, runs update on self as well as parent (main) widget ''' # Get text from bounds lines _1 = self.bound1Line.text() _2 = self.bound2Line.text() # If bounds are entered and put/call is selected if self.property('_pc') and _1 != '' and _2 != '': # Try/except to catch errors thrown from asCurrency() try: # Create a currency counterpart for bounds _1curr = asCurrency(_1) _2curr = asCurrency(_2) # Create an entry based off of bounds, put/call, then create the columns for populating the table and add to model self.parent.model.addRow( Entry(self.property('_pc'), _1, _1curr, _2, _2curr)) # Clear bounds lines, put/call and run parent.update self.update('clear') self.parent.enableChart() # If asCurrency() throws an error, execute error popup except Exception as e: self.parent.ePop.eLabel.setText( 'Please make sure the values you are entering are correct.' ) self.parent.ePop.centerWindow() self.parent.ePop.exec_() # Execute error popup is put/call not selected elif not self.property('_pc'): self.parent.ePop.eLabel.setText( "Please select either 'Put' or 'Call'.") self.parent.ePop.centerWindow() self.parent.ePop.exec_() # Execute error popup if either of the bounds lines are empty else: self.parent.ePop.eLabel.setText( "Please input correct values for the 1x2.") self.parent.ePop.centerWindow() self.parent.ePop.exec_() return def update(self, button): ''' Called when either ToggleButton is clicked or when entry is added. Sets _pc property, which determines whether the added entry is put or call. Untoggles p/c button if other is selected. Clears p/c and bounds lines when entry is added. ''' # If ToggleButton is clicked, set _pc and change ToggleButton _state/style if button == 'put': self.setProperty('_pc', 'P') self.call.setProperty('_state', 0) self.call.setStyleSheet(self.call.sSheet) elif button == 'call': self.setProperty('_pc', 'C') self.put.setProperty('_state', 0) self.put.setStyleSheet(self.put.sSheet) # If entry is added, clear bounds lines, p/c button elif button == 'clear': self.setProperty('_pc', None) self.put.setProperty('_state', 0) self.put.setStyleSheet(self.put.sSheet) self.call.setProperty('_state', 0) self.call.setStyleSheet(self.call.sSheet) self.bound1Line.setText('') self.bound2Line.setText('') return
def setupUI(self, MainWindow): # Oppløsning til skjermen, benyttes for å få korrekt ratio for layout screen_shape = QDesktopWidget().screenGeometry() # Finner oppløsningen til skjermen width = screen_shape.width() height = screen_shape.height() self.centralwidget = QWidget(MainWindow) self.daf_kort = QLabel('DAF') # Label som skal være DAF logo/tekst self.daf_kort.setStyleSheet('font-size: 25pt; font-family: Open Sans; border: 0px solid;') self.daf_lang = QLabel('Deteksjon av Fisk i Video') # Label som skal være DAF logo/tekst self.daf_lang.setStyleSheet('font-size: 18pt; font-family: Open Sans; border: 0px solid;') self.hjelp = QPushButton('') # Hjelp knapp for å vise Brukerguide self.hjelp.setIconSize(QSize(width * 0.1, height * 0.1)) self.hjelp.setStyleSheet('QPushButton{border: 0px solid;}') self.hjelp.setIcon(QIcon("Vedlegg/Help.png")) self.tabell = QTableWidget() self.tabell.setRowCount(0) self.tabell.setColumnCount(3) self.tabell.setColumnWidth(0, width * 0.45) self.tabell.setHorizontalHeaderLabels(["Filnavn", "Filstørrelse", "Lengde"]) self.legg_til_fil = QPushButton('Legg til fil') self.legg_til_fil.setStyleSheet('font-size: 16pt; font-family: Open Sans;') ### MODUS (Hurtig / Sakte) ### self.modus = QLabel('Modus') self.modus.setStyleSheet('font-size: 16pt; font-family: Open Sans; border: 0px solid;') UI_Valgte_Filer.hurtig = QRadioButton('Hurtig') UI_Valgte_Filer.hurtig.setStyleSheet('font-size: 12pt; font-family: Open Sans; border: 0px solid;') UI_Valgte_Filer.sakte = QRadioButton('Sakte') UI_Valgte_Filer.sakte.setStyleSheet('font-size: 12pt; font-family: Open Sans; border: 0px solid;') ### DEVMODE ### self.devMode = QLabel('Utviklingsmodus') self.devMode.setStyleSheet('font-size: 16pt; font-family: Open Sans; border: 0px solid;') UI_Valgte_Filer.devMode = QCheckBox('Aktiver') UI_Valgte_Filer.devMode.setStyleSheet('font-size: 12pt; font-family: Open Sans; border: 0px solid;') ### TESTING ### self.testing = QLabel('Testing') self.testing.setStyleSheet('font-size: 16pt; font-family: Open Sans; border: 0px solid;') UI_Valgte_Filer.testing_test = QRadioButton('Testsett') UI_Valgte_Filer.testing_test.setStyleSheet('font-size: 12pt; font-family: Open Sans; border: 0px solid;') UI_Valgte_Filer.testing_utvikling = QRadioButton('Utviklingssett') UI_Valgte_Filer.testing_utvikling.setStyleSheet('font-size: 12pt; font-family: Open Sans; border: 0px solid;') UI_Valgte_Filer.kjorTesting = QPushButton('Kjør testing') UI_Valgte_Filer.kjorTesting.setStyleSheet('font-size: 16pt; font-family: Open Sans;') ### KNAPPER ### self.kjorDeteksjon = QPushButton('Kjør deteksjon') self.kjorDeteksjon.setStyleSheet('font-size: 16pt; font-family: Open Sans; background-color: #006CD0; color: #ffffff') self.tilbake = QPushButton('Tilbake') self.tilbake.setStyleSheet('font-size: 16pt; font-family: Open Sans;') self.eksporter = QPushButton('Eksporter') self.eksporter.setStyleSheet('font-size: 16pt; font-family: Open Sans;') ### LAYOUT - UI_Valgte_Filer ### ### Layout for Logo ### logo_layout = QVBoxLayout() # Vertikalt layout logo_layout.addWidget(self.daf_kort, alignment=Qt.AlignRight) # Endrer posisjonering til å være til høyre logo_layout.addWidget(self.daf_lang) logo_layout.setAlignment(Qt.AlignRight) ### Box som grupper Layout til Logo ### logo_box = QGroupBox("") # Logo + Overskrift logo_box.setLayout(logo_layout) logo_box.setAlignment(Qt.AlignRight) ### Layout for Brukerguiden ### hjelp_layout = QVBoxLayout() hjelp_layout.addWidget(self.hjelp, alignment=Qt.AlignHCenter) ### Box som grupper Layout til Brukerguiden ### hjelp_box = QGroupBox("") #Hjelp knapp hjelp_box.setLayout(hjelp_layout) hjelp_box.setMaximumWidth(width * 0.125) hjelp_box.setAlignment(Qt.AlignLeft) ### Layout for Tabellen ### tabell_layout = QVBoxLayout() tabell_layout.addWidget(self.tabell) ### Box som grupper Layout til tabellen ### tabell_box = QGroupBox("Filer") # Tabell med filer tabell_box.setLayout(tabell_layout) tabell_box.setAlignment(Qt.AlignLeft) ### Layout for Modus-knapper ### modus_layout = QHBoxLayout() modus_layout.addWidget(UI_Valgte_Filer.hurtig) modus_layout.addWidget(UI_Valgte_Filer.sakte) ### Box som grupper Layout til Modus-knappene ### modus_box = QGroupBox('Modus') # Modus modus_box.setLayout(modus_layout) modus_box.setAlignment(Qt.AlignTop) ### Layout for Utviklingsmodus ### devMode_layout = QHBoxLayout() devMode_layout.addWidget(UI_Valgte_Filer.devMode) ### Box som grupper Layout til Utviklingsmodus ### dev_box = QGroupBox('Utviklingsmodus') # DevMode (imshow eller ikke) dev_box.setLayout(devMode_layout) dev_box.setAlignment(Qt.AlignTop) ### Layout for Testing-knappene ### testing_layout = QHBoxLayout() testing_layout.addWidget(UI_Valgte_Filer.testing_test) testing_layout.addWidget(UI_Valgte_Filer.testing_utvikling) ### Box som grupper Layout for Testing-knappene ### testing_box = QGroupBox('Testing') # Testing (testing av utivklingssett og testsett) testing_box.setLayout(testing_layout) testing_box.setAlignment(Qt.AlignTop) ### Overordnet Layout for knappene til høyre ### button_layout = QHBoxLayout() button_layout.addStretch() button_layout.setSpacing(width * 0.005) # Mellomrom mellom hver knapp button_layout.addWidget(UI_Valgte_Filer.kjorTesting) button_layout.addWidget(self.legg_til_fil) button_layout.addWidget(self.eksporter) button_layout.addWidget(self.tilbake) button_layout.addWidget(self.kjorDeteksjon) ### Overorndet Box som grupper Layout for knappene til høyre ### button_box = QGroupBox("") # Knapper button_box.setLayout(button_layout) button_box.setAlignment(Qt.AlignBottom) ### Overordnet Layout for Tabell ### table_layout = QVBoxLayout() table_layout.addWidget(tabell_box) ### Overorndet Layout for alle knappene ### action_layout = QHBoxLayout() action_layout.addWidget(modus_box) # Ulike modusene (Hurtig og Sakte) action_layout.addWidget(dev_box) # Utviklingsmodus aktiv eller ikke action_layout.addWidget(testing_box) # Testing (testsett eller utviklingssett) action_layout.addWidget(button_box) # Ulike knapper for Legge til filer, Tilbake og Kjør Deteksjon ### Overodnet Layout for Logo og Brukerguiden ### head_layout = QHBoxLayout() head_layout.addWidget(hjelp_box) head_layout.addWidget(logo_box) ### FOR-Loop for føring av filer inn i tabell ### for i in range(len(MainWindow.arr)): size = os.path.getsize(MainWindow.arr[i]) # Henter størrelsen på hver fil i KB sizeMB = (size / 1000000) # Omgjøring til MB sizeMB = np.round(sizeMB, 2) clip = VideoFileClip(MainWindow.arr[i]) clip_min = (clip.duration / 60) # Tillater 10 tegn totalt f.eks 11.1234567 rowPosition = self.tabell.rowCount() self.tabell.insertRow(rowPosition) self.tabell.setItem(rowPosition, 0, QTableWidgetItem(str(MainWindow.arr[i]))) self.tabell.setItem(rowPosition, 1, QTableWidgetItem("%s MB" % sizeMB)) if float(clip_min) < 1: clip = str(clip.duration) self.tabell.setItem(rowPosition, 2, QTableWidgetItem("%s sekunder" % clip)) else: self.tabell.setItem(rowPosition, 2, QTableWidgetItem("%s minutter" % clip_min)) self.tabell.resizeRowsToContents() # Resize for at hele filnavnet skal komme med if UI_Valgte_Filer.kjorTesting.clicked: UI_Valgte_Filer.kjorTesting.clicked.connect(MainWindow.kjor_testing) if self.tilbake.clicked: self.tilbake.clicked.connect(MainWindow.start_UI_Innlesing) if self.hjelp.clicked: self.hjelp.clicked.connect(MainWindow.show_help) if self.legg_til_fil.clicked: # Om Legg til fil knappen velges så åpnes filvelgeren på nytt self.legg_til_fil.clicked.connect(MainWindow.velg_fil) if self.kjorDeteksjon.clicked: # Om Kjør Deteksjon knappen velges så skal Deteksjon.py starte self.kjorDeteksjon.clicked.connect(MainWindow.kjor_deteksjon) if self.eksporter.clicked: # Knapp for valg av resultatmappe self.eksporter.clicked.connect(MainWindow.eksporter) ### Grupperende layout som inkluderer de øvrige layoutene ### main_layout = QVBoxLayout() main_layout.setAlignment(Qt.AlignLeading) main_layout.addLayout(head_layout) main_layout.addLayout(table_layout) main_layout.addLayout(action_layout) ### Setter CentralWidget sitt Layout til main_layout ### self.centralwidget.setLayout(main_layout) ### Endrer CentralWidget til MainWindow til å benytte UI_Valgte_Filer sin CentralWidget ### MainWindow.setCentralWidget(self.centralwidget)
class Interface(QWidget): ''' Main widget ''' def __init__(self): super(Interface, self).__init__() # Initialize window details and geometry self.title = 'Options Viewer' self.setWindowTitle(self.title) self.width = 654 self.height = 342 self.setFixedSize(self.width, self.height) self.setGeometry(0, 0, self.width - 4, self.height - 4) self.centerWindow() # Initialize the ErrorPopup self.ePop = ErrorPopup(self) # Initialize layouts (class, size, margins, spacing) self.layout = QVBoxLayout(self) self.layout.setContentsMargins(0, 0, 0, 0) self.layout.setSpacing(0) self.top = QFrame() self.top.setFixedSize(self.width, 302) self.topLayout = QHBoxLayout(self.top) self.topLayout.setContentsMargins(0, 0, 0, 0) self.topLayout.setSpacing(0) self.topRight = QFrame(self) self.topRight.setObjectName('topRight') self.topRight.setFixedSize(200, 302) self.topRightLayout = QVBoxLayout(self.topRight) self.topRightLayout.setContentsMargins(0, 0, 0, 0) self.topRightLayout.setSpacing(0) self.bottom = QFrame(self) self.bottom.setObjectName('bottom') self.bottom.setFixedSize(self.width, 40) self.bottomLayout = QHBoxLayout(self.bottom) self.bottomLayout.setContentsMargins(0, 0, 0, 0) self.bottomLayout.setSpacing(0) # Create top-right widgets and add to layout self.add1x2 = Add1x2Container(self) self.buttonContainer = ButtonContainer(self) self.topRightLayout.addWidget(self.add1x2) self.topRightLayout.addWidget(QHLine()) self.topRightLayout.addWidget(self.buttonContainer) # Create table and add to layout self.model = EntryModel(self) self.table = Table1x2() self.table.setModel(self.model) self.table.resize() self.topLayout.addWidget(self.table) self.topLayout.addWidget(self.topRight) # Create bottom widgets and add to layout self.bottomContainer = BottomContainer(self) self.helpquitContainer = HelpQuitContainer(self) self.bottomLayout.addWidget(self.bottomContainer) self.bottomLayout.addWidget(self.helpquitContainer) # Create chart and add (along with other layouts/containers) to main layout self.chartContainer = ChartContainer(self) self.layout.addWidget(self.top) self.layout.addWidget(self.chartContainer) self.layout.addWidget(self.bottom) # Initialize with chart hidden self.chartContainer.hide() self.setStyleSheet(open("styles/main.qss", "r").read()) # Uncomment to debug frame locations # self.setStyleSheet("QFrame {background-color: rgb(255,0,0); border:1px solid rgb(0, 0, 0)}") def enableChart(self): ''' Enables chart button and calls plot() ''' self.buttonContainer.chartButton.setEnabled(True) self.chartContainer.plot() def disableChart(self): ''' Clears & hides chart, disables button, resizes window ''' self.chartContainer.figure.clear() self.chartContainer.hide() self.buttonContainer.chartButton.setEnabled(False) try: self.setFixedSize(self.width, 342) self.buttonContainer.chartButton.setText('VVV Show chart VVV') self.buttonContainer.chartButton.disconnect() self.buttonContainer.chartButton.clicked.connect( lambda: self.buttonContainer.showChart()) except: pass def centerWindow(self): ''' Centers window based on screen geometry ''' qr = self.frameGeometry() cp = QDesktopWidget().availableGeometry().center() cp.setY(cp.y() - 250) qr.moveCenter(cp) self.move(qr.topLeft()) return
class ProjWizardFolderPage(QWizardPage): def __init__(self, theWizard): QWizardPage.__init__(self) self.mainConf = novelwriter.CONFIG self.theWizard = theWizard self.mainTheme = theWizard.mainTheme self.setTitle(self.tr("Select Project Folder")) self.theText = QLabel( self.tr( "Select a location to store the project. A new project folder " "will be created in the selected location.")) self.theText.setWordWrap(True) xW = self.mainConf.pxInt(300) vS = self.mainConf.pxInt(12) fS = self.mainConf.pxInt(8) self.projPath = QLineEdit("") self.projPath.setFixedWidth(xW) self.projPath.setPlaceholderText(self.tr("Required")) self.browseButton = QPushButton("...") self.browseButton.setMaximumWidth( int(2.5 * self.mainTheme.getTextWidth("..."))) self.browseButton.clicked.connect(self._doBrowse) self.errLabel = QLabel("") self.errLabel.setWordWrap(True) self.mainForm = QHBoxLayout() self.mainForm.addWidget(QLabel(self.tr("Project Path")), 0) self.mainForm.addWidget(self.projPath, 1) self.mainForm.addWidget(self.browseButton, 0) self.mainForm.setSpacing(fS) self.registerField("projPath*", self.projPath) # Assemble self.outerBox = QVBoxLayout() self.outerBox.setSpacing(vS) self.outerBox.addWidget(self.theText) self.outerBox.addLayout(self.mainForm) self.outerBox.addWidget(self.errLabel) self.outerBox.addStretch(1) self.setLayout(self.outerBox) return def isComplete(self): """Check that the selected path isn't already being used. """ self.errLabel.setText("") if not QWizardPage.isComplete(self): return False setPath = os.path.abspath(os.path.expanduser(self.projPath.text())) parPath = os.path.dirname(setPath) logger.verbose("Path is: %s", setPath) if parPath and not os.path.isdir(parPath): self.errLabel.setText( self. tr("Error: A project folder cannot be created using this path." )) return False if os.path.exists(setPath): self.errLabel.setText( self.tr("Error: The selected path already exists.")) return False return True ## # Slots ## def _doBrowse(self): """Select a project folder. """ lastPath = self.mainConf.lastPath if not os.path.isdir(lastPath): lastPath = "" projDir = QFileDialog.getExistingDirectory( self, self.tr("Select Project Folder"), lastPath, options=QFileDialog.ShowDirsOnly) if projDir: projName = self.field("projName") if projName is not None: fullDir = os.path.join(os.path.abspath(projDir), makeFileNameSafe(projName)) self.projPath.setText(fullDir) else: self.projPath.setText("") return
class FromImageWidget(QWidget): def __init__(self, parent=None): super().__init__(parent) self.setMaximumSize(QtCore.QSize(16777215, 50)) self.setObjectName("widget") self.main_layout = QVBoxLayout(self) self.main_layout.setContentsMargins(0, 0, 0, 0) self.select_img_container = QWidget(self) self.hbox_layout = QHBoxLayout(self.select_img_container) self.hbox_layout.setContentsMargins(11, 11, 11, 11) self.hbox_layout.setSpacing(6) self.hidden_widget2 = QWidget(self.select_img_container) self.hbox_layout.addWidget(self.hidden_widget2) self.select_image = QPushButton(self.select_img_container) self.select_image.setObjectName("selectImage") self.hbox_layout.addWidget(self.select_image) self.hidden_widget1 = QWidget(self.select_img_container) self.hbox_layout.addWidget(self.hidden_widget1) self.main_layout.addWidget(self.select_img_container) self._translate = QtCore.QCoreApplication.translate self.select_image.setText(self._translate("MainWindow", "Select image")) QMetaObject.connectSlotsByName(self) def showImage(self, image_path): layout_utils.cleanLayout(self.main_layout) self.setMaximumSize(QtCore.QSize(16777215, 16777215)) widget = QWidget(self) hbox_layout = QHBoxLayout(widget) pic = QLabel(self) pic.setFixedSize(400, 300) pixmap = QPixmap(image_path) pic.setPixmap(pixmap.scaled(pic.size(), Qt.KeepAspectRatio)) hbox_layout.addWidget(pic) self.main_layout.addWidget(widget) widget_2 = QWidget(self) hbox_layout_2 = QHBoxLayout(widget_2) self.detected_emotion = QLabel(self) self.detected_emotion.setSizePolicy(BQSizePolicy(h_stretch=3)) hbox_layout_2.addWidget(self.detected_emotion) self.select_image = QPushButton(self) self.select_image.setObjectName("selectImage") self.select_image.setText(self._translate("MainWindow", "Select image")) self.select_image.clicked.connect(self.onSelectImage) hbox_layout_2.addWidget(self.select_image) self.main_layout.addWidget(widget_2) self.classifyImage(image_path) def classifyImage(self, imp_path): image = cv2.imread(imp_path) gray_img = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) face_cascade = cv2.CascadeClassifier('resources/opencv/haarcascade_frontalface_alt.xml') faces = face_cascade.detectMultiScale(gray_img, scaleFactor=1.1, minNeighbors=5) if len(faces) > 0: (x, y, w, h) = faces[0] crop_img = image[y: y + h, x: x + w] gray_img = cv2.cvtColor(crop_img, cv2.COLOR_BGR2GRAY) img_out = cv2.resize(gray_img, (48, 48), interpolation=cv2.INTER_CUBIC) predicted = deep_learning_service.predict_image(img_out) emotion = deep_learning_service.get_actual_labels(predicted[0]) self.detected_emotion.setText(self._translate("MainWindow", "Detected emotion: " + emotion)) else: self.detected_emotion.setText(self._translate("MainWindow", "No face detected.")) @pyqtSlot(bool, name='on_selectImage_clicked') def onSelectImage(self): fname = QFileDialog.getOpenFileName(self, 'Open file', QDir.homePath(), "Image files (*.jpg)") if len(fname[0]) > 0: self.showImage(fname[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(self.tr("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( self. tr("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(self.tr("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(self.tr("Show synopsis comments")) # Labels self.lblRefs = QLabel(self.tr("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(self.tr("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(self.tr("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(self.tr("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
class CEditorContent ( QWidget ): def __init__ ( self, editor ): super ().__init__ () self.editor = editor self.toolBarAreaManager = CToolBarAreaManager ( editor ) self.mainLayout = QVBoxLayout () self.mainLayout.setContentsMargins ( 0, 0, 0, 0 ) self.mainLayout.setSpacing ( 0 ) self.contentLayout = QHBoxLayout () self.contentLayout.setContentsMargins ( 0, 0, 0, 0 ) self.contentLayout.setSpacing ( 0 ) self.content = QWidget () self.content.setSizePolicy ( QSizePolicy.Expanding, QSizePolicy.Expanding ) self.editor.signalAdaptiveLayoutChanged.connect ( self.onAdaptiveLayoutChanged ) self.setLayout ( self.mainLayout ) def initialize ( self ): self.toolBarAreaManager.initialize () self.mainLayout.addWidget ( self.toolBarAreaManager.getWidget ( CToolBarAreaManagerArea.Top ) ) self.mainLayout.addLayout ( self.contentLayout ) self.mainLayout.addWidget ( self.toolBarAreaManager.getWidget ( CToolBarAreaManagerArea.Bottom ) ) self.contentLayout.addWidget ( self.toolBarAreaManager.getWidget ( CToolBarAreaManagerArea.Left ) ) self.contentLayout.addWidget ( self.content ) self.contentLayout.addWidget ( self.toolBarAreaManager.getWidget ( CToolBarAreaManagerArea.Right ) ) def getContent ( self ): return self.content def setContent ( self, content ): if isinstance ( content, QWidget ): self.content.setSizePolicy ( QSizePolicy.Expanding, QSizePolicy.Expanding ) self.contentLayout.replaceWidget ( self.content, content ) self.content.setObjectName ( "CEditorContent" ) self.content.deleteLater () self.content = content elif isinstance ( content, QLayout ): contentLayout = content content = QWidget () content.setSizePolicy ( QSizePolicy.Expanding, QSizePolicy.Expanding ) content.setLayout ( contentLayout ) content.setObjectName ( "CEditorContent" ) contentLayout.setContentsMargins ( 0, 0, 0, 0 ) contentLayout.setSpacing ( 0 ) self.contentLayout.replaceWidget ( self.content, content ) self.content.deleteLater () self.content = content def customizeToolBar ( self ): # TODO: CToolBarCustomizeDialog return self.content def toggleToolBarLock ( self ): return self.toolBarAreaManager.toggleLock () def addExpandingSpacer ( self ): return self.toolBarAreaManager.addExpandingSpacer () def addFixedSpacer ( self ): return self.toolBarAreaManager.addFixedSpacer () def getMinimumSizeForOrientation ( self, orientation ) -> QSize: isDefaultOrientation = orientation == self.editor.GetDefaultOrientation () contentMinSize = self.content.layout ().minimumSize () topArea = self.toolBarAreaManager.getWidget ( CToolBarAreaManagerArea.Top ) bottomArea = self.toolBarAreaManager.getWidget ( CToolBarAreaManagerArea.Bottom ) leftArea = self.toolBarAreaManager.getWidget ( CToolBarAreaManagerArea.Left ) rightArea = self.toolBarAreaManager.getWidget ( CToolBarAreaManagerArea.Right ) result = QSize ( 0, 0 ) if isDefaultOrientation: # Take width from left and right areas if we're switching to the editor's default orientation result.setWidth ( result.width () + leftArea.getLargestItemMinimumSize ().width () ) result.setWidth ( result.width () + rightArea.getLargestItemMinimumSize ().width () ) # Use top and bottom area to calculate min height result.setHeight ( result.height () + leftArea.getLargestItemMinimumSize ().height () ) result.setHeight ( result.height () + rightArea.getLargestItemMinimumSize ().height () ) # Add content min size result += contentMinSize # Take the area layout size hints into account. Expand the current result with the toolbar area layout's size hint. # We use size hint rather than minimum size since toolbar area item's size policy is set to preferred. result = result.expandedTo ( QSize ( topArea.layout ().sizeHint ().height (), leftArea.layout ().sizeHint ().width () ) ) result = result.expandedTo ( QSize ( bottomArea.layout ().sizeHint ().height (), rightArea.layout ().sizeHint ().width () ) ) else: # If we're not switching to the default orientation, then we need to use the top and bottom toolbar areas' width # since these areas will be placed at the left and right of the editor content in this case of adaptive layouts result.setWidth ( result.width () + topArea.getLargestItemMinimumSize ().width () ) result.setWidth ( result.width () + bottomArea.getLargestItemMinimumSize ().width () ) # We must also flip where we get toolbar area min height from result.setHeight ( result.height () + leftArea.getLargestItemMinimumSize ().height () ) result.setHeight ( result.height () + rightArea.getLargestItemMinimumSize ().height () ) # Add flipped content min size result += QSize ( contentMinSize.height (), contentMinSize.width () ) result = result.expandedTo ( QSize ( leftArea.layout ().sizeHint ().height (), topArea.layout ().sizeHint ().width () ) ) result = result.expandedTo ( QSize ( rightArea.layout ().sizeHint ().height (), bottomArea.layout ().sizeHint ().width () ) ) return result def onAdaptiveLayoutChanged ( self ): isDefaultOrientation = self.editor.GetOrientation () == self.editor.GetDefaultOrientation () self.mainLayout.setDirection ( QBoxLayout.TopToBottom if isDefaultOrientation else QBoxLayout.LeftToRight ) self.contentLayout.setDirection ( QBoxLayout.LeftToRight if isDefaultOrientation else QBoxLayout.TopToBottom ) def paintEvent ( self, event ): styleOption = QStyleOption () styleOption.initFrom ( self ) painter = QPainter ( self ) self.style ().drawPrimitive ( QStyle.PE_Widget, styleOption, painter, self )
def __init__(self, rapidApp, parent=None) -> None: super().__init__(parent=parent) self.uris = [] self.get_href = re.compile('<a href="?\'?([^"\'>]*)') self.setModal(False) self.setSizeGripEnabled(True) self.search_pending = False self.add_queue = deque() self.rapidApp = rapidApp layout = QVBoxLayout() self.setWindowTitle(_('Error Reports - Rapid Photo Downloader')) self.log = QTextBrowser() self.log.setReadOnly(True) sheet = """ h1 { font-size: large; font-weight: bold; } """ document = self.log.document() # type: QTextDocument document.setDefaultStyleSheet(sheet) # document.setIndentWidth(QFontMetrics(QFont()).boundingRect('200').width()) self.highlightColor = QColor('#cb1dfa') self.textHighlightColor = QColor(Qt.white) self.noFindPalette = QPalette() self.noFindPalette.setColor(QPalette.WindowText, QPalette().color(QPalette.Mid)) self.foundPalette = QPalette() self.foundPalette.setColor(QPalette.WindowText, QPalette().color(QPalette.WindowText)) self.find_cursors = [] self.current_find_index = -1 self.log.anchorClicked.connect(self.anchorClicked) self.log.setOpenLinks(False) self.defaultFont = QFont() self.defaultFont.setPointSize(QFont().pointSize() - 1) self.log.setFont(self.defaultFont) self.log.textChanged.connect(self.textChanged) message = _('Find in reports') self.find = QFindLineEdit(find_text=message) self.find.textEdited.connect(self.onFindChanged) style = self.find.style() # type: QStyle frame_width = style.pixelMetric(QStyle.PM_DefaultFrameWidth) button_margin = style.pixelMetric(QStyle.PM_ButtonMargin) spacing = (frame_width + button_margin) * 2 + 8 self.find.setMinimumWidth( QFontMetrics(QFont()).boundingRect(message).width() + spacing) font_height = QFontMetrics(self.font()).height() size = QSize(font_height, font_height) self.up = QPushButton() self.up.setIcon(QIcon(':/icons/up.svg')) self.up.setIconSize(size) self.up.clicked.connect(self.upClicked) self.up.setToolTip(_('Find the previous occurrence of the phrase')) self.down = QPushButton() self.down.setIcon(QIcon(':/icons/down.svg')) self.down.setIconSize(size) self.down.clicked.connect(self.downClicked) self.down.setToolTip(_('Find the next occurrence of the phrase')) self.highlightAll = QPushButton(_('&Highlight All')) self.highlightAll.setToolTip( _('Highlight all occurrences of the phrase')) self.matchCase = QPushButton(_('&Match Case')) self.matchCase.setToolTip(_('Search with case sensitivity')) self.wholeWords = QPushButton(_('&Whole Words')) self.wholeWords.setToolTip(_('Search whole words only')) for widget in (self.highlightAll, self.matchCase, self.wholeWords): widget.setCheckable(True) widget.setFlat(True) self.highlightAll.toggled.connect(self.highlightAllToggled) self.matchCase.toggled.connect(self.matchCaseToggled) self.wholeWords.toggled.connect(self.wholeWordsToggled) self.findResults = QLabel() self.findResults.setMinimumWidth( QFontMetrics(QFont()).boundingRect( _('%s of %s matches') % (1000, 1000)).width() + spacing) # Translators: match number of total matches in a search, e.g. 1 of 10 matches _('%(matchnumber)s of %(total)s matches') #TODO implement this once translations done findLayout = QHBoxLayout() findLayout.setSpacing(0) spacing = 8 findLayout.addWidget(self.find) findLayout.addWidget(self.up) findLayout.addWidget(self.down) findLayout.addSpacing(spacing) findLayout.addWidget(self.highlightAll) findLayout.addSpacing(spacing) findLayout.addWidget(self.matchCase) findLayout.addSpacing(spacing) findLayout.addWidget(self.wholeWords) findLayout.addSpacing(spacing) findLayout.addWidget(self.findResults) buttons = QDialogButtonBox(QDialogButtonBox.Close) translateDialogBoxButtons(buttons) self.clear = buttons.addButton( _('Clear'), QDialogButtonBox.ActionRole) # type: QPushButton buttons.rejected.connect(self.reject) self.clear.clicked.connect(self.clearClicked) self.clear.setEnabled(False) layout.addWidget(self.log) layout.addLayout(findLayout) layout.addSpacing(6) layout.addWidget(buttons) self.setLayout(layout) self.onFindChanged('') self.icon_lookup = { ErrorType.warning: ':/report/warning.svg', ErrorType.serious_error: ':/report/error.svg', ErrorType.critical_error: ':/report/critical.svg' }
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(self.tr("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(self.tr("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(self.tr("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(self.tr("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
class StatusBar(QWidget): """The statusbar at the bottom of the mainwindow. Attributes: txt: The Text widget in the statusbar. keystring: The KeyString widget in the statusbar. percentage: The Percentage widget in the statusbar. url: The UrlText widget in the statusbar. prog: The Progress widget in the statusbar. cmd: The Command widget in the statusbar. _hbox: The main QHBoxLayout. _stack: The QStackedLayout with cmd/txt widgets. _text_queue: A deque of (error, text) tuples to be displayed. error: True if message is an error, False otherwise _text_pop_timer: A Timer displaying the error messages. _stopwatch: A QTime for the last displayed message. _timer_was_active: Whether the _text_pop_timer was active before hiding the command widget. _previous_widget: A PreviousWidget member - the widget which was displayed when an error interrupted it. _win_id: The window ID the statusbar is associated with. Class attributes: _severity: The severity of the current message, a Severity member. For some reason we need to have this as class attribute so pyqtProperty works correctly. _prompt_active: If we're currently in prompt-mode. For some reason we need to have this as class attribute so pyqtProperty works correctly. _insert_active: If we're currently in insert mode. For some reason we need to have this as class attribute so pyqtProperty works correctly. _command_active: If we're currently in command mode. For some reason we need to have this as class attribute so pyqtProperty works correctly. _caret_mode: The current caret mode (off/on/selection). For some reason we need to have this as class attribute so pyqtProperty works correctly. Signals: resized: Emitted when the statusbar has resized, so the completion widget can adjust its size to it. arg: The new size. moved: Emitted when the statusbar has moved, so the completion widget can move to the right position. arg: The new position. """ resized = pyqtSignal('QRect') moved = pyqtSignal('QPoint') _severity = None _prompt_active = False _insert_active = False _command_active = False _caret_mode = CaretMode.off STYLESHEET = """ QWidget#StatusBar, QWidget#StatusBar QLabel, QWidget#StatusBar QLineEdit { font: {{ font['statusbar'] }}; background-color: {{ color['statusbar.bg'] }}; color: {{ color['statusbar.fg'] }}; } QWidget#StatusBar[caret_mode="on"], QWidget#StatusBar[caret_mode="on"] QLabel, QWidget#StatusBar[caret_mode="on"] QLineEdit { color: {{ color['statusbar.fg.caret'] }}; background-color: {{ color['statusbar.bg.caret'] }}; } QWidget#StatusBar[caret_mode="selection"], QWidget#StatusBar[caret_mode="selection"] QLabel, QWidget#StatusBar[caret_mode="selection"] QLineEdit { color: {{ color['statusbar.fg.caret-selection'] }}; background-color: {{ color['statusbar.bg.caret-selection'] }}; } QWidget#StatusBar[severity="error"], QWidget#StatusBar[severity="error"] QLabel, QWidget#StatusBar[severity="error"] QLineEdit { color: {{ color['statusbar.fg.error'] }}; background-color: {{ color['statusbar.bg.error'] }}; } QWidget#StatusBar[severity="warning"], QWidget#StatusBar[severity="warning"] QLabel, QWidget#StatusBar[severity="warning"] QLineEdit { color: {{ color['statusbar.fg.warning'] }}; background-color: {{ color['statusbar.bg.warning'] }}; } QWidget#StatusBar[prompt_active="true"], QWidget#StatusBar[prompt_active="true"] QLabel, QWidget#StatusBar[prompt_active="true"] QLineEdit { color: {{ color['statusbar.fg.prompt'] }}; background-color: {{ color['statusbar.bg.prompt'] }}; } QWidget#StatusBar[insert_active="true"], QWidget#StatusBar[insert_active="true"] QLabel, QWidget#StatusBar[insert_active="true"] QLineEdit { color: {{ color['statusbar.fg.insert'] }}; background-color: {{ color['statusbar.bg.insert'] }}; } QWidget#StatusBar[command_active="true"], QWidget#StatusBar[command_active="true"] QLabel, QWidget#StatusBar[command_active="true"] QLineEdit { color: {{ color['statusbar.fg.command'] }}; background-color: {{ color['statusbar.bg.command'] }}; } """ def __init__(self, win_id, parent=None): super().__init__(parent) objreg.register('statusbar', self, scope='window', window=win_id) self.setObjectName(self.__class__.__name__) self.setAttribute(Qt.WA_StyledBackground) style.set_register_stylesheet(self) self.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Fixed) self._win_id = win_id self._option = None self._stopwatch = QTime() self._hbox = QHBoxLayout(self) self.set_hbox_padding() objreg.get('config').changed.connect(self.set_hbox_padding) self._hbox.setSpacing(5) self._stack = QStackedLayout() self._hbox.addLayout(self._stack) self._stack.setContentsMargins(0, 0, 0, 0) self.cmd = command.Command(win_id) self._stack.addWidget(self.cmd) objreg.register('status-command', self.cmd, scope='window', window=win_id) self.txt = textwidget.Text() self._stack.addWidget(self.txt) self._timer_was_active = False self._text_queue = collections.deque() self._text_pop_timer = usertypes.Timer(self, 'statusbar_text_pop') self._text_pop_timer.timeout.connect(self._pop_text) self.set_pop_timer_interval() objreg.get('config').changed.connect(self.set_pop_timer_interval) self.prompt = prompt.Prompt(win_id) self._stack.addWidget(self.prompt) self._previous_widget = PreviousWidget.none self.cmd.show_cmd.connect(self._show_cmd_widget) self.cmd.hide_cmd.connect(self._hide_cmd_widget) self._hide_cmd_widget() prompter = objreg.get('prompter', scope='window', window=self._win_id) prompter.show_prompt.connect(self._show_prompt_widget) prompter.hide_prompt.connect(self._hide_prompt_widget) self._hide_prompt_widget() self.keystring = keystring.KeyString() self._hbox.addWidget(self.keystring) self.url = url.UrlText() self._hbox.addWidget(self.url) self.percentage = percentage.Percentage() self._hbox.addWidget(self.percentage) self.tabindex = tabindex.TabIndex() self._hbox.addWidget(self.tabindex) # We add a parent to Progress here because it calls self.show() based # on some signals, and if that happens before it's added to the layout, # it will quickly blink up as independent window. self.prog = progress.Progress(self) self._hbox.addWidget(self.prog) objreg.get('config').changed.connect(self.maybe_hide) QTimer.singleShot(0, self.maybe_hide) def __repr__(self): return utils.get_repr(self) @config.change_filter('ui', 'hide-statusbar') def maybe_hide(self): """Hide the statusbar if it's configured to do so.""" hide = config.get('ui', 'hide-statusbar') if hide: self.hide() else: self.show() @config.change_filter('ui', 'statusbar-padding') def set_hbox_padding(self): padding = config.get('ui', 'statusbar-padding') self._hbox.setContentsMargins(padding.left, 0, padding.right, 0) @pyqtProperty(str) def severity(self): """Getter for self.severity, so it can be used as Qt property. Return: The severity as a string (!) """ if self._severity is None: return "" else: return self._severity.name def _set_severity(self, severity): """Set the severity for the current message. Re-set the stylesheet after setting the value, so everything gets updated by Qt properly. Args: severity: A Severity member. """ if self._severity == severity: # This gets called a lot (e.g. if the completion selection was # changed), and setStyleSheet is relatively expensive, so we ignore # this if there's nothing to change. return log.statusbar.debug("Setting severity to {}".format(severity)) self._severity = severity self.setStyleSheet(style.get_stylesheet(self.STYLESHEET)) if severity != Severity.normal: # If we got an error while command/prompt was shown, raise the text # widget. self._stack.setCurrentWidget(self.txt) @pyqtProperty(bool) def prompt_active(self): """Getter for self.prompt_active, so it can be used as Qt property.""" return self._prompt_active def _set_prompt_active(self, val): """Setter for self.prompt_active. Re-set the stylesheet after setting the value, so everything gets updated by Qt properly. """ log.statusbar.debug("Setting prompt_active to {}".format(val)) self._prompt_active = val self.setStyleSheet(style.get_stylesheet(self.STYLESHEET)) @pyqtProperty(bool) def command_active(self): """Getter for self.command_active, so it can be used as Qt property.""" return self._command_active @pyqtProperty(bool) def insert_active(self): """Getter for self.insert_active, so it can be used as Qt property.""" return self._insert_active @pyqtProperty(str) def caret_mode(self): """Getter for self._caret_mode, so it can be used as Qt property.""" return self._caret_mode.name def set_mode_active(self, mode, val): """Setter for self.{insert,command,caret}_active. Re-set the stylesheet after setting the value, so everything gets updated by Qt properly. """ if mode == usertypes.KeyMode.insert: log.statusbar.debug("Setting insert_active to {}".format(val)) self._insert_active = val if mode == usertypes.KeyMode.command: log.statusbar.debug("Setting command_active to {}".format(val)) self._command_active = val elif mode == usertypes.KeyMode.caret: tab = objreg.get('tabbed-browser', scope='window', window=self._win_id).currentWidget() log.statusbar.debug("Setting caret_mode - val {}, selection " "{}".format(val, tab.caret.selection_enabled)) if val: if tab.caret.selection_enabled: self._set_mode_text("{} selection".format(mode.name)) self._caret_mode = CaretMode.selection else: self._set_mode_text(mode.name) self._caret_mode = CaretMode.on else: self._caret_mode = CaretMode.off self.setStyleSheet(style.get_stylesheet(self.STYLESHEET)) def _set_mode_text(self, mode): """Set the mode text.""" text = "-- {} MODE --".format(mode.upper()) self.txt.set_text(self.txt.Text.normal, text) def _pop_text(self): """Display a text in the statusbar and pop it from _text_queue.""" try: severity, text = self._text_queue.popleft() except IndexError: self._set_severity(Severity.normal) self.txt.set_text(self.txt.Text.temp, '') self._text_pop_timer.stop() # If a previous widget was interrupted by an error, restore it. if self._previous_widget == PreviousWidget.prompt: self._stack.setCurrentWidget(self.prompt) elif self._previous_widget == PreviousWidget.command: self._stack.setCurrentWidget(self.cmd) elif self._previous_widget == PreviousWidget.none: self.maybe_hide() else: raise AssertionError("Unknown _previous_widget!") return self.show() log.statusbar.debug("Displaying message: {} (severity {})".format( text, severity)) log.statusbar.debug("Remaining: {}".format(self._text_queue)) self._set_severity(severity) self.txt.set_text(self.txt.Text.temp, text) def _show_cmd_widget(self): """Show command widget instead of temporary text.""" self._set_severity(Severity.normal) self._previous_widget = PreviousWidget.command if self._text_pop_timer.isActive(): self._timer_was_active = True self._text_pop_timer.stop() self._stack.setCurrentWidget(self.cmd) self.show() def _hide_cmd_widget(self): """Show temporary text instead of command widget.""" log.statusbar.debug("Hiding cmd widget, queue: {}".format( self._text_queue)) self._previous_widget = PreviousWidget.none if self._timer_was_active: # Restart the text pop timer if it was active before hiding. self._pop_text() self._text_pop_timer.start() self._timer_was_active = False self._stack.setCurrentWidget(self.txt) self.maybe_hide() def _show_prompt_widget(self): """Show prompt widget instead of temporary text.""" if self._stack.currentWidget() is self.prompt: return self._set_severity(Severity.normal) self._set_prompt_active(True) self._previous_widget = PreviousWidget.prompt if self._text_pop_timer.isActive(): self._timer_was_active = True self._text_pop_timer.stop() self._stack.setCurrentWidget(self.prompt) self.show() def _hide_prompt_widget(self): """Show temporary text instead of prompt widget.""" self._set_prompt_active(False) self._previous_widget = PreviousWidget.none log.statusbar.debug("Hiding prompt widget, queue: {}".format( self._text_queue)) if self._timer_was_active: # Restart the text pop timer if it was active before hiding. self._pop_text() self._text_pop_timer.start() self._timer_was_active = False self._stack.setCurrentWidget(self.txt) self.maybe_hide() def _disp_text(self, text, severity, immediately=False): """Inner logic for disp_error and disp_temp_text. Args: text: The message to display. severity: The severity of the messages. immediately: If set, message gets displayed immediately instead of queued. """ log.statusbar.debug("Displaying text: {} (severity={})".format( text, severity)) mindelta = config.get('ui', 'message-timeout') if self._stopwatch.isNull(): delta = None self._stopwatch.start() else: delta = self._stopwatch.restart() log.statusbar.debug("queue: {} / delta: {}".format( self._text_queue, delta)) if not self._text_queue and (delta is None or delta > mindelta): # If the queue is empty and we didn't print messages for long # enough, we can take the short route and display the message # immediately. We then start the pop_timer only to restore the # normal state in 2 seconds. log.statusbar.debug("Displaying immediately") self._set_severity(severity) self.show() self.txt.set_text(self.txt.Text.temp, text) self._text_pop_timer.start() elif self._text_queue and self._text_queue[-1] == (severity, text): # If we get the same message multiple times in a row and we're # still displaying it *anyways* we ignore the new one log.statusbar.debug("ignoring") elif immediately: # This message is a reaction to a keypress and should be displayed # immediately, temporarily interrupting the message queue. # We display this immediately and restart the timer.to clear it and # display the rest of the queue later. log.statusbar.debug("Moving to beginning of queue") self._set_severity(severity) self.show() self.txt.set_text(self.txt.Text.temp, text) self._text_pop_timer.start() else: # There are still some messages to be displayed, so we queue this # up. log.statusbar.debug("queueing") self._text_queue.append((severity, text)) self._text_pop_timer.start() @pyqtSlot(str, bool) def disp_error(self, text, immediately=False): """Display an error in the statusbar. Args: text: The message to display. immediately: If set, message gets displayed immediately instead of queued. """ self._disp_text(text, Severity.error, immediately) @pyqtSlot(str, bool) def disp_warning(self, text, immediately=False): """Display a warning in the statusbar. Args: text: The message to display. immediately: If set, message gets displayed immediately instead of queued. """ self._disp_text(text, Severity.warning, immediately) @pyqtSlot(str, bool) def disp_temp_text(self, text, immediately): """Display a temporary text in the statusbar. Args: text: The message to display. immediately: If set, message gets displayed immediately instead of queued. """ self._disp_text(text, Severity.normal, immediately) @pyqtSlot(str) def set_text(self, val): """Set a normal (persistent) text in the status bar.""" self.txt.set_text(self.txt.Text.normal, val) @pyqtSlot(usertypes.KeyMode) def on_mode_entered(self, mode): """Mark certain modes in the commandline.""" keyparsers = objreg.get('keyparsers', scope='window', window=self._win_id) if keyparsers[mode].passthrough: self._set_mode_text(mode.name) if mode in [usertypes.KeyMode.insert, usertypes.KeyMode.command, usertypes.KeyMode.caret]: self.set_mode_active(mode, True) @pyqtSlot(usertypes.KeyMode, usertypes.KeyMode) def on_mode_left(self, old_mode, new_mode): """Clear marked mode.""" keyparsers = objreg.get('keyparsers', scope='window', window=self._win_id) if keyparsers[old_mode].passthrough: if keyparsers[new_mode].passthrough: self._set_mode_text(new_mode.name) else: self.txt.set_text(self.txt.Text.normal, '') if old_mode in [usertypes.KeyMode.insert, usertypes.KeyMode.command, usertypes.KeyMode.caret]: self.set_mode_active(old_mode, False) @config.change_filter('ui', 'message-timeout') def set_pop_timer_interval(self): """Update message timeout when config changed.""" self._text_pop_timer.setInterval(config.get('ui', 'message-timeout')) def resizeEvent(self, e): """Extend resizeEvent of QWidget to emit a resized signal afterwards. Args: e: The QResizeEvent. """ super().resizeEvent(e) self.resized.emit(self.geometry()) def moveEvent(self, e): """Extend moveEvent of QWidget to emit a moved signal afterwards. Args: e: The QMoveEvent. """ super().moveEvent(e) self.moved.emit(e.pos()) def minimumSizeHint(self): """Set the minimum height to the text height plus some padding.""" padding = config.get('ui', 'statusbar-padding') width = super().minimumSizeHint().width() height = self.fontMetrics().height() + padding.top + padding.bottom return QSize(width, height)
def __init__(self, main_window: 'ElectrumWindow') -> None: super().__init__(None) balance_widget = QToolButton() balance_widget.setAutoRaise(True) balance_widget.setPopupMode(QToolButton.MenuButtonPopup) balance_icon_label = QLabel("") balance_icon_label.setPixmap(QPixmap(icon_path("sb_balance.png"))) hbox = QHBoxLayout() hbox.setSpacing(2) hbox.setSizeConstraint(hbox.SetFixedSize) hbox.addWidget(balance_icon_label) self._balance_bsv_label = QLabel("") hbox.addWidget(self._balance_bsv_label) self._balance_equals_label = QLabel("") self._balance_equals_label.setPixmap(QPixmap(icon_path("sb_approximate"))) hbox.addWidget(self._balance_equals_label) self._balance_fiat_label = QLabel("") hbox.addWidget(self._balance_fiat_label) # This is to pad out the text on the RHS so that the menu indicator does not overlay it. hbox.addWidget(QLabel(" ")) balance_widget.setLayout(hbox) balance_widget.addAction(BalancePopupAction(main_window, self, balance_widget)) self._balance_widget = balance_widget self.addPermanentWidget(balance_widget) self._fiat_widget = QWidget() self._fiat_widget.setVisible(False) estimate_icon_label = QLabel("") estimate_icon_label.setPixmap(QPixmap(icon_path("sb_fiat.png"))) hbox = QHBoxLayout() hbox.setSpacing(2) hbox.setSizeConstraint(hbox.SetFixedSize) hbox.addWidget(estimate_icon_label) self._fiat_bsv_label = QLabel("") hbox.addWidget(self._fiat_bsv_label) approximate_icon_label = QLabel("") approximate_icon_label.setPixmap(QPixmap(icon_path("sb_approximate"))) hbox.addWidget(approximate_icon_label) self._fiat_value_label = QLabel("") fm = self._fiat_bsv_label.fontMetrics() width = fm.width("1,000.00 CUR") self._fiat_value_label.setMinimumWidth(width) hbox.addWidget(self._fiat_value_label) self._fiat_widget.setLayout(hbox) self.addPermanentWidget(self._fiat_widget) network_widget = QWidget() network_icon_label = QLabel("") network_icon_label.setPixmap(QPixmap(icon_path("sb_network.png"))) hbox = QHBoxLayout() hbox.setSpacing(2) hbox.addWidget(network_icon_label) self._network_label = QLabel("") sp = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) sp.setHorizontalStretch(1) self._network_label.setSizePolicy(sp) hbox.addWidget(self._network_label) network_widget.setLayout(hbox) network_widget.setMinimumWidth(150) self.addPermanentWidget(network_widget) self.search_box = QLineEdit() # self.search_box.textChanged.connect(self.do_search) self.search_box.hide() self.addPermanentWidget(self.search_box)
def __types_block(self, name): """ Makes block for twilight data selection: [radio buttons: {none, scrape, import}] [browse button (for import), path (for import)] Label not included (combo box contains) :param name: of type of data :return: widget of block, button group of radio buttons, line edit of path """ layout = QVBoxLayout() top_row_layout = QHBoxLayout() button_group = QButtonGroup() # radio buttons button_group.setExclusive(True) none_button = QRadioButton("None") scrape_button = QRadioButton("Scrape") import_button = QRadioButton("Import") button_group.addButton(none_button, 1) # need 1-index because 0 means not found button_group.addButton(scrape_button, 2) button_group.addButton(import_button, 3) top_row_layout.addWidget(none_button) top_row_layout.addWidget(scrape_button) top_row_layout.addWidget(import_button) top_row_layout.addStretch() button_group.buttonClicked.connect( lambda current: self.update_combo_label_clicked(current)) self.combo_box.setCurrentIndex(self.types.index(name)) if name in {"Sun", "Moon", "Nautical" }: # default setting for Paul Revere Battalion slides scrape_button.setChecked(True) scrape_button.click() else: none_button.setChecked(True) none_button.click() top_row = QWidget() top_row.setLayout(top_row_layout) bottom_row_layout = QHBoxLayout() button = QPushButton("Browse") # browse button abbrev_path = QLineEdit() # line for import path full_path = MutableString("") bottom_row_layout.addWidget(button) bottom_row_layout.addWidget(abbrev_path) button.clicked.connect(lambda: self.set_path(abbrev_path, full_path)) abbrev_path.textEdited.connect( lambda: self.set_path(abbrev_path, full_path, abbrev_path.text())) bottom_row = QWidget() bottom_row.setLayout(bottom_row_layout) layout.addWidget(top_row) layout.addWidget(bottom_row) out = QWidget() out.setLayout(layout) layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) top_row_layout.setContentsMargins(0, 0, 5, 0) bottom_row_layout.setContentsMargins(0, 0, 0, 0) bottom_row_layout.setSpacing(5) return out, button, button_group, abbrev_path, full_path
def __init__(self,vector_list): # this is to start grid builder before .show ***note grid builder will require a array of data type called loginfo in the future*** super().__init__() #self.initUI() #this code runs GridBuilder ############################################################################# _widget = QWidget() layout = QGridLayout() layout.setContentsMargins(0,0,0,0) layout.setSpacing(10) #title_label = QLabel("Make Vector") #title_label.setMaximumHeight(35) layout_name = QHBoxLayout() name_text_label = QLabel("Vector Name") #name_text_label.setMaximumWidth(150) name_text_label.setMaximumHeight(35) name_edit = QTextEdit() #name_edit.setMaximumWidth(300) name_edit.setMaximumHeight(35) layout_name.addWidget(name_text_label) layout_name.addWidget(name_edit) layout_name.setSpacing(0) layout_description = QHBoxLayout() description_text_label = QLabel("Vector Description") #description_text_label.setMaximumWidth(150) description_edit = QTextEdit() #description_edit.setMaximumWidth(300) description_edit.setMaximumHeight(150) layout_description.addWidget(description_text_label) layout_description.addWidget(description_edit) layout_description.setSpacing(0) connect_project_button = QPushButton("Make Vector") #self.directory_config = Configure_Directory() connect_project_button.clicked.connect(lambda: self.create_vector(name_edit,description_edit,vector_list)) back_button = QPushButton("Cancel") back_button.clicked.connect(lambda: self.closeApp()) #connect_project_button.clicked.connect(self.directory_config.show_config) #connect_project_button.setMaximumWidth(150) def closeMyApp_OpenNewApp(self): self.close() self.Open = NewApp.NewApp() self.Open.show() widget = QWidget() widget.setLayout(layout) #layout.addWidget(title_label, 0, 0, 1, 3) layout.addLayout(layout_name,1,0,1,3) layout.addLayout(layout_description,2,0,1,3) layout.addWidget(connect_project_button,5,2) layout.addWidget(back_button,5,0) layout.setAlignment(Qt.AlignVCenter|Qt.AlignHCenter) widget.setLayout(layout) _layout = QVBoxLayout(_widget) _layout.addWidget(widget) _layout.setAlignment(Qt.AlignVCenter|Qt.AlignHCenter) self.setCentralWidget(_widget) ############################################################################# self.setGeometry(400, 400, 400, 450) self.setWindowTitle("Make Vector") self.show()
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) 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(self) 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)
def setup(self): """ user interface definition """ self.setWindowTitle('Visualization ' + self.cameraType + " " + self.ccdName + ' v.' + self.version) hbox1 = QHBoxLayout() # horizontal layout pour run snap stop self.sizebuttonMax = 30 self.sizebuttonMin = 30 self.runButton = QToolButton(self) self.runButton.setMaximumWidth(self.sizebuttonMax) self.runButton.setMinimumWidth(self.sizebuttonMax) self.runButton.setMaximumHeight(self.sizebuttonMax) self.runButton.setMinimumHeight(self.sizebuttonMax) self.runButton.setStyleSheet( "QToolButton:!pressed{border-image: url(%s);background-color: transparent ;border-color: green;}" "QToolButton:pressed{image: url(%s);background-color: gray ;border-color: gray}" % (self.iconPlay, self.iconPlay)) self.snapButton = QToolButton(self) self.snapButton.setPopupMode(0) menu = QMenu() #menu.addAction('acq',self.oneImage) menu.addAction('set nb of shot', self.nbShotAction) self.snapButton.setMenu(menu) self.snapButton.setMaximumWidth(self.sizebuttonMax) self.snapButton.setMinimumWidth(self.sizebuttonMax) self.snapButton.setMaximumHeight(self.sizebuttonMax) self.snapButton.setMinimumHeight(self.sizebuttonMax) self.snapButton.setStyleSheet( "QToolButton:!pressed{border-image: url(%s);background-color: transparent ;border-color: green;}" "QToolButton:pressed{image: url(%s);background-color: gray ;border-color: gray}" % (self.iconSnap, self.iconSnap)) self.stopButton = QToolButton(self) self.stopButton.setMaximumWidth(self.sizebuttonMax) self.stopButton.setMinimumWidth(self.sizebuttonMax) self.stopButton.setMaximumHeight(self.sizebuttonMax) self.stopButton.setMinimumHeight(self.sizebuttonMax) self.stopButton.setStyleSheet( "QToolButton:!pressed{border-image: url(%s);background-color: gray ;border-color: gray;}" "QToolButton:pressed{image: url(%s);background-color: gray ;border-color: gray}" % (self.iconStop, self.iconStop)) self.stopButton.setEnabled(False) hbox1.addWidget(self.runButton) hbox1.addWidget(self.snapButton) hbox1.addWidget(self.stopButton) hbox1.setSizeConstraint(QtGui.QLayout.SetFixedSize) hbox1.setContentsMargins(0, 10, 0, 10) self.widgetControl = QWidget(self) self.widgetControl.setLayout(hbox1) self.dockControl = QDockWidget(self) self.dockControl.setWidget(self.widgetControl) self.dockControl.resize(80, 80) self.trigg = QComboBox() self.trigg.setMaximumWidth(80) self.trigg.addItem('OFF') self.trigg.addItem('ON') self.trigg.setStyleSheet('font :bold 10pt;color: white') self.labelTrigger = QLabel('Trigger') self.labelTrigger.setMaximumWidth(70) self.labelTrigger.setStyleSheet('font :bold 10pt') self.itrig = self.trigg.currentIndex() hbox2 = QHBoxLayout() hbox2.setSizeConstraint(QtGui.QLayout.SetFixedSize) hbox2.setContentsMargins(5, 15, 0, 0) hbox2.addWidget(self.labelTrigger) hbox2.addWidget(self.trigg) self.widgetTrig = QWidget(self) self.widgetTrig.setLayout(hbox2) self.dockTrig = QDockWidget(self) self.dockTrig.setWidget(self.widgetTrig) self.labelExp = QLabel('Exposure (ms)') self.labelExp.setStyleSheet('font :bold 10pt') self.labelExp.setMaximumWidth(140) self.labelExp.setAlignment(Qt.AlignCenter) self.hSliderShutter = QSlider(Qt.Horizontal) self.hSliderShutter.setMaximumWidth(80) self.shutterBox = QSpinBox() self.shutterBox.setStyleSheet('font :bold 8pt') self.shutterBox.setMaximumWidth(120) hboxShutter = QHBoxLayout() hboxShutter.setContentsMargins(5, 0, 0, 0) hboxShutter.setSpacing(10) vboxShutter = QVBoxLayout() vboxShutter.setSpacing(0) vboxShutter.addWidget(self.labelExp) #,Qt.AlignLef) hboxShutter.addWidget(self.hSliderShutter) hboxShutter.addWidget(self.shutterBox) vboxShutter.addLayout(hboxShutter) vboxShutter.setSizeConstraint(QtGui.QLayout.SetFixedSize) vboxShutter.setContentsMargins(5, 5, 0, 0) self.widgetShutter = QWidget(self) self.widgetShutter.setLayout(vboxShutter) self.dockShutter = QDockWidget(self) self.dockShutter.setWidget(self.widgetShutter) self.labelGain = QLabel('Gain') self.labelGain.setStyleSheet('font :bold 10pt') self.labelGain.setMaximumWidth(120) self.labelGain.setAlignment(Qt.AlignCenter) self.hSliderGain = QSlider(Qt.Horizontal) self.hSliderGain.setMaximumWidth(80) self.gainBox = QSpinBox() self.gainBox.setMaximumWidth(60) self.gainBox.setStyleSheet('font :bold 8pt') self.gainBox.setMaximumWidth(120) hboxGain = QHBoxLayout() hboxGain.setContentsMargins(5, 0, 0, 0) hboxGain.setSpacing(10) vboxGain = QVBoxLayout() vboxGain.setSpacing(0) vboxGain.addWidget(self.labelGain) hboxGain.addWidget(self.hSliderGain) hboxGain.addWidget(self.gainBox) vboxGain.addLayout(hboxGain) vboxGain.setSizeConstraint(QtGui.QLayout.SetFixedSize) vboxGain.setContentsMargins(5, 5, 0, 0) self.widgetGain = QWidget(self) self.widgetGain.setLayout(vboxGain) self.dockGain = QDockWidget(self) self.dockGain.setWidget(self.widgetGain) # self.TrigSoft=QPushButton('Trig Soft',self) # self.TrigSoft.setMaximumWidth(100) # self.vbox1.addWidget(self.TrigSoft) # self.vbox1.addStretch(1) # self.cameraWidget.setLayout(self.vbox1) # self.cameraWidget.setMinimumSize(150,200) # self.cameraWidget.setMaximumSize(200,900) hMainLayout = QHBoxLayout() if self.light == False: from visu import SEE self.visualisation = SEE( parent=self, name=self.nbcam, **self.kwds ) ## Widget for visualisation and tools self.confVisu permet d'avoir plusieurs camera et donc plusieurs fichier ini de visualisation else: from visu import SEELIGHT self.visualisation = SEELIGHT(parent=self, name=self.nbcam, **self.kwds) self.visualisation.setWindowTitle(self.cameraType + " " + self.ccdName + ' v.' + self.version) self.dockTrig.setTitleBarWidget(QWidget()) self.dockControl.setTitleBarWidget(QWidget()) # to avoid tittle self.dockShutter.setTitleBarWidget(QWidget()) self.dockGain.setTitleBarWidget(QWidget()) if self.separate == True: self.dockTrig.setTitleBarWidget(QWidget()) if self.aff == 'left': self.visualisation.addDockWidget(Qt.LeftDockWidgetArea, self.dockControl) self.visualisation.addDockWidget(Qt.LeftDockWidgetArea, self.dockTrig) self.visualisation.addDockWidget(Qt.LeftDockWidgetArea, self.dockShutter) self.visualisation.addDockWidget(Qt.LeftDockWidgetArea, self.dockGain) else: self.visualisation.addDockWidget(Qt.RightDockWidgetArea, self.dockControl) self.visualisation.addDockWidget(Qt.RightDockWidgetArea, self.dockTrig) self.visualisation.addDockWidget(Qt.RightDockWidgetArea, self.dockShutter) self.visualisation.addDockWidget(Qt.RightDockWidgetArea, self.dockGain) else: #self.dockControl.setFeatures(QDockWidget.DockWidgetMovable) self.visualisation.addDockWidget(Qt.TopDockWidgetArea, self.dockControl) self.visualisation.addDockWidget(Qt.TopDockWidgetArea, self.dockTrig) self.visualisation.addDockWidget(Qt.TopDockWidgetArea, self.dockShutter) self.visualisation.addDockWidget(Qt.TopDockWidgetArea, self.dockGain) hMainLayout.addWidget(self.visualisation) self.setLayout(hMainLayout) self.setContentsMargins(0, 0, 0, 0)
def ui(self): layout = QVBoxLayout() layout.addWidget(self.gen_row('Order Time:', Label(self.order_time))) layout.addWidget(self.gen_row('Stauts:', Label(self.status))) # Bottom btm = QHBoxLayout() btm.setAlignment(Qt.AlignLeft) btm.setContentsMargins(0, 0, 0, 0) btm.setSpacing(15) if self.data_type == 'batch': ok = QPushButton('Download') ok.setObjectName('pinfo_publish_btn') btm.addWidget(ok) ok.clicked.connect(self.download) confirm = QPushButton('Confirm') confirm.setObjectName('pinfo_cancel_btn') confirm.clicked.connect(self.confirm) btm.addWidget(confirm) btm.addStretch(1) layout.addLayout(btm) storage = QLabel('Open Storage Path…') storage.setStyleSheet(""" margin-top: 12px; font-family:SFUIDisplay-Medium; font-size:14px; color:#0073df; """) Binder.click(storage, self.select_storage_path) layout.addWidget(storage) else: ok = QPushButton('Get Streaming ID') ok.setObjectName('pinfo_stream_btn') def openStreamID(_): def cb(path): if path: stream_id = json.loads(path) self.open1.emit(stream_id[0]) deferToThread(lambda: fs.buyer_file_by_order_id(self.order_id). path).addCallback(cb) ok.clicked.connect(openStreamID) btm.addWidget(ok) preview = QPushButton('Preview') preview.setObjectName('pinfo_cancel_btn') def openPreview(_): dlg = PreviewDialog(ws_url=self.ws_url) dlg.show() preview.clicked.connect(openPreview) btm.addWidget(preview) confirm = QPushButton('Confirm') confirm.setObjectName('pinfo_cancel_btn') btm.addWidget(confirm) btm.addStretch(1) layout.addLayout(btm) self.confirmBtn = confirm if self.has_comfirmed: self.confirmBtn.hide() self.setLayout(layout) self.setStyleSheet(""" QWidget#order_item { margin-top: 20px; margin-bottom: 20px; } QLabel#order_item_name { font-family:SFUIDisplay-Regular; font-size:14px; color:#666666; text-align:left; } Label#order_item_value { font-family:SFUIDisplay-Regular; font-size:14px; color:#000000; text-align:left; } QPushButton#pinfo_cancel_btn{ padding-left: 10px; padding-right: 10px; border: 1px solid #3173d8; border-radius: 3px; color: #3173d8; min-height: 30px; max-height: 30px; background: #ffffff; min-width: 80px; max-width: 80px; } QPushButton#pinfo_cancel_btn:hover{ border: 1px solid #3984f7; color: #3984f6; } QPushButton#pinfo_cancel_btn:pressed{ border: 1px solid #2e6dcd; color: #2e6dcd; background: #e5ecf4; } QPushbutton#pinfo_cancel_btn:disabled{ border: 1px solid #8cb8ea; color: #8cb8ea; } QPushButton#pinfo_publish_btn, QPushButton#pinfo_stream_btn{ padding-left: 10px; padding-right: 10px; border: 1px solid #3173d8; border-radius: 3px; color: #ffffff; min-height: 30px; max-height: 30px; min-width: 80px; max-width: 80px; background: #3173d8; } QPushButton#pinfo_publish_btn:hover, QPushButton#pinfo_stream_btn:hover{ background: #3984f7; border: 1px solid #3984f7; } QPushButton#pinfo_publish_btn:pressed, QPushButton#pinfo_stream_btn:pressed{ border: 1px solid #2e6dcd; background: #2e6dcd; } QPushbutton#pinfo_publish_btn:disabled, QPushButton#pinfo_stream_btn:disabled{ border: 1px solid #8cb8ea; background: #98b9eb; } QPushButton#pinfo_stream_btn { min-width: 120px; max-width: 120px; } """)
def __evt_yeahdoc_contextMenu(self, p): """ context menu """ item = self.yeahdoclisttree.currentItem() if item == None or item.isDisabled(): pass else: menu = QMenu() # menu top action = QWidgetAction(self) title = item.text(0) if len(title) < 25: for i in range(len(title), 25): title = title + " " action.setDefaultWidget( QLabel(" <img src='%s'/> %s" % (getPath("iconDir", "yeahdoc/item.png"), title))) menu.addAction(action) menu.addSeparator() menu.addAction(self.__actions["__yeahdoc_open__"]) menu.addAction(self.__actions["__yeahdoc_edit__"]) # change class change_class_menu = QMenu() entry = YeahdocDatasSupply().bb_read1_simple(item.getMark()) current_categoryid = entry['categoryid'] for class_item in YeahdocDatasSupply().bc_list(): action = QAction(class_item["title"], self, \ triggered=lambda re, item=item, categoryid=str(class_item["id"]): \ self.__evt_change_category(categoryid, item)) action.setIcon(QIcon(getPath("iconDir", "yeahdoc/flag/%s" % str(class_item["img"])))) action.setIconVisibleInMenu(True) # mark current class id menu checked if class_item['id'] == current_categoryid: action.setCheckable(True) action.setChecked(True) action.setDisabled(True) change_class_menu.addAction(action) action = QAction(QIcon(getPath("iconDir", "yeahdoc/change.png")), QApplication.translate("YeahdocList", "Change Category"), self) action.setIconVisibleInMenu(True) action.setMenu(change_class_menu) menu.addAction(action) menu.addAction(self.__actions["__yeahdoc_star__"]) menu.addAction(self.__actions["__yeahdoc_rename__"]) menu.addAction(self.__actions["__yeahdoc_delete__"]) menu.addSeparator() setmode = True if entry['lock'] == 0 else False action = QWidgetAction(self) widget = QWidget() layout = QHBoxLayout() layout.setSpacing(0) layout.setMargin(0) widget.setLayout(layout) widgetMore = QWidget() widgetMore.setVisible(False) layoutMore = QHBoxLayout() layoutMore.setSpacing(0) layoutMore.setMargin(0) widgetMore.setLayout(layoutMore) layout.addWidget(QLabel("<img src='%s'/>" % getPath("iconDir", "yeahdoc/password.png"))) passwordMore = QPushButton( QApplication.translate("YeahdocEditor", "Encrypt") if setmode else QApplication.translate( "YeahdocEditor", "Decrypt")) passwordMore.setFlat(True) layout.addWidget(passwordMore) passwordInput = QLineEdit() passwordInput.setEchoMode(QLineEdit.Password) passwordInput.setMaximumWidth(70) layoutMore.addWidget(passwordInput) if setmode: passwordInputAgain = QLineEdit() passwordInputAgain.setEchoMode(QLineEdit.Password) passwordInputAgain.setMaximumWidth(70) layoutMore.addWidget(QLabel(QApplication.translate("YeahdocEditor", "Re"))) layoutMore.addWidget(passwordInputAgain) passwordSubmit = QPushButton("OK") passwordSubmit.setFlat(True) layoutMore.addWidget(passwordSubmit) layout.addWidget(widgetMore) layout.addItem(QSpacerItem(0, 20, QSizePolicy.Expanding, QSizePolicy.Expanding)) action.setDefaultWidget(widget) QObject.connect(passwordSubmit, SIGNAL("clicked ()"), lambda: self.__evt_password(setmode, passwordInput.text(), passwordInputAgain.text() if setmode else "")) QObject.connect(passwordMore, SIGNAL("clicked ()"), lambda: widgetMore.setVisible(not widgetMore.isVisible())) menu.addAction(action) # show it. menu.exec_(self.mapToGlobal(self.yeahdoclisttree.mapTo(self, p)))