def __init__(self): super().__init__() self.setMinimumWidth(640) self.setMinimumHeight(480) # Set up QTabWidget as a central widget self.tab_widget = QTabWidget(self) self.tab_widget.setTabsClosable(True) self.tab_widget.tabCloseRequested.connect(self.on_tab_close_clicked) self.setCentralWidget(self.tab_widget) # Create "Connection" menu menu_bar = self.menuBar() connection_menu = menu_bar.addMenu('Connection') # Add "Create" connection button create_connection_action = QAction('Create', self) create_connection_action.triggered.connect(self.add_new_tab) connection_menu.addAction(create_connection_action) # Add "Close" connection button close_connection_action = QAction('Close', self) close_connection_action.triggered.connect(self.close_current_tab) connection_menu.addAction(close_connection_action) # self.tool_bar = self.addToolBar('test bar') # self.connect_action = self.tool_bar.addAction('connect') self.add_new_tab()
def __init__(self, model): super().__init__() self._model = model layout = QGridLayout() splitter = QSplitter() self._bot_table = _BotTable() self._responses_tab = _ResponsesTab() self._execute_tab = _ExecuteTab(self._responses_tab, model) self._tab_widget = QTabWidget() self._tab_widget.addTab(self._execute_tab, "Execute") self._tab_widget.addTab(self._responses_tab, "Responses") splitter.setOrientation(Qt.Vertical) splitter.addWidget(self._bot_table) splitter.addWidget(self._tab_widget) splitter.setSizes([50, 100]) layout.addWidget(splitter) self.setLayout(layout) self._register_listeners()
def __init__(self, *args, **kw): ConfigWidgetBase.__init__(self, *args, **kw) self.l = l = QVBoxLayout(self) l.setContentsMargins(0, 0, 0, 0) self.tabs_widget = t = QTabWidget(self) l.addWidget(t) self.main_tab = m = MainTab(self) t.addTab(m, _('&Main')) m.start_server.connect(self.start_server) m.stop_server.connect(self.stop_server) m.test_server.connect(self.test_server) m.show_logs.connect(self.view_server_logs) self.opt_autolaunch_server = m.opt_autolaunch_server self.users_tab = ua = Users(self) t.addTab(ua, _('&User accounts')) self.advanced_tab = a = AdvancedTab(self) sa = QScrollArea(self) sa.setWidget(a), sa.setWidgetResizable(True) t.addTab(sa, _('&Advanced')) self.custom_list_tab = clt = CustomList(self) sa = QScrollArea(self) sa.setWidget(clt), sa.setWidgetResizable(True) t.addTab(sa, _('Book &list template')) self.search_net_tab = SearchTheInternet(self) t.addTab(self.search_net_tab, _('&Search the internet')) for tab in self.tabs: if hasattr(tab, 'changed_signal'): tab.changed_signal.connect(self.changed_signal.emit)
def __init__(self, parent): super(QWidget, self).__init__(parent) self.layout = QVBoxLayout(self) self.console = Console("Superconsole") self.tabs = QTabWidget() self.ddosTab = DosTab(self.console) self.portscannerTab = PortScannerTab(self.console) # self.hashcrackerTab = HashcrackerTab(self.console) self.hashGeneratorTab = HashGeneratorTab(self.console) self.rtGenTab = RainbowGeneratorTab(self.console) self.stressTab = CPUStressTab(self.console) # self.tabs.resize(800, 600) self.tabs.addTab(self.ddosTab, "Denial of Service") self.tabs.addTab(self.portscannerTab, "Portscanner") self.tabs.addTab(self.hashGeneratorTab, "HashGenrator") # self.tabs.addTab(self.hashcrackerTab, "Hashcracker (Not Working)") self.tabs.addTab(self.rtGenTab, "Rainbowtable Generator") self.tabs.addTab(self.stressTab, "CPU Stress") self.layout.addWidget(self.tabs) self.layout.addStretch(1) self.layout.addWidget(self.console)
def build_ui(self): self.setWindowTitle("Filesystem Analyzer") settings_action = QAction(QIcon("res/settings.svg"), "Settings", self) settings_action.setShortcut("Ctrl+S") settings_action.triggered.connect(self.settings_action_handler) set_path_action = QAction(QIcon("res/directory-submission-symbol.svg"), "Set path", self) set_path_action.setShortcut("Ctrl+N") set_path_action.triggered.connect(self.set_path_action_handler) refresh_action = QAction(QIcon("res/reload.svg"), "Refresh", self) refresh_action.setShortcut("Ctrl+R") refresh_action.triggered.connect(self.refresh_action_handler) menu_bar = self.menuBar() action_menu = menu_bar.addMenu("&Action") action_menu.addAction(settings_action) action_menu.addAction(set_path_action) action_menu.addAction(refresh_action) toolbar = self.addToolBar("Exit") toolbar.addAction(settings_action) toolbar.addAction(set_path_action) toolbar.addAction(refresh_action) self.progressbar = QProgressBar(self) self.progressbar.hide() self.progressbar.setRange(0, 100) cancel_button = QPushButton(QIcon("res/cancel-button.svg"), "Cancel", self) cancel_button.clicked.connect(self.set_path_cancel) self.statusBar().addPermanentWidget(self.progressbar) self.statusBar().addPermanentWidget(cancel_button) self.tab_widget = QTabWidget(self) self.file_tree_widget = FSFileTreeWidget() self.file_tree_model = FSFileTreeModel() self.file_tree_widget.setModel(self.file_tree_model) self.movie_table_widget = FSMovieTableWidget() self.movie_table_widget.setShowGrid(False) self.movie_table_widget.setAlternatingRowColors(True) self.movie_table_widget.verticalHeader().setVisible(False) self.movie_table_widget.setSelectionBehavior(QTableView.SelectRows) self.movie_table_model = FSMovieTableModel() self.movie_table_widget.setModel(self.movie_table_model) self.tab_widget.addTab(self.file_tree_widget, "General") self.tab_widget.addTab(self.movie_table_widget, "Movies") self.setCentralWidget(self.tab_widget) last_tab_index = self.app.load_setting("last_tab_index") if last_tab_index: self.tab_widget.setCurrentIndex(int(last_tab_index)) self.tab_widget.currentChanged.connect(self.tab_widget_changed) self.show()
def __init__(self, parent=None): QStackedWidget.__init__(self, parent) self.welcome = w = QLabel( '<p>' + _('Double click a file in the left panel to start editing' ' it.')) self.addWidget(w) w.setWordWrap(True) w.setAlignment(Qt.AlignTop | Qt.AlignHCenter) self.container = c = QWidget(self) self.addWidget(c) l = c.l = QVBoxLayout(c) c.setLayout(l) l.setContentsMargins(0, 0, 0, 0) self.editor_tabs = t = QTabWidget(c) l.addWidget(t) t.setDocumentMode(True) t.setTabsClosable(True) t.setMovable(True) pal = self.palette() if pal.color(pal.WindowText).lightness() > 128: i = QImage(I('modified.png')) i.invertPixels() self.modified_icon = QIcon(QPixmap.fromImage(i)) else: self.modified_icon = QIcon(I('modified.png')) self.editor_tabs.currentChanged.connect(self.current_editor_changed) self.editor_tabs.tabCloseRequested.connect(self._close_requested) self.search_panel = SearchPanel(self) l.addWidget(self.search_panel) self.restore_state() self.editor_tabs.tabBar().installEventFilter(self)
def setupUi(self, *args): # {{{ self.resize(990, 670) self.download_shortcut = QShortcut(self) self.download_shortcut.setKey(QKeySequence('Ctrl+D', QKeySequence.PortableText)) p = self.parent() if hasattr(p, 'keyboard'): kname = u'Interface Action: Edit Metadata (Edit Metadata) : menu action : download' sc = p.keyboard.keys_map.get(kname, None) if sc: self.download_shortcut.setKey(sc[0]) self.swap_title_author_shortcut = s = QShortcut(self) s.setKey(QKeySequence('Alt+Down', QKeySequence.PortableText)) self.button_box = bb = QDialogButtonBox(self) self.button_box.accepted.connect(self.accept) self.button_box.rejected.connect(self.reject) self.next_button = QPushButton(QIcon(I('forward.png')), _('Next'), self) self.next_button.setShortcut(QKeySequence('Alt+Right')) self.next_button.clicked.connect(self.next_clicked) self.prev_button = QPushButton(QIcon(I('back.png')), _('Previous'), self) self.prev_button.setShortcut(QKeySequence('Alt+Left')) self.button_box.addButton(self.prev_button, bb.ActionRole) self.button_box.addButton(self.next_button, bb.ActionRole) self.prev_button.clicked.connect(self.prev_clicked) bb.setStandardButtons(bb.Ok|bb.Cancel) bb.button(bb.Ok).setDefault(True) self.scroll_area = QScrollArea(self) self.scroll_area.setFrameShape(QScrollArea.NoFrame) self.scroll_area.setWidgetResizable(True) self.central_widget = QTabWidget(self) self.scroll_area.setWidget(self.central_widget) self.l = QVBoxLayout(self) self.setLayout(self.l) self.l.addWidget(self.scroll_area) ll = self.button_box_layout = QHBoxLayout() self.l.addLayout(ll) ll.addSpacing(10) ll.addWidget(self.button_box) self.setWindowIcon(QIcon(I('edit_input.png'))) self.setWindowTitle(BASE_TITLE) self.create_basic_metadata_widgets() if len(self.db.custom_column_label_map): self.create_custom_metadata_widgets() self.do_layout() geom = gprefs.get('metasingle_window_geometry3', None) if geom is not None: self.restoreGeometry(bytes(geom))
def __init__(self, parent=None): super(PanelQWidget, self).__init__(parent) self.setAcceptDrops(True) # Fields self.tab_widget = QTabWidget() self.layout = QVBoxLayout() self.dashboard_widget = DashboardQWidget() self.synthesis_widget = SynthesisQWidget() self.problems_widget = ProblemsQWidget() self.spy_widget = SpyQWidget() self.hostnames_list = []
def __init__(self, plugin_action): QWidget.__init__(self) self.plugin_action = plugin_action self.l = QVBoxLayout() self.setLayout(self.l) tab_widget = QTabWidget(self) self.l.addWidget(tab_widget) self.basic_tab = BasicTab(self, plugin_action) tab_widget.addTab(self.basic_tab, _('Basic'))
def init_results_widget(self): results_widget = QTabWidget(self) results_widget.setTabsClosable(False) table_view = QTableView(self) table_view.setModel(self.model) table_view.sizePolicy().setVerticalPolicy( QSizePolicy.MinimumExpanding) results_widget.addTab(table_view, 'Data') log = QTextEdit(self) log.setReadOnly(True) self.model.executed.connect(log.append) results_widget.addTab(log, 'Events') return results_widget
def initUI(self): self.tabs = QTabWidget(self) self.tabs.resize(self.appSize[0], self.appSize[1]) self.colorPanel = ColorPanel(self.dbService, self.lang) self.brushPanel = BrushPanel(self.dbService, self.lang) self.tabs.addTab(self.colorPanel, Strings.str_LABEL_COLORS.get(self.lang)) self.tabs.addTab(self.brushPanel, Strings.str_LABEL_BRUSHES.get(self.lang)) self.setWindowTitle("Tabletop Manager") self.move(100, 100) #self.resize(self.appSize[0], self.appSize[1]) self.setFixedSize(self.appSize[0], self.appSize[1]) self.show()
def initResultPage(self): f = QFrame() l = QHBoxLayout() f.setLayout(l) self.convertedTabs = QTabWidget() l.addWidget(self.convertedTabs) ''' This just adds a blank page with an empty tab widget. Pages are added on the fly when the files are converted as this could involve one or many pages depending on combine_route flag and number of routes. self.convertedTabs is the empty tab widget ''' return f
def build_results_widget(self): # Initialize QTabWidget to display table view and log # in differnt unclosable tabs results_widget = QTabWidget(self) results_widget.setTabsClosable(False) # Add table view table_view = QTableView(self) table_view.setModel(self.model) table_view.sizePolicy().setVerticalPolicy(QSizePolicy.MinimumExpanding) results_widget.addTab(table_view, UI.QUERY_RESULTS_DATA_TAB_TEXT) # Att log view log = QTextEdit(self) log.setReadOnly(True) self.model.executed.connect(log.append) results_widget.addTab(log, UI.QUERY_RESULTS_EVENTS_TAB_TEXT) return results_widget
def do_config(self): # Save values that need to be synced between the dialog and the # search widget. self.config['open_external'] = self.open_external.isChecked() # Create the config dialog. It's going to put two config widgets # into a QTabWidget for displaying all of the settings. d = QDialog(self) button_box = QDialogButtonBox(QDialogButtonBox.Close) v = QVBoxLayout(d) button_box.accepted.connect(d.accept) button_box.rejected.connect(d.reject) d.setWindowTitle(_('Customize Get books search')) tab_widget = QTabWidget(d) v.addWidget(tab_widget) v.addWidget(button_box) chooser_config_widget = StoreChooserWidget() search_config_widget = StoreConfigWidget(self.config) tab_widget.addTab(chooser_config_widget, _('Choose s&tores')) tab_widget.addTab(search_config_widget, _('Configure s&earch')) # Restore dialog state. geometry = self.config.get('config_dialog_geometry', None) if geometry: QApplication.instance().safe_restore_geometry(d, geometry) else: d.resize(800, 600) tab_index = self.config.get('config_dialog_tab_index', 0) tab_index = min(tab_index, tab_widget.count() - 1) tab_widget.setCurrentIndex(tab_index) d.exec_() # Save dialog state. self.config['config_dialog_geometry'] = bytearray(d.saveGeometry()) self.config['config_dialog_tab_index'] = tab_widget.currentIndex() search_config_widget.save_settings() self.config_changed() self.gui.load_store_plugins() self.setup_store_checks()
def init_results_widget(self): # Initialize QTabWidget to display table view and log # in differnt unclosable tabs results_widget = QTabWidget(self) results_widget.setTabsClosable(False) # Add table view table_view = QTableView(self) table_view.setModel(self.model) table_view.sizePolicy().setVerticalPolicy( QSizePolicy.MinimumExpanding) results_widget.addTab(table_view, 'Data') # Att log view log = QTextEdit(self) log.setReadOnly(True) self.model.executed.connect(log.append) results_widget.addTab(log, 'Events') return results_widget
def _set_tab(self): self.tab_widget = QTabWidget() # self.tab_widget.currentChanged.connect(self.switch_tab) # tab_widget.setMaximumHeight(self.window.geometry().height() // 2) self.main_layout.addWidget(self.tab_widget) toolbox1 = QToolBox() toolbox2 = QToolBox() toolbox3 = QToolBox() toolbox4 = QToolBox() toolbox5 = QToolBox() groupbox1 = QGroupBox() groupbox2 = QGroupBox() groupbox3 = QGroupBox() groupbox4 = QGroupBox() groupbox5 = QGroupBox() toolbox1.addItem(groupbox1, "") toolbox2.addItem(groupbox2, "") toolbox3.addItem(groupbox3, "") toolbox4.addItem(groupbox4, "") toolbox5.addItem(groupbox5, "") self.tab_widget.addTab(toolbox1, "uArm") self.tab_widget.addTab(toolbox2, "xArm") self.tab_widget.addTab(toolbox3, "OpenMV") self.tab_widget.addTab(toolbox4, "Gcode") self.tab_widget.addTab(toolbox5, "WebView") uarm_layout = QVBoxLayout(groupbox1) xarm_layout = QVBoxLayout(groupbox2) openmv_layout = QHBoxLayout(groupbox3) gcode_layout = QVBoxLayout(groupbox4) webview_layout = QVBoxLayout(groupbox5) self.uarm_ui = UArmUI(self, uarm_layout) self.xarm_ui = XArmUI(self, xarm_layout) self.openmv_ui = OpenMV_UI(self, openmv_layout) self.gcode_ui = GcodeUI(self, gcode_layout) self.webview_ui = WebViewUI(self, webview_layout) self.tab_widget.setCurrentIndex(0)
def __init__(self, dev, ignored_folders=None, parent=None): QDialog.__init__(self, parent) self.l = l = QVBoxLayout() self.setLayout(l) self.la = la = QLabel('<p>' + _('<b>Scanned folders:</b>') + ' ' + _('You can select which folders calibre will ' 'scan when searching this device for books.')) la.setWordWrap(True) l.addWidget(la) self.tabs = QTabWidget(self) l.addWidget(self.tabs) self.widgets = [] for storage in dev.filesystem_cache.entries: self.dev = dev w = Storage(storage, item_func=self.create_item) del self.dev self.tabs.addTab(w, storage.name) self.widgets.append(w) w.itemChanged.connect(self.item_changed) self.la2 = la = QLabel( _('If you a select a previously unselected folder, any sub-folders' ' will not be visible until you restart calibre.')) l.addWidget(la) la.setWordWrap(True) self.bb = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel) self.bb.accepted.connect(self.accept) self.bb.rejected.connect(self.reject) self.sab = self.bb.addButton(_('Select &all'), QDialogButtonBox.ButtonRole.ActionRole) self.sab.clicked.connect(self.select_all) self.snb = self.bb.addButton(_('Select &none'), QDialogButtonBox.ButtonRole.ActionRole) self.snb.clicked.connect(self.select_none) l.addWidget(self.bb) self.setWindowTitle(_('Choose folders to scan')) self.setWindowIcon(QIcon(I('devices/tablet.png'))) self.resize(600, 500)
def initGui(self): self.setGeometry(300, 300, 800, 600) self.setWindowTitle('Road warrior Upload File Converter') self.center() fMain = QFrame() mainLayout = QGridLayout() fMain.setLayout(mainLayout) self.setCentralWidget(fMain) tabWidget = QTabWidget() mainLayout.addWidget(tabWidget, 0, 0) self.closeBtn = QPushButton('Close Application') self.closeBtn.clicked.connect(self.handleCloseClicked) mainLayout.addWidget(self.closeBtn, 1, 0) tabWidget.addTab(self.initConvertPage(), 'Converter') tabWidget.addTab(self.initResultPage(), 'Converter') tabWidget.addTab(self.initConfigPage(), 'Configuration')
def __init__(self): super().__init__() self.setMinimumWidth(640) self.setMinimumHeight(480) self.tab_widget = QTabWidget(self) self.tab_widget.setTabsClosable(True) self.tab_widget.tabCloseRequested.connect(self.on_tab_close_clicked) self.setCentralWidget(self.tab_widget) menu_bar = self.menuBar() connection_menu = menu_bar.addMenu('Connection') create_connection_action = QAction('Create', self) create_connection_action.triggered.connect(self.add_new_tab) connection_menu.addAction(create_connection_action) close_connection_action = QAction('Close', self) close_connection_action.triggered.connect(self.close_current_tab) connection_menu.addAction(close_connection_action) self.add_new_tab()
def __init__(self, title=None, f=None, desc=None): # FIXME: f no lo uso , es qt.windowsflg super(Dialog, self).__init__() if title: self.setWindowTitle(str(title)) self.setWindowModality(QtCore.Qt.ApplicationModal) self._layout = QtWidgets.QVBoxLayout() self.setLayout(self._layout) self.buttonBox = QtWidgets.QDialogButtonBox() self.okButton = QtWidgets.QPushButton("&Aceptar") self.cancelButton = QtWidgets.QPushButton("&Cancelar") self.buttonBox.addButton(self.okButton, QtWidgets.QDialogButtonBox.AcceptRole) self.buttonBox.addButton(self.cancelButton, QtWidgets.QDialogButtonBox.RejectRole) self.okButton.clicked.connect(self.accept) self.cancelButton.clicked.connect(self.reject) self._tab = QTabWidget() self._layout.addWidget(self._tab) self.oKButtonText = None self.cancelButtonText = None
def _set_tab(self): tab_widget = QTabWidget() tab_widget.setMaximumHeight(self.main_ui.window.geometry().height() // 2) self.layout.addWidget(tab_widget) toolBox1 = QToolBox() toolBox2 = QToolBox() groupBox1 = QGroupBox() groupBox2 = QGroupBox() toolBox1.addItem(groupBox1, "") toolBox2.addItem(groupBox2, "") tab_widget.addTab(toolBox1, i18n[self.lang]['Angle']) tab_widget.addTab(toolBox2, i18n[self.lang]['Coordinate']) joint_layout = QVBoxLayout(groupBox1) cartesian_layout = QVBoxLayout(groupBox2) self.cartesian_ui = CoordinateUI(self, cartesian_layout) self.axis_ui = AngleUI(self, joint_layout)
def __init__(self, parent): super(Preferences, self).__init__(parent) self.layout = QVBoxLayout(self) self.tab = QTabWidget(self) self.themeChooser = ThemeChooser(self.tab) self.tab.addTab(self.themeChooser, 'Theme') self.saveOption = SaveOption(self.tab, self.parent().saveThreading) self.tab.addTab(self.saveOption, 'Save') self.layout.addWidget(self.tab) self.buttonBox = QDialogButtonBox(self) self.buttonBox.addButton('Ok', QDialogButtonBox.AcceptRole) self.buttonBox.addButton('Cancel', QDialogButtonBox.RejectRole) self.buttonBox.addButton( 'Apply', QDialogButtonBox.ApplyRole).clicked.connect(self.commit) self.buttonBox.accepted.connect(self.acceptButtonTriggered) self.buttonBox.rejected.connect(self.rejectButtonTriggered) self.layout.addWidget(self.buttonBox) self.setMinimumWidth(self.tab.widget(0).width()) self.setMinimumHeight(self.tab.widget(0).height())
def __init__(self, parent, imgDir): super(QWidget, self).__init__(parent) self.parent = parent self.imgDir = imgDir self.runInThread = ThreadFuns.runInThread ###-- Create clients and statuses self.hwdevice = None self.hwStatus = 0 self.hwStatusMess = "Not Connected" self.rpcClient = None self.rpcConnected = False self.rpcStatusMess = "Not Connected" ###-- Load icons & images self.loadIcons() ###-- Create main layout self.layout = QVBoxLayout() self.header = GuiHeader(self) self.initConsole() self.layout.addWidget(self.header) ###-- Create RPC Whatchdog self.rpc_watchdogThread = QThread() self.myRpcWd = RpcWatchdog(self) self.myRpcWd.moveToThread(self.rpc_watchdogThread) self.rpc_watchdogThread.started.connect(self.myRpcWd.run) self.rpc_watchdogThread.start() ###-- Create Queues and redirect stdout and stderr (eventually) self.queue = Queue() self.queue2 = Queue() sys.stdout = WriteStream(self.queue) sys.stderr = WriteStream(self.queue2) ###-- Init last logs logFile = open(log_File, 'w+') timestamp = strftime('%Y-%m-%d %H:%M:%S', gmtime(now())) log_line = '<b style="color: blue">{}</b><br>'.format( 'STARTING PET4L at ' + timestamp) logFile.write(log_line) logFile.close() ###-- Create the thread to update console log for stdout self.consoleLogThread = QThread() self.myWSReceiver = WriteStreamReceiver(self.queue) self.myWSReceiver.mysignal.connect(self.append_to_console) self.myWSReceiver.moveToThread(self.consoleLogThread) self.consoleLogThread.started.connect(self.myWSReceiver.run) self.consoleLogThread.start() printDbg("Console Log thread started") ###-- Create the thread to update console log for stderr self.consoleLogThread2 = QThread() self.myWSReceiver2 = WriteStreamReceiver(self.queue2) self.myWSReceiver2.mysignal.connect(self.append_to_console) self.myWSReceiver2.moveToThread(self.consoleLogThread2) self.consoleLogThread2.started.connect(self.myWSReceiver2.run) self.consoleLogThread2.start() printDbg("Console Log thread 2 started") ###-- Initialize tabs self.tabs = QTabWidget() self.t_rewards = TabRewards(self) ###-- Add tabs self.tabs.addTab(self.tabRewards, "Spend from Ledger") ###-- Draw Tabs self.splitter = QSplitter(Qt.Vertical) ###-- Add tabs and console to Layout self.splitter.addWidget(self.tabs) self.splitter.addWidget(self.console) self.splitter.setStretchFactor(0, 0) self.splitter.setStretchFactor(1, 1) self.splitter.setSizes([2, 1]) self.layout.addWidget(self.splitter) ###-- Set Layout self.setLayout(self.layout) ###-- Let's go self.mnode_to_change = None printOK("Hello! Welcome to " + parent.title)
def __init__(self, parent=None): super(MainWin, self).__init__(parent) self.setWindowTitle("Eilat Browser") # gc.set_debug(gc.DEBUG_LEAK) self.last_closed = None self.tab_widget = QTabWidget(self) self.tab_widget.setTabBar(MidClickTabBar(self)) self.tab_widget.tabBar().setMovable(True) self.tab_widget.setTabsClosable(True) # the right side of the tab already has the space for # a non-shown close button self.tab_widget.setStyleSheet( 'QTabBar::tab {padding-top: 0px; padding-bottom: 0px; ' 'padding-left: 0.3em;} ' 'QTabBar::tab:selected {color: #00f;}') # tabCloseRequested carries int (index of a tab) self.tab_widget.tabCloseRequested.connect(self.del_tab) self.setCentralWidget(self.tab_widget) self.tooltip = NotifyLabel(parent=self) def restore_last_closed(): """ One-use callback for QShortcut. Opens a fresh new tab with the url address of the last tab closed """ if self.last_closed is not None: url = self.last_closed self.add_tab(url) self.last_closed = None def dump_gc(): """ prints sizes for large memory collectable objects """ objs = gc.get_objects() pairs = [(str(k)[:80], type(k).__name__, sys.getsizeof(k)) for k in objs if sys.getsizeof(k) > 1024 * 4 * 5] for pair in pairs: print(pair) def reload_disk_init(): """ transfer options.yaml and the css directory to global maps """ load_options() load_css() notify("reloaded disk config") set_shortcuts([ ("F9", self, dump_gc), # reload configuration ("Ctrl+Shift+R", self, reload_disk_init), # new tabs ("Ctrl+T", self, self.add_tab), ("Ctrl+Shift+T", self, partial(self.add_tab, scripting=True)), ("Y", self, self.new_tab_from_clipboard), # movement ("M", self, self.inc_tab), ("N", self, partial(self.inc_tab, -1)), ("Ctrl+PgUp", self, partial(self.inc_tab, -1)), ("Ctrl+PgDown", self, self.inc_tab), # destroy/undestroy ("U", self, restore_last_closed), ("Ctrl+W", self, self.del_tab), ("Ctrl+Q", self, self.finalize) ])
def __init__(self, mi=None, prefs=None, parent=None, for_global_prefs=False): QWidget.__init__(self, parent) self.ignore_changed = False self.for_global_prefs = for_global_prefs self.l = l = QHBoxLayout(self) l.setContentsMargins(0, 0, 0, 0) self.setLayout(l) self.settings_tabs = st = QTabWidget(self) l.addWidget(st) self.preview_label = la = Preview(self) l.addWidget(la) if prefs is None: prefs = cprefs self.original_prefs = prefs self.mi = mi or self.default_mi() self.colors_page = cp = QWidget(st) st.addTab(cp, _('&Colors')) cp.l = l = QGridLayout() cp.setLayout(l) if for_global_prefs: msg = _( 'When generating covers, a color scheme for the cover is chosen at random from the' ' color schemes below. You can prevent an individual scheme from being selected by' ' unchecking it. The preview on the right shows the currently selected color scheme.' ) else: msg = _( 'Choose a color scheme to be used for this generated cover.' ) + '<p>' + _( 'In normal cover generation, the color scheme is chosen at random from the list of color schemes below. You' ' can prevent an individual color scheme from being chosen by unchecking it here.' ) cp.la = la = QLabel('<p>' + msg) la.setWordWrap(True) l.addWidget(la, 0, 0, 1, -1) self.colors_list = cl = QListWidget(cp) l.addWidget(cl, 1, 0, 1, -1) self.colors_map = OrderedDict() self.ncs = ncs = QPushButton(QIcon(I('plus.png')), _('&New color scheme'), cp) ncs.clicked.connect(self.create_color_scheme) l.addWidget(ncs) self.ecs = ecs = QPushButton(QIcon(I('format-fill-color.png')), _('&Edit color scheme'), cp) ecs.clicked.connect(self.edit_color_scheme) l.addWidget(ecs, l.rowCount() - 1, 1) self.rcs = rcs = QPushButton(QIcon(I('minus.png')), _('&Remove color scheme'), cp) rcs.clicked.connect(self.remove_color_scheme) l.addWidget(rcs, l.rowCount() - 1, 2) self.styles_page = sp = QWidget(st) st.addTab(sp, _('&Styles')) sp.l = l = QVBoxLayout() sp.setLayout(l) if for_global_prefs: msg = _( 'When generating covers, a style for the cover is chosen at random from the' ' styles below. You can prevent an individual style from being selected by' ' unchecking it. The preview on the right shows the currently selected style.' ) else: msg = _( 'Choose a style to be used for this generated cover.' ) + '<p>' + _( 'In normal cover generation, the style is chosen at random from the list of styles below. You' ' can prevent an individual style from being chosen by unchecking it here.' ) sp.la = la = QLabel('<p>' + msg) la.setWordWrap(True) l.addWidget(la) self.styles_list = sl = QListWidget(sp) l.addWidget(sl) self.style_map = OrderedDict() self.font_page = fp = QWidget(st) st.addTab(fp, _('&Fonts and sizes')) fp.l = l = QFormLayout() fp.setLayout(l) fp.f = [] def add_hline(): f = QFrame() fp.f.append(f) f.setFrameShape(QFrame.Shape.HLine) l.addRow(f) for x, label, size_label in ( ('title', _('&Title font family:'), _('&Title font size:')), ('subtitle', _('&Subtitle font family'), _('&Subtitle font size:')), ('footer', _('&Footer font family'), _('&Footer font size')), ): attr = '%s_font_family' % x ff = FontFamilyChooser(fp) setattr(self, attr, ff) l.addRow(label, ff) ff.family_changed.connect(self.emit_changed) attr = '%s_font_size' % x fs = QSpinBox(fp) setattr(self, attr, fs) fs.setMinimum(8), fs.setMaximum(200), fs.setSuffix(' px') fs.setValue(prefs[attr]) fs.valueChanged.connect(self.emit_changed) l.addRow(size_label, fs) add_hline() self.changed_timer = t = QTimer(self) t.setSingleShot(True), t.setInterval(500), t.timeout.connect( self.emit_changed) def create_sz(label): ans = QSpinBox(self) ans.setSuffix(' px'), ans.setMinimum(100), ans.setMaximum(10000) l.addRow(label, ans) ans.valueChanged.connect(self.changed_timer.start) return ans self.cover_width = create_sz(_('Cover &width:')) self.cover_height = create_sz(_('Cover &height:')) fp.cla = la = QLabel( _('Note that the preview to the side is of fixed aspect ratio, so changing the cover' ' width above will not have any effect. If you change the height, you should also change the width nevertheless' ' as it will be used in actual cover generation.')) la.setWordWrap(True) l.addRow(la) self.templates_page = tp = QWidget(st) st.addTab(tp, _('&Text')) tp.l = l = QVBoxLayout() tp.setLayout(l) tp.la = la = QLabel( _('The text on the generated cover is taken from the metadata of the book.' ' This is controlled via templates. You can use the <b>, <i> and <br> tags' ' in the templates for bold, italic and line breaks, respectively. The' ' default templates use the title, series and authors. You can change them to use' ' whatever metadata you like.')) la.setWordWrap(True), la.setTextFormat(Qt.TextFormat.PlainText) l.addWidget(la) def create_template_widget(title, which, button): attr = which + '_template' heading = QLabel('<h2>' + title) setattr(tp, attr + '_heading', heading) l.addWidget(heading) la = QLabel() setattr(self, attr, la) l.addWidget(la), la.setTextFormat( Qt.TextFormat.PlainText), la.setStyleSheet( 'QLabel {font-family: monospace}') la.setWordWrap(True) b = QPushButton(button) b.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed) connect_lambda(b.clicked, self, lambda self: self.change_template(which)) setattr(self, attr + '_button', b) l.addWidget(b) if which != 'footer': f = QFrame(tp) setattr(tp, attr + '_sep', f), f.setFrameShape(QFrame.Shape.HLine) l.addWidget(f) l.addSpacing(10) create_template_widget(_('The title template'), 'title', _('Change the &title template')) create_template_widget(_('The sub-title template'), 'subtitle', _('Change the &sub-title template')) create_template_widget(_('The footer template'), 'footer', _('Change the &footer template')) l.addStretch(2) self.apply_prefs(prefs) self.changed.connect(self.update_preview) self.styles_list.itemSelectionChanged.connect(self.update_preview) self.colors_list.itemSelectionChanged.connect(self.update_preview) self.update_preview()
def __init__(self, parent, masternode_list, imgDir): super(QWidget, self).__init__(parent) self.parent = parent self.imgDir = imgDir self.runInThread = ThreadFuns.runInThread ###-- Masternode list self.masternode_list = masternode_list ###-- Create clients and statuses self.hwdevice = None self.hwStatus = 0 self.hwStatusMess = "Not Connected" self.rpcClient = None self.rpcConnected = False self.rpcStatusMess = "Not Connected" self.isBlockchainSynced = False ###-- Load icons & images self.loadIcons() ###-- Create main layout self.layout = QVBoxLayout() self.header = GuiHeader(self) self.initConsole() self.layout.addWidget(self.header) ###-- Create RPC Whatchdog self.rpc_watchdogThread = QThread() self.myRpcWd = RpcWatchdog(self) self.myRpcWd.moveToThread(self.rpc_watchdogThread) self.rpc_watchdogThread.started.connect(self.myRpcWd.run) self.rpc_watchdogThread.start() ###-- Create Queues and redirect stdout and stderr (eventually) self.queue = Queue() self.queue2 = Queue() sys.stdout = WriteStream(self.queue) sys.stderr = WriteStream(self.queue2) ###-- Init last logs logFile = open(log_File, 'w+') timestamp = strftime('%Y-%m-%d %H:%M:%S', gmtime(now())) log_line = '<b style="color: blue">{}</b><br>'.format('STARTING SPMT at '+ timestamp) logFile.write(log_line) logFile.close() ###-- Create the thread to update console log for stdout self.consoleLogThread = QThread() self.myWSReceiver = WriteStreamReceiver(self.queue) self.myWSReceiver.mysignal.connect(self.append_to_console) self.myWSReceiver.moveToThread(self.consoleLogThread) self.consoleLogThread.started.connect(self.myWSReceiver.run) self.consoleLogThread.start() printDbg("Console Log thread started") ###-- Create the thread to update console log for stderr self.consoleLogThread2 = QThread() self.myWSReceiver2 = WriteStreamReceiver(self.queue2) self.myWSReceiver2.mysignal.connect(self.append_to_console) self.myWSReceiver2.moveToThread(self.consoleLogThread2) self.consoleLogThread2.started.connect(self.myWSReceiver2.run) self.consoleLogThread2.start() printDbg("Console Log thread 2 started") ###-- Initialize tabs self.tabs = QTabWidget() self.t_main = TabMain(self) self.t_mnconf = TabMNConf(self) self.t_rewards = TabRewards(self) ###-- Add tabs self.tabs.addTab(self.tabMain, "Masternode Control") #self.tabs.addTab(self.tabMNConf, "MN Configuration") self.tabs.addTab(self.tabRewards, "Transfer Rewards") ###-- Connect change action self.tabs.currentChanged.connect(lambda: self.onTabChange()) ###-- Draw Tabs self.splitter = QSplitter(Qt.Vertical) ###-- Add tabs and console to Layout self.splitter.addWidget(self.tabs) self.splitter.addWidget(self.console) self.splitter.setStretchFactor(0,0) self.splitter.setStretchFactor(1,1) self.splitter.setSizes(self.parent.cache.get("splitter_sizes")) self.layout.addWidget(self.splitter) ###-- Set Layout self.setLayout(self.layout) ###-- Let's go self.mnode_to_change = None printOK("Hello! Welcome to " + parent.title) ###-- Hide console if it was previously hidden if self.parent.cache.get("console_hidden"): self.onToggleConsole() ##-- Check version self.onCheckVersion()
def __init__(self, recipe_model, parent=None): QDialog.__init__(self, parent) self.commit_on_change = True self.previous_urn = None self.setWindowIcon(QIcon(I('scheduler.png'))) self.setWindowTitle(_("Schedule news download")) self.l = l = QGridLayout(self) # Left panel self.h = h = QHBoxLayout() l.addLayout(h, 0, 0, 1, 1) self.search = s = SearchBox2(self) self.search.initialize('scheduler_search_history') self.search.setMinimumContentsLength(15) self.go_button = b = QToolButton(self) b.setText(_("Go")) b.clicked.connect(self.search.do_search) h.addWidget(s), h.addWidget(b) self.recipes = RecipesView(self) l.addWidget(self.recipes, 1, 0, 1, 1) self.recipe_model = recipe_model self.recipe_model.do_refresh() self.recipes.setModel(self.recipe_model) self.recipes.setFocus(Qt.OtherFocusReason) self.count_label = la = QLabel(_('%s news sources') % self.recipe_model.showing_count) la.setAlignment(Qt.AlignCenter) l.addWidget(la, 2, 0, 1, 1) self.search.search.connect(self.recipe_model.search) self.recipe_model.searched.connect(self.search.search_done, type=Qt.QueuedConnection) self.recipe_model.searched.connect(self.search_done) # Right Panel self.scroll_area_contents = sac = QWidget(self) self.l.addWidget(sac, 0, 1, 2, 1) sac.v = v = QVBoxLayout(sac) v.setContentsMargins(0, 0, 0, 0) self.detail_box = QTabWidget(self) self.detail_box.setVisible(False) self.detail_box.setCurrentIndex(0) v.addWidget(self.detail_box) v.addItem(QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding)) # First Tab (scheduling) self.tab = QWidget() self.detail_box.addTab(self.tab, _("&Schedule")) self.tab.v = vt = QVBoxLayout(self.tab) vt.setContentsMargins(0, 0, 0, 0) self.blurb = la = QLabel('blurb') la.setWordWrap(True), la.setOpenExternalLinks(True) vt.addWidget(la) self.frame = f = QFrame(self.tab) vt.addWidget(f) f.setFrameShape(f.StyledPanel) f.setFrameShadow(f.Raised) f.v = vf = QVBoxLayout(f) self.schedule = s = QCheckBox(_("&Schedule for download:"), f) self.schedule.stateChanged[int].connect(self.toggle_schedule_info) vf.addWidget(s) f.h = h = QHBoxLayout() vf.addLayout(h) self.days_of_week = QRadioButton(_("&Days of week"), f) self.days_of_month = QRadioButton(_("Da&ys of month"), f) self.every_x_days = QRadioButton(_("Every &x days"), f) self.days_of_week.setChecked(True) h.addWidget(self.days_of_week), h.addWidget(self.days_of_month), h.addWidget(self.every_x_days) self.schedule_stack = ss = QStackedWidget(f) self.schedule_widgets = [] for key in reversed(self.SCHEDULE_TYPES): self.schedule_widgets.insert(0, self.SCHEDULE_TYPES[key](self)) self.schedule_stack.insertWidget(0, self.schedule_widgets[0]) vf.addWidget(ss) self.last_downloaded = la = QLabel(f) la.setWordWrap(True) vf.addWidget(la) self.account = acc = QGroupBox(self.tab) acc.setTitle(_("&Account")) vt.addWidget(acc) acc.g = g = QGridLayout(acc) acc.unla = la = QLabel(_("&Username:"******"&Password:"******"&Show password"), self.account) spw.stateChanged[int].connect(self.set_pw_echo_mode) g.addWidget(spw, 2, 0, 1, 2) self.rla = la = QLabel(_("For the scheduling to work, you must leave calibre running.")) vt.addWidget(la) for b, c in iteritems(self.SCHEDULE_TYPES): b = getattr(self, b) b.toggled.connect(self.schedule_type_selected) b.setToolTip(textwrap.dedent(c.HELP)) # Second tab (advanced settings) self.tab2 = t2 = QWidget() self.detail_box.addTab(self.tab2, _("&Advanced")) self.tab2.g = g = QGridLayout(t2) g.setContentsMargins(0, 0, 0, 0) self.add_title_tag = tt = QCheckBox(_("Add &title as tag"), t2) g.addWidget(tt, 0, 0, 1, 2) t2.la = la = QLabel(_("&Extra tags:")) self.custom_tags = ct = QLineEdit(self) la.setBuddy(ct) g.addWidget(la), g.addWidget(ct, 1, 1) t2.la2 = la = QLabel(_("&Keep at most:")) la.setToolTip(_("Maximum number of copies (issues) of this recipe to keep. Set to 0 to keep all (disable).")) self.keep_issues = ki = QSpinBox(t2) tt.toggled['bool'].connect(self.keep_issues.setEnabled) ki.setMaximum(100000), la.setBuddy(ki) ki.setToolTip(_( "<p>When set, this option will cause calibre to keep, at most, the specified number of issues" " of this periodical. Every time a new issue is downloaded, the oldest one is deleted, if the" " total is larger than this number.\n<p>Note that this feature only works if you have the" " option to add the title as tag checked, above.\n<p>Also, the setting for deleting periodicals" " older than a number of days, below, takes priority over this setting.")) ki.setSpecialValueText(_("all issues")), ki.setSuffix(_(" issues")) g.addWidget(la), g.addWidget(ki, 2, 1) si = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) g.addItem(si, 3, 1, 1, 1) # Bottom area self.hb = h = QHBoxLayout() self.l.addLayout(h, 2, 1, 1, 1) self.labt = la = QLabel(_("Delete downloaded &news older than:")) self.old_news = on = QSpinBox(self) on.setToolTip(_( "<p>Delete downloaded news older than the specified number of days. Set to zero to disable.\n" "<p>You can also control the maximum number of issues of a specific periodical that are kept" " by clicking the Advanced tab for that periodical above.")) on.setSpecialValueText(_("never delete")), on.setSuffix(_(" days")) on.setMaximum(1000), la.setBuddy(on) on.setValue(gconf['oldest_news']) h.addWidget(la), h.addWidget(on) self.download_all_button = b = QPushButton(QIcon(I('news.png')), _("Download &all scheduled"), self) b.setToolTip(_("Download all scheduled news sources at once")) b.clicked.connect(self.download_all_clicked) self.l.addWidget(b, 3, 0, 1, 1) self.bb = bb = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel, self) bb.accepted.connect(self.accept), bb.rejected.connect(self.reject) self.download_button = b = bb.addButton(_('&Download now'), bb.ActionRole) b.setIcon(QIcon(I('arrow-down.png'))), b.setVisible(False) b.clicked.connect(self.download_clicked) self.l.addWidget(bb, 3, 1, 1, 1) geom = gprefs.get('scheduler_dialog_geometry') if geom is not None: QApplication.instance().safe_restore_geometry(self, geom)
def __initUI(self): self.resize(850, 650) self.center() self.setWindowTitle('Application de tracking vidéo') self.statusBar() # status bar at the bottom of the window # QTabWidget of the application showing the 5 tabs self.tabs = QTabWidget() # tab1: display video images & video metadata self.imageTab = ImageDisplay(self) # tab2: plot (y(t), x(t)) self.onePlot = OnePlot(self) # tab3: plot curves x(t) and y(t) self.twoPlots_xy = TwoPlots(self, "position") # tab4: plot curves Vx(t) and Vy(t) self.twoPlots_VxVy = TwoPlots(self, "velocity") # tab5: plot of f(t)=f(x(t), y(t), t) self.functionOfXY = FunctionPlot(self) # tab6: IPython shell self.pythonConsole = PythonConsole(self) self.tabs.addTab(self.imageTab,"Visualisation images") self.tabs.addTab(self.onePlot,"Trajectoire") self.tabs.addTab(self.twoPlots_xy,"Positions") self.tabs.addTab(self.twoPlots_VxVy,"Vitesses") self.tabs.addTab(self.functionOfXY,"Outil de tracé") self.tabs.addTab(self.pythonConsole,"IPython") self.setCentralWidget(self.tabs) # Menu(s) self.menubar = self.menuBar() if platform.uname().system.startswith('Darw') : # Mac OS specificity: self.menubar.setNativeMenuBar(False) ###### Menu 'Files' fileMenu = self.menubar.addMenu('&Fichier') ### Open images directory: qa = QAction(QIcon(VideoTracker.icone_dir+'/open.png'), 'Ouvrir dossier images', self) qa.setShortcut('Ctrl+D') qa.setStatusTip("Ouvre un dossier contenant déjà "+\ "les images d'une vidéo") # connexion avec la méthode 'load_images_from_directory' qui est # définie dans l'objet 'imageTab' : qa.triggered.connect(self.imageTab.load_images_from_directory) fileMenu.addAction(qa) ### Load a video file : qa = QAction(QIcon(VideoTracker.icone_dir+'/open.png'), "Charger un fichier vidéo", self) qa.setShortcut('Ctrl+O') qa.setStatusTip('Ouvre un fihier vidéo et le '+\ 'découpe en images successives...') # connexion avec la méthode 'open_video' qui est définie dans # l'objet 'imageTab' : qa.triggered.connect(self.imageTab.open_video) fileMenu.addAction(qa) ### Export CSV: qa = QAction(QIcon(VideoTracker.icone_dir+'/exportCSV.png'),\ 'Export CSV', self) qa.setStatusTip("Exporte les positions extraites de la vidéo dans un"+\ "fichier CSV.") qa.triggered.connect(self.ExportCSV) fileMenu.addAction(qa) ### Import CSV: qa = QAction(QIcon(VideoTracker.icone_dir+'/importCSV.png'),\ 'Import CSV', self) qa.setStatusTip("Importe les données depuis un fichier CSV forgé par VideoTracker.") qa.triggered.connect(self.ImportCSV) fileMenu.addAction(qa) ### Quit : qa = QAction(QIcon(VideoTracker.icone_dir+'/exit.png'),\ 'Quitter', self) qa.setShortcut('Ctrl+Q') qa.setStatusTip("Quitter l'application") qa.triggered.connect(self.close) fileMenu.addAction(qa) ###### Le menu 'Options' optionMenu = self.menubar.addMenu('&Options') ### Display info box windows: qa = QAction('Afficher boîtes info', self, checkable=True) text = 'Afficher ou non les boîtes de dialogue d\'information' qa.setStatusTip(text)# message in the status bar qa.setChecked(True) qa.triggered.connect(lambda e: self.set_flag("displayInfo",e)) optionMenu.addAction(qa) ### Verbose mode : qa = QAction('Mode verbeux', self, checkable=True) text = 'Afficher ou non des informations dans le shell Python' qa.setStatusTip(text) # message in the status bar qa.setChecked(True) qa.triggered.connect(lambda e: self.set_flag("debug", e)) optionMenu.addAction(qa) ### Clear trajectory plots before a new plot: qa = QAction('Effacement trajectoire avant tracé', self, checkable=True) text = 'Effacer automatiquement le tracé des onglets <Trajectoires> et ' text += '<X(t) et Y(t)> un nouveau tracé ?' qa.setStatusTip(text) # message in the status bar qa.setChecked(True) qa.triggered.connect(lambda e: self.set_flag("autoClearTraj", e) ) optionMenu.addAction(qa) ### draw/not draw the selected color area qa = QAction('Dessiner la sélection couleur de la cible', self, checkable=True) text = 'Dessine la zone sélectionnée pour la couleur de la cible' qa.setStatusTip(text) # message in the status bar qa.setChecked(True) qa.triggered.connect(lambda e: self.set_flag("drawTargetSelection", e)) optionMenu.addAction(qa)
def __init__(self, parent=None, one_line_toolbar=False, toolbar_prefs_name=None): QWidget.__init__(self, parent) self.toolbar_prefs_name = toolbar_prefs_name or self.toolbar_prefs_name self.toolbar1 = QToolBar(self) self.toolbar2 = QToolBar(self) self.toolbar3 = QToolBar(self) for i in range(1, 4): t = getattr(self, 'toolbar%d' % i) t.setIconSize(QSize(18, 18)) self.editor = EditorWidget(self) self.editor.data_changed.connect(self.data_changed) self.set_base_url = self.editor.set_base_url self.set_html = self.editor.set_html self.tabs = QTabWidget(self) self.tabs.setTabPosition(self.tabs.South) self.wyswyg = QWidget(self.tabs) self.code_edit = QPlainTextEdit(self.tabs) self.source_dirty = False self.wyswyg_dirty = True self._layout = QVBoxLayout(self) self.wyswyg.layout = l = QVBoxLayout(self.wyswyg) self.setLayout(self._layout) l.setContentsMargins(0, 0, 0, 0) if one_line_toolbar: tb = QHBoxLayout() l.addLayout(tb) else: tb = l tb.addWidget(self.toolbar1) tb.addWidget(self.toolbar2) tb.addWidget(self.toolbar3) l.addWidget(self.editor) self._layout.addWidget(self.tabs) self.tabs.addTab(self.wyswyg, _('N&ormal view')) self.tabs.addTab(self.code_edit, _('&HTML source')) self.tabs.currentChanged[int].connect(self.change_tab) self.highlighter = Highlighter(self.code_edit.document()) self.layout().setContentsMargins(0, 0, 0, 0) if self.toolbar_prefs_name is not None: hidden = gprefs.get(self.toolbar_prefs_name) if hidden: self.hide_toolbars() # toolbar1 {{{ self.toolbar1.addAction(self.editor.action_undo) self.toolbar1.addAction(self.editor.action_redo) self.toolbar1.addAction(self.editor.action_select_all) self.toolbar1.addAction(self.editor.action_remove_format) self.toolbar1.addAction(self.editor.action_clear) self.toolbar1.addSeparator() for x in ('copy', 'cut', 'paste'): ac = getattr(self.editor, 'action_' + x) self.toolbar1.addAction(ac) self.toolbar1.addSeparator() self.toolbar1.addAction(self.editor.action_background) # }}} # toolbar2 {{{ for x in ('', 'un'): ac = getattr(self.editor, 'action_%sordered_list' % x) self.toolbar2.addAction(ac) self.toolbar2.addSeparator() for x in ('superscript', 'subscript', 'indent', 'outdent'): self.toolbar2.addAction(getattr(self.editor, 'action_' + x)) if x in ('subscript', 'outdent'): self.toolbar2.addSeparator() self.toolbar2.addAction(self.editor.action_block_style) w = self.toolbar2.widgetForAction(self.editor.action_block_style) if hasattr(w, 'setPopupMode'): w.setPopupMode(w.InstantPopup) self.toolbar2.addAction(self.editor.action_insert_link) self.toolbar2.addAction(self.editor.action_insert_hr) # }}} # toolbar3 {{{ for x in ('bold', 'italic', 'underline', 'strikethrough'): ac = getattr(self.editor, 'action_' + x) self.toolbar3.addAction(ac) self.toolbar3.addSeparator() for x in ('left', 'center', 'right', 'justified'): ac = getattr(self.editor, 'action_align_' + x) self.toolbar3.addAction(ac) self.toolbar3.addSeparator() self.toolbar3.addAction(self.editor.action_color) # }}} self.code_edit.textChanged.connect(self.code_dirtied) self.editor.page().contentsChanged.connect(self.wyswyg_dirtied)
def __init__(self, window, plugin, keystore, device_id): title = _("{} Settings").format(plugin.device) super(SettingsDialog, self).__init__(window, title) self.setMaximumWidth(540) devmgr = plugin.device_manager() config = devmgr.config handler = keystore.handler thread = keystore.thread hs_rows, hs_cols = (64, 128) def invoke_client(method, *args, **kw_args): unpair_after = kw_args.pop('unpair_after', False) def task(): client = devmgr.client_by_id(device_id) if not client: raise RuntimeError("Device not connected") if method: getattr(client, method)(*args, **kw_args) if unpair_after: devmgr.unpair_id(device_id) return client.features thread.add(task, on_success=update) def update(features): self.features = features set_label_enabled() if features.bootloader_hash: bl_hash = bh2u(features.bootloader_hash) bl_hash = "\n".join([bl_hash[:32], bl_hash[32:]]) else: bl_hash = "N/A" noyes = [_("No"), _("Yes")] endis = [_("Enable Passphrases"), _("Disable Passphrases")] disen = [_("Disabled"), _("Enabled")] setchange = [_("Set a PIN"), _("Change PIN")] version = "%d.%d.%d" % (features.major_version, features.minor_version, features.patch_version) device_label.setText(features.label) pin_set_label.setText(noyes[features.pin_protection]) passphrases_label.setText(disen[features.passphrase_protection]) bl_hash_label.setText(bl_hash) label_edit.setText(features.label) device_id_label.setText(features.device_id) initialized_label.setText(noyes[features.initialized]) version_label.setText(version) clear_pin_button.setVisible(features.pin_protection) clear_pin_warning.setVisible(features.pin_protection) pin_button.setText(setchange[features.pin_protection]) pin_msg.setVisible(not features.pin_protection) passphrase_button.setText(endis[features.passphrase_protection]) language_label.setText(features.language) def set_label_enabled(): label_apply.setEnabled(label_edit.text() != self.features.label) def rename(): invoke_client('change_label', label_edit.text()) def toggle_passphrase(): title = _("Confirm Toggle Passphrase Protection") currently_enabled = self.features.passphrase_protection if currently_enabled: msg = _("After disabling passphrases, you can only pair this " "Electrum wallet if it had an empty passphrase. " "If its passphrase was not empty, you will need to " "create a new wallet with the install wizard. You " "can use this wallet again at any time by re-enabling " "passphrases and entering its passphrase.") else: msg = _("Your current Electrum wallet can only be used with " "an empty passphrase. You must create a separate " "wallet with the install wizard for other passphrases " "as each one generates a new set of addresses.") msg += "\n\n" + _("Are you sure you want to proceed?") if not self.question(msg, title=title): return invoke_client('toggle_passphrase', unpair_after=currently_enabled) def change_homescreen(): dialog = QFileDialog(self, _("Choose Homescreen")) filename, __ = dialog.getOpenFileName() if not filename: return # user cancelled if filename.endswith('.toif'): img = open(filename, 'rb').read() if img[:8] != b'TOIf\x90\x00\x90\x00': handler.show_error('File is not a TOIF file with size of \ 144x144') return else: from PIL import Image # FIXME im = Image.open(filename) if im.size != (128, 64): handler.show_error('Image must be 128 x 64 pixels') return im = im.convert('1') pix = im.load() img = bytearray(1024) for j in range(64): for i in range(128): if pix[i, j]: o = (i + j * 128) img[o // 8] |= (1 << (7 - o % 8)) img = bytes(img) invoke_client('change_homescreen', img) def clear_homescreen(): invoke_client('change_homescreen', b'\x00') def set_pin(): invoke_client('set_pin', remove=False) def clear_pin(): invoke_client('set_pin', remove=True) def wipe_device(): wallet = window.wallet if wallet and sum(wallet.get_balance()): title = _("Confirm Device Wipe") msg = _("Are you SURE you want to wipe the device?\n" "Your wallet still has bitcoins in it!") if not self.question( msg, title=title, icon=QMessageBox.Critical): return invoke_client('wipe_device', unpair_after=True) def slider_moved(): mins = timeout_slider.sliderPosition() timeout_minutes.setText(_("%2d minutes") % mins) def slider_released(): config.set_session_timeout(timeout_slider.sliderPosition() * 60) # Information tab info_tab = QWidget() info_layout = QVBoxLayout(info_tab) info_glayout = QGridLayout() info_glayout.setColumnStretch(2, 1) device_label = QLabel() pin_set_label = QLabel() passphrases_label = QLabel() version_label = QLabel() device_id_label = QLabel() bl_hash_label = QLabel() bl_hash_label.setWordWrap(True) language_label = QLabel() initialized_label = QLabel() rows = [ (_("Device Label"), device_label), (_("PIN set"), pin_set_label), (_("Passphrases"), passphrases_label), (_("Firmware Version"), version_label), (_("Device ID"), device_id_label), (_("Bootloader Hash"), bl_hash_label), (_("Language"), language_label), (_("Initialized"), initialized_label), ] for row_num, (label, widget) in enumerate(rows): info_glayout.addWidget(QLabel(label), row_num, 0) info_glayout.addWidget(widget, row_num, 1) info_layout.addLayout(info_glayout) # Settings tab settings_tab = QWidget() settings_layout = QVBoxLayout(settings_tab) settings_glayout = QGridLayout() # Settings tab - Label label_msg = QLabel( _("Name this {}. If you have multiple devices " "their labels help distinguish them.").format(plugin.device)) label_msg.setWordWrap(True) label_label = QLabel(_("Device Label")) label_edit = QLineEdit() label_edit.setMinimumWidth(150) label_edit.setMaxLength(plugin.MAX_LABEL_LEN) label_apply = QPushButton(_("Apply")) label_apply.clicked.connect(rename) label_edit.textChanged.connect(set_label_enabled) settings_glayout.addWidget(label_label, 0, 0) settings_glayout.addWidget(label_edit, 0, 1, 1, 2) settings_glayout.addWidget(label_apply, 0, 3) settings_glayout.addWidget(label_msg, 1, 1, 1, -1) pin_button = QPushButton() # Settings tab - PIN pin_label = QLabel(_("PIN Protection")) pin_button.clicked.connect(set_pin) settings_glayout.addWidget(pin_label, 2, 0) settings_glayout.addWidget(pin_button, 2, 1) pin_msg = QLabel( _("PIN protection is strongly recommended. " "A PIN is your only protection against someone " "stealing your bitcoins if they obtain physical " "access to your {}.").format(plugin.device)) pin_msg.setWordWrap(True) pin_msg.setStyleSheet("color: red") settings_glayout.addWidget(pin_msg, 3, 1, 1, -1) # Settings tab - Homescreen homescreen_label = QLabel(_("Homescreen")) homescreen_change_button = QPushButton(_("Change...")) homescreen_clear_button = QPushButton(_("Reset")) homescreen_change_button.clicked.connect(change_homescreen) try: import PIL except ImportError: homescreen_change_button.setDisabled(True) homescreen_change_button.setToolTip( _("Required package 'PIL' is not available - Please install \ it or use the OctoWallet website instead.")) homescreen_clear_button.clicked.connect(clear_homescreen) homescreen_msg = QLabel( _("You can set the homescreen on your " "device to personalize it. You must " "choose a {} x {} monochrome black and " "white image.").format(hs_rows, hs_cols)) homescreen_msg.setWordWrap(True) settings_glayout.addWidget(homescreen_label, 4, 0) settings_glayout.addWidget(homescreen_change_button, 4, 1) settings_glayout.addWidget(homescreen_clear_button, 4, 2) settings_glayout.addWidget(homescreen_msg, 5, 1, 1, -1) # Settings tab - Session Timeout timeout_label = QLabel(_("Session Timeout")) timeout_minutes = QLabel() timeout_slider = QSlider(Qt.Horizontal) timeout_slider.setRange(1, 60) timeout_slider.setSingleStep(1) timeout_slider.setTickInterval(5) timeout_slider.setTickPosition(QSlider.TicksBelow) timeout_slider.setTracking(True) timeout_msg = QLabel( _("Clear the session after the specified period " "of inactivity. Once a session has timed out, " "your PIN and passphrase (if enabled) must be " "re-entered to use the device.")) timeout_msg.setWordWrap(True) timeout_slider.setSliderPosition(config.get_session_timeout() // 60) slider_moved() timeout_slider.valueChanged.connect(slider_moved) timeout_slider.sliderReleased.connect(slider_released) settings_glayout.addWidget(timeout_label, 6, 0) settings_glayout.addWidget(timeout_slider, 6, 1, 1, 3) settings_glayout.addWidget(timeout_minutes, 6, 4) settings_glayout.addWidget(timeout_msg, 7, 1, 1, -1) settings_layout.addLayout(settings_glayout) settings_layout.addStretch(1) # Advanced tab advanced_tab = QWidget() advanced_layout = QVBoxLayout(advanced_tab) advanced_glayout = QGridLayout() # Advanced tab - clear PIN clear_pin_button = QPushButton(_("Disable PIN")) clear_pin_button.clicked.connect(clear_pin) clear_pin_warning = QLabel( _("If you disable your PIN, anyone with physical access to your " "{} device can spend your bitcoins.").format(plugin.device)) clear_pin_warning.setWordWrap(True) clear_pin_warning.setStyleSheet("color: red") advanced_glayout.addWidget(clear_pin_button, 0, 2) advanced_glayout.addWidget(clear_pin_warning, 1, 0, 1, 5) # Advanced tab - toggle passphrase protection passphrase_button = QPushButton() passphrase_button.clicked.connect(toggle_passphrase) passphrase_msg = WWLabel(PASSPHRASE_HELP) passphrase_warning = WWLabel(PASSPHRASE_NOT_PIN) passphrase_warning.setStyleSheet("color: red") advanced_glayout.addWidget(passphrase_button, 3, 2) advanced_glayout.addWidget(passphrase_msg, 4, 0, 1, 5) advanced_glayout.addWidget(passphrase_warning, 5, 0, 1, 5) # Advanced tab - wipe device wipe_device_button = QPushButton(_("Wipe Device")) wipe_device_button.clicked.connect(wipe_device) wipe_device_msg = QLabel( _("Wipe the device, removing all data from it. The firmware " "is left unchanged.")) wipe_device_msg.setWordWrap(True) wipe_device_warning = QLabel( _("Only wipe a device if you have the recovery seed written down " "and the device wallet(s) are empty, otherwise the bitcoins " "will be lost forever.")) wipe_device_warning.setWordWrap(True) wipe_device_warning.setStyleSheet("color: red") advanced_glayout.addWidget(wipe_device_button, 6, 2) advanced_glayout.addWidget(wipe_device_msg, 7, 0, 1, 5) advanced_glayout.addWidget(wipe_device_warning, 8, 0, 1, 5) advanced_layout.addLayout(advanced_glayout) advanced_layout.addStretch(1) tabs = QTabWidget(self) tabs.addTab(info_tab, _("Information")) tabs.addTab(settings_tab, _("Settings")) tabs.addTab(advanced_tab, _("Advanced")) dialog_vbox = QVBoxLayout(self) dialog_vbox.addWidget(tabs) dialog_vbox.addLayout(Buttons(CloseButton(self))) # Update information invoke_client(None)