def new_console(tabto=None, floating=False, dockingarea=QtCore.Qt.RightDockWidgetArea): """ Create a new console and float it as a max widget tabto: name of a widget on top of which the console should be tabbed floating: True to float the console, False to leave it docked dockingarea: The docking area for docking the window (default = right) """ main_window = GetQMaxMainWindow() # create and setup a console console = PythonConsole(formats=HUGOS_THEME) console.setStyleSheet("background-color: #333333;") # create a dock widget for the console dock_widget = QDockWidget(main_window) dock_widget.setWidget(console) dock_widget.setObjectName("pyconsole") dock_widget.setWindowTitle("Python Console") main_window.addDockWidget(dockingarea, dock_widget) if not tabto is None: tabw = main_window.findChild(QWidget, tabto) main_window.tabifyDockWidget(tabw, dock_widget) dock_widget.setFloating(floating) dock_widget.show() # make the console do stuff console.eval_queued() return console
def createDockWidget(self): """ Criar dock """ dock_wgt = QDockWidget() dock_wgt.setWindowTitle("Dock Exemplo") dock_wgt.setAllowedAreas(Qt.AllDockWidgetAreas) dock_wgt.setWidget(QTextEdit()) self.addDockWidget(Qt.LeftDockWidgetArea, dock_wgt)
class Main(QMainWindow): """ MainWindow which contains all widgets of POSM. """ def __init__(self, parent=None): super(Main, self).__init__(parent) self.setWindowTitle("POSM") # All widgets should be destryed when the main window is closed. This the widgets can use the destroyed widget # to allow clean up. E.g. save the database of the TileLoader. self.setAttribute(QtCore.Qt.WA_DeleteOnClose, True) self.resize(config.config.window_size[0], config.config.window_size[1]) self.elements_loader = ElementsLoader() # Element Viewer as DockWidget self.element_viewer = ElementViewer(self) self.dock_element_viewer = QDockWidget() self.dock_element_viewer.setWindowTitle("Element Viewer") self.dock_element_viewer.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable) self.dock_element_viewer.setWidget(self.element_viewer) self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.dock_element_viewer) # LayerManger as DockWidget self.layer_manager = LayerManager(self) self.dock_layer_manager = QDockWidget() self.dock_layer_manager.setWindowTitle("Layer Manager") self.dock_layer_manager.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable) self.dock_layer_manager.setWidget(self.layer_manager) self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.dock_layer_manager) self.viewer = Viewer.Viewer(self) self.setCentralWidget(self.viewer) self.viewer.setFocus() self.viewer.setFocusPolicy(QtCore.Qt.StrongFocus) self.changeset = Changeset(self) self.changset_form = ChangesetForm(self) self.toolbar = QToolBar() self.toolbar.addAction("Load Elements", self.viewer.load_elements) self.toolbar.addAction("Undo Changes", self.viewer.undo_changes) self.toolbar.addAction("Create Node", partial(self.viewer.change_mode, "new_node")) self.toolbar.addAction("Upload Changes", self.changset_form.show) self.toolbar.addAction("Open Configuration", partial(os.startfile, str(config.path_config))) self.addToolBar(self.toolbar) self.statusBar().showMessage("Welcome to POSM!")
def demo_docking_widgets(): """ Demonstrates how to create a QWidget with PySide2 and attach it to the 3dsmax main window. Creates two types of dockable widgets, a QDockWidget and a QToolbar """ # Retrieve 3ds Max Main Window QWdiget main_window = GetQMaxMainWindow() # QAction reused by both dockable widgets. cylinder_icon_path = os.path.dirname(os.path.realpath(__file__)) + "\\cylinder_icon_48.png" cylinder_icon = QtGui.QIcon(cylinder_icon_path) create_cyl_action = QAction(cylinder_icon, u"Create Cylinder", main_window) create_cyl_action.triggered.connect(create_cylinder) # QDockWidget construction and placement over the main window dock_widget = QDockWidget(main_window) # Set for position persistence dock_widget.setObjectName("Creators") # Set to see dock widget name in toolbar customize popup dock_widget.setWindowTitle("Creators") dock_tool_button = QToolButton() dock_tool_button.setAutoRaise(True) dock_tool_button.setDefaultAction(create_cyl_action) dock_tool_button.setToolButtonStyle(QtCore.Qt.ToolButtonTextOnly) dock_widget.setWidget(dock_tool_button) main_window.addDockWidget(QtCore.Qt.LeftDockWidgetArea, dock_widget) dock_widget.setFloating(True) dock_widget.show() # QToolBar construction and attachement to main window toolbar_widget = QToolBar(main_window) # Set for position persistence toolbar_widget.setObjectName("Creators TB") # Set to see dock widget name in toolbar customize popup toolbar_widget.setWindowTitle("Creators TB") toolbar_widget.setFloatable(True) toolbar_widget.addAction(create_cyl_action) main_window.addToolBar(QtCore.Qt.BottomToolBarArea, toolbar_widget) toolbar_widget.show() toolbar_position = get_pos_to_dock_toolbar(dock_widget) make_toolbar_floating(toolbar_widget, toolbar_position)
def _on_select(): global edd it = ed.scene().selectedItems() if len(it) > 0: it = it[0] else: it = None if isinstance(it, Element): edd = QDockWidget() edd.setWidget(it.editor()) edd.setWindowTitle('Element properties') edd.setFeatures(QDockWidget.DockWidgetMovable | QDockWidget.DockWidgetFloatable) w.addDockWidget(Qt.LeftDockWidgetArea, edd) elif edd is not None: w.removeDockWidget(edd) edd = None
category_item.addChild(it) self.addTopLevelItem(category_item) if __name__ == "__main__": app = QApplication() w = QMainWindow() w.setMinimumSize(640, 480) elems = ElementTree() elems.create_from_dict(ELEMENTS) elems.expandAll() dw = QDockWidget() dw.setWidget(elems) dw.setWindowTitle('Elements') dw.setFeatures(QDockWidget.DockWidgetMovable | QDockWidget.DockWidgetFloatable) w.addDockWidget(Qt.LeftDockWidgetArea, dw) sim = Simulator() schem = Schematic() sim.root = schem.root g = Gate('or', 1, 2, False) g.name = 'gate' el = GateElement(sim, g) schem.add_element(el) ed = SchematicEditor(schem) t = QTimer(w) edd = None
def __init__(self, app): super(MainWindow, self).__init__() self._app = app self._selectedIndex = None # model nodeFactory = NodeFactory() rootNode = nodeFactory.create(NodeType.General, 'Root') # for i in range(10000): # for testing childNode0 = nodeFactory.create(NodeType.General, 'RightPirateLeg', rootNode) childNode1 = nodeFactory.create(NodeType.General, 'RightPirateLeg_END', childNode0) childNode2 = nodeFactory.create(NodeType.General, 'LeftFemur', rootNode) childNode3 = nodeFactory.create(NodeType.Sphere, 'LeftTibia', childNode2) childNode4 = nodeFactory.create(NodeType.Sphere, 'LeftFoot', childNode3) transform = childNode4.component(ComponentType.Transform) qTransform = transform.component() translation = qTransform.translation() translation.setX(5) qTransform.setTranslation(translation) # childNode5 = nodeFactory.create(NodeType.Box, 'LeftFoot_END', childNode4) self._model = SceneGraphModel(rootNode) self._sceneView = SceneView(rootNode.entity()) self._container = self.createWindowContainer(self._sceneView) # scene graph view self._treeView = QTreeView() self._treeView.setModel(self._model) self._treeView.setHeaderHidden(True) self._treeView.setAlternatingRowColors(True) dockWidget = QDockWidget() dockWidget.setWidget(self._treeView) dockWidget.setWindowTitle('Scene Graph') dockWidget.setObjectName('sceneGraph') sceneGraphToggleAction = dockWidget.toggleViewAction() self.addDockWidget(Qt.LeftDockWidgetArea, dockWidget) # property editor propertyEditor = PropertyEditor(self._model, nodeFactory, FieldFactory()) dockWidget = QDockWidget() dockWidget.setWidget(propertyEditor) dockWidget.setWindowTitle('Property Editor') dockWidget.setObjectName('propertyEditor') propertyEditorToggleAction = dockWidget.toggleViewAction() self.addDockWidget(Qt.RightDockWidgetArea, dockWidget) # menu menuBar = self.menuBar() menu = menuBar.addMenu('&File') exitAction = menu.addAction('E&xit') exitAction.triggered.connect(self.close) menu.addAction(exitAction) menu = menuBar.addMenu('&Windows') menu.addAction(sceneGraphToggleAction) menu.addAction(propertyEditorToggleAction) menuBar.addMenu(menu) # central widget #button = QPushButton() self.setCentralWidget(self._container) # selection change event selectionModel = self._treeView.selectionModel() selectionModel.currentChanged.connect(propertyEditor.changeSelection)
class MainWindow(QMainWindow): """Provides the parent window that includes the BookmarkWidget, BrowserTabWidget, and a DownloadWidget, to offer the complete web browsing experience.""" def __init__(self): super(MainWindow, self).__init__() self.setWindowTitle('PySide2 tabbed browser Example') self._tab_widget = BrowserTabWidget(create_main_window_with_browser) self._tab_widget.enabled_changed.connect(self._enabled_changed) self._tab_widget.download_requested.connect(self._download_requested) self.setCentralWidget(self._tab_widget) self.connect(self._tab_widget, QtCore.SIGNAL("url_changed(QUrl)"), self.url_changed) self._bookmark_dock = QDockWidget() self._bookmark_dock.setWindowTitle('Bookmarks') self._bookmark_widget = BookmarkWidget() self._bookmark_widget.open_bookmark.connect(self.load_url) self._bookmark_widget.open_bookmark_in_new_tab.connect( self.load_url_in_new_tab) self._bookmark_dock.setWidget(self._bookmark_widget) self.addDockWidget(Qt.LeftDockWidgetArea, self._bookmark_dock) self._find_tool_bar = None self._actions = {} self._create_menu() self._tool_bar = QToolBar() self.addToolBar(self._tool_bar) for action in self._actions.values(): if not action.icon().isNull(): self._tool_bar.addAction(action) self._addres_line_edit = QLineEdit() self._addres_line_edit.setClearButtonEnabled(True) self._addres_line_edit.returnPressed.connect(self.load) self._tool_bar.addWidget(self._addres_line_edit) self._zoom_label = QLabel() self.statusBar().addPermanentWidget(self._zoom_label) self._update_zoom_label() self._bookmarksToolBar = QToolBar() self.addToolBar(Qt.TopToolBarArea, self._bookmarksToolBar) self.insertToolBarBreak(self._bookmarksToolBar) self._bookmark_widget.changed.connect(self._update_bookmarks) self._update_bookmarks() def _update_bookmarks(self): self._bookmark_widget.populate_tool_bar(self._bookmarksToolBar) self._bookmark_widget.populate_other(self._bookmark_menu, 3) def _create_menu(self): file_menu = self.menuBar().addMenu("&File") exit_action = QAction(QIcon.fromTheme("application-exit"), "E&xit", self, shortcut="Ctrl+Q", triggered=qApp.quit) file_menu.addAction(exit_action) navigation_menu = self.menuBar().addMenu("&Navigation") style_icons = ':/qt-project.org/styles/commonstyle/images/' back_action = QAction(QIcon.fromTheme( "go-previous", QIcon(style_icons + 'left-32.png')), "Back", self, shortcut=QKeySequence(QKeySequence.Back), triggered=self._tab_widget.back) self._actions[QWebEnginePage.Back] = back_action back_action.setEnabled(False) navigation_menu.addAction(back_action) forward_action = QAction(QIcon.fromTheme( "go-next", QIcon(style_icons + 'right-32.png')), "Forward", self, shortcut=QKeySequence(QKeySequence.Forward), triggered=self._tab_widget.forward) forward_action.setEnabled(False) self._actions[QWebEnginePage.Forward] = forward_action navigation_menu.addAction(forward_action) reload_action = QAction(QIcon(style_icons + 'refresh-32.png'), "Reload", self, shortcut=QKeySequence(QKeySequence.Refresh), triggered=self._tab_widget.reload) self._actions[QWebEnginePage.Reload] = reload_action reload_action.setEnabled(False) navigation_menu.addAction(reload_action) navigation_menu.addSeparator() new_tab_action = QAction("New Tab", self, shortcut='Ctrl+T', triggered=self.add_browser_tab) navigation_menu.addAction(new_tab_action) close_tab_action = QAction("Close Current Tab", self, shortcut="Ctrl+W", triggered=self._close_current_tab) navigation_menu.addAction(close_tab_action) edit_menu = self.menuBar().addMenu("&Edit") find_action = QAction("Find", self, shortcut=QKeySequence(QKeySequence.Find), triggered=self._show_find) edit_menu.addAction(find_action) edit_menu.addSeparator() undo_action = QAction("Undo", self, shortcut=QKeySequence(QKeySequence.Undo), triggered=self._tab_widget.undo) self._actions[QWebEnginePage.Undo] = undo_action undo_action.setEnabled(False) edit_menu.addAction(undo_action) redo_action = QAction("Redo", self, shortcut=QKeySequence(QKeySequence.Redo), triggered=self._tab_widget.redo) self._actions[QWebEnginePage.Redo] = redo_action redo_action.setEnabled(False) edit_menu.addAction(redo_action) edit_menu.addSeparator() cut_action = QAction("Cut", self, shortcut=QKeySequence(QKeySequence.Cut), triggered=self._tab_widget.cut) self._actions[QWebEnginePage.Cut] = cut_action cut_action.setEnabled(False) edit_menu.addAction(cut_action) copy_action = QAction("Copy", self, shortcut=QKeySequence(QKeySequence.Copy), triggered=self._tab_widget.copy) self._actions[QWebEnginePage.Copy] = copy_action copy_action.setEnabled(False) edit_menu.addAction(copy_action) paste_action = QAction("Paste", self, shortcut=QKeySequence(QKeySequence.Paste), triggered=self._tab_widget.paste) self._actions[QWebEnginePage.Paste] = paste_action paste_action.setEnabled(False) edit_menu.addAction(paste_action) edit_menu.addSeparator() select_all_action = QAction("Select All", self, shortcut=QKeySequence( QKeySequence.SelectAll), triggered=self._tab_widget.select_all) self._actions[QWebEnginePage.SelectAll] = select_all_action select_all_action.setEnabled(False) edit_menu.addAction(select_all_action) self._bookmark_menu = self.menuBar().addMenu("&Bookmarks") add_bookmark_action = QAction("&Add Bookmark", self, triggered=self._add_bookmark) self._bookmark_menu.addAction(add_bookmark_action) add_tool_bar_bookmark_action = QAction( "&Add Bookmark to Tool Bar", self, triggered=self._add_tool_bar_bookmark) self._bookmark_menu.addAction(add_tool_bar_bookmark_action) self._bookmark_menu.addSeparator() tools_menu = self.menuBar().addMenu("&Tools") download_action = QAction( "Open Downloads", self, triggered=DownloadWidget.open_download_directory) tools_menu.addAction(download_action) window_menu = self.menuBar().addMenu("&Window") window_menu.addAction(self._bookmark_dock.toggleViewAction()) window_menu.addSeparator() zoom_in_action = QAction(QIcon.fromTheme("zoom-in"), "Zoom In", self, shortcut=QKeySequence(QKeySequence.ZoomIn), triggered=self._zoom_in) window_menu.addAction(zoom_in_action) zoom_out_action = QAction(QIcon.fromTheme("zoom-out"), "Zoom Out", self, shortcut=QKeySequence(QKeySequence.ZoomOut), triggered=self._zoom_out) window_menu.addAction(zoom_out_action) reset_zoom_action = QAction(QIcon.fromTheme("zoom-original"), "Reset Zoom", self, shortcut="Ctrl+0", triggered=self._reset_zoom) window_menu.addAction(reset_zoom_action) about_menu = self.menuBar().addMenu("&About") about_action = QAction("About Qt", self, shortcut=QKeySequence( QKeySequence.HelpContents), triggered=qApp.aboutQt) about_menu.addAction(about_action) def add_browser_tab(self): return self._tab_widget.add_browser_tab() def _close_current_tab(self): if self._tab_widget.count() > 1: self._tab_widget.close_current_tab() else: self.close() def close_event(self, event): main_windows.remove(self) event.accept() def load(self): url_string = self._addres_line_edit.text().strip() if url_string: self.load_url_string(url_string) def load_url_string(self, url_s): url = QUrl.fromUserInput(url_s) if (url.isValid()): self.load_url(url) def load_url(self, url): self._tab_widget.load(url) def load_url_in_new_tab(self, url): self.add_browser_tab().load(url) def url_changed(self, url): self._addres_line_edit.setText(url.toString()) def _enabled_changed(self, web_action, enabled): action = self._actions[web_action] if action: action.setEnabled(enabled) def _add_bookmark(self): index = self._tab_widget.currentIndex() if index >= 0: url = self._tab_widget.url() title = self._tab_widget.tabText(index) icon = self._tab_widget.tabIcon(index) self._bookmark_widget.add_bookmark(url, title, icon) def _add_tool_bar_bookmark(self): index = self._tab_widget.currentIndex() if index >= 0: url = self._tab_widget.url() title = self._tab_widget.tabText(index) icon = self._tab_widget.tabIcon(index) self._bookmark_widget.add_tool_bar_bookmark(url, title, icon) def _zoom_in(self): new_zoom = self._tab_widget.zoom_factor() * 1.5 if (new_zoom <= WebEngineView.maximum_zoom_factor()): self._tab_widget.set_zoom_factor(new_zoom) self._update_zoom_label() def _zoom_out(self): new_zoom = self._tab_widget.zoom_factor() / 1.5 if (new_zoom >= WebEngineView.minimum_zoom_factor()): self._tab_widget.set_zoom_factor(new_zoom) self._update_zoom_label() def _reset_zoom(self): self._tab_widget.set_zoom_factor(1) self._update_zoom_label() def _update_zoom_label(self): percent = int(self._tab_widget.zoom_factor() * 100) self._zoom_label.setText("{}%".format(percent)) def _download_requested(self, item): # Remove old downloads before opening a new one for old_download in self.statusBar().children(): if type(old_download).__name__ == 'download_widget' and \ old_download.state() != QWebEngineDownloadItem.DownloadInProgress: self.statusBar().removeWidget(old_download) del old_download item.accept() download_widget = download_widget(item) download_widget.removeRequested.connect( self._remove_download_requested, Qt.QueuedConnection) self.statusBar().addWidget(download_widget) def _remove_download_requested(self): download_widget = self.sender() self.statusBar().removeWidget(download_widget) del download_widget def _show_find(self): if self._find_tool_bar is None: self._find_tool_bar = FindToolBar() self._find_tool_bar.find.connect(self._tab_widget.find) self.addToolBar(Qt.BottomToolBarArea, self._find_tool_bar) else: self._find_tool_bar.show() self._find_tool_bar.focus_find() def write_bookmarks(self): self._bookmark_widget.write_bookmarks()
class PhotoEditor(QMainWindow): #Ok def __init__(self): super().__init__() self.iniciaUI() def iniciaUI(self): """ Inicializa a janela e mostra seu conteuda na tela """ self.setFixedSize(650, 650) #self.setGeometry(100,100, 400, 230) self.setWindowTitle("Photo Editor") self.centerMainWindow() self.createToolsDockWidget() self.createMenu() self.createToolBar() self.photoEditorWidgets() self.show() def centerMainWindow(self): #Ok """ Use a classe QDesktopWidget para acessar informações sobre sua tela e use-a para centralizar a janela do aplicativo. """ desktop = QDesktopWidget().screenGeometry() screen_width = desktop.width() screen_height = desktop.height() self.move((screen_width - self.width()) / 2, (screen_height - self.height()) / 2) def createMenu(self): #Ok """ Criar menu para editor de fotos """ self.abre_act = QAction(QIcon('Imagens/open_file.png'), "Abrir", self) self.abre_act.setShortcut('Ctrl+O') self.abre_act.setStatusTip('Abrir uma nova imagem') self.abre_act.triggered.connect(self.openImage) self.salv_act = QAction(QIcon('Imagens/save_file.png'), 'Salvar', self) self.salv_act.setShortcut('Ctrl+S') self.salv_act.setStatusTip('Salvar imagem') self.salv_act.triggered.connect(self.saveToFile) self.prnt_act = QAction(QIcon('Imagens/print.png'), "Imprimir", self) self.prnt_act.setShortcut('Ctrl+P') self.prnt_act.setStatusTip('Imprimir imagem') self.prnt_act.triggered.connect(self.printImage) self.prnt_act.setEnabled(False) self.sair_act = QAction(QIcon('Imagens/exit.png'), 'Sair', self) self.sair_act.setShortcut('Ctrl+Q') self.sair_act.setStatusTip('Sair do programa') self.sair_act.triggered.connect(self.close) self.rt90_act = QAction("Girar 90°", self) self.rt90_act.setStatusTip('Girar imagem 90 ° no sentido horário') self.rt90_act.triggered.connect(self.rotateImage90) self.rt180_act = QAction("Girar 180°", self) self.rt180_act.setStatusTip('Girar imagem 180° no sentido horário') self.rt180_act.triggered.connect(self.rotateImage180) self.flph_act = QAction("Espelhar na Horizontal", self) self.flph_act.setStatusTip('Espelhar imagem no eixo horizontal') self.flph_act.triggered.connect(self.flipImageHorizontal) self.flpv_act = QAction("Espelhar na Vertical", self) self.flpv_act.setStatusTip('Espelhar imagem no eixo vertical') self.flpv_act.triggered.connect(self.flipImageVertical) self.redm_act = QAction("Redimensionar metade", self) self.redm_act.setStatusTip( 'Redimensionar imagem para metade do tamanho original') self.redm_act.triggered.connect(self.resizeImageHalf) self.limp_act = QAction(QIcon('Imagens/clear.png'), "Limpar Imagem", self) self.limp_act.setShortcut("Ctrl+D") self.limp_act.setStatusTip('Limpar a imagem atual') self.limp_act.triggered.connect(self.clearImage) menu_bar = self.menuBar() menu_bar.setNativeMenuBar(False) arqv_menu = menu_bar.addMenu('Arquivo') arqv_menu.addAction(self.abre_act) arqv_menu.addAction(self.salv_act) arqv_menu.addSeparator() arqv_menu.addAction(self.prnt_act) arqv_menu.addSeparator() arqv_menu.addAction(self.sair_act) edit_menu = menu_bar.addMenu('Editar') edit_menu.addAction(self.rt90_act) edit_menu.addAction(self.rt180_act) edit_menu.addSeparator() edit_menu.addAction(self.flph_act) edit_menu.addAction(self.flpv_act) edit_menu.addSeparator() edit_menu.addAction(self.redm_act) edit_menu.addSeparator() edit_menu.addAction(self.limp_act) #??????????????????? view_menu = menu_bar.addMenu('Exibir') view_menu.addAction(self.toggle_dock_tools_act) self.setStatusBar(QStatusBar(self)) def openImage(self): #Ok """ Abrir um arquivo de imagem e exiba seu conteúdo no label. Exibir mensagem de erro se a imagem não puder ser aberta. """ arq_img, _ = QFileDialog.getOpenFileName( self, "Abrir Imagem", "", "Arquivos JPG (*.jpeg *.jpg );;Arquivos PNG (*.png)\ ;;Arquivos Bitmap (*.bmp);;Arquivos GIF (*.gif)") if arq_img: self.img = QPixmap(arq_img) self.img_lbl.setPixmap( self.img.scaled(self.img_lbl.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)) else: QMessageBox.information(self, "Erro", "Não é possível abrir imagem.", QMessageBox.Ok) self.prnt_act.setEnabled(True) def saveToFile(self): #Ok """ Salvar a imagem. Exibir mensagem de erro se a imagem não puder ser salva. """ arq_img, _ = QFileDialog.getSaveFileName( self, "Salvar Imagem", "", "Arquivos JPG (*.jpeg *.jpg );;Arquivos PNG (*.png)\ ;;Arquivos Bitmap (*.bmp);;Arquivos GIF (*.gif)") if arq_img and self.img.isNull() == False: self.img.save(image_file) else: QMessageBox.information(self, "Não é possível salvar imagem.", QMessageBox.Ok) def printImage(self): #Ok """Imprimir Imagem """ printer = QPrinter() printer.setOutputFormat(QPrinter.NativeFormat) prnt_dlg = QPrintDialog(printer) if (prnt_dlg.exec_() == QPrintDialog.Accepted): painter = QPainter() painter.begin(printer) rect = QRect(painter.viewport()) size = QSize(self.img_lbl.pixmap().size()) size.scale(rect.size(), Qt.KeepAspectRatio) painter.setViewport(rect.x(), rect.y(), size.width(), size.height()) painter.setWindow(self.img_lbl.pixmap().rect()) painter.drawPixmap(0, 0, self.img_lbl.pixmap()) painter.end() def rotateImage90(self): #Ok """ Girar imagem 90° no sentido horário """ if self.img.isNull() == False: transform90 = QTransform().rotate(90) pixmap = QPixmap(self.img) rotated = pixmap.transformed(transform90, mode=Qt.SmoothTransformation) self.img_lbl.setPixmap( rotated.scaled(self.img_lbl.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)) self.img = QPixmap(rotated) self.img_lbl.repaint() # repaint the child widget else: # No image to rotate pass def rotateImage180(self): #Ok """ Girar imagem 180° no sentido horário """ if self.img.isNull() == False: transform180 = QTransform().rotate(180) pixmap = QPixmap(self.img) rotated = pixmap.transformed(transform180, mode=Qt.SmoothTransformation) self.img_lbl.setPixmap( rotated.scaled(self.img_lbl.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)) self.img = QPixmap(rotated) self.img_label.repaint() # repaint the child widget else: # No image to rotate pass def flipImageHorizontal(self): #Ok """ Espelhar a imagem no eixo horizontal """ if self.img.isNull() == False: flip_h = QTransform().scale(-1, 1) pixmap = QPixmap(self.img) flipped = pixmap.transformed(flip_h) self.img_lbl.setPixmap( flipped.scaled(self.img_lbl.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)) self.img = QPixmap(flipped) self.img_lbl.repaint() else: pass def flipImageVertical(self): #Ok """ Espelhar a imagem no eixo vertical """ if self.img.isNull() == False: flip_v = QTransform().scale(1, -1) pixmap = QPixmap(self.img) flipped = pixmap.transformed(flip_v) self.img_lbl.setPixmap( flipped.scaled(self.img_lbl.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)) self.img = QPixmap(flipped) self.img_lbl.repaint() else: pass def resizeImageHalf(self): #Ok """ Redimensione a imagem para a metade do tamanho atual. """ if self.img.isNull() == False: resize = QTransform().scale(0.5, 0.5) pixmap = QPixmap(self.img) resized = pixmap.transformed(resize) self.img_lbl.setPixmap( resized.scaled(self.img_lbl.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)) self.img = QPixmap(resized) self.img_lbl.repaint() else: pass def clearImage(self): #Ok """ Limpar a imagem atual no widget QLabel """ self.img_lbl.clear() self.img = QPixmap() def createToolBar(self): #Ok """ Criar barra de ferramentas para editor de fotos """ tool_bar = QToolBar("Barra de Ferramentas do Editor de Fotos") tool_bar.setIconSize(QSize(24, 24)) self.addToolBar(tool_bar) tool_bar.addAction(self.abre_act) tool_bar.addAction(self.salv_act) tool_bar.addAction(self.prnt_act) tool_bar.addAction(self.limp_act) tool_bar.addSeparator() tool_bar.addAction(self.sair_act) def createToolsDockWidget(self): #Ok """ Use o menu Exibir -> Editar Ferramentas de Imagem e clique no widget dock para ligar ou desligar. O dock de ferramentas pode ser colocado à esquerda ou à direita da janela principal. """ self.dock_tools_view = QDockWidget() self.dock_tools_view.setWindowTitle("Ferramentas Edição de Imagem") self.dock_tools_view.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea) self.img_tool = QWidget() self.rt90_btn = QPushButton("Girar 90°") self.rt90_btn.setMinimumSize(QSize(130, 40)) self.rt90_btn.setStatusTip('Girar imagem 90° no sentido horário') self.rt90_btn.clicked.connect(self.rotateImage90) self.rt180_btn = QPushButton("Girar 180°") self.rt180_btn.setMinimumSize(QSize(130, 40)) self.rt180_btn.setStatusTip('Girar imagem 180° no sentido horário') self.rt180_btn.clicked.connect(self.rotateImage180) self.flph_btn = QPushButton("Espelhar na Horizontal") self.flph_btn.setMinimumSize(QSize(130, 40)) self.flph_btn.setStatusTip('Espelhar imagem no eixo horizontal') self.flph_btn.clicked.connect(self.flipImageHorizontal) self.flpv_btn = QPushButton("Espelhar na Vertical") self.flpv_btn.setMinimumSize(QSize(130, 40)) self.flpv_btn.setStatusTip('Espelhar imagem no eixo vertical') self.flpv_btn.clicked.connect(self.flipImageVertical) self.redm_btn = QPushButton("Redimensionar metade") self.redm_btn.setMinimumSize(QSize(130, 40)) self.redm_btn.setStatusTip( 'Redimensionar imagem para metade do tamanho original') self.redm_btn.clicked.connect(self.resizeImageHalf) vbox = QVBoxLayout() vbox.addWidget(self.rt90_btn) vbox.addWidget(self.rt180_btn) vbox.addStretch(1) vbox.addWidget(self.flph_btn) vbox.addWidget(self.flpv_btn) vbox.addStretch(1) vbox.addWidget(self.redm_btn) vbox.addStretch(6) self.img_tool.setLayout(vbox) self.dock_tools_view.setWidget(self.img_tool) self.addDockWidget(Qt.RightDockWidgetArea, self.dock_tools_view) self.toggle_dock_tools_act = self.dock_tools_view.toggleViewAction() def photoEditorWidgets(self): #Ok """ Configurar instâncias de widgets para editor de fotos """ self.img = QPixmap() self.img_lbl = QLabel() self.img_lbl.setAlignment(Qt.AlignCenter) self.img_lbl.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Ignored) self.setCentralWidget(self.img_lbl)
class FB(rv.rvtypes.MinorMode): def __init__(self): rv.rvtypes.MinorMode.__init__(self) self.init("File Browser", None, None, [("File Browser", [ ("Show File Browser", self.toggle, None, self._state) ])]) self.setupUI() self._visible = False self.dock.visibilityChanged.connect(self.setVisible) def setupUI(self): self.dock = QDockWidget() self.dock.setWindowTitle("File Browser") self.masterWidget = QWidget() self.masterLayout = QVBoxLayout(self.masterWidget) self.dock.setWidget(self.masterWidget) movieExt = ["*.mov", "*.mp4", "*.wmv", "*.movieproc"] imgExt = [ "*.ext", "*.tiff", "*.tif", "*.dpx", "*.iff", "*.jpeg", "*.png", "*.ari" ] rawCam = [ ".arw", ".cr2", ".crw", ".dng", ".nef", ".orf", ".pef", ".ptx", ".raf", ".rdc", ".rmf" ] self.fileBrowser = FileBrowser(filterExtension=movieExt + imgExt + rawCam) self.fileBrowser.executed.connect(self.play) self.masterLayout.addWidget(self.fileBrowser) def readPrefs(self): self._visible = rv.commands.readSettings("File Browser", "visible", False) def writePrefs(self, state): rv.commands.writeSettings("File Browser", "visible", state) def setVisible(self, visible): self._visible = visible def dockToggle(self): if self._visible: self.dock.show() else: self.dock.hide() self.writePrefs(self._visible) def toggle(self, event): self._visible = not self._visible self.dockToggle() def _state(self): if self._visible: return rv.commands.CheckedMenuState return rv.commands.UncheckedMenuState def activate(self): print("Activating QCTools") try: rv.rvtypes.MinorMode.activate(self) self.window = rv.qtutils.sessionWindow() self.window.addDockWidget(Qt.BottomDockWidgetArea, self.dock) self.dockToggle() except Exception as e: print("-" * 50) print(str(e)) print("-" * 50) def deactivate(self): print("Deactivating QCTools") self.window.removeDockWidget(self.dock) self.dock.hide() rv.rvtypes.MinorMode.deactivate(self) def clearSession(self): rv.commands.clearSession() def play(self, file, new=True): if new: self.clearSession() source = rv.commands.addSourceVerbose([file], None) mediaInfo = rv.commands.sourceMediaInfo(source) print(mediaInfo) rv.commands.setRealtime(True) rv.commands.setCacheMode(1)
class MainWindow(QMainWindow): """Provides the parent window that includes the BookmarkWidget, BrowserTabWidget, and a DownloadWidget, to offer the complete web browsing experience.""" def __init__(self): super(MainWindow, self).__init__() self.setWindowTitle('PySide2 tabbed browser Example') self._tab_widget = BrowserTabWidget(create_main_window_with_browser) self._tab_widget.enabled_changed.connect(self._enabled_changed) self._tab_widget.download_requested.connect(self._download_requested) self.setCentralWidget(self._tab_widget) self.connect(self._tab_widget, QtCore.SIGNAL("url_changed(QUrl)"), self.url_changed) self._bookmark_dock = QDockWidget() self._bookmark_dock.setWindowTitle('Bookmarks') self._bookmark_widget = BookmarkWidget() self._bookmark_widget.open_bookmark.connect(self.load_url) self._bookmark_widget.open_bookmark_in_new_tab.connect(self.load_url_in_new_tab) self._bookmark_dock.setWidget(self._bookmark_widget) self.addDockWidget(Qt.LeftDockWidgetArea, self._bookmark_dock) self._find_tool_bar = None self._actions = {} self._create_menu() self._tool_bar = QToolBar() self.addToolBar(self._tool_bar) for action in self._actions.values(): if not action.icon().isNull(): self._tool_bar.addAction(action) self._addres_line_edit = QLineEdit() self._addres_line_edit.setClearButtonEnabled(True) self._addres_line_edit.returnPressed.connect(self.load) self._tool_bar.addWidget(self._addres_line_edit) self._zoom_label = QLabel() self.statusBar().addPermanentWidget(self._zoom_label) self._update_zoom_label() self._bookmarksToolBar = QToolBar() self.addToolBar(Qt.TopToolBarArea, self._bookmarksToolBar) self.insertToolBarBreak(self._bookmarksToolBar) self._bookmark_widget.changed.connect(self._update_bookmarks) self._update_bookmarks() def _update_bookmarks(self): self._bookmark_widget.populate_tool_bar(self._bookmarksToolBar) self._bookmark_widget.populate_other(self._bookmark_menu, 3) def _create_menu(self): file_menu = self.menuBar().addMenu("&File") exit_action = QAction(QIcon.fromTheme("application-exit"), "E&xit", self, shortcut = "Ctrl+Q", triggered=qApp.quit) file_menu.addAction(exit_action) navigation_menu = self.menuBar().addMenu("&Navigation") style_icons = ':/qt-project.org/styles/commonstyle/images/' back_action = QAction(QIcon.fromTheme("go-previous", QIcon(style_icons + 'left-32.png')), "Back", self, shortcut = QKeySequence(QKeySequence.Back), triggered = self._tab_widget.back) self._actions[QWebEnginePage.Back] = back_action back_action.setEnabled(False) navigation_menu.addAction(back_action) forward_action = QAction(QIcon.fromTheme("go-next", QIcon(style_icons + 'right-32.png')), "Forward", self, shortcut = QKeySequence(QKeySequence.Forward), triggered = self._tab_widget.forward) forward_action.setEnabled(False) self._actions[QWebEnginePage.Forward] = forward_action navigation_menu.addAction(forward_action) reload_action = QAction(QIcon(style_icons + 'refresh-32.png'), "Reload", self, shortcut = QKeySequence(QKeySequence.Refresh), triggered = self._tab_widget.reload) self._actions[QWebEnginePage.Reload] = reload_action reload_action.setEnabled(False) navigation_menu.addAction(reload_action) navigation_menu.addSeparator() new_tab_action = QAction("New Tab", self, shortcut = 'Ctrl+T', triggered = self.add_browser_tab) navigation_menu.addAction(new_tab_action) close_tab_action = QAction("Close Current Tab", self, shortcut = "Ctrl+W", triggered = self._close_current_tab) navigation_menu.addAction(close_tab_action) edit_menu = self.menuBar().addMenu("&Edit") find_action = QAction("Find", self, shortcut = QKeySequence(QKeySequence.Find), triggered = self._show_find) edit_menu.addAction(find_action) edit_menu.addSeparator() undo_action = QAction("Undo", self, shortcut = QKeySequence(QKeySequence.Undo), triggered = self._tab_widget.undo) self._actions[QWebEnginePage.Undo] = undo_action undo_action.setEnabled(False) edit_menu.addAction(undo_action) redo_action = QAction("Redo", self, shortcut = QKeySequence(QKeySequence.Redo), triggered = self._tab_widget.redo) self._actions[QWebEnginePage.Redo] = redo_action redo_action.setEnabled(False) edit_menu.addAction(redo_action) edit_menu.addSeparator() cut_action = QAction("Cut", self, shortcut = QKeySequence(QKeySequence.Cut), triggered = self._tab_widget.cut) self._actions[QWebEnginePage.Cut] = cut_action cut_action.setEnabled(False) edit_menu.addAction(cut_action) copy_action = QAction("Copy", self, shortcut = QKeySequence(QKeySequence.Copy), triggered = self._tab_widget.copy) self._actions[QWebEnginePage.Copy] = copy_action copy_action.setEnabled(False) edit_menu.addAction(copy_action) paste_action = QAction("Paste", self, shortcut = QKeySequence(QKeySequence.Paste), triggered = self._tab_widget.paste) self._actions[QWebEnginePage.Paste] = paste_action paste_action.setEnabled(False) edit_menu.addAction(paste_action) edit_menu.addSeparator() select_all_action = QAction("Select All", self, shortcut = QKeySequence(QKeySequence.SelectAll), triggered = self._tab_widget.select_all) self._actions[QWebEnginePage.SelectAll] = select_all_action select_all_action.setEnabled(False) edit_menu.addAction(select_all_action) self._bookmark_menu = self.menuBar().addMenu("&Bookmarks") add_bookmark_action = QAction("&Add Bookmark", self, triggered = self._add_bookmark) self._bookmark_menu.addAction(add_bookmark_action) add_tool_bar_bookmark_action = QAction("&Add Bookmark to Tool Bar", self, triggered = self._add_tool_bar_bookmark) self._bookmark_menu.addAction(add_tool_bar_bookmark_action) self._bookmark_menu.addSeparator() tools_menu = self.menuBar().addMenu("&Tools") download_action = QAction("Open Downloads", self, triggered = DownloadWidget.open_download_directory) tools_menu.addAction(download_action) window_menu = self.menuBar().addMenu("&Window") window_menu.addAction(self._bookmark_dock.toggleViewAction()) window_menu.addSeparator() zoom_in_action = QAction(QIcon.fromTheme("zoom-in"), "Zoom In", self, shortcut = QKeySequence(QKeySequence.ZoomIn), triggered = self._zoom_in) window_menu.addAction(zoom_in_action) zoom_out_action = QAction(QIcon.fromTheme("zoom-out"), "Zoom Out", self, shortcut = QKeySequence(QKeySequence.ZoomOut), triggered = self._zoom_out) window_menu.addAction(zoom_out_action) reset_zoom_action = QAction(QIcon.fromTheme("zoom-original"), "Reset Zoom", self, shortcut = "Ctrl+0", triggered = self._reset_zoom) window_menu.addAction(reset_zoom_action) about_menu = self.menuBar().addMenu("&About") about_action = QAction("About Qt", self, shortcut = QKeySequence(QKeySequence.HelpContents), triggered=qApp.aboutQt) about_menu.addAction(about_action) def add_browser_tab(self): return self._tab_widget.add_browser_tab() def _close_current_tab(self): if self._tab_widget.count() > 1: self._tab_widget.close_current_tab() else: self.close() def close_event(self, event): main_windows.remove(self) event.accept() def load(self): url_string = self._addres_line_edit.text().strip() if url_string: self.load_url_string(url_string) def load_url_string(self, url_s): url = QUrl.fromUserInput(url_s) if (url.isValid()): self.load_url(url) def load_url(self, url): self._tab_widget.load(url) def load_url_in_new_tab(self, url): self.add_browser_tab().load(url) def url_changed(self, url): self._addres_line_edit.setText(url.toString()) def _enabled_changed(self, web_action, enabled): action = self._actions[web_action] if action: action.setEnabled(enabled) def _add_bookmark(self): index = self._tab_widget.currentIndex() if index >= 0: url = self._tab_widget.url() title = self._tab_widget.tabText(index) icon = self._tab_widget.tabIcon(index) self._bookmark_widget.add_bookmark(url, title, icon) def _add_tool_bar_bookmark(self): index = self._tab_widget.currentIndex() if index >= 0: url = self._tab_widget.url() title = self._tab_widget.tabText(index) icon = self._tab_widget.tabIcon(index) self._bookmark_widget.add_tool_bar_bookmark(url, title, icon) def _zoom_in(self): new_zoom = self._tab_widget.zoom_factor() * 1.5 if (new_zoom <= WebEngineView.maximum_zoom_factor()): self._tab_widget.set_zoom_factor(new_zoom) self._update_zoom_label() def _zoom_out(self): new_zoom = self._tab_widget.zoom_factor() / 1.5 if (new_zoom >= WebEngineView.minimum_zoom_factor()): self._tab_widget.set_zoom_factor(new_zoom) self._update_zoom_label() def _reset_zoom(self): self._tab_widget.set_zoom_factor(1) self._update_zoom_label() def _update_zoom_label(self): percent = int(self._tab_widget.zoom_factor() * 100) self._zoom_label.setText("{}%".format(percent)) def _download_requested(self, item): # Remove old downloads before opening a new one for old_download in self.statusBar().children(): if type(old_download).__name__ == 'download_widget' and \ old_download.state() != QWebEngineDownloadItem.DownloadInProgress: self.statusBar().removeWidget(old_download) del old_download item.accept() download_widget = download_widget(item) download_widget.removeRequested.connect(self._remove_download_requested, Qt.QueuedConnection) self.statusBar().addWidget(download_widget) def _remove_download_requested(self): download_widget = self.sender() self.statusBar().removeWidget(download_widget) del download_widget def _show_find(self): if self._find_tool_bar is None: self._find_tool_bar = FindToolBar() self._find_tool_bar.find.connect(self._tab_widget.find) self.addToolBar(Qt.BottomToolBarArea, self._find_tool_bar) else: self._find_tool_bar.show() self._find_tool_bar.focus_find() def write_bookmarks(self): self._bookmark_widget.write_bookmarks()
class Main(QMainWindow): """ MainWindow which contains all widgets of Osmapy. """ def __init__(self, parent=None): super(Main, self).__init__(parent) self.setWindowTitle("Osmapy") path_base = pathlib.Path(__file__).parent icon_path = str(path_base / pathlib.Path("assets/appicon.png")) self.setWindowIcon(QIcon(str(icon_path))) # All widgets should be destroyed when the main window is closed. This the widgets can use the destroyed widget # to allow clean up. E.g. save the database of the TileLoader. self.setAttribute(QtCore.Qt.WA_DeleteOnClose, True) self.resize(config.config.window_size[0], config.config.window_size[1]) self.elements_loader = ElementsLoader() # Element Viewer as DockWidget self.element_viewer = ElementViewer(self) self.dock_element_viewer = QDockWidget() self.dock_element_viewer.setWindowTitle("Element Viewer") self.dock_element_viewer.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable) self.dock_element_viewer.setWidget(self.element_viewer) self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.dock_element_viewer) # LayerManger as DockWidget self.layer_manager = LayerManager(self) self.dock_layer_manager = QDockWidget() self.dock_layer_manager.setWindowTitle("Layer Manager") self.dock_layer_manager.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable) self.dock_layer_manager.setWidget(self.layer_manager) self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.dock_layer_manager) self.viewer = Viewer.Viewer(self) self.setCentralWidget(self.viewer) self.viewer.setFocus() self.viewer.setFocusPolicy(QtCore.Qt.StrongFocus) self.changeset = Changeset(self) self.changset_form = ChangesetForm(self) self.toolbar = QToolBar() self.toolbar.addAction("Load Elements", self.viewer.load_elements) self.toolbar.addAction("Undo Changes", self.viewer.undo_changes) self.toolbar.addAction("Create Node", partial(self.viewer.change_mode, "new_node")) self.toolbar.addAction("Upload Changes", self.changset_form.show) if os.name == "nt": self.toolbar.addAction( "Open Configuration", partial(os.startfile, str(config.path_config))) elif sys.platform == "darwin": self.toolbar.addAction( "Open Configuration", partial(call, ["open", str(config.path_config)])) else: self.toolbar.addAction( "Open Configuration", partial(call, ["xdg-open", str(config.path_config)])) self.addToolBar(self.toolbar) self.statusBar().showMessage("Welcome to Osmapy!")
class AsemblerIDE(QMainWindow): def __init__(self): super(AsemblerIDE, self).__init__() self.workspace = None self.backupTimer = 300000 PathManager.START_DIRECTORY = os.getcwd() self.workspaceConfiguration = WorkspaceConfiguration.loadConfiguration( ) self.snippetManager = SnippetManager.loadSnippetConfiguration() self.tooltipManager = TooltipManager.loadTooltipConfiguration() self.configurationManager = ConfigurationManager() self.editorTabs = EditorTabWidget(self.snippetManager, self.tooltipManager) self.menuBar = MenuBar() self.terminal = Terminal() self.toolBar = ToolBar(self.configurationManager) self.statusBar = StatusBar() self.treeView = TreeView(self.configurationManager) self.help = HelpWidget() self.ascii = AsciiTableWidget() self.setStatusBar(self.statusBar) self.addToolBar(self.toolBar) self.addDockWidget(Qt.BottomDockWidgetArea, self.terminal) self.addDockWidget(Qt.RightDockWidgetArea, self.help) self.addDockWidget(Qt.RightDockWidgetArea, self.ascii) self.splitDockWidget(self.help, self.ascii, Qt.Vertical) self.treeDock = QDockWidget() self.treeDock.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea) self.treeDock.setStyleSheet("background-color: #2D2D30; color: white;") self.treeDock.setFeatures(QDockWidget.DockWidgetMovable | QDockWidget.DockWidgetClosable) self.treeDock.setWindowTitle("Workspace explorer") self.treeDock.setWidget(self.treeView) header = QLabel("Workspace explorer") # header.setStyleSheet("background-color: #007ACC;") self.treeDock.setTitleBarWidget(header) self.addDockWidget(Qt.LeftDockWidgetArea, self.treeDock) self.setMenuBar(self.menuBar) self.setMinimumSize(1200, 800) self.setWindowTitle("i386 Assembly Integrated Development Environment") self.setCentralWidget(self.editorTabs) self.setStyleSheet("background-color: #3E3E42; color: white;") self.setWindowIcon(QIcon(resource_path("resources/app_icon.ico"))) self.addTabWidgetEventHandlers() self.addMenuBarEventHandlers() self.addToolBarEventHandlers() self.addTreeViewEventHandlers() self.checkWorkspaceConfiguration() #self.populateTreeView() #self.statusBar.comboBox.currentTextChanged.connect(self.changeEditorSyntax) self.statusBar.tabWidthComboBox.currentTextChanged.connect( self.changeEditorTabWidth) self.timer = QTimer() self.timer.start(self.backupTimer) self.timer.timeout.connect(self.makeBackupSave) self.terminal.console.setFocus() self.tabSwitcher = TabSwitcher(self.editorTabs) self.tabSwitcher.hide() self.projectSwitcher = ProjectSwitcher(self.configurationManager, self.toolBar.projectComboBox) self.projectSwitcher.hide() self.terminal.projectSwitchRequested.connect(self.showProjectSwitcher) self.terminal.tabSwitchRequested.connect(self.showTabSwitcher) self.editorTabs.tabSwitchRequested.connect(self.showTabSwitcher) self.editorTabs.projectSwitchRequested.connect( self.showProjectSwitcher) self.helpDocsDialog = GettingStartedDialog() self.helpDocsDialog.hide() def makeBackupSave(self): self.workspace.saveBackup() self.timer.setInterval( self.backupTimer ) # interval has to be reset cause the timer may have been paused def changeEditorTabWidth(self, text): currentTab: EditorTab = self.editorTabs.getCurrentTab() if currentTab: currentTab.widget.editor.tabSize = int(text) def changeEditorSyntax(self, text): currentTab: EditorTab = self.editorTabs.getCurrentTab() if currentTab: if text == "Assembly": currentTab.widget.editor.sintaksa = AsemblerSintaksa( currentTab.widget.editor.document()) elif text == "C": currentTab.widget.editor.sintaksa = CSyntax( currentTab.widget.editor.document()) currentTab.widget.editor.update() def checkWorkspaceConfiguration(self): defaultWorkspace = self.workspaceConfiguration.getDefaultWorkspace() if defaultWorkspace: if self.openWorkspaceAction(defaultWorkspace): self.show() return else: self.workspaceConfiguration.removeWorkspace(defaultWorkspace) dialog = WorkspaceConfigurationEditor(self.workspaceConfiguration, self) if dialog.exec_(): self.show() else: sys.exit(0) def addTabWidgetEventHandlers(self): self.editorTabs.currentChanged.connect(self.activeTabChanged) def addTreeViewEventHandlers(self): self.treeView.fileDoubleCliked.connect(self.loadFileText) self.treeView.workspaceReload.connect( lambda wsProxy: self.openWorkspaceAction(wsProxy.path, updateWorkspace=True)) self.treeView.workspaceRename.connect( lambda oldPath, wsProxy: self.workspaceConfiguration. replaceWorkpsace(oldPath, wsProxy.path)) self.treeView.newProjectAdded.connect( lambda: self.toolBar.updateComboBox()) self.treeView.projectCompile.connect( lambda proxy: self.compileAction(proxy)) self.treeView.projectDebug.connect( lambda proxy: self.debugAction(proxy)) self.treeView.projectRun.connect(lambda proxy: self.runAction(proxy)) self.treeView.projectRemove.connect( lambda proxy: self.removeProject(proxy)) self.treeView.projectRename.connect( lambda oldPath, project: self.renameProject(oldPath, project)) self.treeView.fileRemove.connect( lambda fileProxy: self.removeFile(fileProxy)) self.treeView.fileRename.connect( lambda oldPath, fileProxy: self.renameFile(oldPath, fileProxy)) self.treeView.fileSave.connect( lambda fileProxy: self.updateEditorTrie(fileProxy)) self.treeView.invalidWorkspace.connect(self.invalidWorkspace) self.treeView.projectSave.connect(self.saveProject) self.treeView.quickAssemblyFile.connect(self.loadFileText) self.treeView.newFile.connect(self.loadFileText) def saveProject(self, projectProxy: ProjectProxy): self.saveAllFiles(projectProxy) def invalidWorkspace(self, workspace: WorkspaceNode): workspace.deleted = True msg = QMessageBox() msg.setStyleSheet("background-color: #2D2D30; color: white;") msg.setModal(True) msg.setIcon(QMessageBox.Critical) msg.setText("Workspace '{}' has been deleted from the disk.".format( workspace.path)) msg.setWindowTitle("Invalid workspace") msg.exec_() if workspace.path in self.workspaceConfiguration.getWorkspaces(): self.workspaceConfiguration.removeWorkspace(workspace.path) self.switchWorkspaceAction() def renameFile(self, oldPath: str, fileProxy: FileProxy): # fileProxy.text = None key = "{}/{}".format(fileProxy.parent.path, oldPath) if key in self.editorTabs.projectTabs: newKey = "{}/{}".format(fileProxy.parent.path, fileProxy.path) tab = self.editorTabs.projectTabs.pop(key) self.editorTabs.projectTabs[newKey] = tab tab.tabName = newKey index = self.editorTabs.tabs.index(fileProxy) tabText = newKey + "*" if fileProxy.hasUnsavedChanges else newKey self.editorTabs.setTabText(index, tabText) def renameProject(self, oldPath: str, project: ProjectNode): self.toolBar.updateComboBox() for fileProxy in project.proxy.files: oldKey = "{}/{}".format(oldPath, fileProxy.path) if oldKey in self.editorTabs.projectTabs: newKey = "{}/{}".format(project.proxy.path, fileProxy.path) tab = self.editorTabs.projectTabs.pop(oldKey) self.editorTabs.projectTabs[newKey] = tab tab.tabName = newKey index = self.editorTabs.tabs.index(fileProxy) tabText = newKey + "*" if fileProxy.hasUnsavedChanges else newKey self.editorTabs.setTabText(index, tabText) def removeFile(self, proxy: FileProxy): key = "{}/{}".format(proxy.parent.path, proxy.path) if key in self.editorTabs.projectTabs: self.editorTabs.closeTab(self.editorTabs.tabs.index(proxy), askToSave=False) def removeProject(self, proxy: ProjectProxy): for file in proxy.files: if file in self.editorTabs.tabs: self.editorTabs.closeTab(self.editorTabs.tabs.index(file), askToSave=False) self.toolBar.updateComboBox() def checkIfWorkspaceDeleted(self): if not os.path.exists(self.workspace.path): self.workspace.deleted = True def activeTabChanged(self, index): if index == -1: self.statusBar.tabWidthComboBox.setCurrentText('4') return syntax = "Assembly" if self.editorTabs.tabs[index].path[-1].lower( ) == "s" else "C" proxy = self.editorTabs.tabs[index] key = "{}/{}".format(proxy.parent.path, proxy.path) self.statusBar.comboBox.setCurrentText(syntax) self.statusBar.tabWidthComboBox.setCurrentText( str(self.editorTabs.projectTabs[key].widget.editor.tabSize)) #self.changeEditorSyntax(syntax) def populateTreeView(self): workspace = WorkspaceNode() workspace.setText(0, "My workspace") self.treeView.setRoot(workspace) for i in range(5): project = ProjectNode() project.setText(0, "My Project {}".format(i + 1)) assemblyFile = AssemblyFileNode() assemblyFile.setText(0, "procedure_{}.S".format(i + 1)) cFile = CFileNode() cFile.setText(0, "main_{}.c".format(i + 1)) self.treeView.addNode(workspace, project) self.treeView.addNode(project, assemblyFile) self.treeView.addNode(project, cFile) project.setExpanded(True) self.workspace = workspace def closeEvent(self, event): if self.tabSwitcher.isActiveWindow(): self.tabSwitcher.hide() if self.helpDocsDialog.isVisible(): self.helpDocsDialog.hide() for proxy in self.editorTabs.tabs: if proxy.hasUnsavedChanges: msg = QMessageBox() msg.setStyleSheet("background-color: #2D2D30; color: white;") msg.setParent(None) msg.setModal(True) msg.setWindowTitle("Confirm Exit") msg.setText("The file {}/{} has been modified.".format( proxy.parent.path, proxy.path)) msg.setInformativeText("Do you want to save the changes?") msg.setStandardButtons(QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel) msg.setDefaultButton(QMessageBox.Save) retValue = msg.exec_() if retValue == QMessageBox.Save: if not self.saveFileAction(): event.ignore() return elif retValue == QMessageBox.Discard: pass else: event.ignore() return self.workspaceConfiguration.saveConfiguration() self.snippetManager.saveConfiguration() self.tooltipManager.saveConfiguration() self.checkIfWorkspaceDeleted() if not self.workspace.deleted: self.workspace.proxy.closedNormally = True self.saveWorkspaceAction() else: if self.workspace.path in self.workspaceConfiguration.getWorkspaces( ): self.workspaceConfiguration.removeWorkspace( self.workspace.path) super(AsemblerIDE, self).closeEvent(event) def addMenuBarEventHandlers(self): self.menuBar.quickAssemblyProjectAction.triggered.connect( self.quickAssemblyProject) self.menuBar.newWorkspaceAction.triggered.connect( self.newWorkspaceAction) self.menuBar.saveWorkspaceAction.triggered.connect( self.saveWorkpsaceAllFiles) self.menuBar.openWorkspaceAction.triggered.connect( self.openWorkspaceAction) self.menuBar.switchWorkspaceAction.triggered.connect( self.switchWorkspaceAction) self.menuBar.saveAction.triggered.connect(self.saveFileAction) self.menuBar.findAction.triggered.connect(self.findAction) self.menuBar.editDefaultWorkspace.triggered.connect( self.editDefaultWorkspaceConfiguration) self.menuBar.editCodeSnippets.triggered.connect(self.editCodeSnippets) self.menuBar.editSettings.triggered.connect(self.editSettings) self.menuBar.aboutAction.triggered.connect(self.showAbout) self.menuBar.helpAction.triggered.connect(self.showGettingStarted) self.menuBar.view.addAction(self.terminal.toggleViewAction()) self.menuBar.view.addAction(self.treeDock.toggleViewAction()) self.menuBar.view.addAction(self.help.toggleViewAction()) self.menuBar.view.addAction(self.ascii.toggleViewAction()) self.menuBar.view.addAction(self.toolBar.toggleViewAction()) def quickAssemblyProject(self): if self.workspace: self.workspace.createQuickAssemblyProject() def showAbout(self): dialog = AboutDialog() dialog.exec_() def showGettingStarted(self): if self.helpDocsDialog.isHidden(): self.helpDocsDialog.show() def findAction(self): currentTab: EditorTabWidget = self.editorTabs.getCurrentTab() if not currentTab: msg = QMessageBox() msg.setStyleSheet("background-color: #2D2D30; color: white;") msg.setModal(True) msg.setIcon(QMessageBox.Critical) msg.setText( "Cannot open file and replace window because there is no open file at the moment." ) msg.setWindowTitle("Find & Replace error") msg.exec_() return currentTab.widget.find.setVisible(True) if currentTab.widget.editor.lastFind: currentTab.widget.find.findLabel.setText( currentTab.widget.editor.lastFind) currentTab.widget.find.findLabel.setFocus() def switchWorkspaceAction(self): remaining = self.timer.remainingTime() self.timer.stop( ) # timer for creating backups needs to be paused when switching ws dialog = WorkspaceConfigurationEditor(self.workspaceConfiguration, self, switch=True) if dialog.exec_() and dialog.workspaceDirectory: self.workspace.proxy.closedNormally = True self.saveWorkspaceAction() if not self.editorTabs.closeAllTabs(): self.timer.start( remaining) # timer for saving backups is resumed return self.openWorkspaceAction(dialog.workspaceDirectory) self.timer.start(remaining) # timer for saving backups is resumed def editDefaultWorkspaceConfiguration(self): editor = DefaultWorkspaceEditor(self.workspaceConfiguration) if editor.exec_(): self.workspaceConfiguration.saveConfiguration() def editCodeSnippets(self): editor = SnippetEditor(self.snippetManager) if editor.exec_(): self.snippetManager.saveConfiguration() def editSettings(self): editor = SettingsEditor(self.tooltipManager) if editor.exec_(): self.tooltipManager.saveConfiguration() def newWorkspaceAction(self): remaining = self.timer.remainingTime() self.timer.stop( ) # timer for creating backups needs to be paused when switching ws if not self.editorTabs.closeAllTabs(): self.timer.start(remaining) # timer for saving backups is resumed return False self.workspace.proxy.closedNormally = True self.saveWorkspaceAction() workspace = WorkspaceNode() name = QFileDialog.getExistingDirectory( self, "New workspace", "select new workspace directory") if name: path = os.path.join(name, ".metadata") backup_path = os.path.join(name, ".backup") if os.path.isdir(path) or os.path.isdir(backup_path): self.msgInvalidFolderError(name) self.timer.start( remaining) # timer for saving backups is resumed return wsname = name[name.rindex(os.path.sep) + 1:] regex = re.compile('[@!#$%^&*()<>?/\|}{~:]') if ' ' in name or regex.search(wsname): msg = QMessageBox() msg.setStyleSheet("background-color: #2D2D30; color: white;") msg.setModal(True) msg.setIcon(QMessageBox.Critical) msg.setText( "Workspace path/name cannot contain whitespace or special characters." ) msg.setWindowTitle("Workspace creation error") msg.exec_() self.timer.start( remaining) # timer for saving backups is resumed return False workspace.path = name proxy = WorkspaceProxy() proxy.path = name workspace.proxy = proxy workspace.setIcon(0, QIcon(resource_path("resources/workspace.png"))) workspace.setText(0, wsname) self.workspace = workspace self.treeView.setRoot(self.workspace) self.saveWorkspaceAction() self.configurationManager.allProjects = [] self.configurationManager.currentProject = None self.toolBar.updateComboBox() self.terminal.executeCommand("cd {}".format(self.workspace.path)) self.workspaceConfiguration.addWorkspace(self.workspace.proxy.path) self.timer.start(remaining) # timer for saving backups is resumed return True self.timer.start(remaining) # timer for saving backups is resumed return False def saveWorkspaceAction(self, workspacePath=None): if self.workspace: self.workspace.saveWorkspace(workspacePath) def saveWorkpsaceAllFiles(self): self.saveAllFiles() self.saveWorkspaceAction() def updateProjectList(self): self.configurationManager.allProjects = [] self.configurationManager.currentProject = None projects = self.treeView.getProjects() if len(projects): self.configurationManager.allProjects = self.treeView.getProjects() self.configurationManager.currentProject = projects[0] self.toolBar.updateComboBox() def openWorkspaceAction(self, workspacePath=None, updateWorkspace=False): if not self.editorTabs.closeAllTabs(): return if not workspacePath: workspacePath = QFileDialog.getExistingDirectory( self, "Open workspace", "select new workspace directory") if not workspacePath: return regex = re.compile('[@!#$%^&*()<>?/\|}{~:]') if ' ' in workspacePath or regex.search( os.path.basename(workspacePath)): msg = QMessageBox() msg.setStyleSheet("background-color: #2D2D30; color: white;") msg.setModal(True) msg.setIcon(QMessageBox.Critical) msg.setText( "Workspace path/name cannot contain whitespace or special characters." ) msg.setWindowTitle("Workspace creation error") msg.exec_() return False path = os.path.join(workspacePath, ".metadata") backup_path = os.path.join(workspacePath, ".backup") if os.path.isdir(path) or os.path.isdir(backup_path): self.msgInvalidFolderError(workspacePath) return workspace = WorkspaceProxy() self.workspace = WorkspaceNode() if os.path.exists(path): try: # in try block in case there is a corrupted .metadata file on the path with open(path, 'rb') as file: workspace = pickle.load(file) except: workspace.closedNormally = False # set it to false to trigger backup msg in case .metadata is corrupted elif not os.path.exists( backup_path ): # creates a .metadata file for a clean new workspace self.workspace.proxy = workspace self.applyWsCompatibilityFix(workspacePath) self.saveWorkspaceAction(workspacePath) self.workspace.proxy = workspace self.applyWsCompatibilityFix(workspacePath) attempted_backup = False if not self.workspace.proxy.closedNormally: if self.restoreBackupMessage(workspacePath, updateWorkspace=updateWorkspace): attempted_backup = True if self.loadWorkspaceAction( workspacePath, backup=True): # attempt to load backup self.updateProjectList() return True else: self.messageBackupError("closedAbruptly") if self.loadWorkspaceAction( workspacePath, backup=False): # attempt to load regular ws file self.updateProjectList() return True # If the regular file won't load for some reason and there was no backup attempt, ask to load the backup file elif not attempted_backup and self.restoreBackupMessage( workspacePath, failedToLoad=True): if self.loadWorkspaceAction( workspacePath, backup=True): # attempt to load the backup file self.updateProjectList() return True else: self.messageBackupError() return False def msgInvalidFolderError(self, path): msg = QMessageBox() msg.setStyleSheet("background-color: #2D2D30; color: white;") msg.setModal(True) msg.setIcon(QMessageBox.Critical) msg.setText( "Invalid folder for a workspace." "\nEnsure there are no .metadata and .backup folders in \n{}". format(path)) msg.setWindowTitle("Failed to load workspace.") msg.exec_() def messageBackupError(self, msgType=None): msg = QMessageBox() msg.setStyleSheet("background-color: #2D2D30; color: white;") msg.setModal(True) msg.setIcon(QMessageBox.Critical) if msgType == "closedAbruptly": msg.setText("Failed to load {}." "\nRegular workspace save will be restored.".format( ".backup workspace file")) else: msg.setText("Failed to load {}.".format(".backup workspace file")) msg.setWindowTitle("Failed to load backup workspace.") msg.exec_() def applyWsCompatibilityFix(self, workspacePath): try: closedNormally = self.workspace.proxy.closedNormally except AttributeError: closedNormally = True self.workspace.proxy.closedNormally = closedNormally # adds attribute to old ws files self.workspace.path = workspacePath # changes the path to currently selected dir, in case it was moved self.workspace.proxy.path = workspacePath def restoreBackupMessage(self, wsName, failedToLoad=False, updateWorkspace=False): try: msg = QMessageBox() msg.setStyleSheet("background-color: #2D2D30; color: white;") msg.setParent(None) msg.setModal(True) msg.setWindowTitle("Workspace recovery") time = strftime( '%m/%d/%Y %H:%M:%S', localtime(os.path.getmtime(os.path.join(wsName, ".backup")))) if failedToLoad: msg.setText("The workplace {} could not be loaded.\n" "\nTime the backup was created: {}".format( wsName, time)) elif updateWorkspace: msg.setText( "Choose if you want to reload workspace or to recover from backup.\n" "\nTime the backup was created: {}".format(wsName, time)) else: msg.setText("The workplace {} was closed unexpectedly.\n" "\nTime the backup was created: {}".format( wsName, time)) if not updateWorkspace: msg.setInformativeText( "Would you like to recover from backup?") else: msg.setInformativeText( "Would you like to recover from backup? Select No if you just want to update the workspace." ) msg.setStandardButtons(QMessageBox.Yes | QMessageBox.No) msg.setDefaultButton(QMessageBox.Yes) retValue = msg.exec_() if retValue == QMessageBox.Yes: return True else: return except: return False def loadWorkspaceAction(self, workspacePath, backup=False): if backup: path = os.path.join(workspacePath, ".backup") else: path = os.path.join(workspacePath, ".metadata") if os.path.exists(path): try: # in try block in case there is a corrupted .metadata file on the path with open(path, 'rb') as file: workspace = pickle.load(file) except: return False else: return False self.workspace = WorkspaceNode() self.workspace.proxy = workspace self.applyWsCompatibilityFix(workspacePath) self.workspace.setIcon(0, QIcon(resource_path("resources/workspace.png"))) self.workspace.setText( 0, workspacePath[workspacePath.rindex(os.path.sep) + 1:]) self.workspace.proxy.closedNormally = False if backup: success = self.workspace.loadBackupWorkspace(workspacePath) else: success = self.workspace.loadWorkspace() if not success: return False self.treeView.setRoot(self.workspace) projects = self.treeView.getProjects() if projects: self.configurationManager.allProjects.clear() self.configurationManager.allProjects.extend(projects) self.toolBar.updateComboBox() #self.treeView.expandAll() self.terminal.executeCommand("cd {}".format(self.workspace.path)) self.workspaceConfiguration.addWorkspace(self.workspace.proxy.path) if workspacePath: self.saveWorkspaceAction(workspacePath) return True def addToolBarEventHandlers(self): self.toolBar.compile.triggered.connect(self.compileAction) self.toolBar.run.triggered.connect(self.runAction) self.toolBar.debug.triggered.connect(self.debugAction) def debugAction(self, projectProxy=None): currentProject: ProjectNode = self.configurationManager.currentProject if not currentProject: self.showNoCurrentProjectMessage("Debug") return if not os.path.exists(currentProject.proxy.getProjectPath()): currentProject.eventManager.invalidProject.emit(currentProject) return proxy = None if projectProxy: proxy = projectProxy else: if currentProject: proxy = currentProject.proxy if proxy: commandString = proxy.getProjectDebugCommand() self.terminal.console.setFocus() if self.terminal.executeCommand(proxy.getProjectCompileCommand()): copmileString = proxy.getProjectCompileCommand() if ' -g ' not in copmileString: msg = QMessageBox() msg.setStyleSheet( "background-color: #2D2D30; color: white;") msg.setModal(True) msg.setIcon(QMessageBox.Warning) msg.setText( "Please set '-g' option in compiler configuration to be able to debug your project." ) msg.setWindowTitle("Debug warning") msg.exec_() return False self.terminal.executeCommand(commandString) self.toolBar.projectComboBox.setCurrentText(proxy.path) def runAction(self, projectProxy=None): currentProject: ProjectNode = self.configurationManager.currentProject if not currentProject: self.showNoCurrentProjectMessage("Run") return if not os.path.exists(currentProject.proxy.getProjectPath()): currentProject.eventManager.invalidProject.emit(currentProject) return proxy = None if projectProxy: proxy = projectProxy else: if currentProject: proxy = currentProject.proxy if proxy: commandString = proxy.getProjectRunCommand() self.terminal.console.setFocus() if self.terminal.executeCommand(proxy.getProjectCompileCommand()): self.terminal.executeCommand(commandString) self.toolBar.projectComboBox.setCurrentText(proxy.path) def compileAction(self, projectProxy=None): currentProject: ProjectNode = self.configurationManager.currentProject if not currentProject: self.showNoCurrentProjectMessage("Compile") return if not os.path.exists(currentProject.proxy.getProjectPath()): currentProject.eventManager.invalidProject.emit(currentProject) return proxy = None if projectProxy: proxy = projectProxy else: if currentProject: proxy = currentProject.proxy if proxy: commandString = proxy.getProjectCompileCommand() self.terminal.console.setFocus() self.terminal.executeCommand(commandString) self.toolBar.projectComboBox.setCurrentText(proxy.path) def showNoCurrentProjectMessage(self, action: str): msg = QMessageBox() msg.setStyleSheet("background-color: #2D2D30; color: white;") msg.setModal(True) msg.setIcon(QMessageBox.Critical) msg.setText("You have to select a project first.") msg.setWindowTitle("{} error".format(action.capitalize())) msg.exec_() def checkExecutable(self): if self.editor.filePath: destination = self.editor.filePath[:-1] + "out" return os.path.exists(destination) return None def loadFileText(self, fileProxy): key = "{}/{}".format(fileProxy.parent.path, fileProxy.path) if key in self.editorTabs.projectTabs: self.editorTabs.setCurrentIndex( self.editorTabs.tabs.index(fileProxy)) return text = self.openFileAction(fileProxy) fileProxy.text = text fileProxy.hasUnsavedChanges = False if fileProxy.getFilePath()[-1].lower() == "c": currentText = "C" else: currentText = "Assembly" update = True if len(self.editorTabs.tabs) == 0: self.editorTabs.tabs.append(fileProxy) update = False self.editorTabs.addNewTab(fileProxy, update) self.statusBar.comboBox.setCurrentText(currentText) if currentText == "Assembly": self.editorTabs.projectTabs[ key].widget.editor.sintaksa = AsemblerSintaksa( self.editorTabs.projectTabs[key].widget.editor.document()) elif currentText == "C": self.editorTabs.projectTabs[key].widget.editor.sintaksa = CSyntax( self.editorTabs.projectTabs[key].widget.editor.document()) def updateEditorTrie(self, proxy: FileProxy): key = "{}/{}".format(proxy.parent.path, proxy.path) if key in self.editorTabs.projectTabs: self.editorTabs.projectTabs[key].widget.editor.updateTrie() self.editorTabs.removeChangeIdentificator(proxy) def saveAllFiles(self, projectProxy=None): couldNotBeSaved = [] for i in range(len(self.editorTabs.tabs)): fileProxy = self.editorTabs.tabs[i] try: if fileProxy and fileProxy.hasUnsavedChanges: if projectProxy and fileProxy.parent.path != projectProxy.path: continue with open(fileProxy.getFilePath(), 'w') as file: file.write(fileProxy.text) fileProxy.hasUnsavedChanges = False self.updateEditorTrie(fileProxy) except: couldNotBeSaved.append(fileProxy.path) self.saveWorkspaceAction() if couldNotBeSaved: msg = QMessageBox() msg.setStyleSheet("background-color: #2D2D30; color: white;") msg.setModal(True) msg.setIcon(QMessageBox.Critical) msg.setText("The following file(s) could not be saved: {}".format( ','.join(couldNotBeSaved))) msg.setWindowTitle("File save error") msg.exec_() def saveFileAction(self): if len(self.editorTabs.tabs): proxy = self.editorTabs.getCurrentFileProxy() if proxy and proxy.hasUnsavedChanges: try: with open(proxy.getFilePath(), 'w') as file: file.write(proxy.text) proxy.hasUnsavedChanges = False self.updateEditorTrie(proxy) except: msg = QMessageBox() msg.setStyleSheet( "background-color: #2D2D30; color: white;") msg.setModal(True) msg.setIcon(QMessageBox.Critical) msg.setText( "The following file could not be saved: {}".format( proxy.path)) msg.setWindowTitle("File save error") msg.exec_() self.saveWorkspaceAction() return True def openFileAction(self, fileName: FileProxy): text = None # if fileName.text: # return fileName.text with open(fileName.getFilePath(), 'r') as file: text = file.read() return text def keyPressEvent(self, event): if event.modifiers() == Qt.ControlModifier: if event.key() == Qt.Key_Tab: self.showTabSwitcher() elif event.key() == Qt.Key_E: self.showProjectSwitcher() super(AsemblerIDE, self).keyPressEvent(event) def showProjectSwitcher(self): if self.projectSwitcher.isHidden() and len( self.configurationManager.allProjects): self.projectSwitcher.showSwitcher() self.projectSwitcher.setFocus() def showTabSwitcher(self): if self.tabSwitcher.isHidden() and len(self.editorTabs.tabs): self.tabSwitcher.showSwitcher() self.tabSwitcher.setFocus()