def openWindow(self): self.window = QMainWindow() self.myGui = App(self.window) self.stacked_layout = QStackedLayout() self.stacked_layout.addWidget(self.myGui)
def __init__(self, msg, after=None, parent=None, size=256, interval=10): QStackedLayout.__init__(self, parent) self.wp = WaitPanel(msg, parent, size, interval) if after is None: after = QWidget(parent) self.after = after self.addWidget(self.wp) self.addWidget(after)
def setup_ui(self): self.l = l = QVBoxLayout(self) self.wait_stack = s = QStackedLayout() l.addLayout(s) l.addWidget(self.bb) self.reports = r = ReportsWidget(self) r.edit_requested.connect(self.edit_requested) r.delete_requested.connect(self.confirm_delete) self.pw = pw = QWidget(self) s.addWidget(pw), s.addWidget(r) pw.l = l = QVBoxLayout(pw) self.pi = pi = ProgressIndicator(self, 256) l.addStretch(1), l.addWidget(pi, alignment=Qt.AlignHCenter), l.addSpacing(10) pw.la = la = QLabel(_('Gathering data, please wait...')) la.setStyleSheet('QLabel { font-size: 30pt; font-weight: bold }') l.addWidget(la, alignment=Qt.AlignHCenter), l.addStretch(1) self.bb.setStandardButtons(self.bb.Close) self.refresh_button = b = self.bb.addButton(_('&Refresh'), self.bb.ActionRole) b.clicked.connect(self.refresh) b.setIcon(QIcon(I('view-refresh.png'))) self.save_button = b = self.bb.addButton(_('&Save'), self.bb.ActionRole) b.clicked.connect(self.reports.to_csv) b.setIcon(QIcon(I('save.png'))) b.setToolTip(_('Export the currently shown report as a CSV file'))
def setup_ui(self): self.stacks = s = QStackedLayout(self) self.w = w = QWidget(self) self.w.l = l = QVBoxLayout(w) self.pi = pi = ProgressIndicator(self, 256) l.addStretch(1), l.addWidget( pi, alignment=Qt.AlignHCenter), l.addSpacing(10) w.la = la = QLabel(_('Gathering data, please wait...')) f = la.font() f.setBold(True), f.setPointSize(28), la.setFont(f) l.addWidget(la, alignment=Qt.AlignHCenter), l.addStretch(1) s.addWidget(w) self.w2 = w = QWidget(self) self.l = l = QVBoxLayout(w) s.addWidget(w) self.la = la = QLabel( _('Choose a program to open %s files') % self.file_type.upper()) self.plist = pl = QListWidget(self) pl.doubleClicked.connect(self.accept) pl.setIconSize(QSize(48, 48)), pl.setSpacing(5) pl.doubleClicked.connect(self.accept) l.addWidget(la), l.addWidget(pl) la.setBuddy(pl) b = self.bb.addButton(_('&Browse computer for program'), self.bb.ActionRole) b.clicked.connect(self.manual) l.addWidget(self.bb)
def __init__(self, preview, parent=None): QWidget.__init__(self, parent) self.preview = preview self.preview_is_refreshing = False self.refresh_needed = False preview.refresh_starting.connect(self.preview_refresh_starting) preview.refreshed.connect(self.preview_refreshed) self.apply_theme() self.setAutoFillBackground(True) self.update_timer = QTimer(self) self.update_timer.timeout.connect(self.update_data) self.update_timer.setSingleShot(True) self.update_timer.setInterval(500) self.now_showing = (None, None, None) self.stack = s = QStackedLayout(self) self.setLayout(s) self.clear_label = la = QLabel( '<h3>' + _('No style information found') + '</h3><p>' + _('Move the cursor inside a HTML tag to see what styles' ' apply to that tag.')) la.setWordWrap(True) la.setAlignment(Qt.AlignTop | Qt.AlignLeft) s.addWidget(la) self.box = box = Box(self) box.hyperlink_activated.connect(self.goto_declaration, type=Qt.QueuedConnection) self.scroll = sc = QScrollArea(self) sc.setWidget(box) sc.setWidgetResizable(True) s.addWidget(sc)
def setup_import_panel(self): self.import_panel = w = QWidget(self) self.stack.addWidget(w) w.stack = s = QStackedLayout(w) self.ig = w = QWidget() s.addWidget(w) w.l = l = QVBoxLayout(w) w.la = la = QLabel( _('Specify the folder containing the previously exported calibre data that you' ' wish to import.')) la.setWordWrap(True) l.addWidget(la) self.export_dir_button = b = QPushButton(QIcon(I('document_open.png')), _('Choose &folder'), self) b.clicked.connect(self.select_import_folder) l.addWidget(b), l.addStretch() self.select_libraries_panel = w = QScrollArea(self) w.setWidgetResizable(True) s.addWidget(w) self.slp = w = QWidget(self) self.select_libraries_panel.setWidget(w) w.l = l = QVBoxLayout(w) w.la = la = QLabel( _('Specify locations for the libraries you want to import. A location must be an empty folder' ' on your computer. If you leave any blank, those libraries will not be imported.' )) la.setWordWrap(True) l.addWidget(la)
def __init__(self, parent, cover_flow): QDialog.__init__(self, parent) self._layout = QStackedLayout() self.setLayout(self._layout) self.setWindowTitle(_('Browse by covers')) self.layout().addWidget(cover_flow) geom = gprefs.get('cover_browser_dialog_geometry', bytearray('')) geom = QByteArray(geom) if not self.restoreGeometry(geom): h, w = available_height()-60, int(available_width()/1.5) self.resize(w, h) self.action_fs_toggle = a = QAction(self) self.addAction(a) a.setShortcuts([QKeySequence('F11', QKeySequence.PortableText), QKeySequence('Ctrl+Shift+F', QKeySequence.PortableText)]) a.triggered.connect(self.toggle_fullscreen) self.action_esc_fs = a = QAction(self) a.triggered.connect(self.show_normal) self.addAction(a) a.setShortcuts([QKeySequence('Esc', QKeySequence.PortableText)]) self.pre_fs_geom = None cover_flow.setFocus(Qt.OtherFocusReason) self.view_action = a = QAction(self) iactions = parent.iactions self.addAction(a) a.setShortcuts(list(iactions['View'].menuless_qaction.shortcuts())+ [QKeySequence(Qt.Key_Space)]) a.triggered.connect(iactions['View'].menuless_qaction.trigger) self.sd_action = a = QAction(self) self.addAction(a) a.setShortcuts(list(iactions['Send To Device']. menuless_qaction.shortcuts())) a.triggered.connect(iactions['Send To Device'].menuless_qaction.trigger)
def setup_ui(self): self.l = l = QVBoxLayout(self) self.stack = s = QStackedLayout() l.addLayout(s) l.addWidget(self.bb) self.welcome = w = QWidget(self) s.addWidget(w) w.l = l = QVBoxLayout(w) w.la = la = QLabel('<p>' + _( 'You can export all calibre data, including your books, settings and plugins' ' into a single directory. Then, you can use this tool to re-import all that' ' data into a different calibre install, for example, on another computer.' ) + '<p>' + _( 'This is a simple way to move your calibre installation with all its data to' ' a new computer, or to replicate your current setup on a second computer.' )) la.setWordWrap(True) l.addWidget(la) l.addSpacing(20) self.exp_button = b = QPushButton(_('&Export all your calibre data')) connect_lambda(b.clicked, self, lambda self: self.show_panel('export')) l.addWidget(b), l.addSpacing(20) self.imp_button = b = QPushButton( _('&Import previously exported data')) connect_lambda(b.clicked, self, lambda self: self.show_panel('import')) l.addWidget(b), l.addStretch(20) self.setup_export_panel() self.setup_import_panel() self.show_panel(self.initial_panel)
def setup_ui(self): self.vl = vl = QVBoxLayout(self) self.stack = l = QStackedLayout() self.pi = pi = ProgressIndicator(self, 256) vl.addLayout(l), vl.addWidget(self.bb) self.restore_defs_button = b = self.bb.addButton(_('Restore &default icons'), self.bb.ActionRole) b.clicked.connect(self.restore_defaults) b.setIcon(QIcon(I('view-refresh.png'))) self.c = c = QWidget(self) self.c.v = v = QVBoxLayout(self.c) v.addStretch(), v.addWidget(pi, 0, Qt.AlignCenter) self.wait_msg = m = QLabel(self) v.addWidget(m, 0, Qt.AlignCenter), v.addStretch() f = m.font() f.setBold(True), f.setPointSize(28), m.setFont(f) self.start_spinner() l.addWidget(c) self.w = w = QWidget(self) l.addWidget(w) w.l = l = QGridLayout(w) def add_row(x, y=None): if isinstance(x, type('')): x = QLabel(x) row = l.rowCount() if y is None: if isinstance(x, QLabel): x.setWordWrap(True) l.addWidget(x, row, 0, 1, 2) else: if isinstance(x, QLabel): x.setBuddy(y) l.addWidget(x, row, 0), l.addWidget(y, row, 1) add_row(_( 'Choose an icon theme below. You will need to restart' ' calibre to see the new icons.')) add_row(_('Current icon theme:') + '\xa0<b>' + (self.current_theme or 'None')) self.sort_by = sb = QComboBox(self) add_row(_('&Sort by:'), sb) sb.addItems([_('Number of icons'), _('Popularity'), _('Name'),]) sb.setEditable(False), sb.setCurrentIndex(gprefs.get('choose_icon_theme_sort_by', 1)) sb.currentIndexChanged[int].connect(self.re_sort) sb.currentIndexChanged[int].connect(lambda : gprefs.set('choose_icon_theme_sort_by', sb.currentIndex())) self.theme_list = tl = QListWidget(self) tl.setVerticalScrollMode(tl.ScrollPerPixel) self.delegate = Delegate(tl) tl.setItemDelegate(self.delegate) tl.itemDoubleClicked.connect(self.accept) add_row(tl) t = Thread(name='GetIconThemes', target=self.get_themes) t.daemon = True t.start()
def setup_ui(self): self.setWindowIcon(QIcon(I('modified.png'))) self.l = l = QVBoxLayout(self) self.stack = s = QStackedLayout() l.addLayout(s), l.addWidget(self.bb) self.listc = c = QWidget(self) s.addWidget(c) c.l = l = QVBoxLayout(c) c.h = h = QHBoxLayout() l.addLayout(h) self.search_bar = sb = QLineEdit(self) sb.setPlaceholderText(_('Search for a snippet')) h.addWidget(sb) self.next_button = b = QPushButton(_('&Next')) b.clicked.connect(self.find_next) h.addWidget(b) c.h2 = h = QHBoxLayout() l.addLayout(h) self.snip_list = sl = QListWidget(self) sl.doubleClicked.connect(self.edit_snippet) h.addWidget(sl) c.l2 = l = QVBoxLayout() h.addLayout(l) self.add_button = b = QToolButton(self) b.setIcon(QIcon(I('plus.png'))), b.setText(_('&Add snippet')), b.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextUnderIcon) b.clicked.connect(self.add_snippet) l.addWidget(b) self.edit_button = b = QToolButton(self) b.setIcon(QIcon(I('modified.png'))), b.setText(_('&Edit snippet')), b.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextUnderIcon) b.clicked.connect(self.edit_snippet) l.addWidget(b) self.add_button = b = QToolButton(self) b.setIcon(QIcon(I('minus.png'))), b.setText(_('&Remove snippet')), b.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextUnderIcon) b.clicked.connect(self.remove_snippet) l.addWidget(b) self.add_button = b = QToolButton(self) b.setIcon(QIcon(I('config.png'))), b.setText(_('Change &built-in')), b.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextUnderIcon) b.clicked.connect(self.change_builtin) l.addWidget(b) for i, snip in enumerate(sorted(user_snippets.get('snippets', []), key=itemgetter('trigger'))): item = self.snip_to_item(snip) if i == 0: self.snip_list.setCurrentItem(item) self.edit_snip = es = EditSnippet(self) self.stack.addWidget(es)
def __init__(self, args): super(DigClock, self).__init__() self.args=args self.setMinimumHeight(200) self.setMinimumWidth(400) #CONFIGURATION ON INITIALIZATION #background self.setAutoFillBackground(True) self.setWindowFlags(QtCore.Qt.FramelessWindowHint) #main widget self.mainW= QLCDNumber() #main layout mainL = QStackedLayout() mainL.addWidget(self.mainW) self.setLayout(mainL) t = threading.Timer(0.5, self.updateTime) t.daemon = True t.start() bg = "" mc = "" if 'background' in self.args: if args['background'] == 'transparent': self.setAttribute(QtCore.Qt.WA_TranslucentBackground) if self.args['background'][0] == '#': bg = "background-color:" + self.args['background'] + ";" if 'color' in self.args: mc = "color: " + self.args['color'] + ";" self.setStyleSheet("QWidget" "{"+ bg + mc + "}")
def __init__(self, parent=None): super().__init__(parent) self._mode = self.Mode_None self._items = [] # QList<Item> self._tab_bar = None # QWidget self._stack = QStackedLayout() # QStackedLayout self._background_pixmap = QPixmap() self._side_widget = QWidget() # QWidget self._side_layout = QVBoxLayout() # QVBoxLayout self._top_layout = QVBoxLayout() # QVBoxLayout self._use_background = False # bool self._menu = None # QMenu self._proxy_style = FancyTabProxyStyle() # FancyTabProxyStyle self._side_layout.setSpacing(0) self._side_layout.setContentsMargins(0, 0, 0, 0) self._side_layout.addSpacerItem( QSpacerItem(0, 0, QSizePolicy.Fixed, QSizePolicy.Expanding)) self._side_widget.setLayout(self._side_layout) self._side_widget.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Expanding) self._top_layout.setSpacing(0) self._top_layout.setContentsMargins(0, 0, 0, 0) self._top_layout.addLayout(self._stack) main_layout = QHBoxLayout() main_layout.setContentsMargins(0, 0, 0, 0) main_layout.setSpacing(1) main_layout.addWidget(self._side_widget) main_layout.addLayout(self._top_layout) self.setLayout(main_layout)
def setup_ui(self): self.setWindowIcon(QIcon(I('diff.png'))) self.stacks = st = QStackedLayout(self) self.busy = BusyWidget(self) self.w = QWidget(self) st.addWidget(self.busy), st.addWidget(self.w) self.setLayout(st) self.l = l = QGridLayout() self.w.setLayout(l) self.view = v = DiffView(self, show_open_in_editor=self.show_open_in_editor) l.addWidget(v, l.rowCount(), 0, 1, -1) r = l.rowCount() self.bp = b = QToolButton(self) b.setIcon(QIcon(I('back.png'))) b.clicked.connect(partial(self.view.next_change, -1)) b.setToolTip(_('Go to previous change') + ' [p]') b.setText(_('&Previous change')), b.setToolButtonStyle( Qt.ToolButtonTextBesideIcon) l.addWidget(b, r, 0) self.bn = b = QToolButton(self) b.setIcon(QIcon(I('forward.png'))) b.clicked.connect(partial(self.view.next_change, 1)) b.setToolTip(_('Go to next change') + ' [n]') b.setText(_('&Next change')), b.setToolButtonStyle( Qt.ToolButtonTextBesideIcon) l.addWidget(b, r, 1) self.search = s = HistoryLineEdit2(self) s.initialize('diff_search_history') l.addWidget(s, r, 2) s.setPlaceholderText(_('Search for text')) s.returnPressed.connect(partial(self.do_search, False)) self.sbn = b = QToolButton(self) b.setIcon(QIcon(I('arrow-down.png'))) b.clicked.connect(partial(self.do_search, False)) b.setToolTip(_('Find next match')) b.setText(_('Next &match')), b.setToolButtonStyle( Qt.ToolButtonTextBesideIcon) l.addWidget(b, r, 3) self.sbp = b = QToolButton(self) b.setIcon(QIcon(I('arrow-up.png'))) b.clicked.connect(partial(self.do_search, True)) b.setToolTip(_('Find previous match')) b.setText(_('P&revious match')), b.setToolButtonStyle( Qt.ToolButtonTextBesideIcon) l.addWidget(b, r, 4) self.lb = b = QRadioButton(_('Left panel'), self) b.setToolTip(_('Perform search in the left panel')) l.addWidget(b, r, 5) self.rb = b = QRadioButton(_('Right panel'), self) b.setToolTip(_('Perform search in the right panel')) l.addWidget(b, r, 6) b.setChecked(True) self.pb = b = QToolButton(self) b.setIcon(QIcon(I('config.png'))) b.setText(_('&Options')), b.setToolButtonStyle( Qt.ToolButtonTextBesideIcon) b.setToolTip(_('Change how the differences are displayed')) b.setPopupMode(b.InstantPopup) m = QMenu(b) b.setMenu(m) cm = self.cm = QMenu(_('Lines of context around each change')) for i in (3, 5, 10, 50): cm.addAction( _('Show %d lines of context') % i, partial(self.change_context, i)) cm.addAction(_('Show all text'), partial(self.change_context, None)) self.beautify_action = m.addAction('', self.toggle_beautify) self.set_beautify_action_text() m.addMenu(cm) l.addWidget(b, r, 7) self.hl = QHBoxLayout() l.addLayout(self.hl, l.rowCount(), 0, 1, -1) self.names = QLabel('') self.hl.addWidget(self.names, r) self.bb.setStandardButtons(self.bb.Close) if self.revert_button_msg is not None: self.rvb = b = self.bb.addButton(self.revert_button_msg, self.bb.ActionRole) b.setIcon(QIcon(I('edit-undo.png'))), b.setAutoDefault(False) b.clicked.connect(self.revert_requested) b.clicked.connect(self.reject) self.bb.button(self.bb.Close).setDefault(True) self.hl.addWidget(self.bb, r) self.view.setFocus(Qt.OtherFocusReason)
def make_layout(horizon=True, grid=False, margin=(0, 0, 0, 0), spacing=0, alignment=None, stack=False): if stack: layout = QStackedLayout() elif grid: layout = QGridLayout() else: if horizon: layout = QHBoxLayout() else: layout = QVBoxLayout() if not isinstance(margin, tuple): margin = (margin, margin, margin, margin) layout.setContentsMargins(*margin) layout.setSpacing(spacing) if alignment is not None: layout.setAlignment(alignment) return layout
def __init__(self, parent=None): QWidget.__init__(self, parent) self.l = l = QVBoxLayout() self.setLayout(l) l.setContentsMargins(0, 0, 0, 0) self.stack = QStackedLayout(l) self.stack.setStackingMode(self.stack.StackAll) self.current_sync_retry_count = 0 self.view = WebView(self) self.view._page.bridge.request_sync.connect(self.request_sync) self.view._page.bridge.request_split.connect(self.request_split) self.view._page.bridge.live_css_data.connect(self.live_css_data) self.view._page.bridge.bridge_ready.connect(self.on_bridge_ready) self.view._page.loadFinished.connect(self.load_finished) self.view._page.loadStarted.connect(self.load_started) self.view.render_process_restarted.connect(self.render_process_restarted) self.pending_go_to_anchor = None self.inspector = self.view.inspector self.stack.addWidget(self.view) self.cover = c = QLabel(_('Loading preview, please wait...')) c.setWordWrap(True) c.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding) c.setStyleSheet('QLabel { background-color: palette(window); }') c.setAlignment(Qt.AlignmentFlag.AlignCenter) self.stack.addWidget(self.cover) self.stack.setCurrentIndex(self.stack.indexOf(self.cover)) self.bar = QToolBar(self) l.addWidget(self.bar) ac = actions['auto-reload-preview'] ac.setCheckable(True) ac.setChecked(True) ac.toggled.connect(self.auto_reload_toggled) self.auto_reload_toggled(ac.isChecked()) self.bar.addAction(ac) ac = actions['sync-preview-to-editor'] ac.setCheckable(True) ac.setChecked(True) ac.toggled.connect(self.sync_toggled) self.sync_toggled(ac.isChecked()) self.bar.addAction(ac) self.bar.addSeparator() ac = actions['split-in-preview'] ac.setCheckable(True) ac.setChecked(False) ac.toggled.connect(self.split_toggled) self.split_toggled(ac.isChecked()) self.bar.addAction(ac) ac = actions['reload-preview'] ac.triggered.connect(self.refresh) self.bar.addAction(ac) actions['preview-dock'].toggled.connect(self.visibility_changed) self.current_name = None self.last_sync_request = None self.refresh_timer = QTimer(self) self.refresh_timer.timeout.connect(self.refresh) parse_worker.start() self.current_sync_request = None self.search = HistoryLineEdit2(self) self.search.initialize('tweak_book_preview_search') self.search.setPlaceholderText(_('Search in preview')) self.search.returnPressed.connect(self.find_next) self.bar.addSeparator() self.bar.addWidget(self.search) for d in ('next', 'prev'): ac = actions['find-%s-preview' % d] ac.triggered.connect(getattr(self, 'find_' + d)) self.bar.addAction(ac)
def setup_ui(self): self.l = l = QVBoxLayout(self) self.setLayout(l) self.h = h = QHBoxLayout() self.filter_text = ft = QLineEdit(self) ft.textChanged.connect(self.do_filter) ft.setPlaceholderText(_('Filter displayed searches')) h.addWidget(ft) self.cft = cft = QToolButton(self) cft.setToolTip(_('Clear filter')), cft.setIcon(QIcon(I('clear_left.png'))) cft.clicked.connect(ft.clear) h.addWidget(cft) l.addLayout(h) self.h2 = h = QHBoxLayout() self.searches = searches = QListView(self) self.stack = stack = QStackedLayout() self.main_widget = mw = QWidget(self) stack.addWidget(mw) self.edit_search_widget = es = EditSearch(mw) stack.addWidget(es) es.done.connect(self.search_editing_done) mw.v = QVBoxLayout(mw) mw.v.setContentsMargins(0, 0, 0, 0) mw.v.addWidget(searches) searches.doubleClicked.connect(self.edit_search) self.model = SearchesModel(self.searches) self.model.dataChanged.connect(self.show_details) searches.setModel(self.model) searches.selectionModel().currentChanged.connect(self.show_details) searches.setSelectionMode(searches.ExtendedSelection) self.delegate = SearchDelegate(searches) searches.setItemDelegate(self.delegate) searches.setAlternatingRowColors(True) h.addLayout(stack, stretch=10) self.v = v = QVBoxLayout() h.addLayout(v) l.addLayout(h) stack.currentChanged.connect(self.stack_current_changed) def pb(text, tooltip=None): b = AnimatablePushButton(text, self) b.setToolTip(tooltip or '') b.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) return b mulmsg = '\n\n' + _('The entries are tried in order until the first one matches.') self.action_button_map = {} for text, action, tooltip in [ (_('&Find'), 'find', _('Run the search using the selected entries.') + mulmsg), (_('&Replace'), 'replace', _('Run replace using the selected entries.') + mulmsg), (_('Replace a&nd Find'), 'replace-find', _('Run replace and then find using the selected entries.') + mulmsg), (_('Replace &all'), 'replace-all', _('Run Replace All for all selected entries in the order selected')), (_('&Count all'), 'count', _('Run Count All for all selected entries')), ]: self.action_button_map[action] = b = pb(text, tooltip) v.addWidget(b) b.clicked.connect(partial(self.run_search, action)) self.d1 = d = QFrame(self) d.setFrameStyle(QFrame.HLine) v.addWidget(d) self.h3 = h = QHBoxLayout() self.upb = b = QToolButton(self) b.setIcon(QIcon(I('arrow-up.png'))), b.setToolTip(_('Move selected entries up')) b.clicked.connect(partial(self.move_entry, -1)) self.dnb = b = QToolButton(self) b.setIcon(QIcon(I('arrow-down.png'))), b.setToolTip(_('Move selected entries down')) b.clicked.connect(partial(self.move_entry, 1)) h.addWidget(self.upb), h.addWidget(self.dnb) v.addLayout(h) self.eb = b = pb(_('&Edit search'), _('Edit the currently selected search')) b.clicked.connect(self.edit_search) v.addWidget(b) self.rb = b = pb(_('Re&move search'), _('Remove the currently selected searches')) b.clicked.connect(self.remove_search) v.addWidget(b) self.ab = b = pb(_('&Add search'), _('Add a new saved search')) b.clicked.connect(self.add_search) v.addWidget(b) self.d2 = d = QFrame(self) d.setFrameStyle(QFrame.HLine) v.addWidget(d) self.where_box = wb = WhereBox(self, emphasize=True) self.where = SearchWidget.DEFAULT_STATE['where'] v.addWidget(wb) self.direction_box = db = DirectionBox(self) self.direction = SearchWidget.DEFAULT_STATE['direction'] v.addWidget(db) self.wr = wr = QCheckBox(_('&Wrap')) wr.setToolTip('<p>'+_('When searching reaches the end, wrap around to the beginning and continue the search')) self.wr.setChecked(SearchWidget.DEFAULT_STATE['wrap']) v.addWidget(wr) self.d3 = d = QFrame(self) d.setFrameStyle(QFrame.HLine) v.addWidget(d) self.description = d = QLabel(' \n \n ') d.setTextFormat(Qt.PlainText) d.setWordWrap(True) mw.v.addWidget(d) self.ib = b = pb(_('&Import'), _('Import saved searches')) b.clicked.connect(self.import_searches) v.addWidget(b) self.eb2 = b = pb(_('E&xport'), _('Export saved searches')) v.addWidget(b) self.em = m = QMenu(_('Export')) m.addAction(_('Export All'), lambda : QTimer.singleShot(0, partial(self.export_searches, all=True))) m.addAction(_('Export Selected'), lambda : QTimer.singleShot(0, partial(self.export_searches, all=False))) b.setMenu(m) self.searches.setFocus(Qt.OtherFocusReason)
class FancyTabWidget(QWidget): # Values are persisted = only add to the end # enum Mode Mode_None = 0 Mode_LargeSidebar = 1 Mode_SmallSidebar = 2 Mode_Tabs = 3 Mode_IconOnlyTabs = 4 Mode_PlainSidebar = 5 def __init__(self, parent=None): super().__init__(parent) self._mode = self.Mode_None self._items = [] # QList<Item> self._tab_bar = None # QWidget self._stack = QStackedLayout() # QStackedLayout self._background_pixmap = QPixmap() self._side_widget = QWidget() # QWidget self._side_layout = QVBoxLayout() # QVBoxLayout self._top_layout = QVBoxLayout() # QVBoxLayout self._use_background = False # bool self._menu = None # QMenu self._proxy_style = FancyTabProxyStyle() # FancyTabProxyStyle self._side_layout.setSpacing(0) self._side_layout.setContentsMargins(0, 0, 0, 0) self._side_layout.addSpacerItem( QSpacerItem(0, 0, QSizePolicy.Fixed, QSizePolicy.Expanding)) self._side_widget.setLayout(self._side_layout) self._side_widget.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Expanding) self._top_layout.setSpacing(0) self._top_layout.setContentsMargins(0, 0, 0, 0) self._top_layout.addLayout(self._stack) main_layout = QHBoxLayout() main_layout.setContentsMargins(0, 0, 0, 0) main_layout.setSpacing(1) main_layout.addWidget(self._side_widget) main_layout.addLayout(self._top_layout) self.setLayout(main_layout) class Item: # enum Type Type_Tab = 0 Type_Spacer = 1 def __init__(self, icon, label): ''' @param: icon QIcon @param: label QString ''' self.type = self.Type_Tab # Type self.tab_label = label # QString self.tab_icon = icon # QIcon self.spacer_size = 0 def AddTab(self, tab, icon, label): ''' @param: tab QWidget @param: icon Qicon @param: label QString ''' self._stack.addWidget(tab) self._items.append(self.Item(icon, label)) def AddSpacer(self, size=40): self._items.append(self.Item(size)) def SetBackgroundPixmap(self, pixmap): ''' @param: pixmap QPixmap ''' self._background_pixmap = pixmap self.update() def AddBottomWidget(self, widget): ''' @param: widget QWidget ''' self._top_layout.addWidget(widget) def current_index(self): ''' @return: int ''' return self._stack.currentIndex() def mode(self): ''' @return: Mode ''' return self._mode def bgPixmap(self): ''' @return: QPixmap ''' return self._background_pixmap bgPixmap = pyqtProperty(QPixmap, bgPixmap, SetBackgroundPixmap) # public Q_SLOTS: def SetCurrentIndex(self, index): bar = self._tab_bar if isinstance(bar, FancyTabBar): bar.setCurrentIndex(index) elif isinstance(bar, QTabBar): bar.setCurrentIndex(index) else: self._stack.setCurrentIndex(index) def SetMode(self, mode): # Remove previous tab bar del self._tab_bar self._tab_bar = None self._use_background = False # Create new tab bar if mode == self.Mode_None: pass elif mode == self.Mode_LargeSidebar: bar = FancyTabBar(self) self._side_layout.insertWidget(0, bar) self._tab_bar = bar for item in self._items: if item.type == self.Item.Type_Spacer: bar.addSpacer(item.spacer_size) else: bar.addTab(item.tab_icon, item.tab_label) bar.setCurrentIndex(self._stack.currentIndex()) bar.currentChanged.connect(self._ShowWidget) self._use_background = True elif mode == self.Mode_Tabs: self._MakeTabBar(QTabBar.RoundedNorth, True, False, False) elif mode == self.Mode_IconOnlyTabs: self._MakeTabBar(QTabBar.RoundedNorth, False, True, False) elif mode == self.Mode_SmallSidebar: self._MakeTabBar(QTabBar.RoundedWest, True, True, True) self._use_background = True elif mode == self.Mode_PlainSidebar: self._MakeTabBar(QTabBar.RoundedWest, True, True, False) else: print('DEBUG: Unknown fancy tab mode %s' % mode) self._tab_bar.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) self._mode = mode self.ModeChanged.emit(mode) self.update() # Q_SIGNALS: CurrentChanged = pyqtSignal(int) # index ModeChanged = pyqtSignal(int) # mode FancyTabWidget::Mode # protected: # override def paintEvent(self, event): ''' @param: event QPaintEvent ''' if not self._use_background: return painter = QPainter(self) rect = self._side_widget.rect().adjusted(0, 0, 1, 0) rect = self.style().visualRect(self.layoutDirection(), self.geometry(), rect) styleHelper.verticalGradient(painter, rect, rect) if not self._background_pixmap.isNull(): pixmap_rect = QRect(self._background_pixmap.rect()) pixmap_rect.moveTo(rect.topLeft()) while pixmap_rect.top() < rect.bottom(): source_rect = QRect(pixmap_rect.intersected(rect)) source_rect.moveTo(0, 0) painter.drawPixmap(pixmap_rect.topLeft(), self._background_pixmap, source_rect) pixmap_rect.moveTop(pixmap_rect.bottom() - 10) painter.setPen(styleHelper.borderColor()) painter.drawLine(rect.topRight(), rect.bottomRight()) # QColor light = styleHelper.sidebarHighlight() painter.setPen(light) painter.drawLine(rect.bottomLeft(), rect.bottomRight()) # override def contextMenuEvent(self, event): ''' @param: event QContextMenuEvent ''' pass # private Q_SLOTS: def _ShowWidget(self, index): self._stack.setCurrentIndex(index) self.CurrentChanged.emit(index) # private: def _MakeTabBar(self, shap, text, icons, fancy): ''' @param: shap QTabBar::Shap @param: text bool @param: icons bool @param: fancy bool ''' bar = QTabBar(self) bar.setShape(shap) bar.setDocumentMode(True) bar.setUsesScrollButtons(True) if shap == QTabBar.RoundedWest: bar.setIconSize(QSize(22, 22)) if fancy: bar.setStyle(self._proxy_style) if shap == QTabBar.RoundedNorth: self._top_layout.insertWidget(0, bar) else: self._side_layout.insertWidget(0, bar) # Item for item in self._items: if item.type != self.Item.Type_Tab: continue label = item.tab_label if shap == QTabBar.RoundedWest: label = QFontMetrics(self.font()).elidedText( label, Qt.ElideMiddle, 100) tab_id = -1 if icons and text: tab_id = bar.addTab(item.tab_icon, label) elif icons: tab_id = bar.addTab(item.tab_icon, '') elif text: tab_id = bar.addTab(label) bar.setTabToolTip(tab_id, item.tab_label) bar.setCurrentIndex(self._stack.currentIndex()) bar.currentChanged.connect(self._ShowWidget) self._tab_bar = bar def _AddMenuItem(self, mapper, group, text, mode): ''' @param: mapper QSignalMapper @param: group QActionGroup @param: text QString @param: mode Mode ''' # QAction action = group.addAction(text) action.setCheckable(True) mapper.setMapping(action, mode) action.triggered.connect(mapper.map) if mode == self._mode: action.setChecked(True)
class Preview(QWidget): sync_requested = pyqtSignal(object, object) split_requested = pyqtSignal(object, object, object) split_start_requested = pyqtSignal() link_clicked = pyqtSignal(object, object) refresh_starting = pyqtSignal() refreshed = pyqtSignal() live_css_data = pyqtSignal(object) render_process_restarted = pyqtSignal() open_file_with = pyqtSignal(object, object, object) edit_file = pyqtSignal(object) def __init__(self, parent=None): QWidget.__init__(self, parent) self.l = l = QVBoxLayout() self.setLayout(l) l.setContentsMargins(0, 0, 0, 0) self.stack = QStackedLayout(l) self.stack.setStackingMode(self.stack.StackAll) self.current_sync_retry_count = 0 self.view = WebView(self) self.view._page.bridge.request_sync.connect(self.request_sync) self.view._page.bridge.request_split.connect(self.request_split) self.view._page.bridge.live_css_data.connect(self.live_css_data) self.view._page.bridge.bridge_ready.connect(self.on_bridge_ready) self.view._page.loadFinished.connect(self.load_finished) self.view._page.loadStarted.connect(self.load_started) self.view.render_process_restarted.connect(self.render_process_restarted) self.pending_go_to_anchor = None self.inspector = self.view.inspector self.stack.addWidget(self.view) self.cover = c = QLabel(_('Loading preview, please wait...')) c.setWordWrap(True) c.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding) c.setStyleSheet('QLabel { background-color: palette(window); }') c.setAlignment(Qt.AlignmentFlag.AlignCenter) self.stack.addWidget(self.cover) self.stack.setCurrentIndex(self.stack.indexOf(self.cover)) self.bar = QToolBar(self) l.addWidget(self.bar) ac = actions['auto-reload-preview'] ac.setCheckable(True) ac.setChecked(True) ac.toggled.connect(self.auto_reload_toggled) self.auto_reload_toggled(ac.isChecked()) self.bar.addAction(ac) ac = actions['sync-preview-to-editor'] ac.setCheckable(True) ac.setChecked(True) ac.toggled.connect(self.sync_toggled) self.sync_toggled(ac.isChecked()) self.bar.addAction(ac) self.bar.addSeparator() ac = actions['split-in-preview'] ac.setCheckable(True) ac.setChecked(False) ac.toggled.connect(self.split_toggled) self.split_toggled(ac.isChecked()) self.bar.addAction(ac) ac = actions['reload-preview'] ac.triggered.connect(self.refresh) self.bar.addAction(ac) actions['preview-dock'].toggled.connect(self.visibility_changed) self.current_name = None self.last_sync_request = None self.refresh_timer = QTimer(self) self.refresh_timer.timeout.connect(self.refresh) parse_worker.start() self.current_sync_request = None self.search = HistoryLineEdit2(self) self.search.initialize('tweak_book_preview_search') self.search.setPlaceholderText(_('Search in preview')) self.search.returnPressed.connect(self.find_next) self.bar.addSeparator() self.bar.addWidget(self.search) for d in ('next', 'prev'): ac = actions['find-%s-preview' % d] ac.triggered.connect(getattr(self, 'find_' + d)) self.bar.addAction(ac) def find(self, direction): text = unicode_type(self.search.text()) self.view._page.findText(text, ( QWebEnginePage.FindFlag.FindBackward if direction == 'prev' else QWebEnginePage.FindFlags(0))) def find_next(self): self.find('next') def find_prev(self): self.find('prev') def go_to_anchor(self, anchor): self.view._page.go_to_anchor(anchor) def request_sync(self, tagname, href, lnum): if self.current_name: c = current_container() if tagname == 'a' and href: if href and href.startswith('#'): name = self.current_name else: name = c.href_to_name(href, self.current_name) if href else None if name == self.current_name: return self.go_to_anchor(urlparse(href).fragment) if name and c.exists(name) and c.mime_map[name] in OEB_DOCS: return self.link_clicked.emit(name, urlparse(href).fragment or TOP) self.sync_requested.emit(self.current_name, lnum) def request_split(self, loc, totals): actions['split-in-preview'].setChecked(False) if not loc or not totals: return error_dialog(self, _('Invalid location'), _('Cannot split on the body tag'), show=True) if self.current_name: self.split_requested.emit(self.current_name, loc, totals) @property def bridge_ready(self): return self.view._page.bridge.ready def sync_to_editor(self, name, sourceline_address): self.current_sync_request = (name, sourceline_address) self.current_sync_retry_count = 0 QTimer.singleShot(100, self._sync_to_editor) def _sync_to_editor(self): if not actions['sync-preview-to-editor'].isChecked() or self.current_sync_retry_count >= 3000 or self.current_sync_request is None: return if self.refresh_timer.isActive() or not self.bridge_ready or self.current_sync_request[0] != self.current_name: self.current_sync_retry_count += 1 return QTimer.singleShot(100, self._sync_to_editor) sourceline_address = self.current_sync_request[1] self.current_sync_request = None self.current_sync_retry_count = 0 self.view._page.go_to_sourceline_address(sourceline_address) def report_worker_launch_error(self): if parse_worker.launch_error is not None: tb, parse_worker.launch_error = parse_worker.launch_error, None error_dialog(self, _('Failed to launch worker'), _( 'Failed to launch the worker process used for rendering the preview'), det_msg=tb, show=True) def name_to_qurl(self, name=None): name = name or self.current_name qurl = QUrl() qurl.setScheme(FAKE_PROTOCOL), qurl.setAuthority(FAKE_HOST), qurl.setPath('/' + name) return qurl def show(self, name): if name != self.current_name: self.refresh_timer.stop() self.current_name = name self.report_worker_launch_error() parse_worker.add_request(name) self.view.set_url(self.name_to_qurl()) return True def refresh(self): if self.current_name: self.refresh_timer.stop() # This will check if the current html has changed in its editor, # and re-parse it if so self.report_worker_launch_error() parse_worker.add_request(self.current_name) # Tell webkit to reload all html and associated resources current_url = self.name_to_qurl() self.refresh_starting.emit() if current_url != self.view.url(): # The container was changed self.view.set_url(current_url) else: self.view.refresh() self.refreshed.emit() def clear(self): self.view.clear() self.current_name = None @property def is_visible(self): return actions['preview-dock'].isChecked() @property def live_css_is_visible(self): try: return actions['live-css-dock'].isChecked() except KeyError: return False def start_refresh_timer(self): if self.live_css_is_visible or (self.is_visible and actions['auto-reload-preview'].isChecked()): self.refresh_timer.start(tprefs['preview_refresh_time'] * 1000) def stop_refresh_timer(self): self.refresh_timer.stop() def auto_reload_toggled(self, checked): if self.live_css_is_visible and not actions['auto-reload-preview'].isChecked(): actions['auto-reload-preview'].setChecked(True) error_dialog(self, _('Cannot disable'), _( 'Auto reloading of the preview panel cannot be disabled while the' ' Live CSS panel is open.'), show=True) actions['auto-reload-preview'].setToolTip(_( 'Auto reload preview when text changes in editor') if not checked else _( 'Disable auto reload of preview')) def sync_toggled(self, checked): actions['sync-preview-to-editor'].setToolTip(_( 'Disable syncing of preview position to editor position') if checked else _( 'Enable syncing of preview position to editor position')) def visibility_changed(self, is_visible): if is_visible: self.refresh() def split_toggled(self, checked): actions['split-in-preview'].setToolTip(textwrap.fill(_( 'Abort file split') if checked else _( 'Split this file at a specified location.\n\nAfter clicking this button, click' ' inside the preview panel above at the location you want the file to be split.'))) if checked: self.split_start_requested.emit() else: self.view._page.split_mode(False) def do_start_split(self): self.view._page.split_mode(True) def stop_split(self): actions['split-in-preview'].setChecked(False) def load_started(self): self.stack.setCurrentIndex(self.stack.indexOf(self.cover)) def on_bridge_ready(self): self.stack.setCurrentIndex(self.stack.indexOf(self.view)) def load_finished(self, ok): self.stack.setCurrentIndex(self.stack.indexOf(self.view)) if self.pending_go_to_anchor: self.view._page.go_to_anchor(self.pending_go_to_anchor) self.pending_go_to_anchor = None if actions['split-in-preview'].isChecked(): if ok: self.do_start_split() else: self.stop_split() def request_live_css_data(self, editor_name, sourceline, tags): if self.view._page.bridge.ready: self.view._page.bridge.live_css(editor_name, sourceline, tags) def apply_settings(self): s = self.view.settings() s.setFontSize(s.DefaultFontSize, tprefs['preview_base_font_size']) s.setFontSize(s.DefaultFixedFontSize, tprefs['preview_mono_font_size']) s.setFontSize(s.MinimumLogicalFontSize, tprefs['preview_minimum_font_size']) s.setFontSize(s.MinimumFontSize, tprefs['preview_minimum_font_size']) sf, ssf, mf = tprefs['engine_preview_serif_family'], tprefs['engine_preview_sans_family'], tprefs['engine_preview_mono_family'] if sf: s.setFontFamily(s.SerifFont, sf) if ssf: s.setFontFamily(s.SansSerifFont, ssf) if mf: s.setFontFamily(s.FixedFont, mf) stdfnt = tprefs['preview_standard_font_family'] or 'serif' stdfnt = getattr(s, {'serif': 'SerifFont', 'sans': 'SansSerifFont', 'mono': 'FixedFont'}[stdfnt]) s.setFontFamily(s.StandardFont, s.fontFamily(stdfnt))
class MiniMarvin(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): self.blockSize = 0 self.ipAddr = QLineEdit(self) self.ipAddrL = QLabel('IP Address: ', self) self.connectButton = QPushButton('Connect', self) self.connectButton.clicked.connect(self.socketConnect) self.statusLabel = QLabel("Not Connected") self.vbox = QVBoxLayout(self) self.vbox.addWidget(self.ipAddrL) self.vbox.addWidget(self.ipAddr) self.vbox.addWidget(self.connectButton) self.vbox.addWidget(self.statusLabel) self.setLayout(self.vbox) self.connected = False self.keylist = [] self.resize(500, 400) self.center() self.setWindowTitle('mini-mARVin') self.show() def openWindow(self): self.window = QMainWindow() self.myGui = App(self.window) self.stacked_layout = QStackedLayout() self.stacked_layout.addWidget(self.myGui) def displayError(self, socketError): self.connected = False if socketError == QAbstractSocket.RemoteHostClosedError: pass else: print( self, "The following error occurred: %s." % self.tcpSocket.errorString()) self.lis.stop() def center(self): '''centers the window on the screen''' screen = QDesktopWidget().screenGeometry() size = self.geometry() self.move((screen.width() - size.width()) / 2, (screen.height() - size.height()) / 2) def socketConnect(self): if (self.connected == False): self.blockSize = 0 self.tcpSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: self.tcpSocket.connect((self.ipAddr.text(), 12000)) self.statusLabel.setText("Connected") self.connectButton.setText("Disconnect") self.connected = True self.openConnection = True self.openWindow() self.lis = keyboard.Listener(on_press=self.on_press) self.lis.start() self.receiveThread = ReceiveThread(self) self.receiveThread.start() except socket.error as eMsg: print("Connection failed." + eMsg) #hi elif (self.connected == True): self.tcpSocket.close() self.statusLabel.setText("Not Connected") self.connectButton.setText("Connect") self.connected = False self.lis.stop() self.receiveThread.join() def on_press(self, key): try: message = '' if key.char == 'w': message = "F" elif key.char == 's': message = "B" elif key.char == 'd': message = "R" elif key.char == 'a': message = "L" elif key.char == 'q': message = "S" print("sending: " + message) self.tcpSocket.sendall(message.encode()) except socket.error as msg: print("excepton in sending or receiving data: " + str(msg)) self.tcpSocket.close() self.statusLabel.setText("Not Connected") self.connectButton.setText("Connect") self.connected = False self.lis.stop() self.recieveThread.join() if key == keyboard.Key.esc: return False #stop listener