def __init__(self): QWidget.__init__(self) self.setMinimumSize(1000,500) self.html = QWebView() vbox=QVBoxLayout() toolbar=QToolBar() toolbar.setIconSize(QSize(48, 48)) back = QAction(QIcon(os.path.join(get_image_file_path(),"left.png")), _("back"), self) back.triggered.connect(self.html.back) toolbar.addAction(back) home = QAction(QIcon(os.path.join(get_image_file_path(),"home.png")), _("home"), self) home.triggered.connect(self.home) toolbar.addAction(home) self.tb_url=QLineEdit() self.tb_url.returnPressed.connect(self.browse) toolbar.addWidget(self.tb_url) vbox.addWidget(toolbar) self.default_url = "http://www.gpvdm.com/welcome.html" self.tb_url.setText(self.default_url) self.browse() vbox.addWidget(self.html) self.setLayout(vbox) return
def initUI(self): # definisco le azioni exitAction = QAction(QIcon('exit.png'), 'Exit', self) exitAction.setShortcut('Ctrl+Q') exitAction.setStatusTip('Exit application') exitAction.triggered.connect(self.close) # creo la barra dei menu e aggiungo i menu menubar = self.menuBar() menubar.setNativeMenuBar(False) fileMenu = menubar.addMenu('&File') fileMenu.addAction(exitAction) # creo la toolbar toolbar = QToolBar() toolbar.addAction(exitAction) self.addToolBar(Qt.RightToolBarArea, toolbar) # toolbar di default sul lato destro della finestra # aggiungo il widget centrale self.setCentralWidget(LoginWindow(self)) # cambio posizione e dimensioni della finestra e ne definisco il titiolo infine la faccio apparire self.resize(600, 400) qr = self.frameGeometry() cp = QDesktopWidget().availableGeometry().center() qr.moveCenter(cp) self.move(qr.topLeft()) self.setWindowTitle('Main window') self.show() # imposto la statusbar per scrivere che l'app è pronta self.statusBar().showMessage('Ready')
def __init__(self, parentWidget, settings): QWidget.__init__(self, parentWidget) self.settings = settings toolbar = QToolBar(self) toolbar.setFloatable(False) toolbar.setMovable(False) addAction = QAction("+", toolbar) addAction.triggered.connect(self.addNotepad) toolbar.addAction(addAction) removeAction = QAction("-", toolbar) removeAction.triggered.connect(self.removeNotepad) toolbar.addAction(removeAction) self.browserView = TreeWidget(self) hLayout = QVBoxLayout(self) hLayout.setContentsMargins(0, 0, 0, 1) hLayout.addWidget(toolbar) hLayout.addWidget(self.browserView) self.currentItem = None self.browserView.itemSelectionChanged.connect(self.handleItemSelected)
def initUI(self): self.setWindowTitle("Children of the Goddess") # definisco l'azione ala chiusura exitAction = QAction(QIcon('exit.png'), 'Exit', self) exitAction.setShortcut('Ctrl+Q') exitAction.setStatusTip('Exit application') exitAction.triggered.connect(self.close) # creo la barra dei menu e aggiungo i menu menubar = self.menuBar() menubar.setNativeMenuBar(False) fileMenu = menubar.addMenu('&File') fileMenu.addAction(exitAction) # creo la toolbar toolbar = QToolBar() toolbar.addAction(exitAction) self.addToolBar(Qt.RightToolBarArea, toolbar) # toolbar di default sul lato destro della finestra # cambio posizione e dimensioni della finestra e ne definisco il titiolo infine la faccio apparire self.resize(600, 400) qr = self.frameGeometry() cp = QDesktopWidget().availableGeometry().center() qr.moveCenter(cp) self.move(qr.topLeft()) self.setWindowTitle('Main window') self.show()
def __init__(self, page, parent=None): super(HelpForm, self).__init__(parent) self.setAttribute(Qt.WA_DeleteOnClose) self.setWindowModality(Qt.WindowModal) # actions backAction = QAction(QIcon(":/back.png"), "&Back", self) backAction.setShortcut(QKeySequence.Back) homeAction = QAction(QIcon(":/home.png"), "&Home", self) homeAction.setShortcut("Home") self.pageLabel = QLabel() #toolbar toolBar = QToolBar() toolBar.addAction(backAction) toolBar.addAction(homeAction) toolBar.addWidget(self.pageLabel) self.textBrowser = QTextBrowser() # layout layout = QVBoxLayout() layout.addWidget(toolBar) layout.addWidget(self.textBrowser, 1) self.setLayout(layout) # signals and slots backAction.triggered.connect(self.textBrowser.backward) homeAction.triggered.connect(self.textBrowser.home) self.textBrowser.sourceChanged.connect(self.updatePageTitle) self.textBrowser.setSearchPaths([":/help"]) self.textBrowser.setSource(QUrl(page)) self.resize(400, 600) self.setWindowTitle("{0} Help".format( QApplication.applicationName()))
def __init__(self,index): QWidget.__init__(self) self.index=index self.vbox=QVBoxLayout() toolbar=QToolBar() toolbar.setIconSize(QSize(48, 48)) self.tb_save = QAction(QIcon(os.path.join(get_image_file_path(),"add.png")), _("Add"), self) self.tb_save.triggered.connect(self.callback_add_item) toolbar.addAction(self.tb_save) self.tb_save = QAction(QIcon(os.path.join(get_image_file_path(),"minus.png")), _("Minus"), self) self.tb_save.triggered.connect(self.callback_delete_item) toolbar.addAction(self.tb_save) self.vbox.addWidget(toolbar) self.tab = QTableWidget() self.tab.resizeColumnsToContents() self.tab.verticalHeader().setVisible(False) self.create_model() self.tab.cellChanged.connect(self.tab_changed) self.vbox.addWidget(self.tab) self.setLayout(self.vbox)
def init(self): self.main_vbox = QVBoxLayout() toolbar=QToolBar() toolbar.setIconSize(QSize(32, 32)) self.tb_save = QAction(QIcon(os.path.join(get_image_file_path(),"save.svg")), "Save image", self) self.tb_save.setStatusTip(_("Close")) self.tb_save.triggered.connect(self.callback_save_image) toolbar.addAction(self.tb_save) self.main_vbox.addWidget(toolbar) self.my_figure=Figure(figsize=(5,4), dpi=100) self.canvas = FigureCanvas(self.my_figure) self.canvas.mpl_connect('key_press_event', self.press) self.canvas.setFocusPolicy( Qt.ClickFocus ) self.canvas.setFocus() self.canvas.figure.patch.set_facecolor('white') #self.canvas.set_size_request(600, 400) self.canvas.show() self.main_vbox.addWidget(self.canvas) #self.canvas.connect('key_press_event', self.on_key_press_event) self.setLayout(self.main_vbox)
def __init__(self, parent, *args): QToolBar.__init__(self, parent, *args) self.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Maximum)) self._dock = parent self.aClose = QToolBar.addAction(self, self.style().standardIcon(QStyle.SP_TitleBarCloseButton), "") closeIcon = self.style().standardIcon(QStyle.SP_DockWidgetCloseButton) if not closeIcon.availableSizes(): # SP_DockWidgetCloseButton is missing on Fedora. Why??? Using fallback closeIcon = self.style().standardIcon( QStyle.SP_DialogCloseButton) self.aClose = QToolBar.addAction(self, closeIcon, "") self.setMovable(False) self.setFloatable(False) self.aClose.triggered.connect(self._dock.close) textHeight = QFontMetrics(self.font()).height() self.setIconSize(QSize(textHeight, textHeight)) # a fake spacer widget self._spacer = QWidget(self) self._spacer.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.MinimumExpanding)) self.addWidget(self._spacer)
def __init__ (self, parent): super().__init__(parent) self.search = SearchWidget(self) self.search.searched.connect(self.populatelist) self.nodelist = QListWidget(self) self.nodelist.setSortingEnabled(True) self.nodelist.setIconSize(QSize(*(FlGlob.mainwindow.style.boldheight,)*2)) self.nodelist.currentItemChanged.connect(self.selectnode) self.nodelist.itemSelectionChanged.connect(self.onselectionchange) self.nodelist.itemActivated.connect(self.activatenode) self.nodelist.setSelectionMode(QAbstractItemView.ExtendedSelection) remwidget = QToolBar(self) remselected = QAction("Remove Selected", self) remselected.setIcon(QIcon.fromTheme("edit-delete")) remselected.setToolTip("Remove selected") remselected.triggered.connect(self.remselected) self.remselaction = remselected remtrash = QAction("Remove Trash", self) remtrash.setIcon(QIcon.fromTheme("edit-clear")) remtrash.setToolTip("Clear all trash") remtrash.triggered.connect(self.remtrash) self.remtrashaction = remtrash remwidget.addAction(remselected) remwidget.addAction(remtrash) layout = QVBoxLayout(self) layout.addWidget(self.search) layout.addWidget(self.nodelist) layout.addWidget(remwidget) self.view = None self.active = False self.setEnabled(False)
def __init__(self): QWidget.__init__(self) self.win_list=windows() self.setFixedSize(900, 600) self.setWindowIcon(QIcon(os.path.join(get_image_file_path(),"doping.png"))) self.setWindowTitle(_("Doping profile editor (www.gpvdm.com)")) self.win_list.set_window(self,"doping") self.main_vbox=QVBoxLayout() toolbar=QToolBar() toolbar.setIconSize(QSize(48, 48)) self.save = QAction(QIcon(os.path.join(get_image_file_path(),"save.png")), _("Save"), self) self.save.triggered.connect(self.callback_save) toolbar.addAction(self.save) spacer = QWidget() spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) toolbar.addWidget(spacer) self.help = QAction(QIcon(os.path.join(get_image_file_path(),"help.png")), _("Help"), self) self.help.triggered.connect(self.callback_help) toolbar.addAction(self.help) self.main_vbox.addWidget(toolbar) self.fig = Figure(figsize=(5,4), dpi=100) self.ax1=None self.show_key=True canvas = FigureCanvas(self.fig) #canvas.set_background('white') #canvas.set_facecolor('white') canvas.figure.patch.set_facecolor('white') canvas.show() self.main_vbox.addWidget(canvas) self.tab = QTableWidget() self.tab.resizeColumnsToContents() self.tab.verticalHeader().setVisible(False) self.tab.clear() self.tab.setColumnCount(4) self.tab.setSelectionBehavior(QAbstractItemView.SelectRows) self.load() self.build_mesh() self.tab.cellChanged.connect(self.tab_changed) self.main_vbox.addWidget(self.tab) self.draw_graph() self.setLayout(self.main_vbox) return
def init(self): self.fig = Figure(figsize=(5, 4), dpi=100) self.canvas = FigureCanvas(self.fig) self.canvas.figure.patch.set_facecolor("white") self.main_vbox = QVBoxLayout() toolbar = QToolBar() toolbar.setIconSize(QSize(48, 48)) self.tb_save = QAction(QIcon(os.path.join(get_image_file_path(), "32_save.png")), _("Save image"), self) self.tb_save.triggered.connect(self.callback_save) toolbar.addAction(self.tb_save) self.tb_ref = QAction( QIcon(os.path.join(get_image_file_path(), "32_ref.png")), _("Insert reference information"), self ) self.tb_ref.triggered.connect(self.callback_ref) toolbar.addAction(self.tb_ref) self.main_vbox.addWidget(toolbar) self.main_vbox.addWidget(self.canvas) # toolbar 2 toolbar2 = QToolBar() toolbar2.setIconSize(QSize(48, 48)) self.tb_add = QAction(QIcon(os.path.join(get_image_file_path(), "add.png")), _("Add section"), self) self.tb_add.triggered.connect(self.callback_add_section) toolbar2.addAction(self.tb_add) self.tb_remove = QAction(QIcon(os.path.join(get_image_file_path(), "minus.png")), _("Delete section"), self) self.tb_remove.triggered.connect(self.callback_remove_item) toolbar2.addAction(self.tb_remove) self.tb_move = QAction(QIcon(os.path.join(get_image_file_path(), "down.png")), _("Move down"), self) self.tb_move.triggered.connect(self.callback_move_down) toolbar2.addAction(self.tb_move) self.main_vbox.addWidget(toolbar2) self.tab = QTableWidget() self.tab.resizeColumnsToContents() self.tab.verticalHeader().setVisible(False) self.main_vbox.addWidget(self.tab) self.setLayout(self.main_vbox) self.load_data() self.build_mesh() self.draw_graph() self.tab.cellChanged.connect(self.on_cell_edited)
def __init__(self, parent = None): super().__init__(parent) self.mTile = None self.mMapDocument = None self.mMapScene = MapScene(self) self.mMapView = MapView(self, MapViewMode.NoStaticContents) self.mToolManager = ToolManager(self) self.mApplyingChanges = False self.mSynchronizing = False self.setObjectName("TileCollisionEditor") widget = QWidget(self) layout = QVBoxLayout(widget) layout.setSpacing(0) layout.setContentsMargins(5, 5, 5, 5) self.mMapView.setScene(self.mMapScene) self.mMapView.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) self.mMapView.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) rectangleObjectsTool = CreateRectangleObjectTool(self) ellipseObjectsTool = CreateEllipseObjectTool(self) polygonObjectsTool = CreatePolygonObjectTool(self) polylineObjectsTool = CreatePolylineObjectTool(self) toolBar = QToolBar(self) toolBar.setMovable(False) toolBar.setFloatable(False) toolBar.setContextMenuPolicy(Qt.ActionsContextMenu) self.mToolManager = ToolManager(self) toolBar.addAction(self.mToolManager.registerTool(ObjectSelectionTool(self))) toolBar.addAction(self.mToolManager.registerTool(EditPolygonTool(self))) toolBar.addAction(self.mToolManager.registerTool(rectangleObjectsTool)) toolBar.addAction(self.mToolManager.registerTool(ellipseObjectsTool)) toolBar.addAction(self.mToolManager.registerTool(polygonObjectsTool)) toolBar.addAction(self.mToolManager.registerTool(polylineObjectsTool)) self.setCentralWidget(self.mMapView) self.addToolBar(toolBar) self.mMapScene.setSelectedTool(self.mToolManager.selectedTool()) self.mToolManager.selectedToolChanged.connect(self.setSelectedTool) zoomComboBox = QComboBox() self.statusBar().addPermanentWidget(zoomComboBox) zoomable = self.mMapView.zoomable() zoomable.connectToComboBox(zoomComboBox) undoShortcut = QShortcut(QKeySequence.Undo, self) redoShortcut = QShortcut(QKeySequence.Redo, self) cutShortcut = QShortcut(QKeySequence.Cut, self) copyShortcut = QShortcut(QKeySequence.Copy, self) pasteShortcut = QShortcut(QKeySequence.Paste, self) deleteShortcut = QShortcut(QKeySequence.Delete, self) deleteShortcut2 = QShortcut(QKeySequence.Back, self) undoShortcut.activated.connect(self.undo) redoShortcut.activated.connect(self.redo) cutShortcut.activated.connect(self.cut) copyShortcut.activated.connect(self.copy) pasteShortcut.activated.connect(self.paste) deleteShortcut.activated.connect(self.delete_) deleteShortcut2.activated.connect(self.delete_) self.retranslateUi() self.resize(300, 300) Utils.restoreGeometry(self)
def initUI(self): QToolTip.setFont(QFont('SansSerif', 10)) self.setToolTip('This is a <b>QWidget</b> widget.') #quitBtn = QPushButton('Quit', self) #quitBtn.clicked.connect(self.quitBtnEvent()) #quitBtn.clicked.connect(QCoreApplication.instance().quit) #quitBtn.setToolTip('This is a <b>QPushButton</b> widget.') #quitBtn.resize(quitBtn.sizeHint()) exitAction = QAction(QIcon('application-exit-4.png'), '&Exit', self) exitAction.setShortcut('Alt+F4') exitAction.setStatusTip('Exit Application') exitAction.triggered.connect(qApp.quit) menuBar = QMenuBar() fileMenu = menuBar.addMenu('&File') fileMenu.addAction(exitAction) fileMenu.resize(fileMenu.sizeHint()) toolBar = QToolBar(self) toolBar.addAction(exitAction) #toolBar.resize(toolBar.sizeHint()) toolBar.setFixedHeight(60) hozLine = QFrame() hozLine.setFrameStyle(QFrame.HLine) #hozLine.setSizePolicy(QSizePolicy.Minimum,QSizePolicy.Expanding) statusBar = QStatusBar(self) statusBar.showMessage('Ready') grid = QGridLayout() lbl_1 = QLabel('1,1') lbl_2 = QLabel('1,2') lbl_3 = QLabel('2,1') lbl_4 = QLabel('2,2') grid.addWidget(lbl_1, 1, 1) grid.addWidget(lbl_2, 1, 2) grid.addWidget(lbl_3, 2, 1) grid.addWidget(lbl_4, 2, 2) vbox = QVBoxLayout() vbox.addWidget(menuBar) vbox.addWidget(hozLine) vbox.addWidget(toolBar) # vbox.addWidget(hozLine) vbox.addLayout(grid) vbox.addStretch(1) vbox.addWidget(statusBar) self.setLayout(vbox) self.setGeometry(300, 300, 500, 500) self.setWindowTitle('Photos') self.setWindowIcon(QIcon('camera-photo-5.png')) self.center() self.show()
def setupEditActions(self): tb = QToolBar(self) tb.setWindowTitle("Edit Actions") self.addToolBar(tb) menu = QMenu("&Edit", self) self.menuBar().addMenu(menu) self.actionUndo = QAction( QIcon.fromTheme("edit-undo", QIcon(rsrcPath + "/editundo.png")), "&Undo", self, shortcut=QKeySequence.Undo ) tb.addAction(self.actionUndo) menu.addAction(self.actionUndo) self.actionRedo = QAction( QIcon.fromTheme("edit-redo", QIcon(rsrcPath + "/editredo.png")), "&Redo", self, priority=QAction.LowPriority, shortcut=QKeySequence.Redo, ) tb.addAction(self.actionRedo) menu.addAction(self.actionRedo) menu.addSeparator() self.actionCut = QAction( QIcon.fromTheme("edit-cut", QIcon(rsrcPath + "/editcut.png")), "Cu&t", self, priority=QAction.LowPriority, shortcut=QKeySequence.Cut, ) tb.addAction(self.actionCut) menu.addAction(self.actionCut) self.actionCopy = QAction( QIcon.fromTheme("edit-copy", QIcon(rsrcPath + "/editcopy.png")), "&Copy", self, priority=QAction.LowPriority, shortcut=QKeySequence.Copy, ) tb.addAction(self.actionCopy) menu.addAction(self.actionCopy) self.actionPaste = QAction( QIcon.fromTheme("edit-paste", QIcon(rsrcPath + "/editpaste.png")), "&Paste", self, priority=QAction.LowPriority, shortcut=QKeySequence.Paste, enabled=(len(QApplication.clipboard().text()) != 0), ) tb.addAction(self.actionPaste) menu.addAction(self.actionPaste)
def init_chrome(self): self.setWindowTitle("FeedViewer") # Set up the minimal FeedViewer chrome toolbar = QToolBar("Toolbar") self.addToolBar(toolbar) btn_act = QAction("<<", self) # for an icon: QAction(QIcon("bug.png"), "Your button", self) btn_act.setStatusTip("Go back") btn_act.triggered.connect(self.go_back) toolbar.addAction(btn_act) btn_act = QAction("Feeds", self) btn_act.setStatusTip("Go forward") btn_act.triggered.connect(self.feed_page) toolbar.addAction(btn_act) btn_act = QAction("Del", self) btn_act.setStatusTip("Go forward") btn_act.triggered.connect(self.delete_feed) toolbar.addAction(btn_act) btn_act = QAction("ToC", self) btn_act.setStatusTip("Go forward") btn_act.triggered.connect(self.table_of_contents) toolbar.addAction(btn_act) btn_act = QAction(">>", self) btn_act.setStatusTip("Go forward") btn_act.triggered.connect(self.go_forward) toolbar.addAction(btn_act) self.webviews = [] self.tabwidget = QTabWidget() self.tabwidget.setTabBarAutoHide(True) self.setCentralWidget(self.tabwidget) self.tabwidget.tabBar().installEventFilter(self) self.prev_middle = -1 self.active_tab = 0 self.setStatusBar(QStatusBar(self)) self.progress = QProgressBar() self.statusBar().addPermanentWidget(self.progress) # Key bindings. # For keys like function keys, use QtGui.QKeySequence("F12") QShortcut("Ctrl+Q", self, activated=self.close) QShortcut("Ctrl+L", self, activated=self.select_urlbar) QShortcut("Ctrl+T", self, activated=self.new_tab) QShortcut("Ctrl+R", self, activated=self.reload) QShortcut("Alt+Left", self, activated=self.go_back) QShortcut("Alt+Right", self, activated=self.go_forward)
def __init__(self, parent = None): super().__init__(parent) self.mOpacityLabel = QLabel() self.mOpacitySlider = QSlider(Qt.Horizontal) self.mLayerView = LayerView() self.mMapDocument = None self.mUpdatingSlider = False self.mChangingLayerOpacity = False self.mUpdatingSlider = False self.setObjectName("layerDock") widget = QWidget(self) layout = QVBoxLayout(widget) layout.setContentsMargins(5, 5, 5, 5) opacityLayout = QHBoxLayout() self.mOpacitySlider.setRange(0, 100) self.mOpacitySlider.setEnabled(False) opacityLayout.addWidget(self.mOpacityLabel) opacityLayout.addWidget(self.mOpacitySlider) self.mOpacityLabel.setBuddy(self.mOpacitySlider) handler = MapDocumentActionHandler.instance() newLayerMenu = QMenu(self) newLayerMenu.addAction(handler.actionAddTileLayer()) newLayerMenu.addAction(handler.actionAddObjectGroup()) newLayerMenu.addAction(handler.actionAddImageLayer()) newIcon = QIcon(":/images/16x16/document-new.png") newLayerButton = QToolButton() newLayerButton.setPopupMode(QToolButton.InstantPopup) newLayerButton.setMenu(newLayerMenu) newLayerButton.setIcon(newIcon) Utils.setThemeIcon(newLayerButton, "document-new") buttonContainer = QToolBar() buttonContainer.setFloatable(False) buttonContainer.setMovable(False) buttonContainer.setIconSize(QSize(16, 16)) buttonContainer.addWidget(newLayerButton) buttonContainer.addAction(handler.actionMoveLayerUp()) buttonContainer.addAction(handler.actionMoveLayerDown()) buttonContainer.addAction(handler.actionDuplicateLayer()) buttonContainer.addAction(handler.actionRemoveLayer()) buttonContainer.addSeparator() buttonContainer.addAction(handler.actionToggleOtherLayers()) listAndToolBar = QVBoxLayout() listAndToolBar.setSpacing(0) listAndToolBar.addWidget(self.mLayerView) listAndToolBar.addWidget(buttonContainer) layout.addLayout(opacityLayout) layout.addLayout(listAndToolBar) self.setWidget(widget) self.retranslateUi() self.mOpacitySlider.valueChanged.connect(self.sliderValueChanged) self.updateOpacitySlider()
def __init__(self, toolbar): TitledToolbar.__init__(self, toolbar, 'Text style') self.currentStyle = None toolbar = QToolBar(self) toolbar.setFloatable(False) toolbar.setMovable(False) self.styleToAction = {} textKeywordAction = QAction(QIcon(':/icons/format-keyword.png'), 'Notepad link', toolbar) textKeywordAction.setCheckable(True); selector = ('olink', None, None) textKeywordAction.setProperty('style', selector) self.styleToAction[selector] = textKeywordAction textKeywordAction.triggered.connect(self.styleSelected) toolbar.addAction(textKeywordAction) textLinkAction = QAction(QIcon(':/icons/format-link.png'), 'Internet link', toolbar) textLinkAction.setCheckable(True); selector = ('link', None, None) textLinkAction.setProperty('style', selector) self.styleToAction[selector] = textLinkAction textLinkAction.triggered.connect(self.styleSelected) toolbar.addAction(textLinkAction) textBoldAction = QAction(QIcon(':/icons/format-text-emphasized.png'), 'Emphasize', toolbar) textBoldAction.setCheckable(True); selector = ('emphasis', None, None) textBoldAction.setProperty('style', selector) self.styleToAction[selector] = textBoldAction textBoldAction.triggered.connect(self.styleSelected) toolbar.addAction(textBoldAction) textHighlightAction = QAction(QIcon(':/icons/format-text-highlight.png'), 'Highlight', toolbar) textHighlightAction.setCheckable(True); selector = ('emphasis', 'role', 'highlight') textHighlightAction.setProperty('style', selector) self.styleToAction[selector] = textHighlightAction textHighlightAction.triggered.connect(self.styleSelected) toolbar.addAction(textHighlightAction) textCodeAction = QAction(QIcon(':/icons/format-text-code.png'), 'Code', toolbar) textCodeAction.setCheckable(True); selector = ('code', None, None) textCodeAction.setProperty('style', selector) self.styleToAction[selector] = textCodeAction textCodeAction.triggered.connect(self.styleSelected) toolbar.addAction(textCodeAction) self.addWidget(toolbar)
def __init__(self): QWidget.__init__(self) self.setFixedSize(900, 600) self.setWindowIcon(QIcon(os.path.join(get_image_file_path(),"jv.png"))) self.setWindowTitle(_("Steady state simulation (www.gpvdm.com)")) self.main_vbox = QVBoxLayout() toolbar=QToolBar() toolbar.setIconSize(QSize(48, 48)) spacer = QWidget() spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) toolbar.addWidget(spacer) self.help = QAction(QIcon(os.path.join(get_image_file_path(),"help.png")), 'Hide', self) self.help.setStatusTip(_("Close")) self.help.triggered.connect(self.callback_help) toolbar.addAction(self.help) self.main_vbox.addWidget(toolbar) self.notebook = QTabWidget() self.notebook.setTabsClosable(True) self.notebook.setMovable(True) self.main_vbox.addWidget(self.notebook) files=["jv.inp","jv_simple.inp","sun_voc.inp"] description=["JV simulation","Diode equation","Suns v.s. Voc"] for i in range(0,len(files)): tab=tab_class() tab.init(files[i],description[i]) self.notebook.addTab(tab,description[i]) self.setLayout(self.main_vbox) self.win_list=windows() self.win_list.load() self.win_list.set_window(self,"jv_window") self.notebook.currentChanged.connect(self.changed_click)
def __init__(self,file_name): QWidget.__init__(self) self.setFixedSize(900, 600) self.setWindowIcon(QIcon(os.path.join(get_image_file_path(),"jv.png"))) self.setWindowTitle(_("Simulation information (www.gpvdm.com)")) self.main_vbox = QVBoxLayout() toolbar=QToolBar() toolbar.setIconSize(QSize(48, 48)) spacer = QWidget() spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) toolbar.addWidget(spacer) self.help = QAction(QIcon(os.path.join(get_image_file_path(),"help.png")), 'Hide', self) self.help.setStatusTip(_("Close")) self.help.triggered.connect(self.callback_help) toolbar.addAction(self.help) self.main_vbox.addWidget(toolbar) self.notebook = QTabWidget() self.notebook.setMovable(True) self.main_vbox.addWidget(self.notebook) files=[file_name] description=["Simulation Information"] for i in range(0,len(files)): tab=tab_class() tab.set_edit(False) tab.init(files[i],description[i]) self.notebook.addTab(tab,description[i]) self.setLayout(self.main_vbox) self.win_list=windows() self.win_list.load() self.win_list.set_window(self,"sim_info_window")
def __init__(self, parent): # QTabWidget.__init__(parent) super(QTabWidget, self).__init__(parent) # self.setParent(parent) self.setMovable(True) toolBar = QToolBar() locatorAct = toolBar.addAction('Locate') locatorAct.triggered.connect(lambda: self.openLoctor()) reloadAct = toolBar.addAction('Reload') reloadAct.triggered.connect(lambda: self.reloadPage()) self.setCornerWidget(toolBar, Qt.TopRightCorner) self.tabBar().setStyleSheet('QTabBar::tab { min-width: 8ex; padding: 2px; margin-right: 4px; }')
def __init__(self): QWidget.__init__(self) self.complex_display=False self.hbox=QVBoxLayout() self.gl_cmp=gl_cmp(os.path.join(os.getcwd(),"snapshots")) toolbar=QToolBar() toolbar.setIconSize(QSize(42, 42)) self.tb_rotate = QAction(QIcon(os.path.join(get_image_file_path(),"rotate.png")), _("Rotate"), self) self.tb_rotate.triggered.connect(self.tb_rotate_click) toolbar.addAction(self.tb_rotate) self.tb_rotate.setEnabled(True) self.tb_contact = QAction(QIcon(os.path.join(get_image_file_path(),"contact.png")), _("Contacts"), self) self.tb_contact.triggered.connect(self.callback_contacts) toolbar.addAction(self.tb_contact) self.tb_mesh = QAction(QIcon(os.path.join(get_image_file_path(),"mesh.png")), _("Edit the electrical mesh"), self) self.tb_mesh.triggered.connect(self.callback_edit_mesh) toolbar.addAction(self.tb_mesh) self.tb_config = QAction(QIcon(os.path.join(get_image_file_path(),"cog.png")), _("Configuration"), self) self.tb_config.triggered.connect(self.callback_configure) toolbar.addAction(self.tb_config) self.hbox.addWidget(toolbar) enable_3d=inp_get_token_value(os.path.join(os.getcwd(),"config.inp") , "#gui_config_3d_enabled") if enable_3d==None: enable_3d="True" enable_3d=str2bool(enable_3d) if enable_3d==True: self.display=glWidget(self) self.hbox.addWidget(self.display) self.display.setMinimumSize(800, 600) self.timer=QTimer() self.timer.setSingleShot(True) self.timer.timeout.connect(self.timer_update) self.timer.start(2000) else: self.add_fallback() self.setLayout(self.hbox) self.electrical_mesh=tab_electrical_mesh() self.electrical_mesh.changed.connect(self.recalculate) self.contacts_window=contacts_window() self.contacts_window.changed.connect(self.recalculate) self.gl_cmp.slider.changed.connect(self.recalculate)
def init(self): self.setFixedSize(900, 600) self.setWindowIcon(QIcon(os.path.join(get_image_file_path(),"cog.png"))) self.setWindowTitle(_("Configure (www.gpvdm.com)")) self.main_vbox = QVBoxLayout() toolbar=QToolBar() toolbar.setIconSize(QSize(48, 48)) spacer = QWidget() spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) toolbar.addWidget(spacer) self.undo = QAction(QIcon(os.path.join(get_image_file_path(),"help.png")), 'Hide', self) self.undo.setStatusTip(_("Close")) self.undo.triggered.connect(self.callback_help) toolbar.addAction(self.undo) self.main_vbox.addWidget(toolbar) self.notebook = QTabWidget() self.notebook.setMovable(True) self.main_vbox.addWidget(self.notebook) files=["math.inp","dump.inp","thermal.inp","led.inp","config.inp"] description=["Math","Dump","Thermal","LED","GUI config"] for i in range(0,len(files)): tab=tab_class() tab.init(files[i],description[i]) self.notebook.addTab(tab,description[i]) self.setLayout(self.main_vbox) self.win_list=windows() self.win_list.load() self.win_list.set_window(self,"config_window")
def __init__(self): super(MainWindow, self).__init__() self.start_logo() self.setupUi(self) self.sysencoding =sys.stdout.encoding #self.centralWidget = PyPreviewer(self) #self.setCentralWidget(self.centralWidget) self.setupEditor() self.setWindowIcon(QIcon('PyPreviewer.ico')) #메뉴 이벤트 생성 self.createEvent() self.dirty = False self.plainTextEdit_2.textChanged.connect(self.setDirty) self.fileName = None self.plainTextEdit_2.setTabStopWidth(35) self.plainTextEdit_2.setPlainText("# -*- coding: utf-8 -*-\n# 반갑습니다~\n# #은 파이썬에서 주석입니다.\nprint(\"이 부분은 출력창입니다.\")\nprint(\"구구단 예제\")\nfor i in range(2,10):\n\tprint(i,\"단\")\n\tfor j in range(2,10):\n\t\tprint(i,\"X\", j, \"=\", i*j)\n# 파이썬 실행은 아래 실행버튼을 눌러주세요.\n# 파이썬 학습 관련 및 예제는 왼쪽 화면을 이용하시기 바랍니다.") #web view #self.exampleView.load(QUrl("http://www.google.com")) self.startfilepath=os.getcwd() +"/PyStudy_web/Main.html" self.exampleView.load(QUrl.fromLocalFile(self.startfilepath)) self.locationEdit = QLineEdit(self) self.locationEdit.setSizePolicy(QSizePolicy.Expanding, self.locationEdit.sizePolicy().verticalPolicy()) self.locationEdit.returnPressed.connect(self.changeLocation) toolBar = QToolBar() self.addToolBar(toolBar) self.insertToolBarBreak(toolBar) toolBar.addAction(self.exampleView.pageAction(QWebPage.Back)) toolBar.addAction(self.exampleView.pageAction(QWebPage.Forward)) toolBar.addAction(self.action_myHome) toolBar.addAction(self.exampleView.pageAction(QWebPage.Reload)) #toolBar.addAction(self.exampleView.pageAction(QWebPage.Stop)) toolBar.addWidget(self.locationEdit) #사용자 입력 파이썬 파일 실행 print ('Connecting process') self.process = QProcess(self) self.process.setProcessChannelMode(QProcess.SeparateChannels) self.process.setInputChannelMode(QProcess.ManagedInputChannel) self.process.readyReadStandardOutput.connect(self.stdoutReady) self.process.readyReadStandardError.connect(self.stderrReady) self.process.started.connect(lambda: print('ExampleProgramStarted!')) self.process.finished.connect(lambda:print('ExampleProgramFinished!')) print('Starting process')
class ToolBarAction(QWidgetAction): def __init__(self, *args, **kwargs): super(ToolBarAction, self).__init__(*args, **kwargs) self._toolBar = QToolBar(styleSheet="QToolBar {background: transparent; border: 0;}") self._toolBar.setIconSize(QSize(16, 16)) self.setDefaultWidget(self._toolBar) def toolBar(self): return self._toolBar def addAction(self, action): self._toolBar.addAction(action) if action.shortcut().toString() > "": action.setToolTip(action.text().replace("&", "") + "<br>" + action.shortcut().toString()) def widgetForAction(self, *args, **kwargs): return self._toolBar.widgetForAction(*args, **kwargs) def addWidget(self, *args, **kwargs): self._toolBar.addWidget(*args, **kwargs) def addSeparator(self): self._toolBar.addSeparator()
def __init__(self): QWidget.__init__(self) edit_boxes=QWidget() vbox=QVBoxLayout() self.lumo=equation_editor("lumo0.inp","LUMO") vbox.addWidget(self.lumo) self.h**o=equation_editor("homo0.inp","H**O") vbox.addWidget(self.h**o) edit_boxes.setLayout(vbox) hbox=QHBoxLayout() toolbar=QToolBar() toolbar.setIconSize(QSize(48, 48)) toolbar.setOrientation(Qt.Vertical) add = QAction(QIcon(os.path.join(get_image_file_path(),"save.png")), _("Save"), self) add.triggered.connect(self.callback_save) toolbar.addAction(add) hbox.addWidget(toolbar) self.LUMO_fig = Figure(figsize=(5,4), dpi=100) self.draw_graph_lumo() self.canvas_lumo = FigureCanvas(self.LUMO_fig) self.canvas_lumo.figure.patch.set_facecolor('white') self.LUMO_fig.tight_layout(pad=0.5) hbox.addWidget(self.canvas_lumo) hbox.addWidget(edit_boxes) self.setLayout(hbox) self.lumo.changed.connect(self.update_graph) self.h**o.changed.connect(self.update_graph)
def make_tool_box1(self): toolbar=QToolBar() toolbar.setIconSize(QSize(42, 42)) if enable_betafeatures()==True: self.qe_button = QAction(QIcon(os.path.join(get_image_file_path(),"qe.png")), _("Quantum efficiency"), self) self.qe_button.triggered.connect(self.callback_qe_window) toolbar.addAction(self.qe_button) self.qe_button.setEnabled(False) self.sim_mode_button=tb_item_sim_mode() toolbar.addWidget(self.sim_mode_button) self.sim_mode_button.setEnabled(False) self.light_button=tb_item_sun() toolbar.addWidget(self.light_button) self.light_button.setEnabled(False) return toolbar
def __init__(self,index): QWidget.__init__(self) self.index=index self.fig = Figure(figsize=(5,4), dpi=100) self.ax1=None self.show_key=True self.hbox=QVBoxLayout() self.edit_list=[] self.line_number=[] self.list=[] print("index=",index) canvas = FigureCanvas(self.fig) # a gtk.DrawingArea #canvas.set_background('white') #canvas.set_facecolor('white') canvas.figure.patch.set_facecolor('white') #canvas.set_size_request(500, 150) #canvas.set_size_request(700,400) self.draw_graph() toolbar=QToolBar() toolbar.setIconSize(QSize(48, 48)) self.tb_save = QAction(QIcon(os.path.join(get_image_file_path(),"save.png")), _("Save graph"), self) self.tb_save.triggered.connect(self.callback_save) toolbar.addAction(self.tb_save) nav_bar=NavigationToolbar(canvas,self) toolbar.addWidget(nav_bar) self.hbox.addWidget(toolbar) self.hbox.addWidget(canvas) self.setLayout(self.hbox)
def __init__(self, parent = None): super().__init__(parent) self.mExpandedGroups = QMapList() self.mObjectsView = ObjectsView() self.mMapDocument = None self.setObjectName("ObjectsDock") self.mActionObjectProperties = QAction(self) self.mActionObjectProperties.setIcon(QIcon(":/images/16x16/document-properties.png")) Utils.setThemeIcon(self.mActionObjectProperties, "document-properties") self.mActionObjectProperties.triggered.connect(self.objectProperties) handler = MapDocumentActionHandler.instance() widget = QWidget(self) layout = QVBoxLayout(widget) layout.setContentsMargins(5, 5, 5, 5) layout.setSpacing(0) layout.addWidget(self.mObjectsView) self.mActionNewLayer = QAction(self) self.mActionNewLayer.setIcon(QIcon(":/images/16x16/document-new.png")) self.mActionNewLayer.triggered.connect(handler.actionAddObjectGroup().triggered) self.mActionMoveToGroup = QAction(self) self.mActionMoveToGroup.setIcon(QIcon(":/images/16x16/layer-object.png")) toolBar = QToolBar() toolBar.setFloatable(False) toolBar.setMovable(False) toolBar.setIconSize(QSize(16, 16)) toolBar.addAction(self.mActionNewLayer) toolBar.addAction(handler.actionDuplicateObjects()) toolBar.addAction(handler.actionRemoveObjects()) toolBar.addAction(self.mActionMoveToGroup) button = toolBar.widgetForAction(self.mActionMoveToGroup) self.mMoveToMenu = QMenu(self) button.setPopupMode(QToolButton.InstantPopup) button.setMenu(self.mMoveToMenu) self.mMoveToMenu.aboutToShow.connect(self.aboutToShowMoveToMenu) self.mMoveToMenu.triggered.connect(self.triggeredMoveToMenu) toolBar.addAction(self.mActionObjectProperties) layout.addWidget(toolBar) self.setWidget(widget) self.retranslateUi() DocumentManager.instance().documentAboutToClose.connect(self.documentAboutToClose)
def __init__(self): QWidget.__init__(self) self.setFixedSize(900, 600) self.setWindowIcon(QIcon(os.path.join(get_image_file_path(),"jv.png"))) self.setWindowTitle(_("Cost and energy payback calculator (BETA - missing realistic data at the moment!!!)")) self.main_vbox = QVBoxLayout() toolbar=QToolBar() toolbar.setIconSize(QSize(48, 48)) self.play = QAction(QIcon(os.path.join(get_image_file_path(),"play.png")), "Re-calcualte", self) self.play.triggered.connect(self.update) toolbar.addAction(self.play) spacer = QWidget() spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) toolbar.addWidget(spacer) self.help = QAction(QIcon(os.path.join(get_image_file_path(),"help.png")), "Help", self) self.help.triggered.connect(self.callback_help) toolbar.addAction(self.help) self.main_vbox.addWidget(toolbar) self.tab= QTableWidget() self.main_vbox.addWidget(self.tab) self.setLayout(self.main_vbox) self.win_list=windows() self.win_list.load() self.win_list.set_window(self,"costs_window") self.update()
def invoke(self): """ the real setup function to show someting. """ self.setupUi(self) # make sure the first col show full self.yeahdoclisttree.header().setResizeMode(0, QHeaderView.ResizeToContents) self.__initAction() # toolbar . classToolbar = QToolBar() classToolbar.setIconSize(QSize(16, 16)) classToolbar.setMovable(False) self.rightsplitter.insertWidget(0, classToolbar) classToolbar.addAction(self.__actions["__yeahdoc_c_new__"]) classToolbar.addAction(self.__actions["__yeahdoc_c_edit__"]) classToolbar.addAction(self.__actions["__yeahdoc_c_rename__"]) classToolbar.addAction(self.__actions["__yeahdoc_c_delete__"]) classToolbar.addWidget(self.__evt_category_view()) # More useful gadgets self.togglebtn.setIcon(QIcon(getPath("iconDir", "yeahdoc/right.png"))) # read datas from db . self.__setupYeahdocCategoryDatas() self.__setupyeahdoclisttreeDatas()
def math(self): toolbar = QToolBar() toolbar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) toolbar.setIconSize(QSize(42, 42)) self.math_opps = [] self.math_subtract_first_point = QAction(icon_get("plot_log_x"), _("Subtract first point"), self) toolbar.addAction(self.math_subtract_first_point) self.math_add_min_point = QAction(icon_get("plot_log_x"), _("Add min point"), self) toolbar.addAction(self.math_add_min_point) self.math_invert_y_axis = QAction(icon_get("plot_invert_y"), _("Invert y-axis"), self) toolbar.addAction(self.math_invert_y_axis) self.math_opps.append( [QAction(icon_get("plot_abs"), _("abs(f())"), self), "abs"]) toolbar.addAction(self.math_opps[-1][0]) self.math_norm_to_peak_of_all_data = QAction( icon_get("plot_log_x"), _("Norm to peak of all data"), self) toolbar.addAction(self.math_norm_to_peak_of_all_data) self.math_heat_map = QAction(icon_get("plot_log_x"), _("Heat map"), self) toolbar.addAction(self.math_heat_map) self.math_heat_map_edit = QAction(icon_get("plot_log_x"), _("Heat map edit"), self) toolbar.addAction(self.math_heat_map_edit) return toolbar
class JobbiUI(QMainWindow): def __init__(self, parent=None): super().__init__(parent) # Init window self._setupWindow() # List containing custom job add widgets self.addElements = [] # Init UI and create GUI components self._createToolBar() self._setupUI() self._createStatusBar() def insertJobs(self, adds): if adds is not None: adds = al.shuffle_adds(adds) adds.reverse() for add in adds: self.insertJobElement(add) # Insert job add objects def insertJobElement(self, jobAdd): element = _JobAddElement(jobAdd.add_heading, jobAdd.add_content, jobAdd.company, jobAdd.company_url, jobAdd.add_url, jobAdd.add_owner) # The first add element will have the index 0, with the current layout, # thus to insert new adds add the top of the list the insertWidget() # method is used insted of addWidget() self.generalLayout.insertWidget(0, element) self.addElements.append(element) def getIndices(self): for el in self.addElements: print(self.generalLayout.indexOf(el)) def updateStatus(self, msg): self.status.showMessage(msg) self.update() def _setupUI(self): # Set central widget to be a scroll area self.mainScrollArea = QScrollArea(self) self.setCentralWidget(self.mainScrollArea) # Main job-add layout self.baseWidget = QWidget() self.generalLayout = QVBoxLayout() self.generalLayout.setContentsMargins(100, 20, 100, 20) self.baseWidget.setLayout(self.generalLayout) # Point baseWidget to the main scroll area self.mainScrollArea.setWidget(self.baseWidget) self.mainScrollArea.setWidgetResizable(True) def _createToolBar(self): # Define main toolbar self.toolbar = QToolBar("Main toolbar") self.addToolBar(self.toolbar) self.toolbar.setIconSize(QSize(22, 22)) self.toolbar.setFixedHeight(36) # Define action to be included in the toolbar and add them to it self.settingsAction = QAction(QIcon(str(img_path / "build-24px.svg")), "Settings", self) self.updateAction = QAction( QIcon(str(img_path / "cloud_download-24px.svg")), "Load adds", self) self.toolbar.addAction(self.settingsAction) self.toolbar.addAction(self.updateAction) def _createStatusBar(self): self.status = QStatusBar() self.status.showMessage("Welcome") self.setStatusBar(self.status) def _setupWindow(self): self.setWindowTitle('Jobbi') self.setGeometry(0, 0, 990, 660) self.setMinimumWidth(800) self.setMinimumHeight(400) # Center main window qt_rectangle = self.frameGeometry() qt_rectangle.moveCenter(QDesktopWidget().availableGeometry().center()) self.move(qt_rectangle.topLeft()) # Set window background color self.setAutoFillBackground(True) p = self.palette() p.setColor(self.backgroundRole(), Qt.white) self.setPalette(p)
class OpenposeGUI(QMainWindow): def __init__(self): super().__init__() loadUi("ui/main_window.ui", self) self.setWindowTitle("OpencvGUI") self.setWindowIcon(QIcon("icon/logo.png")) self.reid_model_path = '../reid/models/stageIII/best_net_E.pth' self.gesture_model_path = r'../pose/models/gesture/[email protected]' # 工具栏 # 所有动作定义在ui文件中 self.tool_bar = QToolBar() self.tool_bar.addAction(self.action_camera) self.tool_bar.addSeparator() self.tool_bar.addAction(self.action_save) self.tool_bar.addAction(self.action_autosave) self.tool_bar.addSeparator() self.tool_bar.addAction(self.action_setting) self.tool_bar.addAction(self.action_filetree) self.addToolBar(self.tool_bar) # 状态栏 self.status_bar = QStatusBar() self.status_fps = QLabel("FPS:00.0") self.status_bar.addPermanentWidget(self.status_fps) self.setStatusBar(self.status_bar) # 组件 self.label_frame = LabelFrame(self) # 用于显示画面 self.dock_setting = SettingDock(self) # 设置 self.dock_filetree = FiletreeDock(self) # 目录 self.dock_media = MediaDock(self) # 视频播放控制 self.timer = QTimer() self.camera = Camera() # 视频控制器 self.openpose_model = OpenposeModel() # openpose模型 self.save_widget = SaveWidget() # 保存窗口 self.gesture_model = GestureModel(self.gesture_model_path) # self.person_tracker = PersonTracker() # 加载person tracker self.controller = Presenter(self.reid_model_path, 0.95) # reid的presenter self.out = None # 设置dock self.setCentralWidget(self.label_frame) self.addDockWidget(Qt.LeftDockWidgetArea, self.dock_setting) self.addDockWidget(Qt.LeftDockWidgetArea, self.dock_filetree) self.addDockWidget(Qt.BottomDockWidgetArea, self.dock_media) # 工具栏动作 self.action_camera.triggered.connect(self.run_camera) self.action_filetree.triggered.connect(self.show_filetree) self.action_setting.triggered.connect(self.show_setting) self.action_save.triggered.connect(self.save) self.action_autosave.triggered.connect(self.auto_save) # 相机计时器 self.camera.timer.timeout.connect(self.update_frame) # 自动保存计时器 self.timer.timeout.connect(self.save) def update_frame(self, interval=2): """更新frame画面""" start_time = time.time() self.dock_media.update_slider(self.frame_pos, self.frame_count) frame = self.frame if frame is None: return None # result, ids, keypoints = self.openpose_model(frame) # 为提升视频流畅度,每interval帧输入一张图片,在函数输入处设定,默认为2 if int(self.frame_pos - 1) % interval == 0: self.controller.update_people(frame) result = self.controller.draw_rects(frame) self.out.write(result) # result, keypoints = self.gesture_recognition(result, keypoints) # # message = self.generate_message(keypoints) # result, obj_ids, pos, imgs = self.controller.tracker.track(frame) self.label_frame.update_frame(result) fps = 1 / (time.time() - start_time) if int(self.frame_pos - 1) % interval == 0: self.status_fps.setText("FPS:{:.1f}".format(fps)) # self.status_bar.showMessage(message) # return result, keypoints return result """custom""" def show_rect(self, result, keypoints): if keypoints[0].size == 1: return bodys = keypoints[0] if bodys[0].size >= 1: person_num = bodys.shape[0] for i in range(person_num): # 每个人 for body in bodys: # 每只手 rect = self.openpose_model.body_bbox(body) if rect: x, y, w, h = rect cv2.rectangle(result, (x, y), (x + w, y + h), (255, 255, 255), 2) # cv2.putText(result, gesture, (x, y), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255)) return result, keypoints """custom""" def save(self): """执行保存操作""" print("Video saved.") self.out.release() # 原先程序的保存是保存当前帧的姿态检测结果 # if not self.label_frame.pixmap(): # QMessageBox.warning(self, "Note", "No data in frame", QMessageBox.Yes) # return # pixmap = self.label_frame.img_to_pixmap(self.openpose_model.get_rendered_image()) # body, hand, face = self.openpose_model.get_keypoints() # message = self.generate_message((body, hand, face)) # body = copy.deepcopy(body) if self.body_on else None # hand = copy.deepcopy(hand) if self.hand_on else None # face = copy.deepcopy(face) if self.face_on else None # keypoints = (body, hand, face) # # if self.timer.isActive(): # self.save_widget.save(pixmap.copy(), *keypoints) # else: # self.save_widget.set_frame(pixmap.copy(), *keypoints, message) # self.save_widget.show() def auto_save(self): """开启或关闭自动保存""" if not self.camera.is_open: self.action_autosave.setChecked(False) if self.action_autosave.isChecked(): self.timer.start(self.save_interval * 1000) else: self.timer.stop() # 功能 def show_setting(self): """隐藏或显示设置""" if self.dock_setting.isHidden(): self.dock_setting.show() else: self.dock_setting.hide() def show_filetree(self): """隐藏或显示目录树""" if self.dock_filetree.isHidden(): self.dock_filetree.show() else: self.dock_filetree.hide() def run_image(self, img_path): """图片""" image = cv2.imdecode(np.fromfile(img_path, dtype=np.uint8), -1) if image is None: QMessageBox.warning(self, "Note", "Read Image error", QMessageBox.Yes) return result, ids, keypoints = self.openpose_model(image) result = self.draw_rects(result) message = self.generate_message(keypoints) self.label_frame.update_frame(result) self.status_bar.showMessage(message) self.dock_media.hide() def run_video(self, video_path): print('视频') """视频""" self.controller = Presenter(self.reid_model_path, 0.95) # reid的presenter self.camera.start(video_path) self.label_frame.resize(*self.resolution) video_w = self.camera.cap.get(cv2.CAP_PROP_FRAME_WIDTH) video_h = self.camera.cap.get(cv2.CAP_PROP_FRAME_HEIGHT) video_fps = self.camera.cap.get(cv2.CAP_PROP_FPS) video_name = os.path.basename(video_path) fourcc = cv2.VideoWriter_fourcc(*'XVID') self.out = cv2.VideoWriter('output/output_' + video_name, fourcc=fourcc, fps=int(video_fps), frameSize=(int(video_w), int(video_h))) self.update_frame() # 初始化画面 self.camera.pause() self.dock_media.reset() self.dock_media.show() def run_camera(self): """相机""" if self.action_camera.isChecked(): self.camera.start(0) self.label_frame.resize(*self.resolution) else: self.label_frame.clear() self.camera.stop() self.status_fps.setText("FPS:00.0") self.dock_media.hide() def gesture_recognition(self, result, keypoints): """实现手势识别""" if self.gesture_on: hands = keypoints[1] if hands[0].size == 1: return result, keypoints person_num = hands[0].shape[0] for i in range(person_num): # 每个人 for hand in hands: # 每只手 rect = self.gesture_model.hand_bbox(hand[i]) gesture = self.gesture_model(hand[i]) if rect: print(rect) x, y, w, h = rect cv2.rectangle(result, (x, y), (x + w, y + h), (255, 255, 255), 2) cv2.putText(result, gesture, (x, y), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255)) return result, keypoints def generate_message(self, keypoints): """获取识别结果信息""" if keypoints[0].size != 1: person_num = keypoints[0].shape[0] message = "person: {}".format(person_num) for i in range(person_num): message += " | person{}(".format(i + 1) if self.body_on: pose_keypoints = keypoints[0][i, :, 2] pose_detected = pose_keypoints[ pose_keypoints > self.body_threshold] message += "pose: {:>2d}/{}".format(pose_detected.size, 25) if self.hand_on: right_hand_keypoinys = keypoints[1][0][i, :, 2] left_hand_keypoinys = keypoints[1][1][i, :, 2] right_hand_detected = right_hand_keypoinys[ right_hand_keypoinys > self.hand_threshold] left_hand_detected = left_hand_keypoinys[ left_hand_keypoinys > self.hand_threshold] message += " | right hand: {:>2d}/{}".format( right_hand_detected.size, 21) message += " | left hand: {:>2d}/{}".format( left_hand_detected.size, 21) message += ")" else: message = "person: {}".format(0) return message @property def body_on(self): return self.dock_setting.body_on @property def hand_on(self): return self.dock_setting.hand_on @property def face_on(self): return self.dock_setting.face_on @property def body_threshold(self): return self.dock_setting.body_threshold @property def hand_threshold(self): return self.dock_setting.hand_threshold @property def face_threshold(self): return self.dock_setting.face_threshold @property def gesture_on(self): return self.dock_setting.gesture_on @property def save_interval(self): return self.dock_setting.save_interval @property def frame(self): return self.camera.frame @property def frame_pos(self): return self.camera.frame_pos @property def frame_count(self): return self.camera.frame_count @property def resolution(self): return self.camera.resolution
class multicopy(QMainWindow): """Create the main window that stores all of the widgets necessary for the application.""" def __init__(self, parent=None): """Initialize the components of the main window.""" super(multicopy, self).__init__(parent) self.resize(1024, 768) self.setWindowTitle('multicopy') window_icon = pkg_resources.resource_filename( 'multicopy.images', 'ic_insert_drive_file_black_48dp_1x.png') self.setWindowIcon(QIcon(window_icon)) self.widget = QWidget() self.layout = QHBoxLayout(self.widget) self.menu_bar = self.menuBar() self.about_dialog = AboutDialog() self.status_bar = self.statusBar() self.status_bar.showMessage('Ready', 5000) self.file_menu() self.help_menu() self.tool_bar_items() def file_menu(self): """Create a file submenu with an Open File item that opens a file dialog.""" self.file_sub_menu = self.menu_bar.addMenu('File') self.open_action = QAction('Open File', self) self.open_action.setStatusTip('Open a file into multicopy.') self.open_action.setShortcut('CTRL+O') self.open_action.triggered.connect(self.open_file) self.exit_action = QAction('Exit Application', self) self.exit_action.setStatusTip('Exit the application.') self.exit_action.setShortcut('CTRL+Q') self.exit_action.triggered.connect(lambda: QApplication.quit()) self.file_sub_menu.addAction(self.open_action) self.file_sub_menu.addAction(self.exit_action) def help_menu(self): """Create a help submenu with an About item tha opens an about dialog.""" self.help_sub_menu = self.menu_bar.addMenu('Help') self.about_action = QAction('About', self) self.about_action.setStatusTip('About the application.') self.about_action.setShortcut('CTRL+H') self.about_action.triggered.connect(lambda: self.about_dialog.exec_()) self.help_sub_menu.addAction(self.about_action) def tool_bar_items(self): """Create a tool bar for the main window.""" self.tool_bar = QToolBar() self.addToolBar(Qt.TopToolBarArea, self.tool_bar) self.tool_bar.setMovable(False) open_icon = pkg_resources.resource_filename( 'multicopy.images', 'ic_open_in_new_black_48dp_1x.png') tool_bar_open_action = QAction(QIcon(open_icon), 'Open File', self) tool_bar_open_action.triggered.connect(self.open_file) self.tool_bar.addAction(tool_bar_open_action) def open_file(self): """Open a QFileDialog to allow the user to open a file into the application.""" filename, accepted = QFileDialog.getOpenFileName(self, 'Open File') if accepted: with open(filename) as file: file.read()
class EmulatorPanel(QWidget): def __init__(self, app, *__args): super().__init__(*__args) self.app = app self.emulator = self.app.dwarf.emulator self.until_address = 0 layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) self._toolbar = QToolBar() self._toolbar.addAction('Start', self.handle_start) self._toolbar.addAction('Step', self.handle_step) self._toolbar.addAction('Stop', self.handle_stop) self._toolbar.addAction('Clean', self.handle_clean) self._toolbar.addAction('Options', self.handle_options) layout.addWidget(self._toolbar) self.tabs = QTabWidget() self.assembly = DisassemblyView(self.app) self.assembly.display_jumps = False self.assembly.follow_jumps = False self.memory_table = MemoryPanel(self.app) self.memory_table._read_only = True self.tabs.addTab(self.assembly, 'Code') self.tabs.addTab(self.memory_table, 'Memory') layout.addWidget(self.tabs) h_box = QHBoxLayout() self.ranges_list = DwarfListView(self.app) self.ranges_list.doubleClicked.connect(self.ranges_item_double_clicked) self._ranges_model = QStandardItemModel(0, 2) self._ranges_model.setHeaderData(0, Qt.Horizontal, 'Memory') self._ranges_model.setHeaderData(0, Qt.Horizontal, Qt.AlignCenter, Qt.TextAlignmentRole) self._ranges_model.setHeaderData(1, Qt.Horizontal, 'Size') self.ranges_list.setModel(self._ranges_model) self._access_list = DwarfListView(self.app) self._access_list.doubleClicked.connect(self.access_item_double_clicked) self._access_model = QStandardItemModel(0, 3) self._access_model.setHeaderData(0, Qt.Horizontal, 'Address') self._access_model.setHeaderData(0, Qt.Horizontal, Qt.AlignCenter, Qt.TextAlignmentRole) self._access_model.setHeaderData(1, Qt.Horizontal, 'Access') self._access_model.setHeaderData(1, Qt.Horizontal, Qt.AlignCenter, Qt.TextAlignmentRole) self._access_model.setHeaderData(2, Qt.Horizontal, 'Value') self._access_list.setModel(self._access_model) h_box.addWidget(self.ranges_list) h_box.addWidget(self._access_list) layout.addLayout(h_box) self.setLayout(layout) self.console = self.app.console.get_emu_console() self.emulator.onEmulatorStart.connect(self.on_emulator_start) self.emulator.onEmulatorStop.connect(self.on_emulator_stop) # self.emulator.onEmulatorStep.connect(self.on_emulator_step) self.emulator.onEmulatorHook.connect(self.on_emulator_hook) self.emulator.onEmulatorMemoryHook.connect(self.on_emulator_memory_hook) self.emulator.onEmulatorMemoryRangeMapped.connect(self.on_emulator_memory_range_mapped) self.emulator.onEmulatorLog.connect(self.on_emulator_log) self._require_register_result = None self._last_instruction_address = 0 def resizeEvent(self, event): self.ranges_list.setFixedHeight((self.height() / 100) * 25) self.ranges_list.setFixedWidth((self.width() / 100) * 30) self._access_list.setFixedHeight((self.height() / 100) * 25) return super().resizeEvent(event) def handle_clean(self): self.ranges_list.clear() self._access_list.clear() self.assembly._lines.clear() self.assembly.viewport().update() # self.memory_table.setRowCount(0) self.console.clear() self.emulator.clean() def handle_options(self): EmulatorConfigsDialog.show_dialog(self.app.dwarf) def handle_start(self): ph = '' if self.until_address > 0: ph = hex(self.until_address) address, inp = InputDialog.input_pointer(self.app, input_content=ph, hint='pointer to last instruction') if address > 0: self.until_address = address self.app.console_panel.show_console_tab('emulator') self.emulator.emulate(self.until_address) # if err > 0: # self.until_address = 0 # self.console.log('cannot start emulator. err: %d' % err) # return def handle_step(self): self.app.console_panel.show_console_tab('emulator') try: result = self.emulator.emulate() if not result: self.console.log('Emulation failed') except self.emulator.EmulatorAlreadyRunningError: self.console.log('Emulator already runnging') except self.emulator.EmulatorSetupFailedError as error: self.until_address = 0 self.console.log(error) def handle_stop(self): self.emulator.stop() def on_emulator_hook(self, instruction): self.app.context_panel.set_context(0, 2, self.emulator.current_context) # check if the previous hook is waiting for a register result if self._require_register_result is not None: row = 1 res = '%s = %s' % (self._require_register_result[1], hex(self.emulator.uc.reg_read(self._require_register_result[0]))) if len(self.assembly._lines) > 1: if self.assembly._lines[len(self.assembly._lines) - row] is None: row = 2 self.assembly._lines[len(self.assembly._lines) - row].string = res # invalidate self._require_register_result = None # check if the code jumped self._last_instruction_address = instruction.address self.assembly.add_instruction(instruction) # add empty line if jump if instruction.is_jump: self.assembly.add_instruction(None) # implicit regs read are notified later through mem access if len(instruction.regs_read) == 0: if len(instruction.operands) > 0: for i in instruction.operands: if i.type == CS_OP_REG: self._require_register_result = [ i.value.reg, instruction.reg_name(i.value.reg) ] break self.assembly.verticalScrollBar().setValue(len(self.assembly._lines)) self.assembly.viewport().update() def on_emulator_log(self, log): self.app.console_panel.show_console_tab('emulator') self.console.log(log) def on_emulator_memory_hook(self, data): uc, access, address, value = data _address = QStandardItem() str_frmt = '' if self.ranges_list.uppercase_hex: if self.app.dwarf.pointer_size > 4: str_frmt = '0x{0:016X}'.format(address) else: str_frmt = '0x{0:08X}'.format(address) else: if self.app.dwarf.pointer_size > 4: str_frmt = '0x{0:016x}'.format(address) else: str_frmt = '0x{0:08x}'.format(address) _address.setText(str_frmt) _address.setTextAlignment(Qt.AlignCenter) _access = QStandardItem() if access == UC_MEM_READ: _access.setText('READ') elif access == UC_MEM_WRITE: _access.setText('WRITE') elif access == UC_MEM_FETCH: _access.setText('FETCH') _access.setTextAlignment(Qt.AlignCenter) _value = QStandardItem() _value.setText(str(value)) self._access_model.appendRow([_address, _access, _value]) res = None row = 1 if len(self.assembly._lines) > 1: if self.assembly._lines[len(self.assembly._lines) - row] is None: row = 2 if access == UC_MEM_READ: if self._require_register_result is not None: res = '%s = %s' % (self._require_register_result[1], hex(value)) else: if self.assembly._lines[len(self.assembly._lines) - row].string: res = '%s, %s = %s' % (self.assembly._lines[len(self.assembly._lines) - row].string, hex(address), hex(value)) else: res = '%s = %s' % (hex(address), hex(value)) if res is not None: # invalidate self._require_register_result = None self.assembly._lines[len(self.assembly._lines) - row].string = res def on_emulator_memory_range_mapped(self, data): address, size = data _address = QStandardItem() str_frmt = '' if self.ranges_list.uppercase_hex: if self.app.dwarf.pointer_size > 4: str_frmt = '0x{0:016X}'.format(address) else: str_frmt = '0x{0:08X}'.format(address) else: if self.app.dwarf.pointer_size > 4: str_frmt = '0x{0:016x}'.format(address) else: str_frmt = '0x{0:08x}'.format(address) _address.setText(str_frmt) _address.setTextAlignment(Qt.AlignCenter) _size = QStandardItem() _size.setText("{0:,d}".format(int(size))) self._ranges_model.appendRow([_address, _size]) def on_emulator_start(self): pass def on_emulator_stop(self): self.app.context_panel.set_context(0, 2, self.emulator.current_context) # check if the previous hook is waiting for a register result if self._require_register_result is not None: row = 1 res = '%s = %s' % (self._require_register_result[1], hex(self.emulator.uc.reg_read(self._require_register_result[0]))) if len(self.assembly._lines) > 1: if self.assembly._lines[len(self.assembly._lines) - row] is None: row = 2 self.assembly._lines[len(self.assembly._lines) - row].string = res # invalidate self._require_register_result = None def ranges_item_double_clicked(self, model_index): row = self._ranges_model.itemFromIndex(model_index).row() if row != -1: item = self._ranges_model.item(row, 0).text() self.memory_table.read_memory(item) self.tabs.setCurrentIndex(1) def access_item_double_clicked(self, model_index): row = self._access_model.itemFromIndex(model_index).row() if row != -1: item = self._access_model.item(row, 0).text() self.memory_table.read_memory(item) self.tabs.setCurrentIndex(1)
class PyGUIno: def __init__(self): # Set up all the window related stuff self._app = QApplication(sys.argv) self._window = QMainWindow() size = self._app.primaryScreen().size() self._window.resize(int(size.width()*0.7), int(size.height()*0.8)) self._window.setObjectName("PyGUIno") self._window.setWindowTitle('PyGUIno') self._window.setWindowIcon(QIcon('resources\\assets\\etsi.png')) self._centralwidget = QWidget(self._window) self._window.setCentralWidget(self._centralwidget) self._centralwidget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.layout = QHBoxLayout() self._centralwidget.setLayout(self.layout) # Create the toolbar and the actions self.toolbar = QToolBar() save_action = QAction(QIcon('resources\\assets\\ic_save_3x.png'), 'Guardar', self._window) save_action.setStatusTip('Guarda la configuración de las gráficas actuales') load_action = QAction(QIcon('resources\\assets\\ic_open_in_new_18pt_3x.png'), 'Cargar', self._window) load_action.setStatusTip('Cargar la configuración de gráficas') self.connect_menu = QAction(QIcon('resources\\assets\\ic_settings_black_48dp.png'), 'Conectar', self._window) self.connect_menu.setStatusTip('Configuración de la conexión a Arduino') self.start_action = QAction(QIcon('resources\\assets\\ic_play_arrow_3x.png'), 'Comenzar', self._window) self.start_action.setEnabled(False) self.start_action.setStatusTip('Comienza la conexión con Arduino') self.stop_action = QAction(QIcon('resources\\assets\\ic_stop_3x.png'), 'Detener', self._window) self.stop_action.setEnabled(False) self.stop_action.setStatusTip('Detiene la conexión con Arduino') add_plot = QAction(QIcon('resources\\assets\\ic_timeline_48pt_3x.png'), 'Añadir gráfica', self._window) add_plot.setStatusTip('Añadir gráfica') board_selector = QComboBox() self.board_choices = [] self.current_board = None schemas = os.listdir("resources\\schemas") self.widgetCoord = WidgetCoordinator() for schema in schemas: fd = open("resources\\schemas\\" + schema, 'r') data = json.load(fd) board_selector.addItem(data['name']) tmp = list() # añadir al dict los pines digitales for x in range(0, data['digital']): tmp.append(x) # añadir al dict los pines analogicos for x in range(data['digital'], data['digital'] + data['analog']): tmp.append("A"+str(x-data['digital'])) self.board_choices.append((tmp, data["data_size"])) self.widgetCoord.data_size = data["data_size"] self.widgetCoord.pin_list = tmp self.current_board = tmp fd.close() # Signal handlers save_action.triggered.connect(self.save) load_action.triggered.connect(self.load) add_plot.triggered.connect(self.ini_graph_dialog) self.connect_menu.triggered.connect(self.comm_config) self.start_action.triggered.connect(self.start) self.stop_action.triggered.connect(self.stop) board_selector.currentIndexChanged.connect(self.switch_board) self.toolbar.addAction(save_action) self.toolbar.addAction(load_action) self.toolbar.addAction(add_plot) self.toolbar.addAction(self.connect_menu) self.toolbar.addAction(self.start_action) self.toolbar.addAction(self.stop_action) self.toolbar.addWidget(board_selector) self._window.addToolBar(self.toolbar) # Create status bar self.statusbar = QStatusBar(self._window) self._window.setStatusBar(self.statusbar) # Create Workspace area left_layout = QVBoxLayout() right_layout = QVBoxLayout() left_layout.setContentsMargins(0, 0, 0, 0) right_layout.setContentsMargins(0, 0, 0, 0) top_left_side = self.widgetCoord.plot_container top_right_side = self.widgetCoord.user_vars_table low_left_side = self.widgetCoord.debug_vars_widget low_right_side = self.widgetCoord.log_container # Prepare horizontal splitter and left and right vertical splitters horizontal_splitter = QSplitter(Qt.Horizontal) horizontal_splitter.setStyleSheet('background-color:rgb(239, 239, 239)') left_vertical_splitter = QSplitter(Qt.Vertical) left_vertical_splitter.setStyleSheet('background-color:rgb(239, 239, 239)') right_vertical_splitter = QSplitter(Qt.Vertical) right_vertical_splitter.setStyleSheet('background-color:rgb(239, 239, 239)') # First add left then add right left_vertical_splitter.addWidget(top_left_side) left_vertical_splitter.addWidget(low_left_side) left_layout.addWidget(left_vertical_splitter) # The same but on the right side right_vertical_splitter.addWidget(top_right_side) right_vertical_splitter.addWidget(low_right_side) right_layout.addWidget(right_vertical_splitter) # Finally add the vertical splitters to the horizontal splitter # And add it to the horizontal layout horizontal_splitter.addWidget(left_vertical_splitter) horizontal_splitter.addWidget(right_vertical_splitter) self.layout.addWidget(horizontal_splitter) self.layout.setContentsMargins(0, 0, 0, 0) def start_pygu(self): self._window.show() sys.exit(self._app.exec_()) # Functions to trigger several menu actions def save(self): try: some_tuple = QFileDialog.getSaveFileName(parent=None, caption='Guardar', directory='') abs_path = some_tuple[0] file = open(abs_path, 'w') data_to_save = json.dumps(self.widgetCoord.save(), sort_keys=True, indent=4, separators=(',', ': ')) print(data_to_save) file.write(data_to_save) file.close() except Exception as e: print(e) def load(self): try: some_tuple = QFileDialog().getOpenFileName(parent=None, caption='Cargar', directory='') abs_path = some_tuple[0] file = open(abs_path, 'r') content = json.load(file) self.widgetCoord.load(content) file.close() except Exception as e: print(e) def comm_config(self): Forms.ConnectionForm(self.connect_menu, self.start_action, self.stop_action, self.widgetCoord) def stop(self): self.widgetCoord.stop_comm() self.connect_menu.setEnabled(True) self.start_action.setEnabled(False) self.stop_action.setEnabled(False) def start(self): self.widgetCoord.start_comm() self.start_action.setEnabled(False) self.stop_action.setEnabled(True) def ini_graph_dialog(self): Forms.PlotForm(self.widgetCoord, self.current_board, self.widgetCoord.resource_dict) def switch_board(self, index): self.current_board = self.board_choices[index][0] self.widgetCoord.pin_list = self.board_choices[index][0] self.widgetCoord.data_size = self.board_choices[index][1]
class QHexWindow(QMainWindow): def __init__(self): super().__init__() self.currentFile = str() self.isUntitled = False self.hexEdit = QHexEdit(self) self.file = QFile() self.fileMenu = QMenu() self.editMenu = QMenu() self.helpMenu = QMenu() self.labelSize = QLabel() self.fileToolBar = QToolBar() self.editToolBar = QToolBar() self.undoAction = QAction() self.redoAction = QAction() self.openAction = QAction() self.saveAction = QAction() self.exitAction = QAction() self.findAction = QAction() self.aboutAction = QAction() self.closeAction = QAction() self.saveAsAction = QAction() self.saveReadable = QAction() self.aboutQtAction = QAction() self.optionsAction = QAction() self.findNextAction = QAction() self.saveReadableSelection = QAction() self.optionsDialog = OptionsDialog(self) self.setAcceptDrops(True) self.init() self.setFixedSize(QSize(1200, 600)) self.show() def closeEvent(self, event: QCloseEvent) -> None: self.writeSettings() def dragEnterEvent(self, event: QDragEnterEvent) -> None: if event.mimeData().hasUrls(): event.accept() def dropEvent(self, event: QDropEvent) -> None: if event.mimeData().hasUrls(): urls = event.mimeData().urls() filepath = urls[0].toLocalFile() self.loadFile(filepath) event.accept() def about(self): QMessageBox.about(self, 'Hex', 'Hexadecimal View') def dataChanged(self): self.setWindowModified(self.hexEdit.isModified()) def open(self): options = QFileDialog().Options() options |= QFileDialog.DontUseNativeDialog filename, _ = QFileDialog.getOpenFileName(self, "Select File", options=options) if filename: self.loadFile(filename) def optionsAccepted(self): self.writeSettings() self.readSettings() def findNext(self): pass def save(self): if self.isUntitled: self.saveAs() else: self.saveFile(self.currentFile) def saveAs(self): filename = QFileDialog.getSaveFileName(self, 'Save As...', self.currentFile) if len(filename) == 0: return False return self.saveFile(filename) def saveSelectionToReadableFile(self): pass def saveToReadableFile(self): pass def setAddress(self): pass def setOverwriteMode(self): pass def setSize(self, size): self.labelSize.setText(str(size)) def showOptionsDialog(self): pass def showSearchDialog(self): pass # noinspection PyUnresolvedReferences def init(self): self.optionsDialog.accepted.connect(self.optionsAccepted) self.hexEdit.dataChanged.connect(self.dataChanged) self.hexEdit.overwriteModeChanged.connect(self.setOverwriteMode) self.setUnifiedTitleAndToolBarOnMac(True) self.setCentralWidget(self.hexEdit) self.createActions() self.createMenus() self.createStatusBar() self.createToolBars() self.readSettings() # noinspection PyUnresolvedReferences def createActions(self): self.openAction = QAction(QIcon('Icons/MenuOpen.svg'), '&Open', self) self.openAction.setStatusTip('Open a existing file') self.openAction.setShortcut(QKeySequence.Open) self.openAction.triggered.connect(self.open) self.saveAction = QAction(QIcon('Icons/MenuSaveAll'), '&Save', self) self.saveAsAction = QAction('Save &As...', self) self.saveReadable = QAction('Save &Readable', self) self.exitAction = QAction('E&xit', self) self.undoAction = QAction(QIcon('Icons/Undo.svg'), '&Undo', self) self.redoAction = QAction(QIcon('Icons/Redo.svg'), '&Redo', self) self.saveReadableSelection = QAction('Save Selection Readable', self) self.aboutAction = QAction('&About', self) self.aboutQtAction = QAction('About &Qt', self) self.findAction = QAction(QIcon('Icons/Find.svg'), '&Find/Replace', self) self.findNextAction = QAction('Find &Next', self) self.optionsAction = QAction('&Options', self) def createMenus(self): self.fileMenu = self.menuBar().addMenu('&File') self.fileMenu.addAction(self.openAction) self.fileMenu.addAction(self.saveAction) self.fileMenu.addAction(self.saveAsAction) self.fileMenu.addAction(self.saveReadable) self.fileMenu.addSeparator() self.fileMenu.addAction(self.exitAction) self.editMenu = self.menuBar().addMenu('&Edit') self.editMenu.addAction(self.undoAction) self.editMenu.addAction(self.redoAction) self.editMenu.addAction(self.saveReadableSelection) self.editMenu.addSeparator() self.editMenu.addAction(self.findAction) self.editMenu.addAction(self.findNextAction) self.editMenu.addSeparator() self.editMenu.addAction(self.optionsAction) self.helpMenu = self.menuBar().addMenu('&Help') self.helpMenu.addAction(self.aboutAction) self.helpMenu.addAction(self.aboutQtAction) def createStatusBar(self): self.statusBar().addPermanentWidget(QLabel('Address:')) labelAddress = QLabel() labelAddress.setMinimumWidth(70) self.statusBar().addPermanentWidget(labelAddress) self.statusBar().addPermanentWidget(QLabel('Size:')) self.labelSize.setMinimumWidth(70) self.statusBar().addPermanentWidget(self.labelSize) self.hexEdit.currentSizeChanged.connect(self.setSize) self.statusBar().addPermanentWidget(QLabel('Mode:')) labelOverwriteMode = QLabel() labelOverwriteMode.setMinimumWidth(70) self.statusBar().addPermanentWidget(labelOverwriteMode) self.statusBar().showMessage('Ready', 2000) def createToolBars(self): self.fileToolBar = self.addToolBar('File') self.fileToolBar.setIconSize(QSize(16, 16)) self.fileToolBar.addAction(self.openAction) self.fileToolBar.addAction(self.saveAction) self.editToolBar = self.addToolBar('Edit') self.editToolBar.setIconSize(QSize(16, 16)) self.editToolBar.addAction(self.undoAction) self.editToolBar.addAction(self.redoAction) self.editToolBar.addAction(self.findAction) def loadFile(self, filename: str): self.file.setFileName(filename) if not self.hexEdit.setDataDevice(self.file): QMessageBox.warning( self, "Hex", f"Cannot read the file {filename}: {self.file.errorString()}.") self.setCurrentFile(filename) self.statusBar().showMessage('File Loaded', 2000) def readSettings(self): pass def saveFile(self, filename: str): pass def setCurrentFile(self, filename: str): currentFile = QFileInfo(filename).canonicalFilePath() isUntitled = len(currentFile) == 0 self.setWindowModified(False) if isUntitled: self.setWindowFilePath("QHexEdit") else: self.setWindowFilePath(currentFile + " - QHexEdit") @staticmethod def strippedName(fullFilename: str) -> str: return QFileInfo(fullFilename).fileName() def writeSettings(self): settings = QSettings() settings.setValue("pos", self.pos()) settings.setValue("size", self.size())
class Window(QMainWindow): # class MainWindow(object): def __init__(self): # def setupUi(self, Window): super(Window, self).__init__() self.setFixedSize(800, 600) self.setWindowTitle( 'BDD (Бинарные решающие диаграммы) в Логическом Криптоанализе') self.setWindowIcon(QIcon('icons/public.png')) self.init_Action() self.init_Content() self.init_StatusBar() self.init_Menu() self.init_ToolBar() self.set_Actions2Menu() self.set_Actions2StatusBar() self.set_Actions2ToolBar() self.set_Triggers2Actions() self.show() def init_Content(self): self.centralwidget = QtWidgets.QWidget(self) self.tabWidget = QtWidgets.QTabWidget(self.centralwidget) self.tabWidget.setGeometry(QtCore.QRect(0, 0, 765, 565)) self.tabWidget.setStyleSheet("") ########____ПЕРВАЯ ВКЛАДКА____ self.tab1 = QtWidgets.QWidget() self.horizontalLayoutWidget1 = QtWidgets.QWidget(self.tab1) self.horizontalLayoutWidget1.setGeometry(QtCore.QRect(8, 8, 740, 528)) self.MainLayout1 = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget1) self.MainLayout1.setContentsMargins(0, 0, 0, 0) self.LeftVlLayout1 = QtWidgets.QVBoxLayout() self.option1HLayout1 = QtWidgets.QHBoxLayout() self.labelKey1 = QtWidgets.QLabel(self.horizontalLayoutWidget1) self.labelKey1.setText("<h3>Число тактов: </h3>") self.keyLine1 = QtWidgets.QLineEdit(self.horizontalLayoutWidget1) self.option1HLayout1.addWidget(self.labelKey1) self.option1HLayout1.addWidget(self.keyLine1) self.LeftVlLayout1.addLayout(self.option1HLayout1) self.option2HLayout1 = QtWidgets.QHBoxLayout() self.labelTaps = QtWidgets.QLabel(self.horizontalLayoutWidget1) self.labelTaps.setText("<h3>Регистры сдвига: </h3>") self.tapsLine = QtWidgets.QLineEdit(self.horizontalLayoutWidget1) self.option2HLayout1.addWidget(self.labelTaps) self.option2HLayout1.addWidget(self.tapsLine) self.LeftVlLayout1.addLayout(self.option2HLayout1) self.labelInput1 = QtWidgets.QLabel(self.horizontalLayoutWidget1) self.labelInput1.setText("<h3>Ввод последовательности:</h3>") self.labelInput1.setText("<h3>Ввод последовательности:</h3>") self.textInput1 = QtWidgets.QPlainTextEdit( self.horizontalLayoutWidget1) self.LeftVlLayout1.addWidget(self.labelInput1) self.LeftVlLayout1.addWidget(self.textInput1) self.buttonHLayout1 = QtWidgets.QHBoxLayout() self.encryptButton1 = QtWidgets.QPushButton( self.horizontalLayoutWidget1) self.encryptButton1.setText("Зашифровать") self.encryptButton1.setStatusTip("Зашифровать") self.buttonHLayout1.addWidget(self.encryptButton1) self.encryptButton1.clicked.connect(self.LFSR) self.LeftVlLayout1.addLayout(self.buttonHLayout1) self.labelOutput1 = QtWidgets.QLabel(self.horizontalLayoutWidget1) self.labelOutput1.setText("<h3>Вывод результата:</h4>") self.textOutput1 = QtWidgets.QPlainTextEdit( self.horizontalLayoutWidget1) self.LeftVlLayout1.addWidget(self.labelOutput1) self.LeftVlLayout1.addWidget(self.textOutput1) self.MainLayout1.addLayout(self.LeftVlLayout1) self.RightVLayout1 = QtWidgets.QVBoxLayout() self.labelFormula1 = QtWidgets.QLabel(self.horizontalLayoutWidget1) self.labelFormula1.setText("<h3>Формулы:</h4>") self.textFormula1 = QtWidgets.QPlainTextEdit( self.horizontalLayoutWidget1) self.labelResult1 = QtWidgets.QLabel(self.horizontalLayoutWidget1) self.textResult1 = QtWidgets.QPlainTextEdit( self.horizontalLayoutWidget1) self.RightVLayout1.addWidget(self.labelFormula1) self.RightVLayout1.addWidget(self.textFormula1) self.RightVLayout1.addWidget(self.textResult1) self.MainLayout1.addLayout(self.RightVLayout1) self.tabWidget.addTab(self.tab1, "РСЛОС") self.tabWidget.setCurrentIndex(0) ########____ВТОРАЯ ВКЛАДКА____ self.tab2 = QtWidgets.QWidget() self.horizontalLayoutWidget = QtWidgets.QWidget(self.tab2) self.horizontalLayoutWidget.setGeometry(QtCore.QRect(8, 8, 740, 528)) self.MainLayout = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget) self.MainLayout.setContentsMargins(0, 0, 0, 0) self.LeftVlLayout = QtWidgets.QVBoxLayout() self.option1HLayout = QtWidgets.QHBoxLayout() self.labelKey = QtWidgets.QLabel(self.horizontalLayoutWidget) self.labelKey.setText("<h3>Ключ: </h3>") self.keyLine = QtWidgets.QLineEdit(self.horizontalLayoutWidget) self.option1HLayout.addWidget(self.labelKey) self.option1HLayout.addWidget(self.keyLine) self.LeftVlLayout.addLayout(self.option1HLayout) self.labelInput = QtWidgets.QLabel(self.horizontalLayoutWidget) self.labelInput.setText("<h3>Входной текст:</h3>") self.textInput = QtWidgets.QPlainTextEdit(self.horizontalLayoutWidget) self.LeftVlLayout.addWidget(self.labelInput) self.LeftVlLayout.addWidget(self.textInput) self.buttonHLayout = QtWidgets.QHBoxLayout() self.encryptButton = QtWidgets.QPushButton(self.horizontalLayoutWidget) self.encryptButton.setText("Зашифровать") self.encryptButton.setStatusTip("Зашифровать") self.decryptButton = QtWidgets.QPushButton(self.horizontalLayoutWidget) self.decryptButton.setText("Расшифровать") self.decryptButton.setStatusTip("Расшифровать") self.buttonHLayout.addWidget(self.decryptButton) self.buttonHLayout.addWidget(self.encryptButton) self.decryptButton.clicked.connect(self.Decrypt) self.encryptButton.clicked.connect(self.Encrypt) self.LeftVlLayout.addLayout(self.buttonHLayout) self.labelOutput = QtWidgets.QLabel(self.horizontalLayoutWidget) self.labelOutput.setText("<h3>Вывод результата:</h4>") self.textOutput = QtWidgets.QPlainTextEdit(self.horizontalLayoutWidget) self.LeftVlLayout.addWidget(self.labelOutput) self.LeftVlLayout.addWidget(self.textOutput) self.MainLayout.addLayout(self.LeftVlLayout) self.RightVLayout = QtWidgets.QVBoxLayout() self.labelFormula = QtWidgets.QLabel(self.horizontalLayoutWidget) self.labelFormula.setText("<h3>Формулы:</h4>") self.textFormula = QtWidgets.QPlainTextEdit( self.horizontalLayoutWidget) self.labelResult = QtWidgets.QLabel(self.horizontalLayoutWidget) self.textResult = QtWidgets.QPlainTextEdit(self.horizontalLayoutWidget) self.RightVLayout.addWidget(self.labelFormula) self.RightVLayout.addWidget(self.textFormula) self.RightVLayout.addWidget(self.textResult) self.MainLayout.addLayout(self.RightVLayout) self.tabWidget.addTab(self.tab2, "Шифр Виженера и Шифр Цезаря") self.setCentralWidget(self.centralwidget) self.tabWidget.setCurrentIndex(0) def init_StatusBar(self): self.statusbar = QtWidgets.QStatusBar(self) self.statusbar.setSizeGripEnabled(True) self.setStatusBar(self.statusbar) def init_Action(self): self.SaveAction = QtWidgets.QAction(QIcon('icons/save.png'), "Сохранить", self) self.ExitAction = QtWidgets.QAction(QIcon('icons/exit.png'), "Выход", self) self.HelpAction = QtWidgets.QAction(QIcon('icons/question.png'), "Помощь", self) self.AboutAction = QtWidgets.QAction(QIcon('icons/about.png'), "О программе", self) self.buildBddAction = QtWidgets.QAction(QIcon('icons/bdd1.png'), 'Построить BDD', self) self.buildRobddAction = QtWidgets.QAction(QIcon('icons/robdd1.png'), 'Построить ROBDD', self) self.SaveAction.setShortcut(('Ctrl+S')) self.ExitAction.setShortcut('Ctrl+Q') self.HelpAction.setShortcut('Ctrl+H') self.AboutAction.setShortcut('Ctrl+I') def set_Actions2StatusBar(self): self.SaveAction.setStatusTip('Сохранить') self.ExitAction.setStatusTip('Выход') self.HelpAction.setStatusTip('Помощь') self.AboutAction.setStatusTip('О программе') self.buildBddAction.setStatusTip('Построить BDD') self.buildRobddAction.setStatusTip('Построить ROBDD') def set_Triggers2Actions(self): self.SaveAction.triggered.connect(self.save1) self.ExitAction.triggered.connect(self.close) self.HelpAction.triggered.connect(self.help) self.AboutAction.triggered.connect(self.about) self.buildBddAction.triggered.connect(self.buildBdd) self.buildRobddAction.triggered.connect(self.buildRobdd) def init_Menu(self): self.menubar = QtWidgets.QMenuBar(self) self.menubar.setGeometry(QtCore.QRect(0, 0, 700, 21)) self.fileMenu = QtWidgets.QMenu(self.menubar) self.helpMenu = QtWidgets.QMenu(self.menubar) self.fileMenu.setTitle("Файл ") self.helpMenu.setTitle("Справка") self.menubar.addAction(self.fileMenu.menuAction()) self.menubar.addAction(self.helpMenu.menuAction()) self.setMenuBar(self.menubar) def set_Actions2Menu(self): self.fileMenu.addAction(self.SaveAction) self.fileMenu.addAction(self.ExitAction) self.helpMenu.addAction(self.HelpAction) self.helpMenu.addAction(self.AboutAction) def init_ToolBar(self): self.toolbar = QToolBar() self.addToolBar(Qt.LeftToolBarArea, self.toolbar) def set_Actions2ToolBar(self): self.toolbar.addAction(self.buildBddAction) self.toolbar.addSeparator() self.toolbar.addAction(self.buildRobddAction) self.toolbar.addSeparator() self.toolbar.addSeparator() self.toolbar.addAction(self.SaveAction) self.toolbar.addSeparator() self.toolbar.addAction(self.HelpAction) self.toolbar.addSeparator() self.toolbar.addAction(self.ExitAction) def closeEvent(self, event): reply = QMessageBox.question(self, 'Выход', "Вы действительно хотите нас покинуть?", QMessageBox.Yes | QMessageBox.No) if reply == QMessageBox.Yes: event.accept() else: event.ignore() def keyPressEvent(self, e): if e.key() == Qt.Key_Escape: self.close() def save1(self): name = QFileDialog.getSaveFileName(self, "Сохранить файл", filter="Text Files (*.txt)")[0] file = open(name, 'w') text = self.textResult1.toPlainText() file.write(text) file.close() #def save(self): def about(self): QMessageBox.about( self, 'О программе', "Исследование библиотеки BDD и ее применение в решении задач логического криптоанализа" ) def help(self): QMessageBox.information( self, 'Помощь', "БИБЛИОТЕКА PBDD (PBL)\n" "\n" "3.1.1 Операторы\n" "В библиотеке используются следующие операторы:\n" "• И - обозначение: &\n" "• ИЛИ - обозначение: |\n" "• Эквиваленция - обозначение: <=>\n" "• Импликация - обозначение: =>\n" "• Отрицание - обозначение: ~\n" "• Исключающее ИЛИ - обозначение: XOR\n" "• Скобки - обозначение: ( )\n" "\n" "\n" "3.1.2 Ключевые слова\n" "Ниже перечислены ключевые слова, которые не могут использоваться как имена переменных вместе с кратким описанием\n" "Var_Order - Используется при объявлении порядка переменных\n" "Main_Exp - Используется для определения логического выражения\n" "XOR - Оператор «Исключающее ИЛИ»\n" "\n" "\n" "3.1.3 Объявление переменных и формул.\n" "Порядок переменных объявляется следующим способом:\n" "Var_Order : x1 x2 x3\n" "\n" "Нет ограничения единственного объявления переменных. Есть возможность объявлять переменные несколько раз, только не следует их повторять. Например:\n" "Var_Order : x1 x2 x3\n" "Var_Order : x4 y1 y2\n" "\n" "Чтобы объявить формулу достаточно использовать оператор «=». Например X представляет собой x1 & x2 & ~x3. Для этого достаточно написать:\n" "X = x1 & x2 & ~x3.\n" "Теперь Х можно использовать вместо x1 & x2 & ~x3 в других формулах.\n" "После того, как произведены объявление всех переменных и формул, с помощью Main_Exp можно задать выражение, которое нужно действительно решить. Например, есть две формулы, хранящиеся в X1 и X2, и нужно решить конъюнкцию формул, то имеем запись:\n" "Main_Exp : X1 & X2.\n" "\n" "3.1.4 Дополнительное\n" "Есть возможность оставлять комментарии, для этого достаточно перед строкой комментария поставить символ #.\n" ) def buildBdd(self): file = QFileDialog.getOpenFileName(self, 'Открыть файл', "", "Text Files (*.txt)")[0] filele = open(file) data = filele.read() self.textFormula1.setPlainText(data) bdd = BDD.bdd_init(file) BDD.ite_build(bdd) stats = BDD.stat_string(bdd) sat_count = BDD.sat_count(bdd) sat_assigns = BDD.all_sat(bdd) sat_assigns_string = "" for x in sat_assigns: sat_assigns_string += str(x) + "\n" STAT_str = "Number of satisfying assignments: " + str(sat_count) + "\n" \ + stats + "\n\nAll satisfying assignts:\n" + "------------------------------\n" \ + sat_assigns_string self.textResult1.setPlainText(STAT_str) def buildRobdd(self): file = QFileDialog.getOpenFileName(self, 'Открыть файл', "", "Text Files (*.txt)")[0] filele = open(file) data = filele.read() self.textFormula1.setPlainText(data) bdd = BDD.bdd_init(file) BDD.ite_build(bdd) BDD.reorder_ite_build(bdd) stats = BDD.stat_string(bdd) sat_count = BDD.sat_count(bdd) sat_assigns = BDD.all_sat(bdd) sat_assigns_string = "" for x in sat_assigns: sat_assigns_string += str(x) + "\n" print(x) BDD.dot_bdd(bdd) STAT_str = "Number of satisfying assignments: " + str(sat_count) + "\n" \ + stats + "\n\nAll satisfying assignts:\n" + "------------------------------\n" \ + sat_assigns_string self.textResult1.setPlainText(STAT_str) def LFSR(self): key = int(self.keyLine1.text()) text = list(self.textInput1.toPlainText()) seed = [] for i in range(len(text)): seed.append(int(text[i])) tapsstr = self.tapsLine.text() tapslist = tapsstr.split(",") taps = [] for i in range(len(tapslist)): taps.append(int(tapslist[i])) print(taps, type(taps)) code = LFSR(seed, taps, key) print(code, type(code)) self.textOutput1.setPlainText(code) def Encrypt(self): key = self.keyLine.text() key = key.upper() word = str(self.textInput.toPlainText()) word = word.upper().replace('', '') if key.isalpha(): text = encryptVigenere(key, word) elif key.isdigit(): text = encryptCaesar(key, word) self.textOutput.setPlainText(text) def Decrypt(self): key = self.keyLine.text() key = key.upper() word = str(self.textInput.toPlainText()) word = word.upper().replace(' ', '') if key.isalpha(): text = decryptVigenere(key, word) elif key.isdigit(): text = decryptCaesar(key, word) self.textOutput.setPlainText(text)
def createGroup(self): self.bottomMenu = QFrame() self.searchText = QLineEdit(self) self.replaceText = QLineEdit(self) toolBar = QToolBar() # Create new action undoAction = QAction(QIcon.fromTheme('edit-undo'), 'Undo', self) undoAction.setStatusTip('Undo') undoAction.triggered.connect(self.undoCall) toolBar.addAction(undoAction) # create redo action redoAction = QAction(QIcon.fromTheme('edit-redo'), 'Redo', self) redoAction.setStatusTip('Undo') redoAction.triggered.connect(self.redoCall) toolBar.addAction(redoAction) toolBar.addSeparator() # create replace action replaceAction = QAction(QIcon.fromTheme('edit-find-replace'), 'Replace', self) replaceAction.triggered.connect(self.replaceCall) toolBar.addAction(replaceAction) # create find action findAction = QAction(QIcon.fromTheme('edit-find'), 'Find', self) findAction.triggered.connect(self.findCall) toolBar.addAction(findAction) # create next action nextAction = QAction(QIcon.fromTheme('go-previous'), 'Find Previous', self) nextAction.triggered.connect(self.nextCall) toolBar.addAction(nextAction) toolBar.addSeparator() # create case action caseAction = QAction(QIcon.fromTheme('edit-case'), 'Aa', self) caseAction.setCheckable(1) caseAction.triggered.connect(self.caseCall) toolBar.addAction(caseAction) box = QHBoxLayout() box.addWidget(toolBar) box.addWidget(self.searchText) box.addWidget(self.replaceText) box.addStretch(1) self.bottomMenu.setLayout(box) return self.bottomMenu
def __init__(self, parent=None): super(GcodeEditor, self).__init__(parent) self.isCaseSensitive = 0 self.setMinimumSize(QSize(300, 200)) self.setWindowTitle("PyQt5 editor test example") lay = QVBoxLayout() lay.setContentsMargins(0,0,0,0) self.setLayout(lay) # make editor self.editor = GcodeDisplay(self) # class patch editor's function to ours # so we get the lines percent update self.editor.emit_percent = self.emit_percent self.editor.setReadOnly(True) ################################ # add menubar actions ################################ # Create new action newAction = QAction(QIcon.fromTheme('document-new'), 'New', self) newAction.setShortcut('Ctrl+N') newAction.setStatusTip('New document') newAction.triggered.connect(self.newCall) # Create open action openAction = QAction(QIcon.fromTheme('document-open'), '&Open', self) openAction.setShortcut('Ctrl+O') openAction.setStatusTip('Open document') openAction.triggered.connect(self.openCall) # Create save action saveAction = QAction(QIcon.fromTheme('document-save'), '&save', self) saveAction.setShortcut('Ctrl+S') saveAction.setStatusTip('save document') saveAction.triggered.connect(self.saveCall) # Create exit action exitAction = QAction(QIcon.fromTheme('application-exit'), '&Exit', self) exitAction.setShortcut('Ctrl+Q') exitAction.setStatusTip('Exit application') exitAction.triggered.connect(self.exitCall) # Create gcode lexer action gCodeLexerAction = QAction(QIcon.fromTheme('lexer.png'), '&Gcode\n lexer', self) gCodeLexerAction.setCheckable(1) gCodeLexerAction.setShortcut('Ctrl+G') gCodeLexerAction.setStatusTip('Set Gcode highlighting') gCodeLexerAction.triggered.connect(self.editor.set_gcode_lexer) # Create gcode lexer action pythonLexerAction = QAction(QIcon.fromTheme('lexer.png'), '&python\n lexer', self) pythonLexerAction.setShortcut('Ctrl+P') pythonLexerAction.setStatusTip('Set Python highlighting') pythonLexerAction.triggered.connect(self.editor.set_python_lexer) # Create toolbar and add action toolBar = QToolBar('File') toolBar.addAction(newAction) toolBar.addAction(openAction) toolBar.addAction(saveAction) toolBar.addAction(exitAction) toolBar.addSeparator() # add lexer actions toolBar.addAction(gCodeLexerAction) toolBar.addAction(pythonLexerAction) toolBar.addSeparator() toolBar.addWidget(QLabel('<html><head/><body><p><span style=" font-size:20pt; font-weight:600;">Edit Mode</span></p></body></html>')) # create a frame for buttons box = QHBoxLayout() box.addWidget(toolBar) self.topMenu = QFrame() self.topMenu.setLayout(box) # add widgets lay.addWidget(self.topMenu) lay.addWidget(self.editor) lay.addWidget(self.createGroup()) self.readOnlyMode()
def __init__(self): QWidgetSavePos.__init__(self, "fxexperiment") self.setMinimumSize(1200, 700) self.main_vbox = QVBoxLayout() self.setWindowTitle( _("Frequency domain experiment editor") + " https://www.gpvdm.com") self.setWindowIcon(icon_get("spectrum")) toolbar = QToolBar() toolbar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) toolbar.setIconSize(QSize(48, 48)) self.new = QAction(icon_get("document-new"), wrap_text(_("New experiment"), 2), self) self.new.triggered.connect(self.callback_add_page) toolbar.addAction(self.new) self.new = QAction(icon_get("edit-delete"), wrap_text(_("Delete experiment"), 4), self) self.new.triggered.connect(self.callback_delete_page) toolbar.addAction(self.new) self.clone = QAction(icon_get("clone"), wrap_text(_("Clone experiment"), 4), self) self.clone.triggered.connect(self.callback_copy_page) toolbar.addAction(self.clone) self.clone = QAction(icon_get("rename"), wrap_text(_("Rename experiment"), 4), self) self.clone.triggered.connect(self.callback_rename_page) toolbar.addAction(self.clone) self.tb_save = QAction(icon_get("document-save-as"), wrap_text(_("Save image"), 3), self) self.tb_save.triggered.connect(self.callback_save) toolbar.addAction(self.tb_save) self.mode = tb_item_is_imps() self.mode.changed.connect(self.callback_mode_changed) toolbar.addWidget(self.mode) spacer = QWidget() spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) toolbar.addWidget(spacer) self.help = QAction(icon_get("help"), _("Help"), self) self.help.setStatusTip(_("Close")) self.help.triggered.connect(self.callback_help) toolbar.addAction(self.help) self.main_vbox.addWidget(toolbar) self.notebook = QTabWidget() self.notebook.setTabBar(QHTabBar()) self.notebook.setTabPosition(QTabWidget.West) self.notebook.setMovable(True) self.notebook.currentChanged.connect(self.callback_tab_changed) self.load_tabs() self.main_vbox.addWidget(self.notebook) self.status_bar = QStatusBar() self.main_vbox.addWidget(self.status_bar) self.setLayout(self.main_vbox)
def toolBar(self): toolBar = QToolBar() toolBar.setOrientation(Qt.Vertical) toolBar.addAction("Sujet supplémentaire").triggered.connect(self.addItem) toolBar.addAction("Supprimer sujet").triggered.connect(self.removeItem) return toolBar
class plot_ribbon(ribbon_base): def plot(self): self.plot_toolbar = QToolBar() self.plot_toolbar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) self.plot_toolbar.setIconSize(QSize(42, 42)) return self.plot_toolbar def export(self): self.file_toolbar = QToolBar() self.file_toolbar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) self.file_toolbar.setIconSize(QSize(42, 42)) self.tb_export_as_jpg = QAction_lock("export_image", _("Export\nimage"), self, "plot_export_image") self.file_toolbar.addAction(self.tb_export_as_jpg) self.tb_export_as_csv = QAction_lock("export_csv", _("Export\ncsv"), self, "plot_export_csv") self.file_toolbar.addAction(self.tb_export_as_csv) self.tb_export_as_txt = QAction_lock("export_xls", _("Export\nxls"), self, "plot_export_xls") self.file_toolbar.addAction(self.tb_export_as_txt) self.tb_export_as_gnuplot = QAction_lock("export_gnuplot", _("Export\ngnuplot"), self, "plot_export_gnuplot") self.file_toolbar.addAction(self.tb_export_as_gnuplot) self.tb_copy = QAction_lock("edit-copy", _("Copy to\nclipboard"), self, "plot_copy_to_clipboard") self.file_toolbar.addAction(self.tb_copy) return self.file_toolbar def color(self): toolbar = QToolBar() toolbar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) toolbar.setIconSize(QSize(42, 42)) self.tb_color_black = QAction(icon_get("black"), _("Black"), self) toolbar.addAction(self.tb_color_black) self.tb_color_rainbow = QAction(icon_get("rainbow"), _("Rainbow"), self) toolbar.addAction(self.tb_color_rainbow) return toolbar def scale(self): toolbar = QToolBar() toolbar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) toolbar.setIconSize(QSize(42, 42)) #self.action = QAction(icon_get("plot_log_x"),"Fix scales", None) #self.action.triggered.connect(self.callback_fix_scales) #self.action.setCheckable(True) self.tb_scale_autoscale = QAction(icon_get("plot_log_x"), _("Autoscale"), self) self.tb_scale_autoscale.setCheckable(True) self.tb_scale_autoscale.setChecked(True) toolbar.addAction(self.tb_scale_autoscale) self.tb_scale_log_y = QAction(icon_get("plot_log_x"), _("Set log scale y"), self) toolbar.addAction(self.tb_scale_log_y) self.tb_scale_log_x = QAction(icon_get("plot_log_x"), _("Set log scale x"), self) toolbar.addAction(self.tb_scale_log_x) return toolbar def math(self): toolbar = QToolBar() toolbar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) toolbar.setIconSize(QSize(42, 42)) self.math_opps = [] self.math_subtract_first_point = QAction(icon_get("plot_log_x"), _("Subtract first point"), self) toolbar.addAction(self.math_subtract_first_point) self.math_add_min_point = QAction(icon_get("plot_log_x"), _("Add min point"), self) toolbar.addAction(self.math_add_min_point) self.math_invert_y_axis = QAction(icon_get("plot_invert_y"), _("Invert y-axis"), self) toolbar.addAction(self.math_invert_y_axis) self.math_opps.append( [QAction(icon_get("plot_abs"), _("abs(f())"), self), "abs"]) toolbar.addAction(self.math_opps[-1][0]) self.math_norm_to_peak_of_all_data = QAction( icon_get("plot_log_x"), _("Norm to peak of all data"), self) toolbar.addAction(self.math_norm_to_peak_of_all_data) self.math_heat_map = QAction(icon_get("plot_log_x"), _("Heat map"), self) toolbar.addAction(self.math_heat_map) self.math_heat_map_edit = QAction(icon_get("plot_log_x"), _("Heat map edit"), self) toolbar.addAction(self.math_heat_map_edit) return toolbar def __init__(self): ribbon_base.__init__(self) #self.setMaximumHeight(130) #self.setStyleSheet("QWidget { background-color:cyan; }") w = self.plot() self.addTab(w, _("Plot")) self.export_ribbon = self.export() self.addTab(self.export_ribbon, _("Export data")) w = self.color() self.addTab(w, _("Color")) self.scale_toolbar = self.scale() self.addTab(self.scale_toolbar, _("Scale")) w = self.math() self.addTab(w, _("Math")) sheet = self.readStyleSheet(os.path.join(get_css_path(), "style.css")) if sheet != None: sheet = str(sheet, 'utf-8') self.setStyleSheet(sheet)
def __init__(self): QWidget.__init__(self) self.file_name = os.path.join(get_sim_path(), "fit_constraints.inp") self.setWindowTitle( _("Fit constraints window") + " - https://www.gpvdm.com") self.setWindowIcon(icon_get("constraints")) self.setFixedSize(900, 700) self.vbox = QVBoxLayout() ########################mm########################## toolbar_mm = QToolBar() toolbar_mm.setIconSize(QSize(32, 32)) self.tb_save = QAction(icon_get("list-add"), _("Add"), self) self.tb_save.triggered.connect(self.callback_add_item_mm) toolbar_mm.addAction(self.tb_save) self.tb_save = QAction(icon_get("list-remove"), _("Minus"), self) self.tb_save.triggered.connect(self.callback_delete_item_mm) toolbar_mm.addAction(self.tb_save) self.tb_down = QAction(icon_get("go-down"), _("Move down"), self) self.tb_down.triggered.connect(self.on_move_down) toolbar_mm.addAction(self.tb_down) self.tb_up = QAction(icon_get("go-up"), _("Move up"), self) self.tb_up.triggered.connect(self.on_move_up) toolbar_mm.addAction(self.tb_up) self.vbox.addWidget(toolbar_mm) self.tab_mm = gpvdm_tab() self.tab_mm.resizeColumnsToContents() self.tab_mm.verticalHeader().setVisible(False) self.create_model_mm() self.tab_mm.cellChanged.connect(self.tab_changed) self.select_param_window_mm = select_param(self.tab_mm) self.select_param_window_mm.set_save_function(self.save_combo) self.select_param_window_mm.file_name_tab_pos = 0 self.select_param_window_mm.token_tab_pos = 1 self.select_param_window_mm.path_tab_pos = 2 self.vbox.addWidget(self.tab_mm) #####################math########################## toolbar_math = QToolBar() toolbar_math.setIconSize(QSize(32, 32)) self.tb_save = QAction(icon_get("list-add"), _("Add"), self) self.tb_save.triggered.connect(self.callback_add_item_math) toolbar_math.addAction(self.tb_save) self.tb_save = QAction(icon_get("list-remove"), _("Minus"), self) self.tb_save.triggered.connect(self.callback_delete_item_math) toolbar_math.addAction(self.tb_save) self.vbox.addWidget(toolbar_math) self.tab_math = gpvdm_tab() self.tab_math.resizeColumnsToContents() self.tab_math.verticalHeader().setVisible(False) self.create_model_math() self.tab_math.cellChanged.connect(self.tab_changed) self.select_param_window_math_a = select_param(self.tab_math) self.select_param_window_math_a.set_save_function(self.save_combo) self.select_param_window_math_a.file_name_tab_pos = 0 self.select_param_window_math_a.token_tab_pos = 1 self.select_param_window_math_a.path_tab_pos = 2 self.select_param_window_math_b = select_param(self.tab_math) self.select_param_window_math_b.set_save_function(self.save_combo) self.select_param_window_math_b.file_name_tab_pos = 4 self.select_param_window_math_b.token_tab_pos = 5 self.select_param_window_math_b.path_tab_pos = 6 self.vbox.addWidget(self.tab_math) self.setLayout(self.vbox) self.get_scan_human_labels = get_scan_human_labels()
def createBridgePanel(self): self.setWindowTitle(self.__windowTitile) self.setWindowIcon(self.iconStart) menubar = self.menuBar() self.statusBar() self.actionNewV2rayConfigFile = QAction( self.translate("bridgePanel", "Add V2Ray-core Config File"), self) self.actionNewV2rayConfigFile.setShortcut(QKeySequence.New) self.actionNewV2rayConfigFile.setStatusTip( self.translate("bridgePanel", "Add V2Ray-core Config File")) self.actionSaveV2rayshellConfigFile = QAction( self.translate("bridgePanel", "Save V2Ray-shell Config File"), self) self.actionSaveV2rayshellConfigFile.setShortcut(QKeySequence.Save) self.actionSaveV2rayshellConfigFile.setStatusTip( self.translate("bridgePanel", "Save V2Ray-shell Config File")) self.actionReloadV2rayshellConfigFile = QAction( self.translate("bridgePanel", "Open V2Ray-shell Config File"), self) self.actionReloadV2rayshellConfigFile.setShortcut(QKeySequence.Open) self.actionReloadV2rayshellConfigFile.setStatusTip( self.translate("bridgePanel", "Open V2Ray-shell Config File")) self.actionQuitV2rayshellPanel = QAction( self.translate("bridgePanel", "Quit"), self) if sys.platform.startswith('win'): self.actionQuitV2rayshellPanel.setShortcut("Ctrl+Q") else: self.actionQuitV2rayshellPanel.setShortcut(QKeySequence.Quit) self.actionQuitV2rayshellPanel.setStatusTip( self.translate("bridgePanel", "Quit V2Ray-shell")) fileMenu = menubar.addMenu(self.translate("bridgePanel", "&File")) fileMenu.addAction(self.actionNewV2rayConfigFile) fileMenu.addSeparator() fileMenu.addAction(self.actionReloadV2rayshellConfigFile) fileMenu.addAction(self.actionSaveV2rayshellConfigFile) fileMenu.addSeparator() fileMenu.addAction(self.actionQuitV2rayshellPanel) self.texteditBridge = QTextEdit(self) self.texteditBridge.setReadOnly(True) self.tableWidgetBridge = QTableWidget() self.tableWidgetBridge.setRowCount(0) self.tableWidgetBridge.setColumnCount(5) self.tableWidgetBridge.setHorizontalHeaderLabels(self.labelBridge) self.tableWidgetBridge.setSelectionMode( QAbstractItemView.SingleSelection) self.tableWidgetBridge.setSelectionBehavior( QAbstractItemView.SelectRows) self.tableWidgetBridge.setEditTriggers( QAbstractItemView.NoEditTriggers) #self.tableWidgetBridge.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) self.tableWidgetBridge.setContextMenuPolicy(Qt.CustomContextMenu) self.popMenu = popMenu = QMenu(self.tableWidgetBridge) self.actionpopMenuAddV2rayConfigFile = QAction( self.translate("bridgePanel", "Add V2Ray Config File"), self) self.actionpopMenuAddV2rayConfigFile.setShortcut("Ctrl+n") self.actionpopMenuEditV2rayConfigFile = QAction( self.translate("bridgePanel", "Edit V2Ray Config File"), self) self.actionpopMenuProxyCheckTimeLag = QAction( self.translate("bridgePanel", "Proxy Time Lag Check..."), self) self.actionpopMenuDeleteRow = QAction( self.translate("bridgePanel", "Delete"), self) popMenu.addAction(self.actionpopMenuAddV2rayConfigFile) popMenu.addAction(self.actionpopMenuEditV2rayConfigFile) popMenu.addAction(self.actionpopMenuProxyCheckTimeLag) popMenu.addAction(self.actionpopMenuDeleteRow) self.actionopenV2rayshellPreferencesPanel = QAction( self.translate("bridgePanel", "preferences"), self) self.actionopenV2rayshellPreferencesPanel.setStatusTip( self.translate("bridgePanel", "Setting V2Ray-shell")) optionMenu = menubar.addMenu(self.translate("bridgePanel", "&options")) optionMenu.addAction(self.actionpopMenuProxyCheckTimeLag) optionMenu.addAction(self.actionopenV2rayshellPreferencesPanel) helpMenu = menubar.addMenu(self.translate("bridgePanel", "&help")) self.actioncheckv2raycoreupdate = QAction( self.translate("bridgePanel", "check V2Ray-core update"), self) self.actionv2rayshellBugreport = QAction( self.translate("bridgePanel", "Bug Report"), self) self.actionaboutv2rayshell = QAction( self.translate("bridgePanel", "About"), self) helpMenu.addAction(self.actioncheckv2raycoreupdate) helpMenu.addAction(self.actionv2rayshellBugreport) helpMenu.addAction(self.actionaboutv2rayshell) toolBar = QToolBar() self.actionV2rayStart = QAction(self.translate("bridgePanel", "Start")) self.actionV2rayStart.setIcon(self.style().standardIcon( getattr(QStyle, "SP_MediaPlay"))) self.actionV2rayStop = QAction(self.translate("bridgePanel", "Stop")) self.actionV2rayStop.setIcon(self.style().standardIcon( getattr(QStyle, "SP_MediaStop"))) toolBar.addAction(self.actionV2rayStart) toolBar.addAction(self.actionV2rayStop) self.addToolBar(toolBar) self.trayIconMenu = QMenu() self.v2rayshellTrayIcon.setContextMenu(self.trayIconMenu) self.trayIconMenushowhidePanel = QAction( self.translate("bridgePanel", "Show/Hide")) self.trayIconMenuclosePanel = QAction( self.translate("bridgePanel", "Quit")) self.trayIconMenu.addAction(self.trayIconMenushowhidePanel) self.trayIconMenu.addSeparator() self.trayIconMenu.addAction(self.trayIconMenuclosePanel) self.splitterBridge = QSplitter(Qt.Vertical) self.splitterBridge.addWidget(self.tableWidgetBridge) self.splitterBridge.addWidget(self.texteditBridge) self.setCentralWidget(self.splitterBridge) self.createBridgePanelSignals() self.onloadV2rayshellConfigFile(init=True) self.onv2raycoreStart() self.autocheckv2raycoreUpdate()
class FrameLessWindow(QWidget): def __init__(self): super(FrameLessWindow, self).__init__() self.initUI() def initUI(self): self.setWindowTitle("无边框窗口") # self.pix = QBitmap('./image/mask2.png') # self.resize(self.pix.size()) self.resize(1200, 800) self.setWindowFlags(Qt.FramelessWindowHint) self.tool_bar = QToolBar() self.normal_action = QAction('#') self.normal_action.setToolTip('还原') self.min_action = QAction("-") self.min_action.setToolTip('最小化') self.max_action = QAction("+") self.max_action.setToolTip('最大化') self.close_action = QAction("x") self.close_action.setToolTip('关闭') self.tool_bar.addAction(self.normal_action) self.tool_bar.addAction(self.min_action) self.tool_bar.addAction(self.max_action) self.tool_bar.addAction(self.close_action) self.min_button = QPushButton("最小") self.max_normal_button = QPushButton("最大") self.close_button = QPushButton("关闭") self.max_normal_button.setCheckable(True) self.max_normal_button.setDefault(False) # 通过水平布局和垂直布局将action设置在右上角 hlayout = QHBoxLayout() hlayout.addStretch(1) hlayout.addWidget(self.tool_bar) # hlayout.addWidget(self.min_button) # hlayout.addWidget(self.max_normal_button) # hlayout.addWidget(self.close_button) vlayout = QVBoxLayout() vlayout.addLayout(hlayout) vlayout.addStretch(1) self.setLayout(vlayout) self.min_button.clicked.connect(self.showMinWindow) self.max_normal_button.clicked.connect(self.showMaxNormalWindow) self.close_button.clicked.connect(self.closeWindow) self.normal_action.triggered.connect(self.showNormalWindow) self.close_action.triggered.connect(self.closeWindow) self.min_action.triggered.connect(self.showMinWindow) self.max_action.triggered.connect(self.showMaxWindow) # 设置窗口背景随窗口改变而改变 def paintEvent(self, event): painter = QPainter(self) painter.drawPixmap(0, 0, self.width(), self.height(), QPixmap('./image/screen1.jpg')) # 鼠标按下事件 def mousePressEvent(self, event): if event.button() == Qt.LeftButton: # 鼠标左键按下,开始拖动 self.m_drag = True # 按下点相对屏幕的坐标 print(event.globalPos()) # 按下点相对窗口坐标,不包含标题栏 print(event.pos()) # 窗口左上角坐标 print(self.pos()) # 按下点相对窗口坐标,包含标题栏 self.m_drapPosition = event.globalPos() - self.pos() # 光标样式 self.setCursor(QCursor(Qt.OpenHandCursor)) def mouseMoveEvent(self, event): # 实时计算窗口左上角坐标(要减去包含标题栏的坐标) self.move(event.globalPos() - self.m_drapPosition) def mouseReleaseEvent(self, event): self.m_drag = False self.setCursor(QCursor(Qt.ArrowCursor)) def closeWindow(self): self.close() def showMinWindow(self): self.showMinimized() def showMaxNormalWindow(self): print(self.max_normal_button.isChecked()) if self.max_normal_button.isChecked(): self.showMaximized() else: self.showNormal() def showMaxWindow(self): self.showMaximized() def showNormalWindow(self): self.showNormal()
class PluginLiteUI(QObject): def __init__(self, ui): super(PluginLiteUI, self).__init__(ui) self.__ui = ui self.__toolbars = e5App().getObject("ToolbarManager") self.__sourcesBrowser = e5App().getObject( "ProjectBrowser").getProjectBrowser("sources") # override window loaded event self.__oldShowEvent = self.__ui.showEvent self.__ui.showEvent = self.__windowLoaded self.__ui._UserInterface__populateToolbarsMenu = self.__populateToolbarsMenu # override source browser createPythonPopupMenus self.__oldCreatePythonPopupMenus = self.__sourcesBrowser._ProjectSourcesBrowser__createPythonPopupMenus self.__sourcesBrowser._ProjectSourcesBrowser__createPythonPopupMenus = self.__createPythonPopupMenus def activate(self): """ Public method to activate this plugin. @return tuple of None and activation status (boolean) """ return None, True def deactivate(self): """ Public method to deactivate this plugin. """ pass def __windowLoaded(self, event): """ Private method that gets called when the main window gets visible. """ # remove preferences items self.__simplifyPreferences() self.__setupMenus() self.__oldShowEvent(event) self.__setupSidebars() self.__hideStatusBar() self.__setupToolbars() e5App().getObject("ViewManager").editorOpenedEd.connect( self.__on_new_editor) # I must run only once self.__ui.showEvent = self.__oldShowEvent self.__showInitialTip() def __setupMenus(self): """ Private method that hides engineer-level menus and makes the others non-detachable. """ # hide unused menus for menu in ["view", "extras", "window", "bookmarks", "plugins"]: UiHelper.hideUnusedMenu(self.__ui, menu) toRemove = { "file": [ "Open &Bookmarked Files", "Search &File...", "Save &Copy...", "Export as", "Print Preview", "&Print" ], "edit": [ "Re&vert to last saved state", "&Indent", "U&nindent", "Toggle Comment", "Convert selection to upper case", "Convert selection to lower case", "Sort", "Complete", "&Calltip", "&Goto Line...", "Goto &Brace", "Goto Last &Edit Location", "Goto Previous Method or Class", "Goto Next Method or Class", "Select to &brace", "&Deselect all", "Shorten empty lines", "Convert &Line End Characters" ], "project": [ "Session", "Add &translation...", "&Diagrams", "Chec&k", "Sho&w", "Source &Documentation", "Pac&kagers", "&Properties...", "&User Properties...", "Filetype Associations...", "Lexer Associations..." ], "settings": [ "E&xport Preferences...", "I&mport Preferences...", "Tool&bars...", "Keyboard &Shortcuts...", "&Export Keyboard Shortcuts...", "&Import Keyboard Shortcuts...", "Show external &tools" ], "help": [ "Show &Versions", "Show &downloadable versions...", "Show Error &Log..." ] } for menu, items in toRemove.iteritems(): UiHelper.removeWidgetActions(self.__ui.getMenu(menu), items) removeFromSearch = [ "&Quicksearch", "Quicksearch &backwards", "Search current word forward", "Search current word backward", "Clear search markers", "Search in &Files...", "Replace in F&iles...", "Search in Open Files...", "Replace in Open Files..." ] for el in self.__ui.getMenu("edit").actions(): if el.text() == self.__ui.tr("&Search"): UiHelper.removeWidgetActions(el.menu(), removeFromSearch) break def __initLiteToolbar(self, ui, toolbarManager): # find first toolbar firstToolbar = None for toolbar in ui.findChildren(QToolBar): if toolbar.isVisible(): firstToolbar = toolbar break toCopy = [ ['file', ["&Save", "&Open...", "&New"]], ['project', ["&Save", "&Open...", "&New..."]], ] self.__toolbar = QToolBar(self.tr("Lite tools"), ui) self.__toolbar.setIconSize(UI.Config.ToolBarIconSize) self.__toolbar.setObjectName("LiteUI") self.__toolbar.setToolTip(self.tr('Pymakr lite tools')) title = self.__toolbar.windowTitle() toolbarManager.addToolBar(self.__toolbar, title) # load new toolbar actions for bar in toCopy: for el in self.__ui.getToolbar(bar[0])[1].actions(): if el.text() in bar[1]: self.__toolbar.addAction(el) toolbarManager.addAction(el, title) ui.registerToolbar("lite", title, self.__toolbar) if firstToolbar: ui.insertToolBar(firstToolbar, self.__toolbar) else: ui.addToolBar(self.__toolbar) self.__toolbar.setIconSize(QSize(32, 32)) def __setupToolbars(self): self.__initLiteToolbar(self.__ui, self.__toolbars) for toolbar in [ "project", "edit", "file", "quicksearch", "search", "spelling" ]: UiHelper.hideToolbar(self.__ui, toolbar) self.__fixToolbars() def __setupSidebars(self): """ Private method that hides the pro-level sidebars """ allLeftTabs = { "File-Browser", "Project-Viewer", "Multiproject-Viewer", "Template-Viewer", "Symbols", "File-Browser" } allBottomTabs = { "Pycom Console", "Shell", "Task-Viewer", "Numbers", "Translator", "Local Shell", "Log-Viewer" } toHideBottom = list(allBottomTabs - bottomTabsToShow) toHideLeft = list(allLeftTabs - leftTabsToShow) UiHelper.hideItemsSidebar(self.__ui.leftSidebar, toHideLeft) UiHelper.hideItemsSidebar(self.__ui.bottomSidebar, toHideBottom) def __fixToolbars(self): self.__toolbars._fixedToolbars = True # ask future toolbars to be fixed for toolbar in self.__ui.findChildren(QToolBar): toolbar.setMovable(False) def __hideStatusBar(self): self.__ui.statusBar().hide() def __populateToolbarsMenu(self, menu): menu.clear() def __on_new_editor(self, editor): itemstoHide = [ "Autosave enabled", "Typing aids enabled", "Automatic Completion enabled", "Complete", "Calltip", "Check", "Show", "Diagrams", "Tools", "New Document View", "New Document View (with new split)", "Close", "Re-Open With Encoding", "Save", "Save As...", "Save Copy..." ] UiHelper.hideWidgetActions(editor.menu, itemstoHide) def __createPythonPopupMenus(self): itemsToRemove = [ "Run unittest...", "Diagrams", "Check", "Show", "Configure..." ] self.__oldCreatePythonPopupMenus() UiHelper.removeWidgetActions(self.__sourcesBrowser.sourceMenu, itemsToRemove) def __simplifyPreferences(self): toDeleteTxt = [ 'Shell', 'Tasks', 'Interface', 'Editor/Autocompletion', 'Editor/Calltips', 'Editor/Code Checkers', 'Editor/Exporters', 'Editor/Filehandling', 'Editor/Highlighters/Properties', 'Editor/Searching', 'Editor/Spell checking', 'Editor/Typing' ] FullUI.PreferencesDialog.SimplifyPreferences.toDeleteExtend( toDeleteTxt) def __showInitialTip(self): if Preferences.Prefs.settings.value("UI/AdvancedInterfaceTipShown", False) != "true": E5MessageBox.information( self.__ui, self.__ui.tr("Pymakr hint"), self.__ui. tr("<b>Hint</b><br><br>If you're an expert, you can always switch to the full interface by selecting<i>Settings > Switch to expert interface</i> in the main menu." )) Preferences.Prefs.settings.setValue("UI/AdvancedInterfaceTipShown", "true")
def __init__(self, *args, **kwargs): super(MainWindow, self).__init__(*args, **kwargs) self.setWindowTitle("Simulation of a random walk") self.setFixedSize(900, 600) self.threadpool = QThreadPool() # layout main_layout = QHBoxLayout() left_layout = QVBoxLayout() right_layout = QVBoxLayout() self.label_title = QLabel("Motivational agent simulation") self.label_title.setAlignment(Qt.AlignCenter) self.label_title.setFixedHeight(20) # Creating the painting context self.scanvas = SimulationCanvas(self, 500, 500) left_layout.addWidget(self.label_title) left_layout.addWidget(self.scanvas) left_layout.setContentsMargins(0, 0, 0, 0) left_layout.setSpacing(0) # Right panel pw = 350 ph = 150 # self.plotView1 = pg.widgets.RemoteGraphicsView.RemoteGraphicsView() # self.plotView1.setFixedWidth( pw+10 ) # self.plotView1.pg.setConfigOptions(antialias=True) self.plotTop = pg.PlotWidget() self.plotTop.setFixedWidth(pw) self.plotTop.setFixedHeight(ph) self.plotTopData = self.plotTop.plot([0], [0]) # self.plotView1.setCentralItem( self.plotTop ) self.plotMiddle = pg.PlotWidget() self.plotMiddle.setFixedWidth(pw) self.plotMiddle.setFixedHeight(ph) self.plotMiddleData = self.plotMiddle.plot([0], [0]) self.plotBottom = pg.PlotWidget() self.plotBottom.setFixedWidth(pw) self.plotBottom.setFixedHeight(ph) self.plotBottomData = self.plotBottom.plot([0], [0]) right_layout.addWidget(self.plotTop) right_layout.addWidget(self.plotMiddle) right_layout.addWidget(self.plotBottom) right_layout.setContentsMargins(0, 0, 0, 0) # Building main layour main_layout.setContentsMargins(0, 0, 0, 0) main_layout.setSpacing(0) main_layout.addLayout(left_layout) main_layout.addLayout(right_layout) self.widget = QWidget() self.widget.setLayout(main_layout) self.setCentralWidget(self.widget) toolbar = QToolBar("Some toolbar") self.addToolBar(toolbar) self.run_text = QLineEdit("10") self.run_text.setFixedWidth(50) self.run_action = QAction("Run", self) self.run_action.setIcon(QIcon("icons/play.png")) self.run_action.setStatusTip("Runs the simulation") self.run_action.triggered.connect(self.onRunClick) self.pause_action = QAction("Pause", self) self.pause_action.setIcon(QIcon("icons/pause.png")) self.pause_action.setStatusTip("Pauses the simulation") self.pause_action.triggered.connect(self.onPauseClick) self.pause_action.setEnabled(False) self.stop_action = QAction("Stop", self) self.stop_action.setIcon(QIcon("icons/stop.png")) self.stop_action.setStatusTip("Stops the simulation") self.stop_action.triggered.connect(self.onStopClick) self.stop_action.setEnabled(False) self.plots_action = QAction("Plots", self) self.plots_action.setIcon(QIcon("icons/plot.png")) self.plots_action.setStatusTip("Shows additional plots") self.plots_action.triggered.connect(self.onPlotsClick) self.screenshot_action = QAction("Screenshot", self) self.screenshot_action.setStatusTip("Saves screenshot") self.screenshot_action.triggered.connect(self.onScreenShotClick) # self.plots_action.setEnabled( False ) self.foodx = QLineEdit("-20") self.foodx.setFixedWidth(50) self.foody = QLineEdit("20") self.foody.setFixedWidth(50) toolbar.addAction(self.run_action) toolbar.addWidget(self.run_text) toolbar.addWidget(QLabel("ms")) toolbar.addAction(self.pause_action) toolbar.addAction(self.stop_action) toolbar.addAction(self.plots_action) toolbar.addAction(self.screenshot_action) toolbar.addWidget(QLabel("Food position:")) toolbar.addWidget(self.foodx) toolbar.addWidget(self.foody) self.statusb = QStatusBar(self) self.setStatusBar(self.statusb) self.simulation = None self.signals = GraphicSignals() self.plots = PlotsWindow(self) self.agentPos = [20.0, 40.0]
class ribbon(QTabWidget): def goto_page(self, page): self.blockSignals(True) for i in range(0, self.count()): if self.tabText(i) == page: self.setCurrentIndex(i) break self.blockSignals(False) def file(self): toolbar = QToolBar() toolbar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) toolbar.setIconSize(QSize(42, 42)) self.home_new = QAction(QIcon_load("document-new"), _("New simulation").replace(" ", "\n"), self) #self.home_new.setText(_("New\nsimulation")) toolbar.addAction(self.home_new) self.home_open = QAction(QIcon_load("document-open"), _("Open\nsimulation"), self) toolbar.addAction(self.home_open) self.home_export = QAction(QIcon_load("document-export"), _("Export\ndata"), self) toolbar.addAction(self.home_export) spacer = QWidget() spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) toolbar.addWidget(spacer) self.home_help = QAction(QIcon_load("internet-web-browser"), _("Help"), self) toolbar.addAction(self.home_help) return toolbar def update(self): #self.device.update() self.database.update() self.simulations.update() self.configure.update() self.information.update() self.home.update() def callback_about_dialog(self): dlg = about_dlg() dlg.exec_() def __init__(self): QTabWidget.__init__(self) self.cluster_tab = None self.setMaximumHeight(140) #self.setStyleSheet("QWidget { background-color:cyan; }") self.myserver = server_get() self.holder = QWidget() self.hbox = QHBoxLayout() self.holder.setLayout(self.hbox) self.toolbar = QToolBar() self.toolbar.setIconSize(QSize(32, 32)) self.about = QToolButton(self) self.about.setText(_("About")) self.about.pressed.connect(self.callback_about_dialog) self.cluster_button = QAction(QIcon_load("not_connected"), _("Connect to cluster"), self) self.cluster_button.triggered.connect(self.callback_cluster_connect) self.toolbar.addAction(self.cluster_button) self.hbox.addWidget(self.toolbar) self.hbox.addWidget(self.about) self.setCornerWidget(self.holder) w = self.file() self.addTab(w, _("File")) self.home = ribbon_home() self.addTab(self.home, _("Home")) self.simulations = ribbon_simulations() self.addTab(self.simulations, _("Simulations")) self.configure = ribbon_configure() self.addTab(self.configure, _("Configure")) #self.device=ribbon_device() #self.addTab(self.device,_("Device")) self.database = ribbon_database() self.addTab(self.database, _("Databases")) if enable_betafeatures() == True: self.tb_cluster = ribbon_cluster() self.addTab(self.tb_cluster, _("Cluster")) self.information = ribbon_information() self.addTab(self.information, _("Information")) #self.setStyleSheet("QWidget { background-color:cyan; }") css_apply(self, "style.css") def callback_cluster_connect(self): dialog = connect_to_cluster() if dialog.exec_(): self.cluster_tab = global_object_get("cluster_tab") global_object_get("notebook_goto_page")(_("Terminal")) if self.myserver.connect() == False: error_dlg(self, _("Can not connect to cluster.")) self.tb_cluster.update() if self.myserver.cluster == True: self.cluster_button.setIcon(QIcon_load("connected")) status_icon_stop(True) else: status_icon_stop(False) self.cluster_button.setIcon(QIcon_load("not_connected"))
def setToolbar(self): toolbar = QToolBar('Main Toolbar') self.addToolBar(toolbar) self.open_btn = QAction(self.ctx.open_icon, 'Open File(s)', self) self.open_btn.setShortcut('Ctrl+O') self.open_btn.setStatusTip('Open File(s)') self.open_folder_btn = QAction(self.ctx.folder_icon, 'Open Folder', self) self.open_folder_btn.setStatusTip('Open Folder') self.open_sample_btn = QAction(self.ctx.sample_icon, 'Open Sample', self) self.open_sample_btn.setStatusTip('Load Sample DICOM Files') self.dcmtree_btn = QAction(self.ctx.tree_icon, 'DICOM Info', self) self.dcmtree_btn.setStatusTip('DICOM Info') self.dcmtree_btn.setEnabled(False) self.settings_btn = QAction(self.ctx.setting_icon, 'Settings', self) self.settings_btn.setStatusTip('Application Settings') self.help_btn_en = QAction(self.ctx.help_icon, 'English', self) self.help_btn_id = QAction(self.ctx.help_icon, 'Bahasa Indonesia', self) self.help_act = QToolButton(self) self.help_act.setIcon(self.ctx.help_icon) self.help_act.setShortcut('F1') self.help_act.setToolTip('Open User Manual') self.help_act.setStatusTip('Open User Manual') self.help_act.setPopupMode(QToolButton.InstantPopup) self.help_act.addAction(self.help_btn_en) self.help_act.addAction(self.help_btn_id) toolbar.addAction(self.open_btn) toolbar.addAction(self.open_folder_btn) toolbar.addAction(self.open_sample_btn) toolbar.addAction(self.dcmtree_btn) toolbar.addAction(self.settings_btn) toolbar.addWidget(self.help_act) rec_ctrl = QToolBar('Records Control') self.addToolBar(rec_ctrl) self.save_btn = QAction(self.ctx.save_icon, 'Save Record', self) self.save_btn.setShortcut('Ctrl+S') self.save_btn.setStatusTip('Save Record to Database') self.openrec_btn = QAction(self.ctx.launch_icon, 'Open Records', self) self.openrec_btn.setStatusTip('Open Patients Record') rec_ctrl.addAction(self.save_btn) rec_ctrl.addAction(self.openrec_btn) img_ctrl = QToolBar('Image Control') self.addToolBar(Qt.BottomToolBarArea, img_ctrl) self.next_btn = QAction(self.ctx.next_icon, 'Next Slice', self) self.next_btn.setStatusTip('Next Slice') self.next_btn.setShortcut(Qt.Key_Up) self.prev_btn = QAction(self.ctx.prev_icon, 'Previous Slice', self) self.prev_btn.setStatusTip('Previous Slice') self.prev_btn.setShortcut(Qt.Key_Down) self.close_img_btn = QAction(self.ctx.close_img_icon, 'Close Images', self) self.close_img_btn.setStatusTip('Close all images') self.close_img_btn.setEnabled(False) self.sort_btn = QPushButton('Sort Images') self.sort_btn.setEnabled(False) self.current_lbl = QLabel('0') self.total_lbl = QLabel('0') self.go_to_slice_sb = QSpinBox() self.go_to_slice_sb.setButtonSymbols(QAbstractSpinBox.NoButtons) self.go_to_slice_sb.setMinimumWidth(30) self.go_to_slice_sb.setMinimum(0) self.go_to_slice_sb.setMaximum(self.ctx.total_img) self.go_to_slice_sb.setWrapping(True) self.go_to_slice_sb.setAlignment(Qt.AlignCenter) self.go_to_slice_btn = QPushButton('Go to slice') img_ctrl.addAction(self.close_img_btn) img_ctrl.addWidget(self.sort_btn) img_ctrl.addSeparator() img_ctrl.addAction(self.prev_btn) img_ctrl.addWidget(self.current_lbl) img_ctrl.addWidget(QLabel('/')) img_ctrl.addWidget(self.total_lbl) img_ctrl.addAction(self.next_btn) img_ctrl.addWidget(self.go_to_slice_sb) img_ctrl.addWidget(self.go_to_slice_btn) view = QToolBar('View Options') self.addToolBar(view) self.windowing_cb = QComboBox() self.window_width_edit = QLineEdit(str(self.window_width)) self.window_level_edit = QLineEdit(str(self.window_level)) self.window_width_edit.setAlignment(Qt.AlignCenter) self.window_width_edit.setMaximumWidth(50) self.window_width_edit.setEnabled(False) self.window_width_edit.setValidator(QIntValidator()) self.window_level_edit.setAlignment(Qt.AlignCenter) self.window_level_edit.setMaximumWidth(50) self.window_level_edit.setEnabled(False) self.window_level_edit.setValidator(QIntValidator()) self.windowing_cb.setEnabled(False) self.windowing_cb.setModel(self.ctx.windowing_model) self.windowing_cb.setModelColumn(self.ctx.windowing_model.fieldIndex('Name')) self.windowing_cb.setPlaceholderText('Windowing') self.windowing_cb.setCurrentIndex(0) view.addWidget(QLabel('Windowing: ')) view.addWidget(self.windowing_cb) view.addWidget(self.window_width_edit) view.addWidget(self.window_level_edit) opts = QToolBar('Options') self.addToolBar(opts) spacer = QWidget(self) spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) spacer.setVisible(True) self.phantom_cb = QComboBox() self.phantom_cb.tag = 'phantom' self.phantom_cb.setModel(self.ctx.phantom_model) self.phantom_cb.setModelColumn(self.ctx.phantom_model.fieldIndex('name')) self.phantom_cb.setPlaceholderText('Phantom') opts.addWidget(spacer) opts.addWidget(QLabel('Phantom: ')) opts.addWidget(self.phantom_cb) opts.addSeparator()
def _createToolBar(self): tools = QToolBar() self.addToolBar(tools) tools.addAction("Exit", self.close)
class QTool(Ui_ToolTab, QWidget, Tool): """[summary] [description] """ def __init__(self, name="QTool", parent_app=None): """ **Constructor** Keyword Arguments: - name {[type]} -- [description] (default: {"QTool"}) - parent_dataset {[type]} -- [description] (default: {None}) - axarr {[type]} -- [description] (default: {None}) """ super().__init__(name=name, parent_app=parent_app) self.setupUi(self) self.tb = QToolBar() self.tb.setIconSize(QSize(24,24)) self.actionActive.setChecked(True) self.actionApplyToTheory.setChecked(True) self.tb.addAction(self.actionActive) self.tb.addAction(self.actionApplyToTheory) self.verticalLayout.insertWidget(0, self.tb) #build the tool widget self.toolParamTable.setIndentation(0) self.toolParamTable.setColumnCount(2) self.toolParamTable.setHeaderItem(QTreeWidgetItem(["Parameter", "Value"])) self.toolParamTable.header().resizeSections(QHeaderView.ResizeToContents) self.toolParamTable.setAlternatingRowColors(True) self.toolParamTable.setFrameShape(QFrame.NoFrame) self.toolParamTable.setFrameShadow(QFrame.Plain) self.toolParamTable.setEditTriggers(self.toolParamTable.NoEditTriggers) self.toolTextBox.setReadOnly(True) self.toolTextBox.setContextMenuPolicy(Qt.CustomContextMenu) self.toolTextBox.customContextMenuRequested.connect(self.toolTextBox_context_menu) connection_id = self.actionActive.triggered.connect(self.handle_actionActivepressed) connection_id = self.actionApplyToTheory.triggered.connect(self.handle_actionApplyToTheorypressed) connection_id = self.toolParamTable.itemDoubleClicked.connect(self.onTreeWidgetItemDoubleClicked) connection_id = self.toolParamTable.itemChanged.connect(self.handle_parameterItemChanged) self.toolParamTable.setEditTriggers(QTreeWidget.EditKeyPressed) def toolTextBox_context_menu(self): """Custom contextual menu for the theory textbox""" menu = self.toolTextBox.createStandardContextMenu() menu.addSeparator() menu.addAction("Increase Font Size", lambda: self.change_toolTextBox_fontsize(1.25)) menu.addAction("Deacrease Font Size", lambda: self.change_toolTextBox_fontsize(0.8)) menu.addAction("Clear Text", self.toolTextBox.clear) menu.exec_(QCursor.pos()) def change_toolTextBox_fontsize(self, factor): """Change the toolTextBox font size by a factor `factor` """ font = self.toolTextBox.currentFont() if factor < 1: font_size = ceil(font.pointSize() * factor) else: font_size = floor(font.pointSize() * factor) font.setPointSize(font_size) self.toolTextBox.document().setDefaultFont(font) def editItem(self, item, column): print(column) def update_parameter_table(self): """Update the Tool parameter table [description] """ #clean table self.toolParamTable.clear() #populate table for param in self.parameters: p = self.parameters[param] if p.display_flag: #only allowed param enter the table if (p.type == ParameterType.string): item = QTreeWidgetItem(self.toolParamTable, [p.name, p.value]) else: item = QTreeWidgetItem(self.toolParamTable, [p.name, "%0.3g" % p.value]) item.setToolTip(0, p.description) item.setFlags(item.flags() | Qt.ItemIsEditable) self.toolParamTable.header().resizeSections(QHeaderView.ResizeToContents) def handle_parameterItemChanged(self, item, column): """Modify parameter values when changed in the Tool table [description] Arguments: - item {[type]} -- [description] - column {[type]} -- [description] """ param_changed = item.text(0) if column == 0: #param was checked/unchecked if item.checkState(0) == Qt.Checked: self.parameters[param_changed].opt_type = OptType.opt elif item.checkState(0) == Qt.Unchecked: self.parameters[param_changed].opt_type = OptType.nopt return #else, assign the entered value new_value = item.text(1) message, success = self.set_param_value(param_changed, new_value) if (not success): msg = QMessageBox() msg.setWindowTitle("Error") if message != '': msg.setText("Not a valid value\n" + message) else: msg.setText("Not a valid value") msg.exec_() item.setText(1, str(self.parameters[param_changed].value)) self.parent_application.update_all_ds_plots() def handle_actionActivepressed(self, checked): if checked: self.actionActive.setIcon( QIcon(':/Icon8/Images/new_icons/icons8-toggle-on.png')) else: self.actionActive.setIcon( QIcon(':/Icon8/Images/new_icons/icons8-toggle-off.png')) self.actionActive.setChecked(checked) self.active = checked self.parent_application.update_all_ds_plots() # def actionActivepressed(self): # self.active = self.actionActive.isChecked() # self.parent_application.update_all_ds_plots() def handle_actionApplyToTheorypressed(self, checked): if checked: self.actionApplyToTheory.setIcon( QIcon(':/Icon8/Images/new_icons/icons8-einstein-yes.png')) else: self.actionApplyToTheory.setIcon( QIcon(':/Icon8/Images/new_icons/icons8-einstein-no.png')) self.actionApplyToTheory.setChecked(checked) self.applytotheory = checked self.parent_application.update_all_ds_plots() def onTreeWidgetItemDoubleClicked(self, item, column): """Start editing text when a table cell is double clicked """ if column == 1: self.toolParamTable.editItem(item, column)
def create_toolbars(self): stdTooBbar = QToolBar('Стандартна') stdTooBbar.addAction(self.newAct) stdTooBbar.addAction(self.openAct) stdTooBbar.addAction(self.saveAct) stdTooBbar.addSeparator() stdTooBbar.addAction(self.printAct) stdTooBbar.addSeparator() stdTooBbar.addAction(self.cutAct) stdTooBbar.addAction(self.copyAct) stdTooBbar.addAction(self.pasteAct) stdTooBbar.addSeparator() stdTooBbar.addAction(self.undoAct) stdTooBbar.addAction(self.redoAct) tableToolBar = QToolBar('Таблиця') tableToolBar.addAction(self.append_table_rowAct) tableToolBar.addAction(self.insert_table_rowAct) tableToolBar.addAction(self.remove_table_rowsAct) self.addToolBar(stdTooBbar) self.addToolBar(tableToolBar)
class EDIT_DETAILS(QMainWindow): def __init__(self, title, prev_scrn, profile, super_layout): super().__init__() self.title = title self.title.setWindowTitle("EDIT STUDENT DETAILS") self.super_layout = super_layout self.previous = prev_scrn self.MAIN_VIEW(profile) def MAIN_VIEW(self, profile): self.comp = COMPONENTS() _id = int(profile["id"]) r = requests.get(url=f"{APP_URL}/users/students/{_id}") self.profile = r.json() self.main_menu = self.menuBar() self.toolbar = QToolBar() self.file_menu = self.main_menu.addMenu("File") self.export = QAction(QIcon("./assets/icons/export_pdf.png"), "Export as PDF", self) self.export.setShortcut("Ctrl+S") self.exit_action = QAction(QIcon("./assets/icons/exit.png"), "Exit", self) self.exit_action.setShortcut("Ctrl+Q") self.file_menu.addAction(self.export) self.file_menu.addAction(self.exit_action) self.export.triggered.connect(self._save_as_file) self.exit_action.triggered.connect(lambda: self.previous()) self.toolbar = self.addToolBar("Toolbar") self.toolbar.addAction(self.exit_action) self.toolbar.addAction(self.export) self.main_widget = QWidget() self.vbox = QVBoxLayout() self.personal_details() self.contact_details() self.parent_detail() self.other_detail() self.main_widget.setLayout(self.vbox) self.scroll = QScrollArea() self.scroll.setWidget(self.main_widget) self.scroll.setWidgetResizable(True) self.setCentralWidget(self.scroll) self.super_layout.addWidget(self) self.super_layout.setCurrentWidget(self) def personal_details(self): _group_box = QGroupBox("Personal Details") _grid = QGridLayout() _group_box.setLayout(_grid) # for views containing school detail of student self.sd_view = QHBoxLayout() self.sd_detail_view = QGridLayout() _grid.addLayout(self.sd_view, 0, 0, 1, 0) self.sd_view.addLayout(self.sd_detail_view) self.sd_view.addLayout(self.comp.pro_pic_view) r = requests.get(url=self.profile["pic"], stream=True) pic = QImage() pic.loadFromData(r.content) self.comp.profile_pic.setPixmap(QPixmap.fromImage(pic)) self.comp.change_pro.clicked.connect( lambda: self.comp._start_video(self.super_layout)) self.comp.cam_btn.clicked.connect( lambda: self.snap(self.comp.image, self.comp.timer, self.comp.cam)) self.sd_detail_view.addWidget(self.comp.m_num, 0, 0) self.sd_detail_view.addWidget(self.comp.m_num_input, 0, 1) self.comp.m_num_input.setText(self.profile["matric_number"]) self.sd_detail_view.addWidget(self.comp.j_num, 1, 0) self.sd_detail_view.addWidget(self.comp.j_num_input, 1, 1) self.comp.j_num_input.setText(self.profile["jamb_number"]) self.sd_detail_view.addWidget(self.comp.college, 2, 0) self.sd_detail_view.addWidget(self.comp.college_select, 2, 1) self.comp.college_select.setCurrentText(self.profile["college"]) self.school() self.comp.college_select.currentIndexChanged.connect( lambda: REGISTER_STUDENT.school( self, self.comp.college_select.currentIndex())) self.sd_detail_view.addWidget(self.comp.dept, 3, 0) self.sd_detail_view.addWidget(self.comp.dept_select, 3, 1) self.comp.dept_select.setCurrentText(self.profile["department"]) self.sd_detail_view.addWidget(self.comp.level, 4, 0) self.sd_detail_view.addWidget(self.comp.level_select, 4, 1) self.comp.level_select.setCurrentText(self.profile["level"]) self.pd_detail_view = QGridLayout() self.name = QLabel("Name:") self.name.setObjectName("Label") _grid.addWidget(self.name, 1, 0) self.pd_detail_view.addWidget(self.comp.l_name, 0, 0) self.pd_detail_view.addWidget(self.comp.l_name_input, 0, 1) self.comp.l_name_input.setText(self.profile["last_name"]) self.pd_detail_view.addWidget(self.comp.m_name, 1, 0) self.pd_detail_view.addWidget(self.comp.m_name_input, 1, 1) self.comp.m_name_input.setText(self.profile["middle_name"]) self.pd_detail_view.addWidget(self.comp.f_name, 2, 0) self.pd_detail_view.addWidget(self.comp.f_name_input, 2, 1) self.comp.f_name_input.setText(self.profile["first_name"]) _grid.addLayout(self.pd_detail_view, 1, 1) _grid.addWidget(self.comp.age, 2, 0) _grid.addWidget(self.comp.age_input, 2, 1) self.comp.age_input.setText(str(self.profile["age"])) _grid.addWidget(self.comp.gender, 3, 0) _grid.addLayout(self.comp.gender_layout, 3, 1) if self.comp.gender_1.text() == self.profile["gender"].upper(): self.comp.gender_1.setChecked(True) else: self.comp.gender_2.setChecked(True) _grid.addWidget(self.comp.dob_label, 4, 0) _grid.addLayout(self.comp.dob_layout, 4, 1) self.comp.dob_date_label.setText(str(self.profile["date_of_birth"])) _grid.addWidget(self.comp.nationality, 5, 0) _grid.addWidget(self.comp.nationality_input, 5, 1) self.comp.nationality_input.setText(self.profile["nationality"]) _grid.addWidget(self.comp.state_origin, 6, 0) _grid.addWidget(self.comp.state_origin_input, 6, 1) self.comp.state_origin_input.setText(self.profile["state_of_origin"]) _grid.addWidget(self.comp.lga_origin, 7, 0) _grid.addWidget(self.comp.lga_origin_input, 7, 1) self.comp.lga_origin_input.setText(self.profile["lga_origin"]) _grid.addWidget(self.comp.marital, 8, 0) _grid.addWidget(self.comp.marital_select, 8, 1) self.comp.marital_select.setCurrentText(self.profile["marital_status"]) self.vbox.addWidget(_group_box) def contact_details(self): _group_box = QGroupBox("Contact Details") _grid = QGridLayout() _group_box.setLayout(_grid) _grid.addWidget(self.comp.address, 0, 0) _grid.addWidget(self.comp.address_input, 0, 1) self.comp.address_input.setText(self.profile["address"]) _grid.addWidget(self.comp.phone, 1, 0) _grid.addWidget(self.comp.phone_input, 1, 1) self.comp.phone_input.setText(self.profile["phone_number"]) _grid.addWidget(self.comp.email, 2, 0) _grid.addWidget(self.comp.email_input, 2, 1) self.comp.email_input.setText(self.profile["email"]) self.vbox.addWidget(_group_box) def parent_detail(self): _group_box = QGroupBox("Parent's/Sponsor's Details") _grid = QGridLayout() _group_box.setLayout(_grid) _grid.addWidget(self.comp.p_name, 0, 0) _grid.addWidget(self.comp.p_name_input, 0, 1) self.comp.p_name_input.setText(self.profile["parent_name"]) _grid.addWidget(self.comp.p_email, 1, 0) _grid.addWidget(self.comp.p_email_input, 1, 1) self.comp.p_email_input.setText(self.profile["parent_email"]) _grid.addWidget(self.comp.p_phone, 2, 0) _grid.addWidget(self.comp.p_phone_input, 2, 1) self.comp.p_phone_input.setText(self.profile["parent_phone"]) self.vbox.addWidget(_group_box) def other_detail(self): _group_box = QGroupBox("Parent's/Sponsor's Details") _grid = QGridLayout() _grid.addWidget(self.comp.dor, 0, 0) self.dor_text = QLabel() _grid.addWidget(self.dor_text, 0, 1) self.dor_text.setText(str(self.profile["date_of_registration"])) _group_box.setLayout(_grid) self.vbox.addWidget(_group_box) self.save_2_db = QPushButton("SAVE") self.save_2_db.setIcon(QIcon("./assets/icons/save_2_db.png")) self.save_2_db.setIconSize(QSize(20, 20)) self.vbox.addWidget(self.save_2_db) self.save_2_db.clicked.connect(self._save_2_db) def _save_2_db(self): _id = int(self.profile["id"]) for image in os.listdir("./assets/temp/"): entries = { "first_name": str(self.comp.f_name_input.text()), "middle_name": str(self.comp.m_name_input.text()), "last_name": str(self.comp.l_name_input.text()), "date_of_birth": str(self.comp.dob_date_label.text()), "age": str(self.comp.age_input.text()), "gender": str((self.comp.gender_1.text() if self.comp.gender_1.isChecked() else self.comp.gender_2.text())), "nationality": str(self.comp.nationality_input.text()), "state_of_origin": str(self.comp.state_origin_input.text()), "lga_origin": str(self.comp.lga_origin_input.text()), "marital_status": str(self.comp.marital_select.currentText()), # Assigning Variables "jamb_number": str(self.comp.j_num_input.text()), "college": str(self.comp.college_select.currentText()), "department": str(self.comp.dept_select.currentText()), "level": str(self.comp.level_select.currentText()), "matric_number": str(self.comp.m_num_input.text()), # Assigning Variables "address": str(self.comp.address_input.text()), "phone_number": str(self.comp.phone_input.text()), "email": str(self.comp.email_input.text()), # Assigning Variables "parent_name": str(self.comp.p_name_input.text()), "parent_email": str(self.comp.p_email_input.text()), "parent_phone": str(self.comp.p_phone_input.text()), "date_of_registration": str(self.comp.dor_text.text()), } file = {"image": open(f"./assets/temp/{image}", "rb").read()} if self.comp.isConnected(): r = requests.post(url=f"{APP_URL}/users/students/{_id}", data=entries, files=file) def _save_as_file(self): self._save_2_db() from student_detail.view_details import VIEW_DETAILS view_details = VIEW_DETAILS._save_file(self) def snap(self, image, timer, cam): image_cropped = image[0:480, 80:560] cv2.imwrite( "./assets/temp/temp.jpg", image_cropped, ) timer.stop() cam.release() self.super_layout.setCurrentWidget(self) self.comp.profile_pic.setPixmap( QPixmap.fromImage(QImage("./assets/temp/temp.jpg"))) def school(self): if (self.comp.college_select.currentIndex() == 0 or self.comp.college_select.currentIndex() == 1 or self.comp.college_select.currentIndex() == 4 or self.comp.college_select.currentIndex() == 6 or self.comp.college_select.currentIndex() == 7 or self.comp.college_select.currentIndex() == 9 or self.comp.college_select.currentIndex() == 10): self.comp.level_select.clear() self.comp.level_select.addItems(["100L", "200L", "300L", "400L"]) elif (self.comp.college_select.currentIndex() == 2 or self.comp.college_select.currentIndex() == 3 or self.comp.college_select.currentIndex() == 5 or self.comp.college_select.currentIndex() == 8): self.comp.level_select.clear() self.comp.level_select.addItems( ["100L", "200L", "300L", "400L", "500L"]) elif self.comp.college_select.currentIndex() == 11: self.comp.level_select.clear() self.comp.level_select.addItems( ["100L", "200L", "300L", "400L", "500L", "600L"]) if self.comp.college_select.currentIndex() == 0: self.comp.dept_select.clear() self.comp.dept_select.addItems([ "AGRIBUSINESS MANAGEMENT", "AGRICULTURAL ECONOMICS", "AGRICULTURAL EXTENSION AND RURAL SOCIOLOGY", ]) elif self.comp.college_select.currentIndex() == 1: self.comp.dept_select.clear() self.comp.dept_select.addItems([ "ANIMAL BREEDING AND PHYSIOLOGY", "ANIMAL NUTRITION AND FORAGE SCIENCE", "ANIMAL PRODUCTION AND LIVESTOCK MANAGEMENT", ]) elif self.comp.college_select.currentIndex() == 2: self.comp.dept_select.clear() self.comp.dept_select.addItems([ "FOOD SCIENCE AND TECHNOLOGY", "HOME SCIENCE/HOSPITALITY MANAGEMENT AND TOURISM", "HUMAN NUTRITION AND DIETETICS", ]) elif self.comp.college_select.currentIndex() == 3: self.comp.dept_select.clear() self.comp.dept_select.addItems([ "AGRONOMY", "PLANT HEALTH MANAGEMENT", "SOIL SCIENCE AND METREOLOGY" ]) elif self.comp.college_select.currentIndex() == 4: self.comp.dept_select.clear() self.comp.dept_select.addItems([ "ADULT AND CONTINUING EDUCATION", "EDUCATIONAL FOUNDATION", "INDUSTRIAL TECHNOLOGY EDUCATION", "LIBRARY AND INFORMATION SCIENCE", "PSYCHOLOGY AND COUNSELING", "SCIENCE EDUCATION", ]) elif self.comp.college_select.currentIndex() == 5: self.comp.dept_select.clear() self.comp.dept_select.addItems([ "AGRICULTURAL AND BIO-RESOURCES ENGINEERING", "CHEMICAL ENGINEERING", "CIVIL ENGINEERING", "COMPUTER ENGINEERING", "ELECTRICAL AND ELECTRONICS ENGINEERING", "MECHANICAL ENGINEERING", ]) elif self.comp.college_select.currentIndex() == 6: self.comp.dept_select.clear() self.comp.dept_select.addItems([ "FRENCH LANGUAGE", "GERMAN LANGUAGE", "HISTORY AND PHILOSOPHY OF SCIENCE", "NIGERIA HISTORY", "PEACE AND CONFLICT STUDIES", "PHILOSOPHY AND LOGIC", "PHYSICAL AND HEALTH EDUCATION", "SOCIAL SCIENCE", ]) elif self.comp.college_select.currentIndex() == 7: self.comp.dept_select.clear() self.comp.dept_select.addItems([ "ACCOUNTING", "BANKING AND FINANCE", "BUSINESS ADMINISTRATION", "ECONOMICS", "ENTREPRENEURIAL STUDIES", "HUMAN RESOURCE MANAGEMENT", "MARKETING", ]) elif self.comp.college_select.currentIndex() == 8: self.comp.dept_select.clear() self.comp.dept_select.addItems([ "ENVIRONMENTAL MANAGEMENT AND TOXICOLOGY", "FORESTRY AND ENVIRONMENTAL MANAGEMENT", "FISHERIES AND AQUATIC RESOURCES MANAGEMENT", ]) elif self.comp.college_select.currentIndex() == 9: self.comp.dept_select.clear() self.comp.dept_select.addItems([ "BIOCHEMISTRY", "MICROBIOLOGY", "PLANT SCIENCE AND BIOTECHNOLOGY", "ZOOLOGY AND ENVIRONMENTAL BIOLOGY", ]) elif self.comp.college_select.currentIndex() == 10: self.comp.dept_select.clear() self.comp.dept_select.addItems([ "CHEMISTRY", "PHYSICS", "COMPUTER SCIENCE", "STATISTICS", "MATHEMATICS", ]) elif self.comp.college_select.currentIndex() == 11: self.comp.dept_select.clear() self.comp.dept_select.addItems([ "VERTINARY ANATOMY", "VERTINARY MEDICINE", "VERTINARY PUBLIC HEALTH AND PREVENTIVE MEDICINE", ])
class Window(QMainWindow): """ This class is the main class of the application. It creates the main window of the application. Inherits: QMainWindow """ def __init__(self): """ This method initialize the grid and set the toolbar Params: None Return: None """ super().__init__() self.controller = ConfigController(self) self.initScreen() self.timer = QTimer() self.timer.timeout.connect(self.timerEvent) def initScreen(self): """ This method sets up the screen of the application. It sets the toolbar and the window title. Then the widget is shown. Params: None Return: None """ self.createToolBar() self.setWindowTitle(WINDOW_TITLE) self.statusBar().showMessage("Please, choose your configuration.") self.progressBar = TimerBar() self.statusBar().addPermanentWidget(self.progressBar) self.show() def createToolBar(self): """ Creates a ToolBar with 3 buttons: a file selector, a settings button and a start button. Params: None Return: None """ self.toolbar = QToolBar(self) addFileAction = QAction(QIcon(ADD_FILES_ICON), ADD_FILES_TIP, self) addFileAction.setShortcut('Ctrl+O') addFileAction.triggered.connect(self.fileSelectDialog) resolveAction = QAction(QIcon(START_ICON), START_TIP, self) resolveAction.triggered.connect(self.controller.solve) # resolveAction.setShortcut('Ctrl+K') settingsAction = QAction(QIcon(SETTINGS_ICON), SETTINGS_TIP, self) settingsAction.triggered.connect(self.settings) nextConfigAction = QAction(QIcon(NEXT_CONFIG_ICON), NEXT_CONFIG_TIP, self) nextConfigAction.triggered.connect(self.controller.displayNextConfig) predConfigAction = QAction(QIcon(PRED_CONFIG_ICON), PRED_CONFIG_TIP, self) predConfigAction.triggered.connect(self.controller.displayPredConfig) self.addToolBar(self.toolbar) self.toolbar.addAction(addFileAction) self.toolbar.addAction(resolveAction) self.toolbar.addAction(settingsAction) self.toolbar.addAction(predConfigAction) self.toolbar.addAction(nextConfigAction) def settings(self): """ Opens a settings dialog. Params: none Return: none """ settingsDialog = SettingsDialog(self) settingsDialog.exec_() def startTimer(self): """ Demarre le timer de résolution et affiche sa progression dans la timer bar """ self.startTime = time.time() self.timer.start(1000) def stopTimer(self): """ Arrete le timer de résolution et demande au controller d'arreter le thread de résolution """ self.timer.stop() self.controller.endSolving() def timerEvent(self): """ Met a jour la valeur de la progress bar lors de la reception d'un signal du timer """ self.progressBar.setValue(time.time() - self.startTime) def fileSelectDialog(self): """ Opens a file selection dialog and display on the grid the selected file. Params: none Return: none """ file_dialog = QFileDialog() file_dialog.setFileMode(QFileDialog.ExistingFiles) if file_dialog.exec_(): print(file_dialog.selectedFiles()) self.controller.setConfiguration(file_dialog.selectedFiles()[0]) self.statusBar().showMessage("Ready")
class SvnProjectHelper(VcsProjectHelper): """ Class implementing the VCS project helper for Subversion. """ def __init__(self, vcsObject, projectObject, parent=None, name=None): """ Constructor @param vcsObject reference to the vcs object @param projectObject reference to the project object @param parent parent widget (QWidget) @param name name of this object (string) """ VcsProjectHelper.__init__(self, vcsObject, projectObject, parent, name) def getActions(self): """ Public method to get a list of all actions. @return list of all actions (list of E5Action) """ return self.actions[:] def initActions(self): """ Public method to generate the action objects. """ self.vcsNewAct = E5Action(self.tr('New from repository'), UI.PixmapCache.getIcon("vcsCheckout.png"), self.tr('&New from repository...'), 0, 0, self, 'subversion_new') self.vcsNewAct.setStatusTip( self.tr('Create a new project from the VCS repository')) self.vcsNewAct.setWhatsThis( self.tr("""<b>New from repository</b>""" """<p>This creates a new local project from the VCS""" """ repository.</p>""")) self.vcsNewAct.triggered.connect(self._vcsCheckout) self.actions.append(self.vcsNewAct) self.vcsUpdateAct = E5Action(self.tr('Update from repository'), UI.PixmapCache.getIcon("vcsUpdate.png"), self.tr('&Update from repository'), 0, 0, self, 'subversion_update') self.vcsUpdateAct.setStatusTip( self.tr('Update the local project from the VCS repository')) self.vcsUpdateAct.setWhatsThis( self.tr("""<b>Update from repository</b>""" """<p>This updates the local project from the VCS""" """ repository.</p>""")) self.vcsUpdateAct.triggered.connect(self._vcsUpdate) self.actions.append(self.vcsUpdateAct) self.vcsCommitAct = E5Action( self.tr('Commit changes to repository'), UI.PixmapCache.getIcon("vcsCommit.png"), self.tr('&Commit changes to repository...'), 0, 0, self, 'subversion_commit') self.vcsCommitAct.setStatusTip( self.tr( 'Commit changes to the local project to the VCS repository')) self.vcsCommitAct.setWhatsThis( self.tr( """<b>Commit changes to repository</b>""" """<p>This commits changes to the local project to the VCS""" """ repository.</p>""")) self.vcsCommitAct.triggered.connect(self._vcsCommit) self.actions.append(self.vcsCommitAct) self.svnLogBrowserAct = E5Action(self.tr('Show log browser'), UI.PixmapCache.getIcon("vcsLog.png"), self.tr('Show log browser'), 0, 0, self, 'subversion_log_browser') self.svnLogBrowserAct.setStatusTip( self.tr('Show a dialog to browse the log of the local project')) self.svnLogBrowserAct.setWhatsThis( self. tr("""<b>Show log browser</b>""" """<p>This shows a dialog to browse the log of the local""" """ project. A limited number of entries is shown first. More""" """ can be retrieved later on.</p>""")) self.svnLogBrowserAct.triggered.connect(self._vcsLogBrowser) self.actions.append(self.svnLogBrowserAct) self.vcsDiffAct = E5Action(self.tr('Show differences'), UI.PixmapCache.getIcon("vcsDiff.png"), self.tr('Show &difference'), 0, 0, self, 'subversion_diff') self.vcsDiffAct.setStatusTip( self.tr( 'Show the difference of the local project to the repository')) self.vcsDiffAct.setWhatsThis( self.tr("""<b>Show differences</b>""" """<p>This shows differences of the local project to the""" """ repository.</p>""")) self.vcsDiffAct.triggered.connect(self._vcsDiff) self.actions.append(self.vcsDiffAct) self.svnExtDiffAct = E5Action(self.tr('Show differences (extended)'), UI.PixmapCache.getIcon("vcsDiff.png"), self.tr('Show differences (extended)'), 0, 0, self, 'subversion_extendeddiff') self.svnExtDiffAct.setStatusTip( self. tr('Show the difference of revisions of the project to the repository' )) self.svnExtDiffAct.setWhatsThis( self.tr("""<b>Show differences (extended)</b>""" """<p>This shows differences of selectable revisions of""" """ the project.</p>""")) self.svnExtDiffAct.triggered.connect(self.__svnExtendedDiff) self.actions.append(self.svnExtDiffAct) self.svnUrlDiffAct = E5Action(self.tr('Show differences (URLs)'), UI.PixmapCache.getIcon("vcsDiff.png"), self.tr('Show differences (URLs)'), 0, 0, self, 'subversion_urldiff') self.svnUrlDiffAct.setStatusTip( self. tr('Show the difference of the project between two repository URLs' )) self.svnUrlDiffAct.setWhatsThis( self.tr("""<b>Show differences (URLs)</b>""" """<p>This shows differences of the project between""" """ two repository URLs.</p>""")) self.svnUrlDiffAct.triggered.connect(self.__svnUrlDiff) self.actions.append(self.svnUrlDiffAct) self.vcsStatusAct = E5Action(self.tr('Show status'), UI.PixmapCache.getIcon("vcsStatus.png"), self.tr('Show &status'), 0, 0, self, 'subversion_status') self.vcsStatusAct.setStatusTip( self.tr('Show the status of the local project')) self.vcsStatusAct.setWhatsThis( self.tr("""<b>Show status</b>""" """<p>This shows the status of the local project.</p>""")) self.vcsStatusAct.triggered.connect(self._vcsStatus) self.actions.append(self.vcsStatusAct) self.svnChangeListsAct = E5Action( self.tr('Show change lists'), UI.PixmapCache.getIcon("vcsChangeLists.png"), self.tr('Show change lists'), 0, 0, self, 'subversion_changelists') self.svnChangeListsAct.setStatusTip( self. tr('Show the change lists and associated files of the local project' )) self.svnChangeListsAct.setWhatsThis( self. tr("""<b>Show change lists</b>""" """<p>This shows the change lists and associated files of the""" """ local project.</p>""")) self.svnChangeListsAct.triggered.connect(self.__svnChangeLists) self.actions.append(self.svnChangeListsAct) self.vcsTagAct = E5Action(self.tr('Tag in repository'), UI.PixmapCache.getIcon("vcsTag.png"), self.tr('&Tag in repository...'), 0, 0, self, 'subversion_tag') self.vcsTagAct.setStatusTip( self.tr('Tag the local project in the repository')) self.vcsTagAct.setWhatsThis( self.tr( """<b>Tag in repository</b>""" """<p>This tags the local project in the repository.</p>""")) self.vcsTagAct.triggered.connect(self._vcsTag) self.actions.append(self.vcsTagAct) self.vcsExportAct = E5Action(self.tr('Export from repository'), UI.PixmapCache.getIcon("vcsExport.png"), self.tr('&Export from repository...'), 0, 0, self, 'subversion_export') self.vcsExportAct.setStatusTip( self.tr('Export a project from the repository')) self.vcsExportAct.setWhatsThis( self.tr("""<b>Export from repository</b>""" """<p>This exports a project from the repository.</p>""")) self.vcsExportAct.triggered.connect(self._vcsExport) self.actions.append(self.vcsExportAct) self.vcsPropsAct = E5Action(self.tr('Command options'), self.tr('Command &options...'), 0, 0, self, 'subversion_options') self.vcsPropsAct.setStatusTip(self.tr('Show the VCS command options')) self.vcsPropsAct.setWhatsThis( self. tr("""<b>Command options...</b>""" """<p>This shows a dialog to edit the VCS command options.</p>""" )) self.vcsPropsAct.triggered.connect(self._vcsCommandOptions) self.actions.append(self.vcsPropsAct) self.vcsRevertAct = E5Action(self.tr('Revert changes'), UI.PixmapCache.getIcon("vcsRevert.png"), self.tr('Re&vert changes'), 0, 0, self, 'subversion_revert') self.vcsRevertAct.setStatusTip( self.tr('Revert all changes made to the local project')) self.vcsRevertAct.setWhatsThis( self. tr("""<b>Revert changes</b>""" """<p>This reverts all changes made to the local project.</p>""" )) self.vcsRevertAct.triggered.connect(self._vcsRevert) self.actions.append(self.vcsRevertAct) self.vcsMergeAct = E5Action(self.tr('Merge'), UI.PixmapCache.getIcon("vcsMerge.png"), self.tr('Mer&ge changes...'), 0, 0, self, 'subversion_merge') self.vcsMergeAct.setStatusTip( self.tr('Merge changes of a tag/revision into the local project')) self.vcsMergeAct.setWhatsThis( self.tr( """<b>Merge</b>""" """<p>This merges changes of a tag/revision into the local""" """ project.</p>""")) self.vcsMergeAct.triggered.connect(self._vcsMerge) self.actions.append(self.vcsMergeAct) self.vcsSwitchAct = E5Action(self.tr('Switch'), UI.PixmapCache.getIcon("vcsSwitch.png"), self.tr('S&witch...'), 0, 0, self, 'subversion_switch') self.vcsSwitchAct.setStatusTip( self.tr('Switch the local copy to another tag/branch')) self.vcsSwitchAct.setWhatsThis( self. tr("""<b>Switch</b>""" """<p>This switches the local copy to another tag/branch.</p>""" )) self.vcsSwitchAct.triggered.connect(self._vcsSwitch) self.actions.append(self.vcsSwitchAct) self.vcsResolveAct = E5Action(self.tr('Conflicts resolved'), self.tr('Con&flicts resolved'), 0, 0, self, 'subversion_resolve') self.vcsResolveAct.setStatusTip( self.tr('Mark all conflicts of the local project as resolved')) self.vcsResolveAct.setWhatsThis( self.tr("""<b>Conflicts resolved</b>""" """<p>This marks all conflicts of the local project as""" """ resolved.</p>""")) self.vcsResolveAct.triggered.connect(self.__svnResolve) self.actions.append(self.vcsResolveAct) self.vcsCleanupAct = E5Action(self.tr('Cleanup'), self.tr('Cleanu&p'), 0, 0, self, 'subversion_cleanup') self.vcsCleanupAct.setStatusTip(self.tr('Cleanup the local project')) self.vcsCleanupAct.setWhatsThis( self.tr( """<b>Cleanup</b>""" """<p>This performs a cleanup of the local project.</p>""")) self.vcsCleanupAct.triggered.connect(self._vcsCleanup) self.actions.append(self.vcsCleanupAct) self.vcsCommandAct = E5Action(self.tr('Execute command'), self.tr('E&xecute command...'), 0, 0, self, 'subversion_command') self.vcsCommandAct.setStatusTip( self.tr('Execute an arbitrary VCS command')) self.vcsCommandAct.setWhatsThis( self. tr("""<b>Execute command</b>""" """<p>This opens a dialog to enter an arbitrary VCS command.</p>""" )) self.vcsCommandAct.triggered.connect(self._vcsCommand) self.actions.append(self.vcsCommandAct) self.svnTagListAct = E5Action(self.tr('List tags'), self.tr('List tags...'), 0, 0, self, 'subversion_list_tags') self.svnTagListAct.setStatusTip(self.tr('List tags of the project')) self.svnTagListAct.setWhatsThis( self.tr("""<b>List tags</b>""" """<p>This lists the tags of the project.</p>""")) self.svnTagListAct.triggered.connect(self.__svnTagList) self.actions.append(self.svnTagListAct) self.svnBranchListAct = E5Action(self.tr('List branches'), self.tr('List branches...'), 0, 0, self, 'subversion_list_branches') self.svnBranchListAct.setStatusTip( self.tr('List branches of the project')) self.svnBranchListAct.setWhatsThis( self.tr("""<b>List branches</b>""" """<p>This lists the branches of the project.</p>""")) self.svnBranchListAct.triggered.connect(self.__svnBranchList) self.actions.append(self.svnBranchListAct) self.svnListAct = E5Action(self.tr('List repository contents'), self.tr('List repository contents...'), 0, 0, self, 'subversion_contents') self.svnListAct.setStatusTip( self.tr('Lists the contents of the repository')) self.svnListAct.setWhatsThis( self.tr("""<b>List repository contents</b>""" """<p>This lists the contents of the repository.</p>""")) self.svnListAct.triggered.connect(self.__svnTagList) self.actions.append(self.svnListAct) self.svnPropSetAct = E5Action(self.tr('Set Property'), self.tr('Set Property...'), 0, 0, self, 'subversion_property_set') self.svnPropSetAct.setStatusTip( self.tr('Set a property for the project files')) self.svnPropSetAct.setWhatsThis( self.tr("""<b>Set Property</b>""" """<p>This sets a property for the project files.</p>""")) self.svnPropSetAct.triggered.connect(self.__svnPropSet) self.actions.append(self.svnPropSetAct) self.svnPropListAct = E5Action(self.tr('List Properties'), self.tr('List Properties...'), 0, 0, self, 'subversion_property_list') self.svnPropListAct.setStatusTip( self.tr('List properties of the project files')) self.svnPropListAct.setWhatsThis( self.tr( """<b>List Properties</b>""" """<p>This lists the properties of the project files.</p>""")) self.svnPropListAct.triggered.connect(self.__svnPropList) self.actions.append(self.svnPropListAct) self.svnPropDelAct = E5Action(self.tr('Delete Property'), self.tr('Delete Property...'), 0, 0, self, 'subversion_property_delete') self.svnPropDelAct.setStatusTip( self.tr('Delete a property for the project files')) self.svnPropDelAct.setWhatsThis( self.tr( """<b>Delete Property</b>""" """<p>This deletes a property for the project files.</p>""")) self.svnPropDelAct.triggered.connect(self.__svnPropDel) self.actions.append(self.svnPropDelAct) self.svnRelocateAct = E5Action(self.tr('Relocate'), UI.PixmapCache.getIcon("vcsSwitch.png"), self.tr('Relocate...'), 0, 0, self, 'subversion_relocate') self.svnRelocateAct.setStatusTip( self.tr('Relocate the working copy to a new repository URL')) self.svnRelocateAct.setWhatsThis( self.tr( """<b>Relocate</b>""" """<p>This relocates the working copy to a new repository""" """ URL.</p>""")) self.svnRelocateAct.triggered.connect(self.__svnRelocate) self.actions.append(self.svnRelocateAct) self.svnRepoBrowserAct = E5Action( self.tr('Repository Browser'), UI.PixmapCache.getIcon("vcsRepoBrowser.png"), self.tr('Repository Browser...'), 0, 0, self, 'subversion_repo_browser') self.svnRepoBrowserAct.setStatusTip( self.tr('Show the Repository Browser dialog')) self.svnRepoBrowserAct.setWhatsThis( self.tr("""<b>Repository Browser</b>""" """<p>This shows the Repository Browser dialog.</p>""")) self.svnRepoBrowserAct.triggered.connect(self.__svnRepoBrowser) self.actions.append(self.svnRepoBrowserAct) self.svnConfigAct = E5Action(self.tr('Configure'), self.tr('Configure...'), 0, 0, self, 'subversion_configure') self.svnConfigAct.setStatusTip( self. tr('Show the configuration dialog with the Subversion page selected' )) self.svnConfigAct.setWhatsThis( self.tr( """<b>Configure</b>""" """<p>Show the configuration dialog with the Subversion page""" """ selected.</p>""")) self.svnConfigAct.triggered.connect(self.__svnConfigure) self.actions.append(self.svnConfigAct) self.svnUpgradeAct = E5Action(self.tr('Upgrade'), self.tr('Upgrade...'), 0, 0, self, 'subversion_upgrade') self.svnUpgradeAct.setStatusTip( self.tr('Upgrade the working copy to the current format')) self.svnUpgradeAct.setWhatsThis( self.tr( """<b>Upgrade</b>""" """<p>Upgrades the working copy to the current format.</p>""")) self.svnUpgradeAct.triggered.connect(self.__svnUpgrade) self.actions.append(self.svnUpgradeAct) def initMenu(self, menu): """ Public method to generate the VCS menu. @param menu reference to the menu to be populated (QMenu) """ menu.clear() act = menu.addAction( UI.PixmapCache.getIcon( os.path.join("VcsPlugins", "vcsSubversion", "icons", "subversion.png")), self.vcs.vcsName(), self._vcsInfoDisplay) font = act.font() font.setBold(True) act.setFont(font) menu.addSeparator() menu.addAction(self.vcsUpdateAct) menu.addAction(self.vcsCommitAct) menu.addSeparator() menu.addAction(self.vcsTagAct) if self.vcs.otherData["standardLayout"]: menu.addAction(self.svnTagListAct) menu.addAction(self.svnBranchListAct) else: menu.addAction(self.svnListAct) menu.addSeparator() menu.addAction(self.svnLogBrowserAct) menu.addSeparator() menu.addAction(self.vcsStatusAct) menu.addAction(self.svnChangeListsAct) menu.addSeparator() menu.addAction(self.vcsDiffAct) menu.addAction(self.svnExtDiffAct) menu.addAction(self.svnUrlDiffAct) menu.addSeparator() menu.addAction(self.vcsRevertAct) menu.addAction(self.vcsMergeAct) menu.addAction(self.vcsResolveAct) menu.addSeparator() menu.addAction(self.svnRelocateAct) menu.addAction(self.vcsSwitchAct) menu.addSeparator() menu.addAction(self.svnPropSetAct) menu.addAction(self.svnPropListAct) menu.addAction(self.svnPropDelAct) menu.addSeparator() menu.addAction(self.vcsCleanupAct) menu.addSeparator() menu.addAction(self.vcsCommandAct) menu.addAction(self.svnRepoBrowserAct) menu.addAction(self.svnUpgradeAct) menu.addSeparator() menu.addAction(self.vcsPropsAct) menu.addSeparator() menu.addAction(self.svnConfigAct) menu.addSeparator() menu.addAction(self.vcsNewAct) menu.addAction(self.vcsExportAct) def initToolbar(self, ui, toolbarManager): """ Public slot to initialize the VCS toolbar. @param ui reference to the main window (UserInterface) @param toolbarManager reference to a toolbar manager object (E5ToolBarManager) """ self.__toolbar = QToolBar(self.tr("Subversion (svn)"), ui) self.__toolbar.setIconSize(UI.Config.ToolBarIconSize) self.__toolbar.setObjectName("SubversionToolbar") self.__toolbar.setToolTip(self.tr('Subversion (svn)')) self.__toolbar.addAction(self.svnLogBrowserAct) self.__toolbar.addAction(self.vcsStatusAct) self.__toolbar.addSeparator() self.__toolbar.addAction(self.vcsDiffAct) self.__toolbar.addSeparator() self.__toolbar.addAction(self.svnRepoBrowserAct) self.__toolbar.addAction(self.vcsNewAct) self.__toolbar.addAction(self.vcsExportAct) self.__toolbar.addSeparator() title = self.__toolbar.windowTitle() toolbarManager.addToolBar(self.__toolbar, title) toolbarManager.addAction(self.vcsUpdateAct, title) toolbarManager.addAction(self.vcsCommitAct, title) toolbarManager.addAction(self.svnExtDiffAct, title) toolbarManager.addAction(self.svnUrlDiffAct, title) toolbarManager.addAction(self.svnChangeListsAct, title) toolbarManager.addAction(self.vcsTagAct, title) toolbarManager.addAction(self.vcsRevertAct, title) toolbarManager.addAction(self.vcsMergeAct, title) toolbarManager.addAction(self.vcsSwitchAct, title) toolbarManager.addAction(self.svnRelocateAct, title) self.__toolbar.setEnabled(False) self.__toolbar.setVisible(False) ui.registerToolbar("subversion", self.__toolbar.windowTitle(), self.__toolbar) ui.addToolBar(self.__toolbar) def removeToolbar(self, ui, toolbarManager): """ Public method to remove a toolbar created by initToolbar(). @param ui reference to the main window (UserInterface) @param toolbarManager reference to a toolbar manager object (E5ToolBarManager) """ ui.removeToolBar(self.__toolbar) ui.unregisterToolbar("subversion") title = self.__toolbar.windowTitle() toolbarManager.removeCategoryActions(title) toolbarManager.removeToolBar(self.__toolbar) self.__toolbar.deleteLater() self.__toolbar = None def __svnResolve(self): """ Private slot used to resolve conflicts of the local project. """ self.vcs.svnResolve(self.project.ppath) def __svnPropList(self): """ Private slot used to list the properties of the project files. """ self.vcs.svnListProps(self.project.ppath, True) def __svnPropSet(self): """ Private slot used to set a property for the project files. """ self.vcs.svnSetProp(self.project.ppath, True) def __svnPropDel(self): """ Private slot used to delete a property for the project files. """ self.vcs.svnDelProp(self.project.ppath, True) def __svnTagList(self): """ Private slot used to list the tags of the project. """ self.vcs.svnListTagBranch(self.project.ppath, True) def __svnBranchList(self): """ Private slot used to list the branches of the project. """ self.vcs.svnListTagBranch(self.project.ppath, False) def __svnExtendedDiff(self): """ Private slot used to perform a svn diff with the selection of revisions. """ self.vcs.svnExtendedDiff(self.project.ppath) def __svnUrlDiff(self): """ Private slot used to perform a svn diff with the selection of repository URLs. """ self.vcs.svnUrlDiff(self.project.ppath) def __svnRelocate(self): """ Private slot used to relocate the working copy to a new repository URL. """ self.vcs.svnRelocate(self.project.ppath) def __svnRepoBrowser(self): """ Private slot to open the repository browser. """ self.vcs.svnRepoBrowser(projectPath=self.project.ppath) def __svnConfigure(self): """ Private slot to open the configuration dialog. """ e5App().getObject("UserInterface").showPreferences( "zzz_subversionPage") def __svnChangeLists(self): """ Private slot used to show a list of change lists. """ self.vcs.svnShowChangelists(self.project.ppath) def __svnUpgrade(self): """ Private slot used to upgrade the working copy format. """ self.vcs.svnUpgrade(self.project.ppath)
class MainWindow(QtWidgets.QMainWindow): MaxRecentFiles = 5 def __init__(self, app_title="CSV Viewer"): super().__init__() self.progress = QProgressBar() self.threadpool = QThreadPool() self.app_title = app_title self.setMinimumSize(600, 300) self.df = None self.round_num = 2 self.recentFileActs = [] # settings self.settings = QtCore.QSettings('CSV_Viewer', 'CSV_Viewer') self.round_num = self.settings.value('round_numbers', self.round_num, int) # toolbar self.toolbar = QToolBar("MainToolbar") self.toolbar.setIconSize(QSize(16, 16)) self.toolbar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) self.addToolBar(self.toolbar) # open action style = self.toolbar.style() icon = style.standardIcon(QStyle.SP_FileDialogStart) self.button_open = QAction(icon, "Open", self) self.button_open.setShortcut('Ctrl+O') self.button_open.setStatusTip("Open CSV file...") self.button_open.triggered.connect(self.onToolbarOpenButtonClick) self.toolbar.addAction(self.button_open) self.button_open.setEnabled(True) # summary action style_summary = self.toolbar.style() icon = style_summary.standardIcon(QStyle.SP_FileDialogListView) self.button_summary = QAction(icon, "Summary", self) self.button_summary.setShortcut('Ctrl+S') self.button_summary.setStatusTip("Show summary for the current file") self.button_summary.triggered.connect(self.onToolbarSummaryButtonClick) self.toolbar.addAction(self.button_summary) # info action style_info = self.toolbar.style() icon = style_info.standardIcon(QStyle.SP_FileIcon) self.button_info = QAction(icon, "Info", self) self.button_info.setShortcut('Ctrl+I') self.button_info.setStatusTip("Show summary for the current file") self.button_info.triggered.connect(self.onToolbarInfoButtonClick) self.toolbar.addAction(self.button_info) # resize action style_resize = self.toolbar.style() icon = style_resize.standardIcon(QStyle.SP_BrowserReload) self.button_resize = QAction(icon, "Resize columns", self) self.button_resize.setShortcut('Ctrl+R') self.button_resize.setStatusTip("Resize columns width to content") self.button_resize.triggered.connect(self.onResizeColumns) self.toolbar.addAction(self.button_resize) # export to xlsx action style_xlsx = self.toolbar.style() icon = style_xlsx.standardIcon(QStyle.SP_FileLinkIcon) self.button_xlsx = QAction(icon, "Xlsx", self) self.button_xlsx.setStatusTip("Export data to xlsx file") self.button_xlsx.triggered.connect(self.onExportXlsx) self.toolbar.addAction(self.button_xlsx) # export to sqlite action style_sqlite = self.toolbar.style() icon = style_sqlite.standardIcon(QStyle.SP_FileLinkIcon) self.button_sqlite = QAction(icon, "SQLite", self) self.button_sqlite.setStatusTip("Export data to SQLite database") self.button_sqlite.triggered.connect(self.onExportSQLite) self.toolbar.addAction(self.button_sqlite) # export to html action style_html = self.toolbar.style() icon = style_html.standardIcon(QStyle.SP_FileLinkIcon) self.button_html = QAction(icon, "HTML", self) self.button_html.setStatusTip("Export data to HTML file") self.button_html.triggered.connect(self.onExportHTML) self.toolbar.addAction(self.button_html) # export to CSV action style_csv = self.toolbar.style() icon = style_csv.standardIcon(QStyle.SP_FileLinkIcon) self.button_csv = QAction(icon, "CSV", self) self.button_csv.setStatusTip("Export data to CSV file") self.button_csv.triggered.connect(self.onExportCSV) self.toolbar.addAction(self.button_csv) # export to Markdown action style_mark = self.toolbar.style() icon = style_mark.standardIcon(QStyle.SP_FileLinkIcon) self.button_mark = QAction(icon, "Markdown", self) self.button_mark.setStatusTip("Export data to Markdown file") self.button_mark.triggered.connect(self.onExportMarkdown) self.toolbar.addAction(self.button_mark) # import data from world bank climate api style_api = self.toolbar.style() icon = style_api.standardIcon(QStyle.SP_DialogSaveButton) self.button_api = QAction(icon, "API", self) self.button_api.setStatusTip("Import data from World Bank Climate API") self.button_api.triggered.connect(self.onImportFromAPI) self.toolbar.addAction(self.button_api) self.button_api.setEnabled(True) # close action style_close = self.toolbar.style() icon = style_close.standardIcon(QStyle.SP_DialogCloseButton) self.button_close = QAction(icon, "Close", self) self.button_close.setShortcut('Ctrl+X') self.button_close.setStatusTip("Close CSV file...") self.button_close.triggered.connect(self.onToolbarCloseButtonClick) self.toolbar.addAction(self.button_close) # quit action self.button_quit = QAction("Quit", self) self.button_quit.setShortcut('Ctrl+Q') self.button_quit.setStatusTip("Quit application") self.button_quit.triggered.connect(self.close) # toolbar show/hide action self.button_tool = QAction("Show/Hide toolbar", self) self.button_tool.setShortcut('Ctrl+T') self.button_tool.setStatusTip("Show or hide toolbar") self.button_tool.triggered.connect(self.showToolbar) # remove NaN self.button_nan = QAction("Remove NaN", self) self.button_nan.setShortcut('Ctrl+R') self.button_nan.setStatusTip("Remove rows with missing values") self.button_nan.triggered.connect(self.onRemoveNaN) # settings action style_settings = self.toolbar.style() icon = style_settings.standardIcon(QStyle.SP_ComputerIcon) self.button_settings = QAction(icon, "Settings", self) self.button_settings.setStatusTip("Application settings") self.button_settings.triggered.connect(self.onSettings) self.toolbar.addAction(self.button_settings) self.button_settings.setEnabled(True) # about action style_about = self.toolbar.style() icon = style_about.standardIcon(QStyle.SP_FileDialogInfoView) self.button_about = QAction(icon, "About", self) self.button_about.setStatusTip("About application") self.button_about.triggered.connect(self.about) self.toolbar.addAction(self.button_about) self.button_about.setEnabled(True) self.setButtons(False) # recent menu action for i in range(MainWindow.MaxRecentFiles): self.recentFileActs.append( QAction(self, visible=False, triggered=self.openRecentFile) ) # menu bar menu = self.menuBar() file_menu = menu.addMenu("&File") file_menu.addAction(self.button_open) file_menu.addAction(self.button_close) file_menu.addSeparator() file_menu.addAction(self.button_nan) file_menu.addSeparator() file_menu.addAction(self.button_settings) self.separatorAct = file_menu.addSeparator() for i in range(MainWindow.MaxRecentFiles): file_menu.addAction(self.recentFileActs[i]) file_menu.addSeparator() file_menu.addAction(self.button_quit) view_menu = menu.addMenu("Vie&w") view_menu.addAction(self.button_summary) view_menu.addAction(self.button_info) view_menu.addSeparator() view_menu.addAction(self.button_resize) view_menu.addSeparator() view_menu.addAction(self.button_tool) export_menu = menu.addMenu("&Export") export_menu.addAction(self.button_xlsx) export_menu.addAction(self.button_sqlite) export_menu.addAction(self.button_html) export_menu.addAction(self.button_csv) export_menu.addAction(self.button_mark) import_menu = menu.addMenu("&Import") import_menu.addAction(self.button_api) help_menu = menu.addMenu("&Help") help_menu.addAction(self.button_about) self.updateRecentFileActions() # status bar self.my_status = QStatusBar(self) self.my_status.addPermanentWidget(self.progress) self.progress.hide() self.labelStatus = QLabel("Rows: 0 Cols: 0") self.my_status.addPermanentWidget(self.labelStatus) self.setStatusBar(self.my_status) # set TableView self.table = QtWidgets.QTableView() self.table.setSelectionBehavior(QtWidgets.QTableView.SelectRows) self.table.setSelectionMode(QtWidgets.QTableView.SingleSelection) self.setCentralWidget(self.table) self.setWindowTitle(self.app_title) self.setMinimumSize(400, 250) self.setGeometry(200, 100, 1000, 600) def onToolbarOpenButtonClick(self) -> None: """ Show open dialog """ dlg = ParameterDialog() dlg.setWindowTitle("Open") if dlg.exec_(): file_name = dlg.filename.text() separator = dlg.separator decimal = dlg.decimal header = dlg.header index = dlg.index else: file_name = None if file_name: self.saveRecent(file_name) self.open_csv_file(file_name, separator, decimal, header, index) def onOpenRecentFile(self, file_name: str, sep=',', decimal='.') -> None: """ Open file from recent list, show open dialog """ dlg = ParameterDialog(file_name, sep, decimal) dlg.setWindowTitle("Open") if dlg.exec_(): file_name = dlg.filename.text() separator = dlg.separator decimal = dlg.decimal header = dlg.header index = dlg.index else: file_name = None if file_name: self.saveRecent(file_name) self.open_csv_file(file_name, separator, decimal, header, index) def open_csv_file(self, file_name: str, sep=',', decimal=".", header=True, index=True) -> None: """ Open csv file, load to tableview, set statusbar, enable close icon""" try: if header: my_header = 'infer' else: my_header = None if index: my_index = 0 else: my_index = False print(my_header, my_index) data = pd.read_csv(file_name, sep=sep, decimal=decimal, header=my_header, index_col=my_index) self.df = data self.model = TableModel(self.df, self.round_num) self.labelStatus.setText(f"Rows: {self.df.shape[0]} Cols: {self.df.shape[1]}") self.table.setModel(self.model) if data.shape[0] > 0: self.table.selectRow(0) self.setButtons(True) self.setWindowTitle(self.app_title + ": " + file_name) except Exception as e: QMessageBox.warning(self, 'Error', f"Error loading the file:\n {file_name}") def setButtons(self, state: bool) -> None: """ Set state of buttons/actions """ self.button_close.setEnabled(state) self.button_summary.setEnabled(state) self.button_info.setEnabled(state) self.button_resize.setEnabled(state) self.button_xlsx.setEnabled(state) self.button_sqlite.setEnabled(state) self.button_html.setEnabled(state) self.button_csv.setEnabled(state) self.button_nan.setEnabled(state) self.button_mark.setEnabled(state) def onResizeColumns(self) -> None: """Resize columns action, run from menu View->Resize columns""" self.table.resizeColumnsToContents() def onToolbarCloseButtonClick(self) -> None: """Clear tableview, set statusbar and disable toolbar close, summary and info icons""" self.table.setModel(None) self.df = None self.setButtons(False) self.setWindowTitle(self.app_title) self.labelStatus.setText("Rows: 0 Cols: 0") def onToolbarSummaryButtonClick(self) -> None: """Show Summary dialog""" dlg = SummaryDialog(self.df.describe()) dlg.setWindowTitle("Summary") dlg.exec_() def onToolbarInfoButtonClick(self) -> None: """Show Info dialog""" # buf = io.StringIO() # self.df.info(buf=buf) # tmp = buf.getvalue() dlg = InfoDialog(self.df) dlg.setWindowTitle("Info") dlg.exec_() def onExportXlsx(self) -> None: """ Export data to xlsx file """ file_name, _ = QFileDialog.getSaveFileName(self, 'Export to xlsx', '', ".xlsx(*.xlsx)") if file_name: self.df.to_excel(file_name, engine='xlsxwriter') def onExportSQLite(self) -> None: file_name, _ = QFileDialog.getSaveFileName(self, 'Export to sqlite db', '', ".sqlite(*.sqlite)") if file_name: engine = create_engine(f'sqlite:///{file_name}', echo=False) self.df.to_sql('csv_data', con=engine) def onExportHTML(self) -> None: """ Export data to HTML file """ file_name, _ = QFileDialog.getSaveFileName(self, 'Export to HTML file', '', ".html(*.html)") if file_name: self.df.to_html(file_name) def onExportCSV(self) -> None: """ Export data to new CSV file """ file_name, _ = QFileDialog.getSaveFileName(self, 'Export to CSV file', '', ".csv(*.csv)") if file_name: self.df.to_csv(file_name, sep=',', decimal='.') def onImportFromAPI(self) -> None: dlg = ApiDialog() dlg.setWindowTitle("Import a Data CSV via API") if dlg.exec_(): file_name = dlg.filename.text() address = dlg.address.text() else: file_name = None if file_name and address: res, text = dataload.import_data_by_api(address) if res: with open(file_name, "w") as f: f.write(text) self.onOpenRecentFile(file_name) else: QMessageBox.warning(self, "Error", text) def closeEvent(self, event) -> None: """ Quit application, ask user before """ if not app_test: result = QMessageBox.question( self, self.app_title, "Are you sure you want to quit?", QMessageBox.Yes | QMessageBox.No, ) if app_test or result == QMessageBox.Yes: event.accept() else: event.ignore() def about(self) -> None: """ Show About dialog (info about application)""" dlg = AboutDialog() dlg.exec_() def openRecentFile(self) -> None: """ Open file from recent list action """ action = self.sender() if action: self.onOpenRecentFile(action.data()) def saveRecent(self, file_name) -> None: """ Save information about currently opened file, update recent list""" settings = QSettings('CSV_Viewer', 'CSV_Viewer') files = settings.value('recentFileList', []) try: files.remove(file_name) except ValueError: pass files.insert(0, file_name) del files[MainWindow.MaxRecentFiles:] settings.setValue('recentFileList', files) for widget in QtWidgets.QApplication.topLevelWidgets(): if isinstance(widget, MainWindow): widget.updateRecentFileActions() def updateRecentFileActions(self) -> None: """ Update recent file list """ settings = QSettings('CSV_Viewer', 'CSV_Viewer') files = settings.value('recentFileList', []) numRecentFiles = min(len(files), MainWindow.MaxRecentFiles) for i in range(numRecentFiles): text = "&%d %s" % (i + 1, self.strippedName(files[i])) self.recentFileActs[i].setText(text) self.recentFileActs[i].setData(files[i]) self.recentFileActs[i].setVisible(True) for j in range(numRecentFiles, MainWindow.MaxRecentFiles): self.recentFileActs[j].setVisible(False) self.separatorAct.setVisible((numRecentFiles > 0)) def strippedName(self, fullFileName: str) -> str: """ Return only file name, without path""" return QFileInfo(fullFileName).fileName() def showToolbar(self): """ show / hide main toolbar""" if self.toolbar.isHidden(): self.toolbar.show() else: self.toolbar.hide() def onSettings(self): """ Round numbers to """ n, result = QInputDialog.getInt(self, "Settings", "Round numbers to:", self.round_num, 0, 10, 1) if result and n != self.round_num: self.round_num = n self.settings.setValue('round_numbers', self.round_num) if self.df.shape[0] > 0: index = self.table.currentIndex() self.model = TableModel(self.df, self.round_num) self.table.setModel(self.model) self.table.selectRow(index.row()) def onRemoveNaN(self): """ Remove rows with missing values """ if self.df.shape[0] > 0: button = QMessageBox.question(self, "Remove NaN", "Remove rows with missing values?") if button == QMessageBox.Yes: self.df.dropna(axis=0, how='any', inplace=True) self.model = TableModel(self.df, self.round_num) self.table.setModel(self.model) self.table.selectRow(0) self.labelStatus.setText(f"Rows: {self.df.shape[0]} Cols: {self.df.shape[1]}") def onExportMarkdown(self): """ export to markdown table in thread """ file_name, _ = QFileDialog.getSaveFileName(self, 'Export to Markdown file', '', ".md(*.md)") if file_name: worker = MarkdownWorker(file_name, self.df) worker.signals.progress.connect(self.update_progress) worker.signals.status.connect(self.update_status) self.threadpool.start(worker) def update_progress(self, progress): self.progress.setValue(progress) def update_status(self, status): if status: self.progress.show() else: self.progress.hide()
class App(QDialog): def __init__(self): super().__init__() self.title = 'PyDAQviewer' self.left = 200 self.top = 200 self.width = 600 self.height = 400 self.initUI() self.update_PathFileNames() def initUI(self): self.setWindowTitle(self.title) self.setGeometry(self.left, self.top, self.width, self.height) self.setWindowIcon(QIcon('docs/imgs/ISWI_Logo_sm.jpg')) # Tool bar self.tb = QToolBar(self) tuto = QAction(QIcon('docs/imgs/open.png'), "&Tutorial (Ctrl+T)", self, shortcut="Ctrl+T", triggered=self.tutorial) self.tb.addAction(tuto) alert = QAction(QIcon('docs/imgs/new.png'), "&About (Ctrl+A)", self, shortcut="Ctrl+A", triggered=self.about) self.tb.addAction(alert) qt = QAction(QIcon('docs/imgs/qt_icon.png'), "&About Qt (Ctrl+G)", self, shortcut="Ctrl+G", triggered=self.aboutQt) self.tb.addAction(qt) #Horizontal layout self.createHorizontalLayout() self.createGroupGridBox() windowLayout = QVBoxLayout() windowLayout.addWidget(self.tb) windowLayout.addWidget(self.horizontalQWidget) windowLayout.addWidget(self.horizontalGroupBox) # Text :Show what is going on when clicking on button plot self.TextInfo = QTextEdit("Ready!", self) self.TextInfo.setReadOnly(True) windowLayout.addWidget(self.TextInfo) # Plot Button buttonPlot = QPushButton('Plot', self) buttonPlot.clicked.connect(self.on_plot) windowLayout.addWidget(buttonPlot) self.setLayout(windowLayout) self.show() def tutorial(self): webbrowser.open('file://' + os.path.realpath("docs/Tutorial.html")) def about(self): QMessageBox.about( self, "PyDAQviewer", ''' The VLF PyDAQviewer (Data Acquisition data viewer) is a Python program designed to make it easier to view and analyze data acquired with your AWESOME receiver.\n Author: Ahmed Ammar \n Date Created: Tue Mar 13 15:27:51 2018 \n ''') def aboutQt(self): QMessageBox.aboutQt(self) def createHorizontalLayout(self): self.horizontalQWidget = QWidget() layout1 = QHBoxLayout() # Label Date label_date = QLabel('Date', self) layout1.addWidget(label_date) # QDateEdit: Edit Date DateEdit = QDateEdit(self) DateEdit.setDisplayFormat("dd-MMMM-yyyy") DateEdit.setLocale(QLocale(QLocale.English, QLocale.UnitedStates)) DateEdit.setCalendarPopup(True) layout1.addWidget(DateEdit) today = QDateTime.currentDateTime().date() DateEdit.setDate(QDate(today)) DateEdit.dateChanged[QDate].connect(self.on_ShowDate) self.date = DateEdit.date() self.date = self.date.toPyDate() self.year, self.month, self.day = self.date.year, '{:02d}'.format( self.date.month), '{:02d}'.format(self.date.day) # Edit path to Narrowband Data label_PathNarrow = QLabel('Path to Narrowband Data', self) layout1.addWidget(label_PathNarrow) self.PathText = QLineEdit("C:/NarrowbandData/", self) self.PathText.textChanged[str].connect(self.update_PathFileNames) layout1.addWidget(self.PathText) # Select directory button BtnSelectDir = QPushButton('...', self) BtnSelectDir.clicked.connect(self.on_SelectDir) layout1.addWidget(BtnSelectDir) self.horizontalQWidget.setLayout(layout1) def createGroupGridBox(self): # Group Box self.horizontalGroupBox = QGroupBox(" Subplots") self.layout2 = QGridLayout() self.layout2.setColumnStretch(1, 4) self.layout2.setColumnStretch(2, 4) ## Groupbox elements ### Subplots self.subplot1 = QCheckBox("Subplot N° 1", self) self.subplot1.setChecked(True) self.subplot1.toggled.connect(self.update_PathFileNames) self.layout2.addWidget(self.subplot1, 0, 0) self.subplot2 = QCheckBox("Subplot N° 2", self) self.subplot2.setChecked(True) self.subplot2.toggled.connect(self.update_PathFileNames) self.layout2.addWidget(self.subplot2, 1, 0) self.subplot3 = QCheckBox("Subplot N° 3", self) self.subplot3.toggled.connect(self.update_PathFileNames) self.layout2.addWidget(self.subplot3, 2, 0) self.subplot4 = QCheckBox("Subplot N° 4", self) self.subplot4.toggled.connect(self.update_PathFileNames) self.layout2.addWidget(self.subplot4, 3, 0) self.subplot5 = QCheckBox("Subplot N° 5", self) self.subplot5.toggled.connect(self.update_PathFileNames) self.layout2.addWidget(self.subplot5, 4, 0) self.subplot6 = QCheckBox("Subplot N° 6", self) self.subplot6.toggled.connect(self.update_PathFileNames) self.layout2.addWidget(self.subplot6, 5, 0) ## Recievers self.Rx1 = QComboBox(self) self.Rx1.addItems(Rx_ID.keys()) self.layout2.addWidget(self.Rx1, 0, 1) self.Rx1.currentIndexChanged.connect(self.update_PathFileNames) self.Rx2 = QComboBox(self) self.Rx2.addItems(Rx_ID.keys()) self.layout2.addWidget(self.Rx2, 1, 1) self.Rx2.currentIndexChanged.connect(self.update_PathFileNames) self.Rx3 = QComboBox(self) self.Rx3.addItems(Rx_ID.keys()) self.layout2.addWidget(self.Rx3, 2, 1) self.Rx3.currentIndexChanged.connect(self.update_PathFileNames) self.Rx4 = QComboBox(self) self.Rx4.addItems(Rx_ID.keys()) self.layout2.addWidget(self.Rx4, 3, 1) self.Rx4.currentIndexChanged.connect(self.update_PathFileNames) self.Rx5 = QComboBox(self) self.Rx5.addItems(Rx_ID.keys()) self.layout2.addWidget(self.Rx5, 4, 1) self.Rx5.currentIndexChanged.connect(self.update_PathFileNames) self.Rx6 = QComboBox(self) self.Rx6.addItems(Rx_ID.keys()) self.layout2.addWidget(self.Rx6, 5, 1) self.Rx6.currentIndexChanged.connect(self.update_PathFileNames) ## Transmitters self.Tx1 = QComboBox(self) self.Tx1.addItems(Tx_ID.keys()) self.layout2.addWidget(self.Tx1, 0, 2) self.Tx1.currentIndexChanged.connect(self.update_PathFileNames) self.Tx2 = QComboBox(self) self.Tx2.addItems(Tx_ID.keys()) self.layout2.addWidget(self.Tx2, 1, 2) self.Tx2.currentIndexChanged.connect(self.update_PathFileNames) self.Tx3 = QComboBox(self) self.Tx3.addItems(Tx_ID.keys()) self.layout2.addWidget(self.Tx3, 2, 2) self.Tx3.currentIndexChanged.connect(self.update_PathFileNames) self.Tx4 = QComboBox(self) self.Tx4.addItems(Tx_ID.keys()) self.layout2.addWidget(self.Tx4, 3, 2) self.Tx4.currentIndexChanged.connect(self.update_PathFileNames) self.Tx5 = QComboBox(self) self.Tx5.addItems(Tx_ID.keys()) self.layout2.addWidget(self.Tx5, 4, 2) self.Tx5.currentIndexChanged.connect(self.update_PathFileNames) self.Tx6 = QComboBox(self) self.Tx6.addItems(Tx_ID.keys()) self.layout2.addWidget(self.Tx6, 5, 2) self.Tx6.currentIndexChanged.connect(self.update_PathFileNames) ## High/Low res self.Low_High1 = QCheckBox("Low Res/(High Res)", self) self.layout2.addWidget(self.Low_High1, 0, 4) self.Low_High1.toggled.connect(self.update_PathFileNames) self.Low_High2 = QCheckBox("Low Res/(High Res)", self) self.layout2.addWidget(self.Low_High2, 1, 4) self.Low_High2.toggled.connect(self.update_PathFileNames) self.Low_High3 = QCheckBox("Low Res/(High Res)", self) self.layout2.addWidget(self.Low_High3, 2, 4) self.Low_High3.toggled.connect(self.update_PathFileNames) self.Low_High4 = QCheckBox("Low Res/(High Res)", self) self.layout2.addWidget(self.Low_High4, 3, 4) self.Low_High4.toggled.connect(self.update_PathFileNames) self.Low_High5 = QCheckBox("Low Res/(High Res)", self) self.layout2.addWidget(self.Low_High5, 4, 4) self.Low_High5.toggled.connect(self.update_PathFileNames) self.Low_High6 = QCheckBox("Low Res/(High Res)", self) self.layout2.addWidget(self.Low_High6, 5, 4) self.Low_High6.toggled.connect(self.update_PathFileNames) ## Amp/Phi self.Amplitude_Phase1 = QCheckBox("Amplitude/(Phase)", self) self.layout2.addWidget(self.Amplitude_Phase1, 0, 5) self.Amplitude_Phase1.toggled.connect(self.update_PathFileNames) self.Amplitude_Phase2 = QCheckBox("Amplitude/(Phase)", self) self.layout2.addWidget(self.Amplitude_Phase2, 1, 5) self.Amplitude_Phase2.toggled.connect(self.update_PathFileNames) self.Amplitude_Phase3 = QCheckBox("Amplitude/(Phase)", self) self.layout2.addWidget(self.Amplitude_Phase3, 2, 5) self.Amplitude_Phase3.toggled.connect(self.update_PathFileNames) self.Amplitude_Phase4 = QCheckBox("Amplitude/(Phase)", self) self.layout2.addWidget(self.Amplitude_Phase4, 3, 5) self.Amplitude_Phase4.toggled.connect(self.update_PathFileNames) self.Amplitude_Phase5 = QCheckBox("Amplitude/(Phase)", self) self.layout2.addWidget(self.Amplitude_Phase5, 4, 5) self.Amplitude_Phase5.toggled.connect(self.update_PathFileNames) self.Amplitude_Phase6 = QCheckBox("Amplitude/(Phase)", self) self.layout2.addWidget(self.Amplitude_Phase6, 5, 5) self.Amplitude_Phase6.toggled.connect(self.update_PathFileNames) self.setLayout(self.layout2) self.horizontalGroupBox.setLayout(self.layout2) def update_PathFileNames(self): # print(str(self.date.year)) self.pathnames = [] self.filenames = [] self.TitlePlot = [] if self.subplot1.isChecked(): self.Rx1.setEnabled(True) self.Tx1.setEnabled(True) self.Low_High1.setEnabled(True) self.Amplitude_Phase1.setEnabled(True) self.path1= self.PathText.text() + \ self.Rx1.currentText() + "/" + str(self.year) + \ "/" + str(self.month) + "/" + str(self.day) + "/" if self.Amplitude_Phase1.isChecked() and self.Low_High1.isChecked( ): self.AmpPhi = "D" elif self.Low_High1.isChecked(): self.AmpPhi = "C" elif self.Amplitude_Phase1.isChecked(): self.AmpPhi = "B" else: self.AmpPhi = "A" self.file1=Rx_ID[self.Rx1.currentText()]+ str(self.year)[2:]+str(self.month)+str(self.day)+ \ "*" + Tx_ID[self.Tx1.currentText()] + self.AmpPhi + ".mat" self.title1= self.Rx1.currentText() +", "+ str(self.year) + \ "/" + str(self.month) + "/" + str(self.day)+ ", "+ self.Tx1.currentText() self.pathnames.append(self.path1) self.filenames.append(self.file1) self.TitlePlot.append(self.title1) else: self.Rx1.setEnabled(False) self.Tx1.setEnabled(False) self.Low_High1.setEnabled(False) self.Amplitude_Phase1.setEnabled(False) if self.subplot2.isChecked(): self.Rx2.setEnabled(True) self.Tx2.setEnabled(True) self.Low_High2.setEnabled(True) self.Amplitude_Phase2.setEnabled(True) self.path2= self.PathText.text()+ \ self.Rx2.currentText() + "/" + str(self.year) + \ "/" + str(self.month) + "/" + str(self.day) + "/" if self.Amplitude_Phase2.isChecked() and self.Low_High2.isChecked( ): self.AmpPhi = "D" elif self.Low_High2.isChecked(): self.AmpPhi = "C" elif self.Amplitude_Phase2.isChecked(): self.AmpPhi = "B" else: self.AmpPhi = "A" self.file2=Rx_ID[self.Rx2.currentText()]+ str(self.year)[2:]+str(self.month)+str(self.day)+ \ "*" + Tx_ID[self.Tx2.currentText()] + self.AmpPhi + ".mat" self.title2= self.Rx2.currentText() +", "+ str(self.year) + \ "/" + str(self.month) + "/" + str(self.day)+ ", "+ self.Tx2.currentText() self.pathnames.append(self.path2) self.filenames.append(self.file2) self.TitlePlot.append(self.title2) else: self.Rx2.setEnabled(False) self.Tx2.setEnabled(False) self.Low_High2.setEnabled(False) self.Amplitude_Phase2.setEnabled(False) if self.subplot3.isChecked(): self.Rx3.setEnabled(True) self.Tx3.setEnabled(True) self.Low_High3.setEnabled(True) self.Amplitude_Phase3.setEnabled(True) self.path3= self.PathText.text() + \ self.Rx3.currentText() + "/" + str(self.year) + \ "/" + str(self.month) + "/" + str(self.day) + "/" if self.Amplitude_Phase3.isChecked() and self.Low_High3.isChecked( ): self.AmpPhi = "D" elif self.Low_High3.isChecked(): self.AmpPhi = "C" elif self.Amplitude_Phase3.isChecked(): self.AmpPhi = "B" else: self.AmpPhi = "A" self.file3=Rx_ID[self.Rx3.currentText()]+ str(self.year)[2:]+str(self.month)+str(self.day)+ \ "*" + Tx_ID[self.Tx3.currentText()] + self.AmpPhi + ".mat" self.title3= self.Rx3.currentText() +", "+ str(self.year) + \ "/" + str(self.month) + "/" + str(self.day)+ ", "+ self.Tx3.currentText() self.pathnames.append(self.path3) self.filenames.append(self.file3) self.TitlePlot.append(self.title3) else: self.Rx3.setEnabled(False) self.Tx3.setEnabled(False) self.Low_High3.setEnabled(False) self.Amplitude_Phase3.setEnabled(False) if self.subplot4.isChecked(): self.Rx4.setEnabled(True) self.Tx4.setEnabled(True) self.Low_High4.setEnabled(True) self.Amplitude_Phase4.setEnabled(True) self.path4= self.PathText.text() + \ self.Rx4.currentText() + "/" + str(self.year) + \ "/" + str(self.month) + "/" + str(self.day) + "/" if self.Amplitude_Phase4.isChecked() and self.Low_High4.isChecked( ): self.AmpPhi = "D" elif self.Low_High4.isChecked(): self.AmpPhi = "C" elif self.Amplitude_Phase4.isChecked(): self.AmpPhi = "B" else: self.AmpPhi = "A" self.file4=Rx_ID[self.Rx4.currentText()]+ str(self.year)[2:]+str(self.month)+str(self.day)+ \ "*" + Tx_ID[self.Tx4.currentText()] + self.AmpPhi + ".mat" self.title4= self.Rx4.currentText() +", "+ str(self.year) + \ "/" + str(self.month) + "/" + str(self.day)+ ", "+ self.Tx4.currentText() self.pathnames.append(self.path4) self.filenames.append(self.file4) self.TitlePlot.append(self.title4) else: self.Rx4.setEnabled(False) self.Tx4.setEnabled(False) self.Low_High4.setEnabled(False) self.Amplitude_Phase4.setEnabled(False) if self.subplot5.isChecked(): self.Rx5.setEnabled(True) self.Tx5.setEnabled(True) self.Low_High5.setEnabled(True) self.Amplitude_Phase5.setEnabled(True) self.path5= self.PathText.text() + \ self.Rx5.currentText() + "/" + str(self.year) + \ "/" + str(self.month) + "/" + str(self.day) + "/" if self.Amplitude_Phase5.isChecked() and self.Low_High5.isChecked( ): self.AmpPhi = "D" elif self.Low_High5.isChecked(): self.AmpPhi = "C" elif self.Amplitude_Phase5.isChecked(): self.AmpPhi = "B" else: self.AmpPhi = "A" self.file5=Rx_ID[self.Rx5.currentText()]+ str(self.year)[2:]+str(self.month)+str(self.day)+ \ "*" + Tx_ID[self.Tx5.currentText()] + self.AmpPhi + ".mat" self.title5= self.Rx5.currentText() +", "+ str(self.year) + \ "/" + str(self.month) + "/" + str(self.day)+ ", "+ self.Tx5.currentText() self.pathnames.append(self.path5) self.filenames.append(self.file5) self.TitlePlot.append(self.title5) else: self.Rx5.setEnabled(False) self.Tx5.setEnabled(False) self.Low_High5.setEnabled(False) self.Amplitude_Phase5.setEnabled(False) if self.subplot6.isChecked(): self.Rx6.setEnabled(True) self.Tx6.setEnabled(True) self.Low_High6.setEnabled(True) self.Amplitude_Phase6.setEnabled(True) self.path6= self.PathText.text() + \ self.Rx6.currentText() + "/" + str(self.year) + \ "/" + str(self.month) + "/" + str(self.day) + "/" if self.Amplitude_Phase6.isChecked() and self.Low_High6.isChecked( ): self.AmpPhi = "D" elif self.Low_High6.isChecked(): self.AmpPhi = "C" elif self.Amplitude_Phase6.isChecked(): self.AmpPhi = "B" else: self.AmpPhi = "A" self.file6=Rx_ID[self.Rx6.currentText()]+ str(self.year)[2:]+str(self.month)+str(self.day)+ \ "*" + Tx_ID[self.Tx6.currentText()] + self.AmpPhi + ".mat" self.title6= self.Rx6.currentText() +", "+ str(self.year) + \ "/" + str(self.month) + "/" + str(self.day)+ ", "+ self.Tx6.currentText() self.pathnames.append(self.path6) self.filenames.append(self.file6) self.TitlePlot.append(self.title6) else: self.Rx6.setEnabled(False) self.Tx6.setEnabled(False) self.Low_High6.setEnabled(False) self.Amplitude_Phase6.setEnabled(False) print(self.pathnames) print(self.filenames) print(self.TitlePlot) def on_SelectDir(self): file = str( QFileDialog.getExistingDirectory( self, "Select Data's Directory (NarrowbandData)")) self.PathText.setText(file + "/") def on_plot(self): try: print(self.pathnames[0]) Plot_Data(pathnames=self.pathnames, filenames=self.filenames, TitlePlot=self.TitlePlot) self.TextInfo.clear() self.TextInfo.textCursor().insertHtml( "<p><h3><font color='blue'>Loaded Data: </font></p>") for data in DataLoaded_list: self.TextInfo.textCursor().insertHtml( "<pre><h4><font color='green'>" + data + ", </font></pre>") except: self.TextInfo.clear() for data in DataError_List: self.TextInfo.textCursor().insertHtml( "<pre><h4><font color='red'>Error!" + "\n" + data + ", </font></pre>") def on_ShowDate(self, date): ''' Select Year, Month and Day from calander ''' # print(date.toPyDate()) self.date = date.toPyDate() self.year, self.month, self.day = self.date.year, '{:02d}'.format( self.date.month), '{:02d}'.format(self.date.day) self.update_PathFileNames()
def __init__(self,name): QWidgetSavePos.__init__(self,name) self.main_vbox = QVBoxLayout() #self.setFixedSize(900, 700) self.setWindowTitle(_("Fit window")+" https://www.gpvdm.com") self.setWindowIcon(icon_get("fit")) toolbar=QToolBar() toolbar.setIconSize(QSize(48, 48)) toolbar.setToolButtonStyle( Qt.ToolButtonTextUnderIcon) self.order_widget=order_widget() self.order_widget.new_text=_("New fit") self.order_widget.delete_text=_("Delete fit") self.order_widget.clone_text=_("Clone fit") self.order_widget.rename_text=_("Rename fit") self.order_widget.new_dlg_text=_("New fit name:") self.order_widget.base_file_name=["fit","fit_data","fit_patch","fit_math"] self.order_widget.new_tab_name=_("fit ") self.order_widget.clone_dlg_text=_("Clone the current fit to a new fit called:") self.order_widget.rename_dlg_text=_("Rename the fit to be called:") self.order_widget.delete_dlg_text=_("Should I remove the fit file ") self.order_widget.name_token="#fit_name" self.order_widget.init() toolbar.addWidget(self.order_widget) self.order_widget.added.connect(self.callback_add_page) toolbar.addSeparator() self.tb_configure= QAction(icon_get("preferences-system"), wrap_text(_("Configure"),4), self) self.tb_configure.triggered.connect(self.callback_configure) toolbar.addAction(self.tb_configure) self.import_data= QAction(icon_get("import"), _("Import data"), self) self.import_data.triggered.connect(self.callback_import) toolbar.addAction(self.import_data) toolbar.addSeparator() self.play= QAction(icon_get("media-playback-start"), wrap_text(_("Run a single fit"),4), self) self.play.triggered.connect(self.callback_one_fit) toolbar.addAction(self.play) self.play= QAction(icon_get("forward"),wrap_text( _("Start the fitting process"),4), self) self.play.triggered.connect(self.callback_do_fit) toolbar.addAction(self.play) self.pause= QAction(icon_get("media-playback-pause"), wrap_text(_("Stop the simulation"),4), self) self.pause.triggered.connect(self.callback_stop) toolbar.addAction(self.pause) spacer = QWidget() spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) toolbar.addWidget(spacer) self.help = QAction(icon_get("help"), _("Help"), self) self.help.triggered.connect(self.callback_help) toolbar.addAction(self.help) self.main_vbox.addWidget(toolbar) self.notebook = QTabWidget() self.order_widget.notebook_pointer=self.notebook css_apply(self.notebook,"style_h.css") self.notebook.setTabBar(QHTabBar()) self.notebook.setTabPosition(QTabWidget.West) self.notebook.setMovable(True) self.load_tabs() self.main_vbox.addWidget(self.notebook) self.status_bar=QStatusBar() self.main_vbox.addWidget(self.status_bar) self.setLayout(self.main_vbox) self.fit_configure_window=None
class OvirtClient(QWidget): """ This class will handle the main window where all user's VMs will be listed. This will be rendered only if authentication was successfull since it doesn't make sense otherwise. Additionally, a Thread will be started checking VM status changes and update the board accordingly. """ stopThread = False # Sentinel for stopping the Thread execution autologoutWarn = False # Has the user been warned about autologout yet? openviewer_vms = [] # Initiated VMs in terms of the viewer updatesignal = pyqtSignal( int, str) # Signal to update the status icons on status changes reloadsignal = pyqtSignal() # Signal to reload the main widget warnlogoutsignal = pyqtSignal( ) # Signal to warn the user about an imminent autologout logoutsignal = pyqtSignal( bool ) # Signal to logout the current user and require credentials again lastclick = int(time( )) # Timestamp of the last click. If a timeout policy is defined and # the time exceeds this value, an autologout will be performed. def __init__(self): QWidget.__init__(self) self.initUI() def vm_based_resize(self, vmnum): """ Description: Depending on the number of VMs which the user has permissions on, we need to resize the main window accordingly in height.The fewer they are, the smaller the window will be. If MAXHEIGHT is reached, a scrollbar will also be shown (that's processed in a different place, though) Parameters: The number of VMs. Returns: The actual window height. """ global MAXHEIGHT if not vmnum: # If user has no machines, resize window to the minimum winheight = 150 no_machines = QLabel(_('no_vms')) no_machines.setWordWrap(True) no_machines.setAlignment(Qt.AlignCenter) self.grid.addWidget(no_machines, 0, 0) self.setMinimumHeight(winheight) else: # User has at least one VM if vmnum > 5: # More than 5 means resizing the window to the maximum winheight = MAXHEIGHT self.setFixedHeight(winheight) else: # Otherwise, resize depending on the number of VMs winheight = vmnum * 100 + 50 self.setFixedHeight(winheight) return winheight def get_os_icon(self, os): """ Description: Depending on the VM's OS, this method returns which icon should be used to illustrate it. Arguments: oVirt-style string representing the VM's OS Returns: The file name under IMGDIR that should be shown. """ if 'ubuntu' in os: return 'ubuntu' elif 'rhel' in os: return 'redhat' elif 'centos' in os: return 'centos' elif 'debian' in os: return 'debian' elif 'linux' in os: return 'linux' elif 'win' in os: return 'windows' return 'unknown' def generate_toolbar(self): """ Description: There will be a toolbar in the main widget with some buttons, this method will render them. Arguments: None Returns: Nothing """ global IMGDIR, conf self.toolBar = QToolBar(self) refreshAction = QAction(QIcon(IMGDIR + 'refresh.png'), _('refresh'), self) refreshAction.setShortcut('Ctrl+R') refreshAction.triggered.connect(self.refresh_grid) self.toolBar.addAction(refreshAction) self.forgetCredsAction = QAction(QIcon(IMGDIR + 'forget.png'), _('forget_credentials'), self) self.forgetCredsAction.setShortcut('Ctrl+F') self.forgetCredsAction.triggered.connect(self.forget_creds) if not isfile(conf.USERCREDSFILE): self.forgetCredsAction.setDisabled(True) self.toolBar.addAction(self.forgetCredsAction) aboutAction = QAction(QIcon(IMGDIR + 'about.png'), _('about'), self) aboutAction.setShortcut('Ctrl+I') aboutAction.triggered.connect(self.about) self.toolBar.addAction(aboutAction) exitAction = QAction(QIcon(IMGDIR + 'exit.png'), _('exit'), self) exitAction.setShortcut('Ctrl+Q') exitAction.triggered.connect(self.quit_button) self.toolBar.addAction(exitAction) self.grid.addWidget(self.toolBar, 0, 3, Qt.AlignRight) def make_button(self, filename, tooltip, alignment=Qt.AlignCenter): """ Description: Creates a QLabel which will contain an image and will simulate a button. No associated text will be shown. Arguments: 1. filename: The filename of the icon/image to show 2. tooltip: Some text to show as a tooltip to the image 3. alignment: Alignment of the button (center by default) Returns: The created QLabel button """ global STANDARDCELLCSS, IMGDIR filepath = '%s%s%s' % (IMGDIR, filename, '.png') icon = QImage(filepath) image = QLabel() image.setToolTip('<span style="color:#B9B900">%s</span>' % (tooltip)) image.setStyleSheet(STANDARDCELLCSS) image.setPixmap(QPixmap.fromImage(icon)) image.setAlignment(alignment) return image def compare_vms(self, vm1, vm2): """ Description: VM list will be sorted by names. This method is the comparison method for two VMs. We just sort them alphabetically. Arguments: Two VMs (oVirt VM objects) Returns: -1, 0 or 1 depending on the name-based sorting """ if vm1.name.lower() < vm2.name.lower(): return -1 if vm1.name.lower() == vm2.name.lower(): return 0 return 1 def p22p3_compare_vms(self, cmpfunct): """ Wrapper for Python 2 -> 3 conversion for the old cmp= method of sorted()""" class K: def __init__(self, obj, *args): self.obj = obj def __lt__(self, other): return cmpfunct(self.obj, other.obj) < 0 def __gt__(self, other): return cmpfunct(self.obj, other.obj) > 0 def __eq__(self, other): return cmpfunct(self.obj, other.obj) == 0 def __le__(self, other): return cmpfunct(self.obj, other.obj) <= 0 def __ge__(self, other): return cmpfunct(self.obj, other.obj) >= 0 def __ne__(self, other): return cmpfunct(self.obj, other.obj) != 0 return K def current_vm_status(self, vmstatus): """ Description: Single translation between oVirt-like status to human-readable status Arguments: oVirt-like status Returns: Human-readable status """ if vmstatus == 'up': hrstatus = _('up') elif vmstatus == 'down': hrstatus = _('down') elif vmstatus == 'powering_down': hrstatus = _('powering_down') elif vmstatus == 'wait_for_launch': hrstatus = _('wait_for_launch') elif vmstatus == 'powering_up': hrstatus = _('powering_up') elif vmstatus == 'reboot_in_progress': hrstatus = _('rebooting') else: hrstatus = 'unknown' return hrstatus def toggle_vm_action(self, vmstatus): """ Description: Returns the available action for the current VM's status. If machine is up, available action is turn it off and viceversa. Arguments: Current vm status Returns: Toggle action for the current status. """ if vmstatus == 'up': vmaction = _('shut_down') if vmstatus == 'down': vmaction = _('power_on') return vmaction def toggle_action_text(self, vmstatus): """ Description: One of the columns shows the current VM's status. This method returns the toggle tooltip text so the user know what will happen if they click on the status icon. Arguments: Current vm status Returns: The tooltip's informative text. """ rettxt = '%s <b>%s</b>.' % (_('current_vm_status'), self.current_vm_status(vmstatus)) if vmstatus == 'up': rettxt += ' %s %s' % (_('click_to_action'), _('shut_down')) if vmstatus == 'down': rettxt += ' %s %s' % (_('click_to_action'), _('power_on')) return rettxt def change_status(self, rowid): """ Description: If the user clicks on the column which determines VM's status, we'll allow them to change VM's status. This method shows a confirmation dialog and if accepted, it will be notified to oVirt. Arguments: The row id that has been clicked. This relationship is stored using the VmData class. Returns: Nothing """ global conf self.lastclick = int(time()) # Last click timestamp update curvmstatus = self.vmdata[rowid].vmstatus if curvmstatus != 'up' and curvmstatus != 'down': QMessageBox.warning(None, _('apptitle') + ': ' + _('warning'), _('vm_in_unchangeable_status')) return reply = QMessageBox.question( None, _('apptitle') + ': ' + _('confirm'), '%s <b>%s</b>. %s: <b>%s</b>.' % (_('current_vm_status'), self.current_vm_status(curvmstatus), _('confirm_vm_status_change'), self.toggle_vm_action(curvmstatus)), QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: try: vms_service = conf.OVIRTCONN.vms_service() vm = vms_service.list(search='id=%s' % (self.vmdata[rowid].vmid))[0] except Error: QMessageBox.critical(None, _('apptitle') + ': ' + _('error'), _('unexpected_connection_drop')) quit() if curvmstatus == 'up': try: vm_service = vms_service.vm_service( id=self.vmdata[rowid].vmid) vm_service.shutdown() QMessageBox.information( None, _('apptitle') + ': ' + _('success'), _('shutting_down_vm')) except Error: QMessageBox.warning(None, _('apptitle') + ': ' + _('warning'), _('vm_in_unchangeable_status')) if curvmstatus == 'down': try: vm_service = vms_service.vm_service( id=self.vmdata[rowid].vmid) vm_service.start() QMessageBox.information( None, _('apptitle') + ': ' + _('success'), _('powering_up_vm')) except Error: QMessageBox.warning(None, _('apptitle') + ': ' + _('warning'), _('vm_in_unchangeable_status')) def get_viewer_ticket(self, vmid): """ Description: Connecting to the machine involves two steps, the first one is obtaining a 'ticket' string for the connection request. This is done making a request to the oVirt API and then parsing the resulting XML document to get the ticket hash. Also, the request may return more than one ticket: One for SPICE and another for VNC. In this case, we'll return the one that the user defined in the settings file (SPICE as default). Arguments: The VM UUID in oVirt-format Returns: The ticket hash string """ global conf req = urllib.request.Request( '%s/%s/%s/%s' % (conf.CONFIG['ovirturl'], 'vms', vmid, 'graphicsconsoles')) # Python 2 -> 3 conversion: encodestring expects a byte-like string, not str base64str = encodestring( ('%s:%s' % (conf.USERNAME + '@' + conf.CONFIG['ovirtdomain'], conf.PASSWORD)).encode()).decode().replace('\n', '') req.add_header('Authorization', 'Basic ' + base64str) req.add_header('filter', 'true') unverified_ctxt = SSLContext(PROTOCOL_TLSv1) tickethash = urllib.request.urlopen(req, context=unverified_ctxt).read() xmlcontent = ET.fromstring(tickethash) ticket = None for data in xmlcontent.findall('graphics_console'): proto = data.findall('protocol')[0] if proto.text.lower() == conf.CONFIG['prefproto'].lower(): return data.get('id') else: ticket = data.get('id') return ticket def store_vv_file(self, vmid, ticket): """ Description: Connecting to the machine involves two steps, the second one is obtaining a 'vv' file with the connection parameters, which we can later pipe to virt-viewer and the connection will be opened. Arguments: 1. vmid: The VM UUID in oVirt-format. 2. ticket: The ticket obtained in the first step (method get_viewer_ticket) Returns: The temporary filename with all the parameters to connect to the machine (piped to virt-viewer) """ global conf if not ticket: return False req = urllib.request.Request( '%s/%s/%s/%s/%s' % (conf.CONFIG['ovirturl'], 'vms', vmid, 'graphicsconsoles', ticket)) # Python 2 -> 3 conversion: encodestring expects a byte-like string, not str base64str = encodestring( ('%s:%s' % (conf.USERNAME + '@' + conf.CONFIG['ovirtdomain'], conf.PASSWORD)).encode()).decode().replace('\n', '') req.add_header('Authorization', 'Basic ' + base64str) req.add_header('Content-Type', 'application/xml') req.add_header('Accept', 'application/x-virt-viewer') req.add_header('filter', 'true') unverified_ctxt = SSLContext(PROTOCOL_TLSv1) try: contents = urllib.request.urlopen(req, context=unverified_ctxt).read() if conf.CONFIG['fullscreen'] == '1': contents = contents.replace('fullscreen=0', 'fullscreen=1') filename = '/tmp/viewer-' + str(randint(10000, 99999)) f = open(filename, 'wb') f.write(contents) f.close() return filename except urllib.request.HTTPError as em: QMessageBox.critical( None, _('apptitle') + ': ' + _('error'), _('unexpected_request_error') + '(' + str(em.code) + '): ' + em.reason + '. ' + _('check_vm_config_updated')) return None def viewer_exit(self, vmname): self.openviewer_vms.remove( vmname) # Remove the VM from the list of opened viewers self.reloadsignal.emit( ) # Enforce a reload signal to update the status icon ASAP def create_viewer_thread(self, vmname, filename): global conf def runInThread(vmname, onExit, popenArgs): viewer = Popen(popenArgs) viewer.wait() onExit(vmname) return thread = threading.Thread(target=runInThread, args=(vmname, self.viewer_exit, [ conf.CONFIG['remote_viewer_path'], '-t', vmname, '-f', '--', 'file://%s' % (filename) ])) thread.start() # Returns immediately after the thread starts return thread def connect2machine(self, vmid, vmname): """ Description: Connecting to the machine involves two steps, this method does both and makes sure everything is ok to call virt-viewer afterwards. Arguments: 1. vmid: The VM UUID in oVirt-format. 2. vmname: Just for displaying purposes, the VM name Returns: Nothing. Opens the view-viewer display. """ viewer_ticket = self.get_viewer_ticket(vmid) filename = self.store_vv_file(vmid, viewer_ticket) if filename: self.create_viewer_thread(vmname, filename) else: if vmname in self.openviewer_vms: self.openviewer_vms.remove( vmname) # Remove the VM from the list of opened viewers QMessageBox.critical(None, _('apptitle') + ': ' + _('error'), _('no_viewer_file')) def connect(self, rowid): """ Description: Whenever the user clicks on the 'connect' row, this method will make sure the VM status is up and only then will call the connect2machine method. Arguments: The row id that has been clicked. This relationship is stored using the VmData class. Returns: Nothing """ self.lastclick = int(time()) # Last click timestamp update vmid = self.vmdata[rowid].vmid vmname = self.vmdata[rowid].vmname vmstatus = self.vmdata[rowid].vmstatus if vmstatus != 'up': QMessageBox.warning(None, _('apptitle') + ': ' + _('warning'), _('cannot_connect_if_vm_not_up')) return if vmname in self.openviewer_vms: QMessageBox.critical(None, _('apptitle') + ': ' + _('error'), _('cannot_open_more_viewer_sessions')) return self.openviewer_vms.append(vmname) self.refresh_grid( ) # Enforce a dashboard reload to make the icon refresh self.connect2machine(vmid, vmname) def acquire_vm_from_vmpool(self, rowid): """ Description: A machine will be acquired by a user if they click on the icon of a VmPool Arguments: The row id that has been clicked. This relationship is stored using the VmData class. Returns: Nothing """ self.lastclick = int(time()) # Last click timestamp update vmtype = self.vmdata[rowid].vmtype if vmtype == 'vmpool': try: QMessageBox.information(None, _('apptitle') + ': ' + _('info'), _('acquiring_vm_from_pool')) vmpool_service = conf.OVIRTCONN.vm_pools_service() vmp = vmpool_service.pool_service(id=self.vmdata[rowid].vmid) vmp.allocate_vm() self.refresh_grid() except Error as e: QMessageBox.critical(None, _('apptitle') + ': ' + _('error'), str(e)) else: QMessageBox.warning(None, _('apptitle') + ': ' + _('warning'), _('object_is_not_a_vmpool')) def refresh_grid(self): """ Description: Invoked when the user clicks on the 'Refresh' button in the toolbar. Reloads the board. Arguments: None Returns: Nothing """ self.lastclick = int(time()) # Last click timestamp update self.load_vms() def about(self): """ Description: Invoked when the user clicks on the 'About' button in the toolbar. Arguments: None Returns: Nothing """ self.lastclick = int(time()) # Last click timestamp update About() def forget_creds(self): """ Description: Invoked when the user clicks on the 'Forget credentials' button in the toolbar. Arguments: None Returns: Nothing """ global conf self.lastclick = int(time()) # Last click timestamp update reply = QMessageBox.question(None, _('apptitle') + ': ' + _('confirm'), _('confirm_forget_creds'), QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: remove(conf.USERCREDSFILE) self.forgetCredsAction.setDisabled(True) QMessageBox.information(None, _('apptitle') + ': ' + _('success'), _('creds_forgotten')) def list_vmpools(self, row, delta, step, vmpools): """ Description: Creates one row per VmPool that the user has access to. Arguments: 1. The index of the first row to loop over. 2. Delta step to sum to the progress bar. 3. The current step of the progress bar 4. The oVirt list of VmPools. Returns: The final step of the progress bar """ # For cleanness reasons, we'll firstly show available VmPools for vm in vmpools: vmname = vm.name # OS icon ostype = 'vmpool' imageOsicon = self.make_button(ostype, '<b>' + _('vmpool') + '</b>') # Machine name gridvmname = QLabel(vmname) gridvmname.setStyleSheet(STANDARDCELLCSS) gridvmname.setAlignment(Qt.AlignCenter) # Acquire VM button connect = self.make_button('grab', _('grab_vm_vmpool')) connect.mousePressEvent = lambda x, r=row: self.acquire_vm_from_vmpool( r) # Fill row with known info self.grid.addWidget(imageOsicon, row, 0) self.grid.addWidget(gridvmname, row, 1) self.grid.addWidget(connect, row, 2) # Store the correspondence between row number <-> VMPool data vmd = VmData() vmd.vmid = vm.id vmd.vmname = vm.name vmd.vmstatus = None vmd.vmtype = 'vmpool' self.vmdata[row] = vmd row += 1 step += delta self.pbar.setValue(step) return step def list_vms(self, row, delta, step, vms): """ Description: Creates one row per VM that the user has access to. Arguments: 1. The index of the first row to loop over. 2. Delta step to sum to the progress bar. 3. The current step of the progress bar 4. The oVirt list of VMs. Returns: Nothing """ # Now we'll show up the VMs for vm in vms: vmname = vm.name vmstatus = vm.status.value # OS icon ostype = self.get_os_icon(vm.os.type.lower()) imageOsicon = self.make_button( ostype, '<b>%s</b> OS' % (ostype.capitalize())) # Machine name gridvmname = QLabel(vmname) gridvmname.setStyleSheet(STANDARDCELLCSS) gridvmname.setAlignment(Qt.AlignCenter) # Connect button. Depending on whether it has already been hit, a different icon # will be shown and the behavior will also be different. if vmname not in self.openviewer_vms: connect = self.make_button('connect', _('connect')) connect.mousePressEvent = lambda x, r=row: self.connect(r) else: connect = self.make_button('viewer', _('viewer_already_opened')) # Status icon curaction = self.current_vm_status(vmstatus) imageSticon = self.make_button(vmstatus, self.toggle_action_text(vmstatus)) imageSticon.mousePressEvent = lambda x, r=row: self.change_status(r ) # Fill row with known info self.grid.addWidget(imageOsicon, row, 0) self.grid.addWidget(gridvmname, row, 1) self.grid.addWidget(imageSticon, row, 2) self.grid.addWidget(connect, row, 3) # Store the correspondence between row number <-> VM data vmd = VmData() vmd.vmid = vm.id vmd.vmname = vm.name vmd.vmstatus = vmstatus vmd.vmtype = 'vm' self.vmdata[row] = vmd row += 1 step += delta self.pbar.setValue(step) def load_vms(self): """ Description: Main core VM loader method. Will connect to oVirt, get the VM list and render them. Arguments: None Returns: Nothing """ global conf, MAXHEIGHT, BACKGROUNDCSS, STANDARDCELLCSS QObjectCleanupHandler().add(self.layout()) if not conf.USERNAME: quit() # Used to store row <-> VM correspondence self.vmdata = {} step = 0 self.pbarlayout = QGridLayout(self) self.pbar = QProgressBar(self) self.grid = QGridLayout() self.grid.setHorizontalSpacing(0) # Initially, set the layout to the progress bar self.pbar.setGeometry(250, 250, 200, 100) self.pbar.setValue(0) self.pbarlayout.addWidget(self.pbar, 0, 0) self.setLayout(self.pbarlayout) self.setStyleSheet(BACKGROUNDCSS) try: # Try getting the VM list from oVirt vms_serv = conf.OVIRTCONN.vms_service() vmpools_serv = conf.OVIRTCONN.vm_pools_service() vms = sorted(vms_serv.list(), key=self.p22p3_compare_vms(self.compare_vms)) vmpools = sorted(vmpools_serv.list(), key=self.p22p3_compare_vms(self.compare_vms)) except Error: QMessageBox.critical(None, _('apptitle') + ': ' + _('error'), _('unexpected_connection_drop')) quit() # Set the main widget height based on the number of VMs winheight = self.vm_based_resize(len(vms) + len(vmpools)) if len(vms) + len(vmpools) > 0: delta = int(100 / (len(vms) + len(vmpools))) else: delta = int(100) if vmpools: step = self.list_vmpools(1, delta, step, vmpools) if vms: self.list_vms(len(vmpools) + 1, delta, step, vms) # Once loading has concluded, progress bar is dismissed and the layout set to the QGridLayout self.pbar.hide() QObjectCleanupHandler().add(self.layout()) # First row is special: Number of VMs + Toolbar total_machines = QLabel( _('total_machines') + ': <font color="#AA8738">' + str(len(vms)) + '</font>, ' + _('total_vmpools') + ': <font color="#AA8738">' + str(len(vmpools)) + '</font>', self) self.grid.addWidget(total_machines, 0, 0, 1, 3, Qt.AlignCenter) self.generate_toolbar() # We wrap the main widget inside another widget with a vertical scrollbar wrapper = QWidget() wrapper.setLayout(self.grid) scroll = QScrollArea() scroll.setWidget(wrapper) scroll.setWidgetResizable(True) scroll.setFixedHeight(winheight) layout = QVBoxLayout() layout.addWidget(scroll) layout.setContentsMargins(0, 0, 0, 20) self.setLayout(layout) def update_status_icon(self, i, newstatus): """ Description: Invoked when the background thread emits the signal announcing a status change, so the corresponding VM status icon should be updated. Arguments: i: Row that has changed their status. The VM can be matched with VmData(). newstatus: The new status for the VM. Returns: Nothing """ imageSticon = self.make_button(newstatus, self.toggle_action_text(newstatus)) imageSticon.mousePressEvent = lambda x, r=i: self.change_status(r) self.grid.addWidget(imageSticon, i, 2) def logout_warn(self): """ Description: Called if the warn_autologout setting has been set in the config. It will warn user to reset their idle, otherwise an enforced logout will be performed by calling the logout() method. Arguments: None Returns: Nothing """ self.autologoutwarnwin = QMessageBox(None) self.autologoutwarnwin.setIcon(QMessageBox.Warning) self.autologoutwarnwin.setText(_('auto_logout_warn')) self.autologoutwarnwin.setWindowTitle(_('auto_logout_warn_title')) self.autologoutwarnwin.setStandardButtons(QMessageBox.Ok) self.autologoutwarnwin.buttonClicked.connect( self.autologoutwarn_accepted) self.autologoutwarnwin.exec_() def logout(self, reconnect=False): """ Description: Invoked when the autologout parameter is set in the config and the idle time is overreached. This should require authentication again. Arguments: None Returns: Nothing """ if conf.OVIRTCONN: try: conf.SOCKOBJ.close() except Error: pass self.stopThread = True conf.USERNAME = None self.autologoutWarn = False # Hide the layout so next user doesn't see the previous content self.hide() try: self.autologoutwarnwin.accept() except AttributeError: # Usually when the notify_autologout setting has not been set pass # This will be called upon autologout events if reconnect: creds = Credentials(None) creds.finished.connect(self.start_vmpane) creds.exec_() def autologoutwarn_accepted(self): """ Description: Callback issued when the user accepts the message box warning about an imminent autologout event. Arguments: None Returns: Nothing """ self.lastclick = int(time()) self.autologoutWarn = False # This will make the warning be shown next times as well def refresh_statuses(self): """ Description: Background thread that will look for VM status changes and send a signal to the main thread so the corresponding icons are updated. Also, if there's a change in the number of VMs that the user controls, the main Widgets will be reloaded. It'll also check the autologout setting & act accordingly. Arguments: None Returns: Nothing ("infinite" loop) """ global UPDATESLEEPINTERVAL autologout = False while 1 and not self.stopThread: if conf.OVIRTCONN: try: vms_service = conf.OVIRTCONN.vms_service() ovirt_num_machines = len(vms_service.list()) except Error: sys.exit('[ERROR] ' + _('unexpected_connection_drop')) if ovirt_num_machines != len(self.vmdata): # If the number of VMs has changed, we should reload the main widget self.reloadsignal.emit() else: for i in self.vmdata: vmid = self.vmdata[i].vmid vmstatus = self.vmdata[i].vmstatus try: ovirtvm = vms_service.list(search='id=%s' % (vmid))[0] except Error: sys.exit('[ERROR] ' + _('unexpected_connection_drop')) if ovirtvm: curstatus = ovirtvm.status.value if vmstatus != curstatus: # If there has been a status change, emit the signal to update icons self.vmdata[i].vmstatus = curstatus self.updatesignal.emit(i, curstatus) # If there is any currently open viewer, we'll reset the idle time so we don't close the session # while there still is any open session. if self.openviewer_vms: self.lastclick = int(time()) # Last click timestamp update # If the autologout warning has not been shown yet and it's configured, we do so if conf.CONFIG['autologout'] != 0 and conf.CONFIG['notify_autologout'] != 0 and not self.autologoutWarn and \ (int(time() - self.lastclick) >= (conf.CONFIG['autologout'] - conf.CONFIG['notify_autologout']) * 60): self.autologoutWarn = True self.warnlogoutsignal.emit() # If there's no credentials file and autologout is set, we check for the last # click and if surpassed, a logout will be performed. if conf.CONFIG['autologout'] != 0 and not isfile( conf.USERCREDSFILE): if (int(time()) - self.lastclick) >= ( conf.CONFIG['autologout'] * 60): self.stopThread = True autologout = True sleep(UPDATESLEEPINTERVAL) else: return if autologout: self.logoutsignal.emit(True) def restart_thread(self): """ Description: Simply starts or restarts the background thread Arguments: None Returns: Nothing """ self.stopThread = False self.lastclick = int(time()) self.thread = threading.Thread(target=self.refresh_statuses, args=()) self.thread.daemon = True # Daemonize thread self.thread.start() def start_vmpane(self): """ Description: This method will be called when the Credentials dialog is closed. This should happen on successful authentication. We should then load the main widget and fill it with the VMs that the user has permissions on. Additionally, a background thread will be started to check VM status changed so the main widget is updated should this happen. Arguments: None Returns: Nothing """ self.show() self.load_vms() self.center() self.restart_thread() def confirm_quit(self): """ Description: Asks for confirmation from the user's side to close the app. Arguments: None Returns: True if the user wants to close the app, False otherwise. """ global conf reply = QMessageBox.question(None, _('apptitle') + ': ' + _('confirm'), _('confirm_quit'), QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: self.logout(reconnect=False) return True else: return False def quit_button(self): """ Description: Triggered when the Exit button in the Toolbar is hit. Confirmation will be required. Arguments: None Returns: Nothing, exits if user confirms. """ self.lastclick = int(time()) # Last click timestamp update if self.confirm_quit(): quit() def closeEvent(self, event): """ Description: The red 'x'. If the user hits it, we'll ask for confirmation. Arguments: None Returns: Nothing, exits if users confirms. """ if self.confirm_quit(): event.accept() else: event.ignore() def initUI(self): """ Description: Sets the size of the widget, the window title, centers the window, connects signals to methods and opens the Credentials dialog if needed. Arguments: None Returns: Nothing. """ global conf, MAXWIDTH, MAXHEIGHT, IMGDIR, VERSION self.setFixedSize(MAXWIDTH, MAXHEIGHT) self.center() self.setWindowTitle(_('apptitle') + ' ' + VERSION) self.setWindowIcon(QIcon(IMGDIR + 'appicon.png')) self.show() self.updatesignal.connect(self.update_status_icon) self.logoutsignal.connect(self.logout) self.warnlogoutsignal.connect(self.logout_warn) self.reloadsignal.connect(self.load_vms) if not conf.USERNAME: creds = Credentials(self) creds.finished.connect(self.start_vmpane) creds.exec_() def center(self): """ Description: Just centers the window Arguments: None Returns: Nothing """ qr = self.frameGeometry() cp = QDesktopWidget().availableGeometry().center() qr.moveCenter(cp) self.move(qr.topLeft())