def outputContextMenu(self, listview: QListView, pos: QPoint): current_model = listview.model() menu = QMenu() edit_action = QAction( "Edit clicked" if len(listview.selectedIndexes()) > 1 else "Edit", menu) edit_action.triggered.connect(self.editCurrentTarget) menu.addAction(edit_action) delete_action = QAction("Remove", menu) delete_action.triggered.connect(lambda: current_model.__delitem__( [i.row() for i in listview.selectedIndexes()])) menu.addAction(delete_action) selected_istemp = current_model[ listview.currentIndex().row()].temporary mark_temp_action = QAction("Mark temp", menu) mark_temp_action.setCheckable(True) mark_temp_action.setChecked(selected_istemp) mark_temp_action.triggered.connect(lambda: [ current_model[i.row()].switch_temporary(not selected_istemp) for i in listview.selectedIndexes() ]) menu.addAction(mark_temp_action) self.addTargetActions(menu) menu.exec_(listview.mapToGlobal(pos))
class TableWidget(QTableWidget): def __init__(self, parent: Optional[QWidget] = None) -> None: super().__init__(parent) self._context_menu = QMenu(self) self._copy_table_action = self._context_menu.addAction('Copy table to clipboard', self._copyTableActionTriggered) self._copy_row_action = self._context_menu.addAction('Copy row to clipboard', self._copyRowActionTriggered) self.addActions((self._copy_table_action, self._copy_row_action)) def contextMenuEvent(self, event: QEvent) -> None: self._copy_table_action.setEnabled(bool(self.rowCount())) self._copy_row_action.setEnabled(bool(self.selectedItems())) self._context_menu.exec_(self.viewport().mapToGlobal(event.pos())) def _copyRowsToClipboard(self, rows: Iterable[int]) -> None: if not rows or not self.columnCount(): return rows_text = ['\t'.join(self.model().headerData(column, Qt.Horizontal) for column in range(self.columnCount()))] for row in rows: rows_text.append('\t'.join(self.item(row, column).text() for column in range(self.columnCount()))) QApplication.clipboard().setText('\n'.join(rows_text)) def _copyTableActionTriggered(self) -> None: self._copyRowsToClipboard(tuple(range(self.rowCount()))) def _copyRowActionTriggered(self) -> None: selected_rows = sorted({self.row(selected_item) for selected_item in self.selectedItems()}) self._copyRowsToClipboard(selected_rows)
def slot_shot_context_menu(self, pos: QPoint) -> None: menu = QMenu(self.dock) menu.addAction('Copy cursor address', self.copy_cursor_address) menu.addAction('Copy selected bytes', self.copy_selected_bytes) if self.symbols is not None: menu.addAction('Copy symbol at or before cursor address', self.slot_copy_symbol) if abs(self.selected_bytes) == 4: menu.addAction('Copy selected as pointer address', self.copy_selected_pointer_address) menu.addSeparator() menu.addAction('Only mark as pointer', self.mark_as_pointer) if self.is_linked: menu.addAction( 'Mark as pointer in all linked editors and add constraint', self.mark_as_all_pointer) # General actions menu.addSeparator() menu.addAction('Add annotation at cursor', self.open_new_annotation_dialog) menu.addAction('Add manual constraint at cursor', self.open_new_constraint_dialog) if self.is_linked: menu.addAction('Mark selected bytes only in current variant', self.mark_only_in_current) menu.addAction('Goto', self.slot_show_goto_dialog) # Allow plugins to add context menu entries by registering a context menu handler for handler in self.contextmenu_handlers: handler(self, menu) menu.exec_(pos)
def slotHeaderMenu(self, pt): menu = QMenu() menu.addAction("This") menu.addAction("is") menu.addAction("just") menu.addAction("a") menu.addAction("test") menu.exec_(pt)
def showContextMenu(self, pos): if not self.ui.ganttView.leftView().indexAt(pos).isValid(): self.ui.ganttView.selectionModel().clearSelection() menu = QMenu(self.ui.ganttView.leftView()) menu.addAction(self.newEntryAction) menu.addAction(self.removeEntryAction) menu.exec_(self.ui.ganttView.leftView().viewport().mapToGlobal(pos))
def contextMenuEvent(self, e): context = QMenu(self) crap = QAction("thisone", self) crap.triggered.connect(self.fuckthisshit) context.addAction(crap) context.addAction(QAction("test 2", self)) context.addAction(QAction("test 3", self)) context.exec_(e.globalPos())
def constructContextMenu(self, position): globalPosition = self.mapToGlobal(position) menu = QMenu() optionsEntry = QAction('Options', menu) optionsEntry.setData(self.openOptions) def rotate(): mousePosition = QCursor.pos() self.rotate(mousePosition) rotateEntry = QAction('Rotate', menu) rotateEntry.setData(rotate) aboutEntry = QAction('About', menu) aboutEntry.setData(self.openAbout) quitEntry = QAction('Close', menu) quitEntry.setData(self.quit) menu.addAction(optionsEntry) menu.addAction(rotateEntry) menu.addAction(aboutEntry) menu.addAction(quitEntry) selectedItem = menu.exec_(globalPosition) """:type : QAction""" if selectedItem: selectedItem.data()()
def _handle_tab_context_menu(self, point): index = self.tabBar().tabAt(point) if index < 0: return tab_count = len(self._webengineviews) context_menu = QMenu() duplicate_tab_action = context_menu.addAction("Duplicate Tab") close_other_tabs_action = context_menu.addAction("Close Other Tabs") close_other_tabs_action.setEnabled(tab_count > 1) close_tabs_to_the_right_action = context_menu.addAction("Close Tabs to the Right") close_tabs_to_the_right_action.setEnabled(index < tab_count - 1) close_tab_action = context_menu.addAction("&Close Tab") chosen_action = context_menu.exec_(self.tabBar().mapToGlobal(point)) if chosen_action == duplicate_tab_action: current_url = self.url() self.add_browser_tab().load(current_url) elif chosen_action == close_other_tabs_action: for t in range(tab_count - 1, -1, -1): if t != index: self.handle_tab_close_request(t) elif chosen_action == close_tabs_to_the_right_action: for t in range(tab_count - 1, index, -1): self.handle_tab_close_request(t) elif chosen_action == close_tab_action: self.handle_tab_close_request(index)
def inputContextMenu(self, pos: QPoint): menu = QMenu() preview_action = QAction("Preview", menu) preview_action.triggered.connect( lambda: self.previewInput(self.list_input_files.currentItem())) menu.addAction(preview_action) self.addTargetActions(menu) action = menu.exec_(self.list_input_files.mapToGlobal(pos))
def context_menu_event(self, event): context_menu = QMenu() open_in_new_tab_action = context_menu.addAction("Open in New Tab") remove_action = context_menu.addAction("Remove...") current_item = self._current_item() open_in_new_tab_action.setEnabled(current_item is not None) remove_action.setEnabled(current_item is not None) chosen_action = context_menu.exec_(event.globalPos()) if chosen_action == open_in_new_tab_action: self.open_bookmarkInNewTab.emit(current_item.data(_url_role)) elif chosen_action == remove_action: self._remove_item(current_item)
def contextMenuEvent(self, QContextMenuEvent): menu = QMenu() menu.addAction(self.action_fullscreen) menu.addSeparator() menu.addAction(self.action_image_gallery) menu.addSeparator() menu.addAction(self.action_previous_image) menu.addAction(self.action_next_image) menu.addSeparator() menu.addAction(self.action_normal_size) menu.addAction(self.action_fit_screen) menu.addAction(self.action_fit_vertical) menu.addAction(self.action_fit_horizontal) menu.addSeparator() menu.addAction(self.action_zoom_in) menu.addAction(self.action_zoom_out) menu.addSeparator() menu.addAction(self.action_copy) menu.addAction(self.action_move) menu.addSeparator() menu.addAction(self.action_delete) menu.exec_(QContextMenuEvent.globalPos())
def context_menu(self, point): selected = self.keyListView.selectedIndexes() if not selected: return index = selected[0] item = self.list_model.item(index.row()) key = item.data() pop_menu = QMenu() _set_default_key_action = pop_menu.addAction( qta.icon('fa.check', color=icon_color['color'], color_active=icon_color['active']), '设为默认') if key_cache.is_cur_key(key) or key.timeout: _set_default_key_action.setEnabled(False) pop_menu.addSeparator() _encrypt_files_action = pop_menu.addAction( qta.icon('ei.lock', color=icon_color['color'], color_active=icon_color['active']), "加密文件") _decrypt_files_action = pop_menu.addAction( qta.icon('ei.unlock', color=icon_color['color'], color_active=icon_color['active']), "解密文件") pop_menu.addSeparator() _reload_key_action = pop_menu.addAction( qta.icon('fa.refresh', color=icon_color['color'], color_active=icon_color['active']), "重新加载") _reload_key_action.setEnabled(key.timeout) selected_action = pop_menu.exec_(QCursor.pos()) if selected_action == _encrypt_files_action: self.encrypt_files_action() elif selected_action == _set_default_key_action: self.set_default_key_action() elif selected_action == _reload_key_action: self.reload_key_action() elif selected_action == _decrypt_files_action: self.decrypt_files_action()
def contextMenuEvent(self, event): state = self.state() context_menu = QMenu() launch_action = context_menu.addAction("Launch") launch_action.setEnabled(state == QWebEngineDownloadItem.DownloadCompleted) show_in_folder_action = context_menu.addAction("Show in Folder") show_in_folder_action.setEnabled(state == QWebEngineDownloadItem.DownloadCompleted) cancel_action = context_menu.addAction("Cancel") cancel_action.setEnabled(state == QWebEngineDownloadItem.DownloadInProgress) remove_action = context_menu.addAction("Remove") remove_action.setEnabled(state != QWebEngineDownloadItem.DownloadInProgress) chosen_action = context_menu.exec_(event.globalPos()) if chosen_action == launch_action: self._launch() elif chosen_action == show_in_folder_action: path = QFileInfo(self._download_item.path()).absolutePath() DownloadWidget.open_file(path) elif chosen_action == cancel_action: self._download_item.cancel() elif chosen_action == remove_action: self.remove_requested.emit()
def generateMenu(self, pos): print(pos) row_num = -1 for i in self.tableWidget.selectionModel().selection().indexes(): row_num = i.row() menu = QMenu() item1 = menu.addAction(u"选项一") item2 = menu.addAction(u"选项二") item3 = menu.addAction(u"选项三") action = menu.exec_(self.tableWidget.mapToGlobal(pos)) if action == item1: print('您选了选项一,当前行文字内容是:', self.tableWidget.item(row_num, 0).text(), self.tableWidget.item(row_num, 1).text(), self.tableWidget.item(row_num, 2).text()) elif action == item2: print('您选了选项二,当前行文字内容是:', self.tableWidget.item(row_num, 0).text(), self.tableWidget.item(row_num, 1).text(), self.tableWidget.item(row_num, 2).text()) elif action == item3: print('您选了选项三,当前行文字内容是:', self.tableWidget.item(row_num, 0).text(), self.tableWidget.item(row_num, 1).text(), self.tableWidget.item(row_num, 2).text()) else: return
def contextMenuEvent(self, event): menu = QMenu() testAction = QAction("Test", None) testAction.triggered.connect(self.print_out) menu.addAction(testAction) menu.exec_(event.screenPos())
class EvelynDesktop(QStackedWidget): INTERVAL_SECS = 30 ALERT_SECS = 5 signal_get_ping = Signal() signal_post_history = Signal(int, QDateTime) def __init__( self, config_file: str ) -> None: super().__init__() # load config try: self.config = Config(config_file) except Exception as e: QMessageBox.critical(self, 'Config error', str(e)) QTimer.singleShot(0, self.close) return # load settings self.settings = Settings() # state self.state_key: Optional[int] = None # label widget self.label_ping = ClickableLabel('Loading ...', self.post_history) self.label_ping.setTextFormat(Qt.RichText) self.label_ping.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum) layout_ping = QGridLayout() layout_ping.setContentsMargins(0, 0, 0, 0) layout_ping.addWidget(self.label_ping) self.widget_ping = QWidget() self.widget_ping.setLayout(layout_ping) self.addWidget(self.widget_ping) # alert widget self.label_alert = QLabel() self.label_alert.setWordWrap(True) self.label_alert.setAlignment(Qt.AlignCenter) self.label_alert.setStyleSheet(f'background: #dddddd;') self.addWidget(self.label_alert) # context menu self.action_report_done = QAction('Report done ...') self.action_report_done.triggered.connect(self.report_done) self.action_exit = QAction('Exit') self.action_exit.triggered.connect(self.close) self.action_frameless = QAction('Frameless window') self.action_frameless.setCheckable(True) self.action_frameless.triggered.connect(self.set_frameless_window) self.action_homepage = QAction('Open homepage') self.action_homepage.triggered.connect(self.open_homepage) self.context_menu = QMenu() self.context_menu.addAction(self.action_report_done) self.context_menu.addAction(self.action_exit) self.context_menu.addAction(self.action_frameless) self.context_menu.addAction(self.action_homepage) # threads self.thread_communication = QThread() self.thread_communication.start() # workers self.worker_communication = CommunicationWorker( netloc=self.config.netloc, base_path=self.config.base_path, api_key=self.config.api_key, guild=self.config.guild, member=self.config.member) self.worker_communication.moveToThread(self.thread_communication) # signals self.worker_communication.signal_get_ping_done.connect(self.get_ping_done) self.worker_communication.signal_post_history_done.connect(self.post_history_done) self.signal_get_ping.connect(self.worker_communication.get_ping) self.signal_post_history.connect(self.worker_communication.post_history) # get ping timer QTimer.singleShot(0, self.get_ping) self.timer_ping = QTimer() self.timer_ping.timeout.connect(self.get_ping) self.timer_ping.setTimerType(Qt.VeryCoarseTimer) self.timer_ping.start(self.INTERVAL_SECS * 1000) # switch label timer self.timer_label = QTimer() self.timer_label.timeout.connect(lambda: self.setCurrentWidget(self.widget_ping)) self.timer_label.setSingleShot(True) self.timer_label.setTimerType(Qt.CoarseTimer) # window attributes size = self.settings.get('window', 'size', type_=QSize) if size is not None: self.resize(size) pos = self.settings.get('window', 'pos', type_=QPoint) if pos is not None: self.move(pos) frameless = self.settings.get('window', 'frameless', type_=bool) if frameless is not None and frameless: QTimer.singleShot(100, self.action_frameless.trigger) self.setWindowFlag(Qt.WindowStaysOnTopHint, self.config.window_stays_on_top) self.setAttribute(Qt.WA_TranslucentBackground) self.setWindowTitle('Evelyn Reminder') def closeEvent( self, event: QCloseEvent ) -> None: # save settings with suppress_and_log_exception(): self.settings.set('window', 'size', self.size()) self.settings.set('window', 'pos', self.pos()) self.settings.set('window', 'frameless', bool(self.windowFlags() & Qt.FramelessWindowHint)) # stop communication thread with suppress_and_log_exception(): self.thread_communication.quit() self.thread_communication.wait() # done super().closeEvent(event) def contextMenuEvent( self, event: QContextMenuEvent ) -> None: self.context_menu.exec_(event.globalPos()) @Slot() def get_ping(self) -> None: logging.info('Get ping ...') self.signal_get_ping.emit() @Slot(int, str, str) def get_ping_done( self, key: int, text: str, color: str ) -> None: logging.info('Get ping done') if key == -1: self.state_key = None self.label_ping.setWordWrap(True) else: self.state_key = key self.label_ping.setWordWrap(False) self.label_ping.setText(text) self.widget_ping.setStyleSheet(f'background : {color}; ') @Slot() def post_history( self, date_time: QDateTime = QDateTime() ) -> None: # this method is called as Slot by ClickableLabel.mouseReleaseEvent() without arguments # this method is called directly by EvelynDesktop.report_done() with a date_time if self.state_key is None: return logging.info('Post history ...') self.label_alert.setText('Sending ...') self.label_alert.setStyleSheet(f'background: #dddddd;') self.setCurrentWidget(self.label_alert) self.signal_post_history.emit(self.state_key, date_time) @Slot(str, bool) def post_history_done( self, text: str, error: bool ) -> None: logging.info('Post history done') self.label_alert.setText(text) if error: self.label_alert.setStyleSheet(f'background: #dd4b4b;') self.timer_label.start(self.ALERT_SECS * 1000) # trigger instant ping update to avoid outdated info self.timer_ping.stop() self.timer_ping.start(self.INTERVAL_SECS * 1000) self.get_ping() @Slot() def report_done(self) -> None: self.timer_ping.stop() # stop ping update while dialog is open report_done_dialog = ReportDoneDialog(self) response = report_done_dialog.exec() if response != QDialog.Accepted: self.timer_ping.start(self.INTERVAL_SECS * 1000) self.get_ping() return date_time = report_done_dialog.get_date_time() self.post_history(date_time) @Slot(bool) def set_frameless_window( self, value: bool ) -> None: pos = self.pos() self.setWindowFlag(Qt.FramelessWindowHint, value) # workaround: window goes invisible otherwise self.setVisible(True) # workaround: window would move up otherwise if value: QTimer.singleShot(100, lambda: self.move(pos)) @Slot() def open_homepage(self) -> None: webbrowser.open('https://github.com/stefs/evelyn-reminder')
class EntryWidget(TritonWidget): def __init__(self, base, account): TritonWidget.__init__(self, base) self.account = account self.type = account['type'] self.name = account['name'] self.icon = account['icon'].replace('\\', '/') self.timer = None self.secretWidget = None self.iconWidget = None self.closeEvent = self.widgetDeleted self.boxLayout = QHBoxLayout(self) self.boxLayout.setContentsMargins(0, 0, 0, 0) self.image = QLabel() self.image.setFixedSize(48, 48) self.reloadIcon() self.detailWidget = QWidget() self.detailLayout = QVBoxLayout(self.detailWidget) self.detailLayout.setContentsMargins(0, 0, 0, 0) self.nameLabel = EditableLabel(True, None) self.nameLabel.callback = self.renameAccount self.nameLabel.setText(self.name) self.nameLabel.setAlignment(Qt.AlignTop) self.nameLabel.setFont(QFont('Helvetica', 11)) self.passLabel = EditableLabel(False, self.openPassLabel) self.passLabel.disableEdit() self.passLabel.setAlignment(Qt.AlignBottom) self.detailLayout.addWidget(self.nameLabel) self.detailLayout.addWidget(self.passLabel) self.showButton = PixmapButton(QPixmap('icons/RefreshIcon.png').scaled(48, 48)) self.showButton.clicked.connect(self.buttonPressed) self.timerProgress = QRoundProgressBar() self.timerProgress.setBarStyle(QRoundProgressBar.BarStyle.PIE) self.timerProgress.setFixedSize(48, 48) self.timerProgress.setFormat('') self.timerProgress.mouseReleaseEvent = self.buttonPressed palette = QPalette() brush = QBrush(QColor(155, 183, 214)) brush.setStyle(Qt.SolidPattern) palette.setBrush(QPalette.Active, QPalette.Highlight, brush) self.timerProgress.setPalette(palette) self.timerProgress.hide() self.boxLayout.addWidget(self.image) self.boxLayout.addSpacing(5) self.boxLayout.addWidget(self.detailWidget) self.boxLayout.addWidget(self.showButton, 0, Qt.AlignRight) self.boxLayout.addWidget(self.timerProgress, 0, Qt.AlignRight) self.setFixedSize(360, 48) self.hidePassword() self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.openContextMenu) self.menu = QMenu(self) self.removeAction = QAction('Remove') self.removeAction.triggered.connect(self.removeAccount) self.iconAction = QAction('Edit icon') self.iconAction.triggered.connect(self.editIcon) self.showAction = QAction('Show secret key') self.showAction.triggered.connect(self.showSecretKey) self.menu.addAction(self.removeAction) self.menu.addSeparator() self.menu.addAction(self.iconAction) self.menu.addAction(self.showAction) def getValue(self): return self.base.getAuthCode(self.account) def widgetDeleted(self, *args): self.stopTimer() self.name = None self.account = None def buttonPressed(self, *args): if not self.timer: self.showPassword() def openPassLabel(self, *args): self.buttonPressed() self.passLabel.mouseDoubleClickEvent() def openContextMenu(self, point): self.menu.exec_(self.mapToGlobal(point)) def reloadIcon(self): pixmap = QPixmap(self.icon).scaled(48, 48) self.image.setPixmap(pixmap) def stopTimer(self): if self.timer: self.timer.stop() self.timer = None def hidePassword(self): font = QFont('Helvetica', 10, weight=QFont.Bold) font.setLetterSpacing(QFont.PercentageSpacing, 110) self.stopTimer() self.passLabel.setText('* ' * 5) self.passLabel.setFont(font) self.passLabel.disableEdit() self.showButton.show() self.timerProgress.hide() def showPassword(self): font = QFont('Helvetica', 13, weight=QFont.Bold) font.setLetterSpacing(QFont.PercentageSpacing, 110) self.passLabel.setText(self.getValue()) self.passLabel.setFont(font) self.passLabel.enableEdit() self.showButton.hide() self.timerProgress.show() self.timerEnd = time.time() + 15 if not self.timer: self.timerProgress.setValue(100) self.timer = QTimer() self.timer.timeout.connect(self.updateProgress) self.timer.start(100) def updateProgress(self): if self.timerProgress.isHidden() or self.timerEnd <= time.time(): self.hidePassword() return delta = (self.timerEnd - time.time()) / 15 * 100 self.timerProgress.setValue(delta) def removeAccount(self): reply = QMessageBox.question(self, self.name, 'ATTENTION! Deleting this account is an irreversible action!\n\nAre you absolutely sure?', QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: self.base.deleteAccount(self.account) def renameAccount(self, name): index = self.base.getAccountIndex(self.account) self.account['name'] = name self.base.setAccount(index, self.account) def editIcon(self): self.iconWidget = EditIconWidget(self.base, self.name, self.editIconCallback) def editIconCallback(self, icon): index = self.base.getAccountIndex(self.account) self.icon = icon.replace('\\', '/') self.account['icon'] = icon self.base.setAccount(index, self.account) self.reloadIcon() def showSecretKey(self): if self.type == Globals.OTPAuth: keys = [ ('Key', self.account['key']) ] elif self.type == Globals.SteamAuth: keys = [ ('Steam ID', self.account['steamId']), ('Shared Secret', self.account['sharedSecret']), ('Identity Secret', self.account['identitySecret']) ] else: keys = [] self.secretWidget = ShowSecretWidget(self.base, keys, self.name)