def contextMenuEvent(self, event): index = self.indexAt(event.pos()) item = self.model().get_item(index) children = item.child_count() if index.column() == KEY_COL and children: menu = QMenu(self) collapse = menu.addAction('Collapse All') expand = menu.addAction('Expand All') check = None uncheck = None if children: menu.addSeparator() check = menu.addAction('Check All') uncheck = menu.addAction('Uncheck All') action = menu.exec_(QCursor.pos()) if action == collapse: self.collapse_selection(item, index) elif action == expand: self.expand_selection(item, index) elif action == check: self.itemDelegateForColumn(STATUS_COL).setChildData( item, True) self.itemDelegateForColumn(STATUS_COL).updateModel(index) elif action == uncheck: self.itemDelegateForColumn(STATUS_COL).setChildData( item, False) self.itemDelegateForColumn(STATUS_COL).updateModel(index)
def _setup_difficulties_menu(self): game = default_database.default_prime2_game_description() for i, trick_level in enumerate(LayoutTrickLevel): if trick_level not in { LayoutTrickLevel.NO_TRICKS, LayoutTrickLevel.MINIMAL_RESTRICTIONS }: difficulty_action = QAction(self) difficulty_action.setText(trick_level.long_name) self.menu_difficulties.addAction(difficulty_action) difficulty_action.triggered.connect( functools.partial(self._open_difficulty_details_popup, trick_level)) configurable_tricks = TrickLevelConfiguration.all_possible_tricks() tricks_in_use = used_tricks(game.world_list) for trick in sorted(game.resource_database.trick, key=lambda _trick: _trick.long_name): if trick.index not in configurable_tricks or trick not in tricks_in_use: continue trick_menu = QMenu(self) trick_menu.setTitle(trick.long_name) self.menu_trick_details.addAction(trick_menu.menuAction()) used_difficulties = difficulties_for_trick(game.world_list, trick) for i, trick_level in enumerate(LayoutTrickLevel): if trick_level in used_difficulties: difficulty_action = QAction(self) difficulty_action.setText(trick_level.long_name) trick_menu.addAction(difficulty_action) difficulty_action.triggered.connect( functools.partial(self._open_trick_details_popup, trick, trick_level))
def main(): basePath = os.path.dirname(os.path.realpath(__file__)) app = QApplication(sys.argv) contextMenu = QMenu() fixAction = QAction( "Run 'create__ap --fix-unmanaged' in the terminal as root to fix possible issues" ) contextMenu.addAction(fixAction) activeIcon = QIcon() activeIcon.addFile(os.path.join(basePath, "wifi.svg")) inactiveIcon = QIcon() inactiveIcon.addFile(os.path.join(basePath, "wifi-off.svg")) trayIcon = QSystemTrayIcon(inactiveIcon) trayIcon.setContextMenu(contextMenu) trayIcon.activated.connect(handleTrayIconClick) def syncIcon(): if serviceIsActive(): trayIcon.setIcon(activeIcon) else: trayIcon.setIcon(inactiveIcon) timer = QTimer() timer.setInterval(1000) timer.timeout.connect(syncIcon) timer.start() trayIcon.show() sys.exit(app.exec_())
def mouseDoubleClickEvent(self, e): add_relationships_menu = QMenu(self._spine_db_editor) title = TitleWidgetAction("Add relationships", self._spine_db_editor) add_relationships_menu.addAction(title) add_relationships_menu.triggered.connect(self._start_relationship) self._populate_add_relationships_menu(add_relationships_menu) add_relationships_menu.popup(e.screenPos())
def initUI(self): self.statusBar().showMessage('准备就绪') self.setGeometry(300, 300, 400, 200) self.setWindowTitle('test') exitact = QAction(QIcon('picture.jpeg'), '退出(&E)', self) exitact.setShortcut('Ctrl+Q') exitact.setStatusTip('退出程序') exitact.triggered.connect(qApp.quit) savemenu = QMenu('保存方式(&S)', self) saveact = QAction(QIcon('picture.jpeg'), '保存...', self) saveact.setShortcut("Ctrl+S") saveact.setStatusTip('保存文件') savesact = QAction(QIcon('picture.jpeg'), '另存为...(&O)', self) savesact.setStatusTip('文件另存为') savemenu.addAction(saveact) savemenu.addAction(savesact) newact = QAction(QIcon('picture.jpeg'), '新建(&N)', self) newact.setShortcut('Ctrl+N') menubar = self.menuBar() fileMenu = menubar.addMenu('文件(&F)') fileMenu.addAction(newact) fileMenu.addMenu(savemenu) fileMenu.addSeparator() fileMenu.addAction(exitact) self.show()
class Menubar(QMenuBar): def __init__(self, parent=None): super().__init__(parent) self.connect_db = ConnectDatabase(parent) self.init_menubar_menus() def init_menubar_menus(self): self.menu_icon = QMenu("Logo", self) self.logo = QIcon("view/images/branding/zephyrus_transparent.png") self.menu_icon.setIcon(self.logo) self.file_menu = QMenu("File", self) self.edit_menu = QMenu("Edit", self) self.database_menu = QMenu("Database", self) self.view_menu = QMenu("View", self) self.help_menu = QMenu("Help", self) self.theme_menu = QMenu("Theme", self.view_menu) self.addMenu(self.menu_icon) self.addMenu(self.file_menu) self.addMenu(self.edit_menu) self.addMenu(self.database_menu) self.addMenu(self.view_menu) self.addMenu(self.help_menu) self.view_menu.addMenu(self.theme_menu) connect_db_action = QAction(QIcon("view/images/menubar/database-connect.png"), "Connect Database", self) connect_db_action.setStatusTip("Connect a new database") connect_db_action.triggered.connect(self.connect_db.show) self.database_menu.addAction(connect_db_action) self.help_menu.addAction("About", self.about_page) def about_page(self): webbrowser.open("https://university-collab.github.io/zephyrus/")
class ObjectTree(QTreeView): def __init__(self, parent=None): super(ObjectTree, self).__init__(parent) self.menu = QMenu(parent=self) self.create_context_menu() def create_context_menu(self): self.action_export_buffer = QAction("Export buffer", self) self.menu.addAction(self.action_export_buffer) #self.action_export_hex = QAction("Export as hex string", self) #self.menu.addAction(self.action_export_hex) def setModel(self, model: PySide2.QtCore.QAbstractItemModel): super(ObjectTree, self).setModel(model) self.expandAll() def mouseReleaseEvent(self, event: PySide2.QtGui.QMouseEvent): if event.button() == Qt.RightButton: index = self.indexAt(event.pos()) if index.isValid(): node = index.internalPointer() action = self.menu.exec_(self.mapToGlobal(event.pos())) if action == self.action_export_buffer: file_path, _ = QFileDialog.getSaveFileName( self, "Save file") file = open(file_path, "wb") file.write(node.buffer) file.close() else: super(ObjectTree, self).mouseReleaseEvent(event)
def contextMenuEvent(self, event): state = self.state() contextMenu = QMenu() launchAction = contextMenu.addAction("Launch") launchAction.setEnabled( state == QWebEngineDownloadItem.DownloadCompleted) showInFolderAction = contextMenu.addAction("Show in Folder") showInFolderAction.setEnabled( state == QWebEngineDownloadItem.DownloadCompleted) cancelAction = contextMenu.addAction("Cancel") cancelAction.setEnabled( state == QWebEngineDownloadItem.DownloadInProgress) removeAction = contextMenu.addAction("Remove") removeAction.setEnabled( state != QWebEngineDownloadItem.DownloadInProgress) chosenAction = contextMenu.exec_(event.globalPos()) if chosenAction == launchAction: self._launch() elif chosenAction == showInFolderAction: DownloadWidget.openFile( QFileInfo(self._downloadItem.path()).absolutePath()) elif chosenAction == cancelAction: self._downloadItem.cancel() elif chosenAction == removeAction: self.removeRequested.emit()
def contextMenuEvent(self, event): src, dir = self.nav.mouse_src_dir() ### menu = QMenu(self) actionDelVtx = None actionAddVtx = None actionEdgeBezier = None actionAddSquare = None if self.cadobj.ivtx_picked() != -1: actionDelVtx = menu.addAction("delete vtx") elif self.cadobj.iedge_picked() != -1: actionAddVtx = menu.addAction("add vtx") edge_type = self.cadobj.edge_type(self.cadobj.iedge_picked()) if edge_type == 0: actionEdgeBezier = menu.addAction("set bezier") else: actionAddSquare = menu.addAction("add square") #### action = menu.exec_(self.mapToGlobal(event.pos())) if action == actionAddVtx != None: self.cadobj.add_vtx_edge(iedge=self.cadobj.ccad.iedge_picked, pos=[src[0], src[1]]) if action == actionAddSquare != None: x0, y0 = src[0], src[1] self.cadobj.add_polygon([ x0 - 1, y0 - 1, x0 + 1, y0 - 1, x0 + 1, y0 + 1, x0 - 1, y0 + 1 ]) self.cadobj.remesh() if action == actionEdgeBezier != None: self.cadobj.set_edge_type(self.cadobj.iedge_picked(), 1, [0.2, 0.3, -0.2, 0.3]) self.update() self.updated_cadmshfem.emit()
class ViewMenuButton(QPushButton): sig_action = None def __init__(self, btn_name: str, show_field, actions_map: list): """ Creates a QPushButton with a dropdown menu on it. :param btn_name: Button name (always displayed) :type btn_name: str :param actions_map: list of actions to put in the dropdown menu [(action_name, action_key), (separator_name), ...] :type actions_map: list :param show_field: entry field to display on create operations :type show_field: function """ QPushButton.__init__(self, btn_name) self.menu = QMenu(self) for a in actions_map: if a == 'sep': # This is a separator self.menu.addSeparator() else: # Regular action t, k = a if k.startswith( 'create_' ): # If we have a create feature, we display the entry field self.menu.addAction(t, lambda k=k: show_field(k)) else: self.menu.addAction(t, lambda k=k: self.sig_action.emit(k)) self.setMenu(self.menu) self.menu.setStyleSheet(get_stylesheet("menu"))
class View(MVPBase.BaseView): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) def start(self): super().start() # File Menu self.file_menu = QMenu("&File") self.file_menu_quit = QAction("E&xit", self.file_menu) self.file_menu.addAction(self.file_menu_quit) # Window Menu self.view_menu = QMenu("&View") act = QAction("&Labeler", self.view_menu) act.setData("labeler") self.view_menu.addAction(act) act = QAction("&Test", self.view_menu) act.setData("test") self.view_menu.addAction(act) act = QAction("&Options", self.view_menu) act.setData("options") self.view_menu.addAction(act) # Edit Menu self.edit_menu = QMenu("&Edit") self.edit_menu.addAction("delete") # Add them all self.parent.window.menuBar().addMenu(self.file_menu) self.parent.window.menuBar().addMenu(self.view_menu) self.parent.window.menuBar().addMenu(self.edit_menu)
def onCustomContextMenu(self, localPosition: QPoint): """ Show a custom context menu with a "Download file" action when a file is right-clicked. :param localPosition: position where the user clicked. """ selectedFile = self.selectedFile() if selectedFile is None: return globalPosition = self.listWidget.mapToGlobal(localPosition) downloadAction = QAction("Download file") downloadAction.setEnabled(selectedFile.type in [FileSystemItemType.File]) downloadAction.triggered.connect(self.downloadFile) downloadRecursiveAction = QAction("Download files recursively") downloadRecursiveAction.setEnabled(selectedFile.type in [FileSystemItemType.Directory]) downloadRecursiveAction.triggered.connect(self.downloadDirectoryRecursively) itemMenu = QMenu() itemMenu.addAction(downloadAction) itemMenu.addAction(downloadRecursiveAction) itemMenu.exec_(globalPosition)
def __init__(self, parent=None): QSystemTrayIcon.__init__(self, parent) # タスクトレイアイコン クリックメニュー登録 menu = QMenu(parent) qt_action = menu.addAction("Status") qt_action.triggered.connect(self.Message) menu.addSeparator() quit_action = menu.addAction("&Quit") quit_action.triggered.connect(self.Quit) # タスクトレイアイコン クリックメニュー設定 self.setContextMenu(menu) # 初期アイコン設定 self.setIcon(QIcon(str(Path(script_path / 'icon.jpg').resolve()))) # run competitive companion server if not shutil.which('node'): QMessageBox.critical(None, "error", "node not found", QMessageBox.Ok) sys.exit() # elif socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect_ex(('127.0.0.1', 8080)) != 0: # QMessageBox.critical(None, "error", "port:8080 is alreday in use", QMessageBox.Ok) # sys.exit() else: self.proc = subprocess.Popen( ['node', str(Path(script_path / 'index.js').resolve())])
def chooseFileContextMenu(self): if hasattr(self, 'dataDisplay'): menu = QMenu(self) addStatementAction = QAction('Add Statement') addStatementAction.triggered.connect(self.addFile) menu.addAction(addStatementAction) menu.exec_(QCursor.pos())
def _setup_difficulties_menu(self, game: RandovaniaGame, menu: QtWidgets.QMenu): from randovania.game_description import default_database game = default_database.game_description_for(game) tricks_in_use = used_tricks(game) menu.clear() for trick in sorted(game.resource_database.trick, key=lambda _trick: _trick.long_name): if trick not in tricks_in_use: continue trick_menu = QtWidgets.QMenu(self) trick_menu.setTitle(trick.long_name) menu.addAction(trick_menu.menuAction()) used_difficulties = difficulties_for_trick(game, trick) for i, trick_level in enumerate(iterate_enum(LayoutTrickLevel)): if trick_level in used_difficulties: difficulty_action = QtWidgets.QAction(self) difficulty_action.setText(trick_level.long_name) trick_menu.addAction(difficulty_action) difficulty_action.triggered.connect( functools.partial(self._open_trick_details_popup, game, trick, trick_level))
class Window(QMainWindow): def __init__(self, ui_file, parent=None): super(Window, self).__init__(parent) ui_file = QFile(ui_file) ui_file.open(QFile.ReadOnly) loader = QUiLoader() self.window = loader.load(ui_file) ui_file.close() self.line = self.window.findChild(QLineEdit, 'lineEdit') # btn = self.window.findChild(QPushButton, 'pushButton') # btn.clicked.connect(self.btn_handler) self.window.pushButton.clicked.connect(self.btn_handler) # tBtn = self.window.findChild(QToolButton,'toolButton') self.makeOptionButton() # self.window.resizeEvent = types.MethodType(self.window.resizeEvent, QResizeEvent)#.__get__(self.window, QMainWindow) self.window.show() def btn_handler(self): self.window.hide() cameraview = MyGui() cameraview.show() #CameraView("cameraview.ui") def makeOptionButton(self): self.menu = QMenu() self.testAction = QAction("Options", self) self.menu.addAction(self.testAction) self.window.toolButton.setMenu(self.menu) self.window.toolButton.setPopupMode(QToolButton.InstantPopup)
class SystemTray(QSystemTrayIcon): def __init__(self, app): super(SystemTray, self).__init__() self.app = app self.systemTray = QSystemTrayIcon( QIcon(f"{sys.argv[0]}/assets/app_icon.png")) self.trayMenu = QMenu() self.systemTray.setContextMenu(self.trayMenu) self.menu_title_setup() self.open_action_setup() self.exit_action_setup() self.systemTray.show() def menu_title_setup(self): self.trayMenu.menuTitle = self.trayMenu.addAction("Saharah Paper") self.trayMenu.menuTitle.setEnabled(False) self.trayMenu.addSeparator() def open_action_setup(self): self.trayMenu.openAction = self.trayMenu.addAction("Settings") self.trayMenu.openAction.triggered.connect(self.handle_open) def handle_open(self): self.app.mainWindow.show() def exit_action_setup(self): self.trayMenu.exitAction = self.trayMenu.addAction("Exit") self.trayMenu.exitAction.triggered.connect(self.app.quit)
def get_actions(self, actions_dict, menu): actions = [] for k in actions_dict: v_dict = actions_dict[k] try: method = v_dict['method'] data = None try: data = v_dict['data'] except KeyError: pass action = NodeInstanceAction(k, menu, data) action.triggered_with_data.connect( method) # see NodeInstanceAction for explanation action.triggered_without_data.connect( method) # see NodeInstanceAction for explanation actions.append(action) except KeyError: action_menu = QMenu(k, menu) sub_actions = self.get_actions(v_dict, action_menu) for a in sub_actions: action_menu.addAction(a) actions.append(action_menu) return actions
def createSettingsMenu(self): self.applicationSettingsAction = QAction("Settings", self) settingsManagerMenu = QMenu("Settings") settingsManagerMenu.addAction(self.applicationSettingsAction) return settingsManagerMenu
def _create_tray_icon(self): menu = QMenu() self._mode_group = QActionGroup(menu) self._mode_group.triggered.connect(self._mode_changed) self._mode_off = QAction("&Off", parent=menu) self._mode_off.setCheckable(True) self._mode_off.setChecked(True) self._mode_group.addAction(self._mode_off) menu.addAction(self._mode_off) self._mode_enabled = QAction("&Enabled", parent=menu) self._mode_enabled.setCheckable(True) self._mode_group.addAction(self._mode_enabled) menu.addAction(self._mode_enabled) self._mode_training = QAction("&Training mode", parent=menu) self._mode_training.setCheckable(True) self._mode_group.addAction(self._mode_training) menu.addAction(self._mode_training) menu.addSeparator() menu.addAction("&Preferences", self.open_preferences) menu.addSeparator() menu.addAction("E&xit", self.exit) pixmap = QPixmap(32, 32) pixmap.fill(Qt.white) icon = QIcon(pixmap) self._tray_icon = QSystemTrayIcon(parent=self) self._tray_icon.setContextMenu(menu) self._tray_icon.setIcon(icon) self._tray_icon.show()
class WorkspaceChooser(QListWidget): def __init__(self, algManager, parent=None): QListWidget.__init__(self, parent) self.algManager = algManager self._createPopupMenu() def _createPopupMenu(self): self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.onContextMenu) self.algorithmMenu = QMenu(None) self.algorithmMenu.addAction("Adjust parameters...", self.adjustAlgorithm) def onContextMenu(self, pos): self.clickedItem = self.itemAt(pos) if self.clickedItem is None: return if self.clickedItem.data(1)[:9] == 'Algorithm': self.algorithmMenu.exec_(self.mapToGlobal(pos)) def adjustAlgorithm(self): wsName = self.clickedItem.text() self.algManager.adjustAlogrithmParameters(wsName)
def _show_table_context_menu(self, pos): menu = QMenu(self._ui.map_table_view) menu.addAction("Insert row before") menu.addAction("Insert row after") menu.addAction("Remove row") menu.addSeparator() menu.addAction("Append column") menu.addAction("Trim columns") global_pos = self._ui.map_table_view.mapToGlobal(pos) action = menu.exec_(global_pos) if action is None: return action_text = action.text() selected_indexes = self._ui.map_table_view.selectedIndexes() selected_rows = sorted([index.row() for index in selected_indexes]) first_row = selected_rows[0] if action_text == "Insert row before": self._model.insertRows(first_row, 1) elif action_text == "Insert row after": self._model.insertRows(first_row + 1, 1) elif action_text == "Remove row": self._model.removeRows(first_row, 1) elif action_text == "Append column": self._model.append_column() elif action_text == "Trim columns": self._model.trim_columns()
def get_synchronize_with_submenu(self) -> QMenu: """ Get submenu for 'Synchronize with' context menu. """ mnu = QMenu("&Synchronize with", self) groups = { v.sync_state for v in self.workspace.view_manager.views if (v is not self) and isinstance(v, SynchronizedView) } if len(groups) == 0: act = QAction('None available', self) act.setEnabled(False) mnu.addAction(act) else: for group in groups: act = QAction( ', '.join( [v.caption for v in group.views if v is not self]), self) act.setCheckable(True) act.setChecked(group is self.sync_state) act.toggled.connect( lambda checked, s=group: self.sync_with_state_object( s if checked else None)) mnu.addAction(act) return mnu
def contextMenuEvent(self, event): """Context menu of tab options. """ tab_index = self.tabBar().tabAt(event.pos()) tab_menu = None # Currently over a tab if tab_index > -1: #rename_action = QAction("Rename", self) #rename_action.triggered.connect(self._setNewTabName(tab_index)) remove_tab_action = QAction( QIcon(os.path.join('images', 'edit-delete.png')), "Close", self) remove_tab_action.triggered.connect( self._removeSelectedTab(tab_index)) tab_menu = QMenu(self) #tab_menu.addAction(rename_action) tab_menu.addSeparator() tab_menu.addAction(remove_tab_action) if tab_index == 0: remove_tab_action.setDisabled(True) # In tab bar, but not over any tabs else: new_page_action = QAction("Insert New Page", self) new_page_action.triggered.connect(self.newPage) tab_menu = QMenu(self) tab_menu.addAction(new_page_action) tab_menu.exec_(event.globalPos()) self.focusInEvent(QFocusEvent(QEvent.FocusIn))
def _handleTabContextMenu(self, point): index = self.tabBar().tabAt(point) if index < 0: return tabCount = len(self._webengineviews) contextMenu = QMenu() duplicateTabAction = contextMenu.addAction("Duplicate Tab") closeOtherTabsAction = contextMenu.addAction("Close Other Tabs") closeOtherTabsAction.setEnabled(tabCount > 1) closeTabsToTheRightAction = contextMenu.addAction( "Close Tabs to the Right") closeTabsToTheRightAction.setEnabled(index < tabCount - 1) closeTabAction = contextMenu.addAction("&Close Tab") chosenAction = contextMenu.exec_(self.tabBar().mapToGlobal(point)) if chosenAction == duplicateTabAction: currentUrl = self.url() self.addBrowserTab().load(currentUrl) elif chosenAction == closeOtherTabsAction: for t in range(tabCount - 1, -1, -1): if t != index: self.handleTabCloseRequest(t) elif chosenAction == closeTabsToTheRightAction: for t in range(tabCount - 1, index, -1): self.handleTabCloseRequest(t) elif chosenAction == closeTabAction: self.handleTabCloseRequest(index)
class ButtonOptions(QPushButton): def __init__(self, parent, options, main_icon_path): super().__init__(parent) self.main_icon_path = main_icon_path self.options = options self.menu = QMenu(self) self.setIcon(QIcon(self.main_icon_path)) self.setIconSize(QSize(22, 22)) self.clicked.connect(self.showMenu) self.set_menu() def set_menu(self): for option in self.options: button = QAction(QIcon(option["icon"]), option["text"], self.parent()) button.setToolTip(option['tooltip']) button.parm = str(option["parm"]) button.callback = option["callback"] button.triggered.connect(self._call_callback_for_parm) self.menu.addAction(button) self.setMenu(self.menu) def _call_callback_for_parm(self): sender = self.sender() sender.callback(sender.parm)
def set_menu(self, _): delete_option = QMenu() delete_option.addAction( QAction("删除", delete_option, triggered=self.delete_table_thread.start)) delete_option.exec_(QCursor.pos())
def _build_menu(self): menu = QMenu() self.connect_action = QAction('Connect') self.disconnect_action = QAction('Disconnect') self.config_action = QAction('Config') self.logs_action = QAction('Logs') self.exit_action = QAction('Exit') self.disconnect_action.setDisabled(True) self.connect_action.triggered.connect(self._click_connect) self.disconnect_action.triggered.connect(self._click_disconnect) self.config_action.triggered.connect(self._click_config) self.logs_action.triggered.connect(self._click_logs) self.exit_action.triggered.connect(self._click_exit) menu.addAction(self.connect_action) menu.addAction(self.disconnect_action) menu.addSeparator() menu.addAction(self.config_action) menu.addAction(self.logs_action) menu.addSeparator() menu.addAction(self.exit_action) return menu
def contextMenuEvent(self, event): contextMenu = QMenu(self) row = self.rowAt(event.pos().y()) reg = self.item(row, 0).text() unsetRegAction = QAction("Cancel symbolization", self) symRegAction = QAction("Symbolize Register", self) if reg in self.symRegs: contextMenu.addAction(unsetRegAction) else: contextMenu.addAction(symRegAction) action = contextMenu.exec_(self.viewport().mapToGlobal(event.pos())) if action == symRegAction: text, ok = QInputDialog.getText(self, "Symbolize register", "Size(bytes):") if ok: size = int(text) else: size = 8 self.symRegs[reg] = size self.updateContents() elif action == unsetRegAction: del self.symRegs[reg] self.updateContents()
class MyItem(QGraphicsItem): def __init__(self, _id): super(MyItem, self).__init__() self.setFlag(QGraphicsItem.ItemIsMovable) self.itemId = _id self.scaleFactor = 1 def paint(self, painter, options, widget): painter.scale(self.scaleFactor, self.scaleFactor) rect = self.boundingRect() if self.itemId == 1: pen = QPen(Qt.red, 2) painter.drawRect(rect) else: pen = QPen(Qt.blue, 2) painter.drawEllipse(rect) def setScaleFactor(self, value): self.scaleFactor = value self.update() def boundingRect(self): return QRectF(0, 0, 100, 100) def contextMenuEvent(self, event): self.menu = QMenu() self.action = QAction(f'Item {self.itemId}') self.menu.addAction(self.action) self.menu.exec_(event.screenPos())
def testMenu(self): self._actionDestroyed = False w = QWidget() menu = QMenu(w) act = menu.addAction("MENU") _ref = weakref.ref(act, self.actionDestroyed) act = None self.assertFalse(self._actionDestroyed) menu.clear() self.assertTrue(self._actionDestroyed)
def contextMenuEvent(self, event): i=self.indexAt(event.pos()) #print(self.indexAt(event.pos())) menu = QMenu(self) deleteAction = menu.addAction("删除") pasteAction = menu.addAction("粘贴") action = menu.exec_(self.mapToGlobal(event.pos())) if action == deleteAction: p=self.parent() while p!=None: oldp=p p=p.parent() oldp.treat_delete(self.model().filePath(i)) elif action == pasteAction: p=self.parent() while p!=None: oldp=p p=p.parent() oldp.treat_paste(self.model().filePath(i))
def context_menu_event(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: DownloadWidget.open_file(QFileInfo(self._download_item.path()).absolutePath()) elif chosen_action == cancel_action: self._download_item.cancel() elif chosen_action == remove_action: self.remove_requested.emit()
def createHeaderMenus(self): for headInfo in self.headers: x = headInfo['x'] x = x - self.position if self.currPosX > x and self.currPosX < x+self.w and self.currPosY > self.t and self.currPosY < self.h+self.t: if 0 == self.headers.index(headInfo): break self.selectedHeader = headInfo menu = QMenu() if headInfo['flagCluster']: menu.addAction(self.scatterAct) else: menu.addAction(self.deleteAct) menu.addAction(self.groupAct) menu.exec_(QtGui.QCursor.pos())
class MainWindow(Ui_Form): def __init__(self, parent=None): super(MainWindow, self).__init__(parent) self.appname = "poliBeePsync" self.settings_fname = 'pbs-settings.ini' self.data_fname = 'pbs.data' self.setupUi(self) self.w = QWidget() self.status_signal = MySignal() self.status_signal.sig.connect(self.update_status_bar) self.logging_signal = MySignal() self.logging_signal.sig.connect(self.myStream_message) logging_console_hdl = SignalLoggingHandler(self.logging_signal) logger.addHandler(logging_console_hdl) commonlogger.addHandler(logging_console_hdl) self.about_text() self.timer = QTimer(self) # settings_path is a string containing the path to settings self.settings_path = None # settings is a dictionary of settings self.settings = None # load_settings() sets settings_path and settings self.load_settings() self.load_data() self.timer.timeout.connect(self.syncfiles) self.timer.start(1000 * 60 * int(self.settings['UpdateEvery'])) self.loginthread = LoginThread(self.user, self) self.loginthread.signal_error.sig.connect(self.update_status_bar) self.loginthread.signal_ok.sig.connect(self.update_status_bar) self.refreshcoursesthread = RefreshCoursesThread(self.user, self) self.refreshcoursesthread.dumpuser.sig.connect(self.dumpUser) self.refreshcoursesthread.newcourses.sig.connect(self.addtocoursesview) self.refreshcoursesthread.newcourses.sig.connect(self.syncnewcourses) self.refreshcoursesthread.removable.sig.connect(self.rmfromcoursesview) self.downloadthread = DownloadThread(self.user, self.settings['RootFolder'], self) self.downloadthread.dumpuser.sig.connect(self.dumpUser) self.downloadthread.download_signal.connect( self.update_course_download) self.downloadthread.initial_sizes.connect(self.setinizialsizes) self.downloadthread.date_signal.connect(self.update_file_localtime) self._window.userCode.setText(str(self.user.username)) self._window.userCode.editingFinished.connect(self.setusercode) self._window.password.setText(self.user.password) self._window.password.editingFinished.connect(self.setpassword) self._window.trylogin.clicked.connect(self.testlogin) self._window.courses_model = CoursesListModel(self.user. available_courses) self._window.coursesView.setModel(self._window.courses_model) self._resizeview() self._window.refreshCourses.clicked.connect(self.refreshcourses) self._window.syncNow.clicked.connect(self.syncfiles) if self.settings['SyncNewCourses'] == str(True): self._window.sync_new = Qt.Checked else: self._window.sync_new = Qt.Unchecked self._window.rootfolder.setText(self.settings['RootFolder']) self._window.rootfolder.textChanged.connect(self.rootfolderslot) self._window.addSyncNewCourses.setCheckState(self._window.sync_new) self._window.addSyncNewCourses.stateChanged.connect(self.syncnewslot) self._window.timerMinutes.setValue(int(self.settings['UpdateEvery'])) self._window.timerMinutes.valueChanged.connect(self.updateminuteslot) self._window.changeRootFolder.clicked.connect(self.chooserootdir) self._window.version_label.setText("Current version: {}." .format(__version__)) self._window.check_version.clicked.connect(self.checknewversion) self.trayIconMenu = QMenu() self.trayIcon = QSystemTrayIcon(self.icon, self.w) self.trayIcon.activated.connect(self._activate_traymenu) self.createTray() @Slot() def _resizeview(self, **kwargs): self._window.coursesView.setColumnWidth(3, 160) self._window.coursesView.resizeColumnToContents(1) self._window.coursesView.setColumnWidth(0, 320) def checknewversion(self): rawdata = requests.get('https://pypi.python.org/pypi/' 'poliBeePsync/json') latest = json.loads(rawdata.text)['info']['version'] self._window.version_label.setTextFormat(Qt.RichText) self._window.version_label.setOpenExternalLinks(True) self._window.version_label.setLocale(QLocale(QLocale.English, QLocale.UnitedStates)) self._window.version_label.setScaledContents(True) self._window.version_label.setWordWrap(True) if latest != __version__: newtext = """<p>Current version: {}.<br> Latest version: {}. </p> <p>Visit <a href='https://jacotsu.github.io/polibeepsync/dirhtml/index.html\ #how-to-install-upgrade-remove'>here</a> to find out how to upgrade. """.format(__version__, latest) else: newtext = "Current version: {} up-to-date.".format(__version__) self._window.version_label.setText(newtext) def _update_time(self, folder, file, path_list): logger.debug(f'inside {folder.name}') for path in path_list: logger.debug(f'namegoto: {path}') folder_dict = {'name': path} fakefolder = Folder(folder_dict) logger.debug(f'contained folders: {folder.folders}') ind = folder.folders.index(fakefolder) goto = folder.folders[ind] self._update_time(goto, file, path_list) if file in folder.files: ind = folder.files.index(file) thisfile = folder.files[ind] thisfile.local_creation_time = file.local_creation_time @Slot(tuple) def update_file_localtime(self, data, **kwargs): course, coursefile, path = data rootpath = os.path.join(self.settings['RootFolder'], course.save_folder_name) if path.startswith(rootpath): partial = path[len(rootpath):] path_list = filter(None, partial.split(os.path.sep)) self._update_time(course.documents, coursefile, path_list) @Slot(Course) def update_course_download(self, course, **kwargs): if course in self.user.available_courses: updating = self.user.available_courses[course.name] updating.downloaded_size = course.downloaded_size row = self._window.courses_model.courses.index(updating) where = self._window.courses_model.index(row, 3) self._window.courses_model.dataChanged.emit(where, where) @Slot(Course) def setinizialsizes(self, course, **kwargs): if course in self.user.available_courses: updating = self.user.available_courses[course.name] updating.downloaded_size = course.downloaded_size updating.total_file_size = course.total_file_size row = self._window.courses_model.courses.index(updating) where = self._window.courses_model.index(row, 3) self._window.courses_model.dataChanged.emit(where, where) self.dumpUser() @Slot(list) def syncnewcourses(self, newlist): if self.settings['SyncNewCourses'] == 'True': for elem in newlist: elem.sync = True def load_settings(self): for path in [user_config_dir(self.appname), user_data_dir(self.appname)]: try: os.makedirs(path, exist_ok=True) except OSError: logger.critical('OSError while calling os.makedirs.', exc_info=True) logger.critical(f"I couldn't create {path}.\nStart" " poliBeePsync with --debug " "error to get more details.") self.settings_path = os.path.join(user_config_dir(self.appname), self.settings_fname) defaults = { 'UpdateEvery': '60', 'RootFolder': os.path.join(os.path.expanduser('~'), self.appname), 'SyncNewCourses': 'False' } self.settings = filesettings.settingsFromFile(self.settings_path, defaults) def load_data(self): try: with open(os.path.join(user_data_dir(self.appname), self.data_fname), 'rb') as f: self.user = pickle.load(f) self.user.password = keyring\ .get_password('beep.metid.polimi.it', self.user.username) logger.info("Data has been loaded successfully.") except (EOFError, pickle.PickleError): logger.error('Settings corrupted', exc_info=True) self.user = User('', '') except FileNotFoundError: logger.error('Settings file not found.') self.user = User('', '') logger.error("I couldn't find data in the" " predefined directory. Ignore this" "message if you're using poliBeePsync" " for the first time.") @Slot(str) def update_status_bar(self, status): self._window.statusbar.showMessage(status) @Slot(int) def syncnewslot(self, state): if state == 2: self.settings['SyncNewCourses'] = 'True' else: self.settings['SyncNewCourses'] = 'False' filesettings.settingsToFile(self.settings, self.settings_path) @Slot(int) def updateminuteslot(self, minutes): self.settings['UpdateEvery'] = str(minutes) filesettings.settingsToFile(self.settings, self.settings_path) self.timer.start(1000 * 60 * int(self.settings['UpdateEvery'])) @Slot(str) def rootfolderslot(self, path): self.settings['RootFolder'] = path filesettings.settingsToFile(self.settings, self.settings_path) @Slot() def chooserootdir(self): currentdir = self.settings['RootFolder'] flags = QFileDialog.DontResolveSymlinks | QFileDialog.ShowDirsOnly newroot = QFileDialog.getExistingDirectory(None, "Open Directory", currentdir, flags) if newroot != "" and str(newroot) != currentdir: self.settings['RootFolder'] = str(newroot) filesettings.settingsToFile(self.settings, self.settings_path) self._window.rootfolder.setText(newroot) # we delete the already present downloadthread and recreate it # because otherwise it uses the old download folder. I don't know # if there's a cleaner approach del self.downloadthread self.downloadthread = DownloadThread(self.user, self.settings['RootFolder'], self) self.downloadthread.dumpuser.sig.connect(self.dumpUser) self.dumpUser() @Slot() def setusercode(self): newcode = self._window.userCode.text() try: if len(newcode) == 8: self.user.username = newcode logger.info(f'User code changed to {newcode}.') keyring.set_password('beep.metid.polimi.it', self.user.username, self.user.password) except OSError: logger.critical("I couldn't save data to disk. Run" " poliBeePsync with option --debug" " error to get more details.") logger.error('OSError raised while trying to write the User' 'instance to disk.', exc_info=True) @Slot() def setpassword(self): newpass = self._window.password.text() self.user.password = newpass try: keyring.set_password('beep.metid.polimi.it', self.user.username, self.user.password) logger.info("Password changed.") except OSError: logger.critical("I couldn't save data to disk. Run" " poliBeePsync with option --debug" " error to get more details.") logger.error('OSError raised while trying to write the User' 'instance to disk.', exc_info=True) @Slot() def testlogin(self): if not self.loginthread.isRunning(): self.loginthread.exiting = False self.loginthread.start() self.status_signal.sig.emit("Logging in, please wait.") @Slot(list) def addtocoursesview(self, addlist): for elem in addlist: self._window.courses_model.insertRows(0, 1, elem) @Slot(list) def rmfromcoursesview(self, removelist): for elem in removelist: index = self._window.courses_model.courses.index(elem) self._window.courses_model.removeRows(index, 1) @Slot() def dumpUser(self): # we don't use the message... with open(os.path.join(user_data_dir(self.appname), self.data_fname), 'wb') as f: tmp_pw = self.user.password self.user.password = '' pickle.dump(self.user, f) self.user.password = tmp_pw @Slot() def refreshcourses(self): self.status_signal.sig.emit('Searching for online updates...' 'this may take a while.') if not self.loginthread.isRunning(): self.loginthread.exiting = False self.loginthread.signal_ok.sig.connect(self.do_refreshcourses) self.loginthread.start() def do_refreshcourses(self): self.loginthread.signal_ok.sig.disconnect(self.do_refreshcourses) if not self.refreshcoursesthread.isRunning(): self.refreshcoursesthread.start() @Slot() def syncfiles(self): # we delete the already present downloadthread and recreate it # because otherwise it uses the old download folder. I don't know # if there's a cleaner approach del self.downloadthread self.downloadthread = DownloadThread(self.user, self.settings['RootFolder'], self) self.downloadthread.dumpuser.sig.connect(self.dumpUser) self.refreshcoursesthread.finished.connect(self.do_syncfiles) self.refreshcourses() @Slot() def do_syncfiles(self): self.refreshcoursesthread.finished.disconnect(self.do_syncfiles) self.status_signal.sig.emit('Started syncing.') self.downloadthread.start() @Slot(str) def myStream_message(self, message): self._window.status.moveCursor(QTextCursor.End) self._window.status.insertPlainText(message + "\n") def restore_window(self): self._window.setWindowState(self.windowState() & ~Qt.WindowMinimized | Qt.WindowActive) self._window.show() def createTray(self): restoreAction = QAction("&Restore", self, triggered=self.restore_window) quitAction = QAction("&Quit", self, triggered=qApp.quit) self.trayIconMenu.addAction(restoreAction) self.trayIconMenu.addAction(quitAction) self.trayIcon.setContextMenu(self.trayIconMenu) self.trayIcon.show() @Slot(str) def _activate_traymenu(self, reason): if reason == QSystemTrayIcon.ActivationReason.DoubleClick: self.restore_window() else: self.trayIconMenu.activateWindow() self.trayIconMenu.popup(QCursor.pos()) def closeEvent(self, event): self._window.hide() event.ignore() def about_text(self): self._window.label_3 = QLabel() self._window.label_3.setTextFormat(Qt.RichText) self._window.label_3.setOpenExternalLinks(True) self._window.label_3.setLocale(QLocale(QLocale.English, QLocale.UnitedStates)) self._window.label_3.setScaledContents(True) self._window.label_3.setWordWrap(True) text = """ <html> <head/> <body> <p>poliBeePsync is a program written by Davide Olianas, released under GNU GPLv3+.</p> <p>Feel free to contact me at <a href=\"mailto:[email protected]\">[email protected]</a> for suggestions and bug reports.</p> <p>More information is available on the <a href=\"http://www.davideolianas.com/polibeepsync\"> <span style=\" text-decoration: underline; color:#0000ff;\"> official website</span></a>. </p> </body> </html> """ self._window.label_3.setText(QApplication.translate("Form", text, None))