def recursiveAddItems(menu, items): for item in items: if item == 'separator': menu.addSeparator() continue if not isinstance(item, dict): LOG.warn("Skipping unrecognized menu item: %s", item) continue title = item.get('title') or '' items = item.get('items') provider = item.get('provider') if items is not None: new_menu = QMenu(parent=self, title=title) recursiveAddItems(new_menu, items) menu.addMenu(new_menu) elif provider is not None: new_menu = _initialize_object_from_dict(item, parent=menu) new_menu.setTitle(title) menu.addMenu(new_menu) else: act = QAction(parent=self, text=title) self.getMenuAction(act, title, item.get('action')) act.setShortcut(item.get('shortcut', '')) menu.addAction(act)
def getContextMenus(self, event): if self._menu: return None menu = QMenu(parent=self.getViewWidget()) menu.setTitle("Slicing") if self.slice_direction != 'vertical': horizontal_action = QAction('Horizontal slice', menu) horizontal_action.toggled.connect(self.sigToggleHorizontalSlice) horizontal_action.setCheckable(True) menu.addAction(horizontal_action) if self.slice_direction != 'horizontal': vertical_action = QAction('Vertical slice', menu) vertical_action.toggled.connect(self.sigToggleVerticalSlice) vertical_action.setCheckable(True) menu.addAction(vertical_action) if self.slice_direction == 'depth': depth_action = QAction('Depth slice', menu) depth_action.toggled.connect(self.sigToggleDepthSlice) depth_action.setCheckable(True) menu.addAction(depth_action) make_primary_action = QAction('Set as Primary View', menu) make_primary_action.triggered.connect(self.makePrimary) menu.addAction(make_primary_action) self._menu = menu return menu
def recursiveAddItems(menu, items): for item in items: if item == 'separator': menu.addSeparator() continue if not isinstance(item, dict): LOG.warn("Skipping unrecognized menu item: %s", item) continue title = item.get('title') or '' items = item.get('items') provider = item.get('provider') args = item.get('args') or [] kwargs = item.get('kwargs') or {} if items is not None: new_menu = QMenu(parent=self, title=title) recursiveAddItems(new_menu, items) menu.addMenu(new_menu) elif provider is not None: new_menu = _initialize_object_from_dict(item, parent=menu) new_menu.setTitle(title) menu.addMenu(new_menu) else: self.getMenuAction(menu, title, item.get('action'), item.get('args', []), item.get('kwargs', {}))
def main(): logmodule = qrainbowstyle.extras.OutputLogger() qInstallMessageHandler(qrainbowstyle.extras.qt_message_handler) QtWidgets.QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps) QtWidgets.QApplication.setAttribute(Qt.AA_EnableHighDpiScaling) app = QtWidgets.QApplication(sys.argv) app.setStyleSheet(qrainbowstyle.load_stylesheet(style="oceanic")) # Package options # qrainbowstyle.align_buttons_left() # qrainbowstyle.use_darwin_buttons() qrainbowstyle.setAppIcon( os.path.join(os.path.dirname(os.path.realpath(__file__)), "github_logo.png")) # Create frameless mainwindow win = qrainbowstyle.windows.FramelessWindow() menu = QMenu(win) menu.setTitle("Some menu") menu.addAction(QAction("TEST ACTION", menu)) win.addMenu(menu) # Example for spinner spinner = qrainbowstyle.widgets.WaitingSpinner(win, centerOnParent=True, modality=Qt.WindowModal, roundness=70.0, fade=70.0, radius=9.0, lines=24, line_length=35.0, line_width=2.0) spinner.start() spinner.fadeIn() t = QTimer() t.setSingleShot(True) t.timeout.connect(spinner.fadeOut) t.start(5000) win.setMinimumSize(QSize(500, 300)) # Example of using signals win.closeClicked.connect(lambda: print("Close clicked!")) # Create content widget and pass reference to main window widget = WidgetGallery(win) # Add widget to main window and show it win.addContentWidget(widget) win.show() # Fullscreen test # win.showFullScreen() sys.exit(app.exec())
class WorkflowableROI(ROI): # FIXME: do we still want this for our (e.g.) CorrelationStage process_actions??? def __init__(self, *args, **kwargs): super(WorkflowableROI, self).__init__(*args, **kwargs) self.operation = ROIOperation(self) self._param = None def parameter(self) -> Parameter: raise NotImplementedError def getMenu(self): if self.menu is None: self.menu = QMenu() self.menu.setTitle("ROI") if self.removable: # FIXME: if the removable attr is changed, the menu will not react and remAct won't show remAct = QAction("Remove ROI", self.menu) remAct.triggered.connect(self.removeClicked) self.menu.addAction(remAct) self.menu.remAct = remAct editAct = QAction("Edit ROI", self.menu) editAct.triggered.connect(self.edit_parameters) self.menu.addAction(editAct) self.menu.editAct = editAct self.menu.setEnabled(True) return self.menu def contextMenuEnabled(self): return True def edit_parameters(self): class DefocusParameterTree(QWidget): def __init__(self, *args, **kwargs): super(DefocusParameterTree, self).__init__(*args, **kwargs) self.setLayout(QVBoxLayout()) self.parameter_tree = ParameterTree() self.layout().addWidget(self.parameter_tree) self.layout().setContentsMargins(0, 0, 0, 0) def setParameters(self, *args, **kwargs): self.parameter_tree.setParameters(*args, **kwargs) # self.parameter_tree = DefocusParameterTree() self.parameter_tree = DefocusParameterTree() self.parameter_tree.setParameters(self.parameter()) self.parameter_tree.setWindowFlags(Qt.FramelessWindowHint | Qt.Popup) # self.parameter_tree = QLabel('blah') self.parameter_tree.show() self.parameter_tree.activateWindow() self.parameter_tree.raise_() self.parameter_tree.move(QCursor().pos()) self.parameter_tree.setFocus(Qt.PopupFocusReason) self.parameter_tree.resize(QSize(300, 400))
def append_qmenu(self, button_name: str, menu_text: str, menu_icon: QIcon = None) -> QMenu: button: 'QToolButton' = self.get_control_widget(button_name) action = None if button is not None: menu = button.menu() new_menu = QMenu(menu) new_menu.setTitle(menu_text) # menu.addMenu() menu.addMenu(new_menu) # if menu is None: # self.add_menu_to(button_name, [action_text], [action_command], action_icon=action_icon) # else: # action = QAction(text=action_text, parent=menu) # if action_icon is not None: # action.setIcon(action_icon) # menu.addAction(action) # action.triggered.connect(action_command) return new_menu
class TaskWindow(FramelessWindow): send_task = Signal(int, str, dict, int) get_tasks = Signal() def __init__(self, parent): super(TaskWindow, self).__init__(parent) self.setContentsMargins(11, 11, 11, 11) self.content_widget = MainTaskWidget(self) self.content_widget.send_task.connect(self.send_task.emit) self.addContentWidget(self.content_widget) self.spinner = WaitingSpinner(self, modality=Qt.WindowModal, roundness=70.0, fade=70.0, radius=15.0, lines=6, line_length=25.0, line_width=4.0, speed=1.0) self.menu = QMenu(self) self.menu.setTitle("Task") self.reload_action = QAction(self.menu) self.reload_action.setText("Reload tasks") self.reload_action.triggered.connect(self.setupUi) self.menu.addAction(self.reload_action) self.addMenu(self.menu) def setupUi(self): self.spinner.start() self.get_tasks.emit() @Slot(dict) def process_task_message(self, message): if self.isVisible(): event = message.get("event") if event == "options": self.content_widget.set_tasks( message.get("options").get("tasks")) self.spinner.stop()
class UiMainWindow(QMainWindow): """ Main application window """ def __init__(self, parent=None): super(UiMainWindow, self).__init__(parent) DispatchHandle.setup(self) self.showMaximized() self.setMinimumSize(QSize(640, 480)) self.setDockOptions(QMainWindow.AnimatedDocks) self.setWindowTitle("SpecViz") self.widget_central = QWidget(self) self.setCentralWidget(self.widget_central) # Toolbar self.layout_vertical = QVBoxLayout(self.widget_central) # MDI area setup self.mdi_area = MdiArea(self.widget_central) self.mdi_area.setFrameShape(QFrame.StyledPanel) self.mdi_area.setFrameShadow(QFrame.Plain) self.mdi_area.setLineWidth(2) brush = QBrush(QColor(200, 200, 200)) brush.setStyle(Qt.SolidPattern) self.mdi_area.setBackground(brush) self.mdi_area.setAcceptDrops(True) self.layout_vertical.addWidget(self.mdi_area) # Menu bar setup self.menu_bar = QMenuBar(self) self.menu_file = QMenu(self.menu_bar) self.menu_file.setTitle("File") self.menu_edit = QMenu(self.menu_bar) self.menu_edit.setTitle("Edit") self.menu_view = QMenu(self.menu_bar) self.menu_edit.setTitle("View") self.menu_docks = QMenu(self.menu_bar) self.setMenuBar(self.menu_bar) # Status bar setup self.status_bar = QStatusBar(self) self.setStatusBar(self.status_bar)
def main(): logmodule = qrainbowstyle.extras.OutputLogger() qInstallMessageHandler(qt_message_handler) QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps) QApplication.setAttribute(Qt.AA_EnableHighDpiScaling) app = QApplication(sys.argv) app.setStyleSheet(qrainbowstyle.load_stylesheet(style="oceanic")) qrainbowstyle.setAppIcon( os.path.join(os.path.dirname(os.path.realpath(__file__)), "github_logo.png")) dialog = FramelessWindow() dialog.setWindowTitle("FDialog") dialog.resize(1100, 600) dialog.show() oneMenu = QMenu() oneMenu.setTitle("Tools") oneMenu.addActions( [QAction("Clicker", oneMenu), QAction("Initializer", oneMenu)]) twomenu = QMenu() twomenu.setTitle("File") twomenu.addActions([QAction("Open", twomenu), QAction("Save", twomenu)]) thirdmenu = QMenu() thirdmenu.setTitle("Settings") thirdmenu.addActions([QAction("Network", thirdmenu)]) looper = StyleLooper() style = QAction("Change style", thirdmenu) style.triggered.connect(looper.change) thirdmenu.addAction(style) dialog.addMenu(twomenu) dialog.addMenu(oneMenu) dialog.addMenu(thirdmenu) box = FramelessWarningMessageBox(dialog) box.setText("Warning :)") box.show() sys.exit(app.exec())
class MainWindow(FramelessWindow): def __init__(self): super(MainWindow, self).__init__() self.que = [] self.algorithms = [ FCFS, SSTF, SCAN, C_SCAN, C_LOOK, SSTF_EDF, SSTF_FDF_SCAN ] self.menu = QMenu(self) self.style_picker_action = QWidgetAction(self.menu) self.style_picker = StylePickerHorizontal(self) self.style_picker_action.setDefaultWidget(self.style_picker) self.menu.addAction(self.style_picker_action) self.menu.setTitle("Simulation") self.addMenu(self.menu) self.main_widget = MainWidget(self) self.addContentWidget(self.main_widget) def createRequests(self) -> None: """Fills queue with disk access requests.""" for x in range(REQUESTS_COUNT - REAL_TIME_COUNT): self.que.append( Request(random.randint(MIN_ARRIVE_TIME, MAX_ARRIVE_TIME), random.randint(0, DISK_SIZE))) for x in range(REAL_TIME_COUNT): self.que.append( Request(random.randint(MIN_ARRIVE_TIME, MAX_ARRIVE_TIME), random.randint(0, DISK_SIZE), real_time=True, deadline=random.randint(MIN_DEADLINE, MAX_DEADLINE))) self.que.sort(key=lambda req: req.arrive_time) for index, request in enumerate(self.que): request.set_id(index + 1) def saveProcessesToFile(self) -> None: """Saves requests to file using pickle.""" with open(PICKLED_FILENAME, "wb") as file: pickle.dump(self.que, file) def loadProcessesFromFile(self) -> None: """Load requests from files using pickle.""" with open(PICKLED_FILENAME, "rb") as file: self.que = pickle.load(file) def setupAlgorithms(self): self.table = AlgorithmsTable(self.main_widget) self.tableModel = AlgorithmsTableModel(self.table) self.tableModel.setDiskSize(DISK_SIZE) self.table.setModel(self.tableModel) self.main_widget.addWidget(self.table) for algorithm in self.algorithms: algorithm_instance = algorithm(self.que, START_POS, DISK_SIZE) self.tableModel.addAlgorithm(algorithm_instance) self.start_button = QPushButton("Start", self) self.start_button.clicked.connect(self.tableModel.start) self.main_widget.addWidget(self.start_button)
def SetMenuTitle(menu: QW.QMenu, label: str): label = SanitiseLabel(label) menu.setTitle(label)
class PreviewTable(QTableView): """Import wizard preview widget""" def __init__(self, parent): QTableView.__init__(self, parent) self._model = None # Setting up actions self.date_dayfirst_action = create_action(self, "dayfirst", triggered=ft_partial( self.parse_to_type, atype="date", dayfirst=True)) self.date_monthfirst_action = create_action(self, "monthfirst", triggered=ft_partial( self.parse_to_type, atype="date", dayfirst=False)) self.perc_action = create_action(self, "perc", triggered=ft_partial( self.parse_to_type, atype="perc")) self.acc_action = create_action(self, "account", triggered=ft_partial( self.parse_to_type, atype="account")) self.str_action = create_action(self, "unicode", triggered=ft_partial( self.parse_to_type, atype="unicode")) self.int_action = create_action(self, "int", triggered=ft_partial( self.parse_to_type, atype="int")) self.float_action = create_action(self, "float", triggered=ft_partial( self.parse_to_type, atype="float")) # Setting up menus self.date_menu = QMenu() self.date_menu.setTitle("Date") add_actions(self.date_menu, (self.date_dayfirst_action, self.date_monthfirst_action)) self.parse_menu = QMenu(self) self.parse_menu.addMenu(self.date_menu) add_actions(self.parse_menu, (self.perc_action, self.acc_action)) self.parse_menu.setTitle("String to") self.opt_menu = QMenu(self) self.opt_menu.addMenu(self.parse_menu) add_actions(self.opt_menu, (self.str_action, self.int_action, self.float_action)) def _shape_text(self, text, colsep=u"\t", rowsep=u"\n", transpose=False, skiprows=0, comments='#'): """Decode the shape of the given text""" assert colsep != rowsep out = [] text_rows = text.split(rowsep)[skiprows:] for row in text_rows: stripped = to_text_string(row).strip() if len(stripped) == 0 or stripped.startswith(comments): continue line = to_text_string(row).split(colsep) line = [try_to_parse(to_text_string(x)) for x in line] out.append(line) # Replace missing elements with np.nan's or None's if programs.is_module_installed('numpy'): from numpy import nan out = list(zip_longest(*out, fillvalue=nan)) else: out = list(zip_longest(*out, fillvalue=None)) # Tranpose the last result to get the expected one out = [[r[col] for r in out] for col in range(len(out[0]))] if transpose: return [[r[col] for r in out] for col in range(len(out[0]))] return out def get_data(self): """Return model data""" if self._model is None: return None return self._model.get_data() def process_data(self, text, colsep=u"\t", rowsep=u"\n", transpose=False, skiprows=0, comments='#'): """Put data into table model""" data = self._shape_text(text, colsep, rowsep, transpose, skiprows, comments) self._model = PreviewTableModel(data) self.setModel(self._model) @Slot() def parse_to_type(self, **kwargs): """Parse to a given type""" indexes = self.selectedIndexes() if not indexes: return for index in indexes: self.model().parse_data_type(index, **kwargs) def contextMenuEvent(self, event): """Reimplement Qt method""" self.opt_menu.popup(event.globalPos()) event.accept()
class Q7Diff(Q7Window, Ui_Q7DiffWindow): def __init__(self, control, fgprintindexA, fgprintindexB, diag): Q7Window.__init__(self, Q7Window.VIEW_DIFF, control, None, fgprintindexA) self._depthExpanded = 0 self._lastEntered = None self._fgidxA = fgprintindexA self._fgidxB = fgprintindexB ldiag = self.diagAnalysis(diag) self.treeviewA.expanded[QModelIndex].connect(self.expandNode) self.treeviewA.collapsed.connect(self.collapseNode) self.treeviewA.clicked[QModelIndex].connect(self.clickedNode) self.treeviewA.customContextMenuRequested[QPoint].connect( self.clickedNode) self.treeviewB.expanded[QModelIndex].connect(self.expandNode) self.treeviewB.collapsed.connect(self.collapseNode) self.treeviewB.clicked[QModelIndex].connect(self.clickedNode) self.treeviewB.customContextMenuRequested[QPoint].connect( self.clickedNode) # QObject.connect(self.treeviewA, # SIGNAL("expanded(QModelIndex)"), # self.expandNode) # QObject.connect(self.treeviewA, # SIGNAL("collapsed()"), # self.collapseNode) # QObject.connect(self.treeviewA, # SIGNAL("clicked(QModelIndex)"), # self.clickedNode) # QObject.connect(self.treeviewA, # SIGNAL("customContextMenuRequested(QPoint)"), # self.clickedNode) # QObject.connect(self.treeviewB, # SIGNAL("expanded(QModelIndex)"), # self.expandNode) # QObject.connect(self.treeviewB, # SIGNAL("collapsed()"), # self.collapseNode) # QObject.connect(self.treeviewB, # SIGNAL("clicked(QModelIndex)"), # self.clickedNode) # QObject.connect(self.treeviewB, # SIGNAL("customContextMenuRequested(QPoint)"), # self.clickedNode) # QObject.connect(self.bLockScroll, # SIGNAL("clicked()"), # self.syncScrolls) self.bLockScroll.clicked.connect(self.syncScrolls) self.bClose.clicked.connect(self.leave) self.bInfo.clicked.connect(self.infoTreeView) self.bZoomIn.clicked.connect(self.expandLevel) self.bZoomOut.clicked.connect(self.collapseLevel) self.bZoomAll.clicked.connect(self.expandMinMax) self.bSaveDiff.clicked.connect(self.savediff) self.setContextMenuPolicy(Qt.CustomContextMenu) self.popupmenu = QMenu() self.proxyA = Q7DiffTreeModel(self._fgidxA) self.proxyB = Q7DiffTreeModel(self._fgidxB) self.proxyA.setDiag(ldiag) self.proxyB.setDiag(ldiag) self.treeviewA.setModel(self.proxyA) self.treeviewB.setModel(self.proxyB) fga = Q7FingerPrint.getByIndex(self._fgidxA) fgb = Q7FingerPrint.getByIndex(self._fgidxB) model_a = fga.model model_b = fgb.model self.treeviewA.setItemDelegate( Q7DiffItemDelegate(self.treeviewA, model_a, ldiag)) self.treeviewB.setItemDelegate( Q7DiffItemDelegate(self.treeviewB, model_b, ldiag)) self.treeviewA.setControlWindow(self, model_a) self.treeviewB.setControlWindow(self, model_b) self.treeviewA.hideColumn(NMT.COLUMN_FLAG_LINK) self.treeviewA.hideColumn(NMT.COLUMN_FLAG_CHECK) self.treeviewA.hideColumn(NMT.COLUMN_FLAG_SELECT) self.treeviewA.hideColumn(NMT.COLUMN_FLAG_USER) self.treeviewB.hideColumn(NMT.COLUMN_FLAG_LINK) self.treeviewB.hideColumn(NMT.COLUMN_FLAG_CHECK) self.treeviewB.hideColumn(NMT.COLUMN_FLAG_SELECT) self.treeviewB.hideColumn(NMT.COLUMN_FLAG_USER) self.wvsa = self.treeviewA.verticalScrollBar() self.wvsb = self.treeviewB.verticalScrollBar() self.uvsa = self.verticalScrollBarA self.uvsb = self.verticalScrollBarB self.uvsa.setToolTip("%s/%s" % (fga.filedir, fga.filename)) self.uvsb.setToolTip("%s/%s" % (fgb.filedir, fgb.filename)) self.syncScrolls(True) def diagAnalysis(self, diag): ldiag = {} for k in diag: ldiag[k] = DIFF_NX for d in diag[k]: if d[0] == 'NA': ldiag[d[1]] = DIFF_NA if d[0] == 'ND': ldiag[d[1]] = DIFF_ND if d[0] in ['CT']: ldiag[k] = DIFF_CT if d[0] in ['C3', 'C1', 'C2']: ldiag[k] = DIFF_CQ if d[0] in ['C6', 'C7']: ldiag[k] = DIFF_CV if d[0] in ['C4', 'C5']: ldiag[k] = DIFF_CS return ldiag def syncScrolls(self, force=False): self.uvsa.valueChanged[int].connect(self.wvsa.setValue[int]) self.uvsb.valueChanged[int].connect(self.wvsb.setValue[int]) self.wvsa.valueChanged[int].connect(self.uvsa.setValue[int]) self.wvsb.valueChanged[int].connect(self.uvsb.setValue[int]) # # QObject.connect(self.uvsa, SIGNAL("valueChanged(int)"), # self.wvsa, SLOT("setValue(int)")) # QObject.connect(self.uvsb, SIGNAL("valueChanged(int)"), # self.wvsb, SLOT("setValue(int)")) # QObject.connect(self.wvsa, SIGNAL("valueChanged(int)"), # self.uvsa, SLOT("setValue(int)")) # QObject.connect(self.wvsb, SIGNAL("valueChanged(int)"), # self.uvsb, SLOT("setValue(int)")) if force or self.bLockScroll.isChecked(): self.wvsa.valueChanged[int].connect(self.wvsb.setValue[int]) self.wvsb.valueChanged[int].connect(self.wvsa.setValue[int]) # QObject.connect(self.wvsa, SIGNAL("valueChanged(int)"), # self.wvsb, SLOT("setValue(int)")) # QObject.connect(self.wvsb, SIGNAL("valueChanged(int)"), # self.wvsa, SLOT("setValue(int)")) else: self.wvsa.valueChanged[int].disconnect(self.wvsb.setValue[int]) self.wvsb.valueChanged[int].disconnect(self.wvsa.setValue[int]) # QObject.disconnect(self.wvsa, SIGNAL("valueChanged(int)"), # self.wvsb, SLOT("setValue(int)")) # QObject.disconnect(self.wvsb, SIGNAL("valueChanged(int)"), # self.wvsa, SLOT("setValue(int)")) def model(self): return self._fgprint.model def modelIndex(self, idx): if not idx.isValid(): return -1 midx = idx # if (idx.model() != self.treeview.M()): # midx=self.treeview.model().mapToSource(idx) return midx def modelData(self, idx): if not idx.isValid(): return None return self.modelIndex(idx).internalPointer() def infoTreeView(self): self._control.helpWindow('Tree') def savediff(self): pass def expandMinMax(self): if self._depthExpanded == Q7FingerPrint.getByIndex( self._fgidxA).depth - 2: self._depthExpanded = -1 self.treeviewA.collapseAll() self.treeviewB.collapseAll() else: self._depthExpanded = Q7FingerPrint.getByIndex( self._fgidxA).depth - 2 self.treeviewA.expandAll() self.treeviewB.expandAll() self.resizeAll() def expandLevel(self): if self._depthExpanded < Q7FingerPrint.getByIndex( self._fgidxA).depth - 2: self._depthExpanded += 1 self.treeviewA.expandToDepth(self._depthExpanded) self.treeviewB.expandToDepth(self._depthExpanded) self.resizeAll() def collapseLevel(self): if self._depthExpanded != -1: self._depthExpanded -= 1 if self._depthExpanded == -1: self.treeviewA.collapseAll() self.treeviewB.collapseAll() else: self.treeviewA.expandToDepth(self._depthExpanded) self.treeviewB.expandToDepth(self._depthExpanded) self.resizeAll() def updateStatus(self, node): return self.lineEdit.clear() self.lineEdit.insert(node.sidsPath()) def updateMenu(self, nodeidxs): return nodeidx = self.modelIndex(nodeidxs) if not nodeidx.isValid: return False if nodeidx.internalPointer() is None: return False if nodeidx.internalPointer().sidsPath() == '/CGNSTree': return False self.setLastEntered(nodeidxs) if nodeidx != -1: node = nodeidx.internalPointer() lknode = not node.sidsIsLink() lznode = node.hasLazyLoad() actlist = ( ("About %s" % node.sidsType(), self.aboutSIDS, None, False), None, ("Mark/unmark node", self.marknode, 'Space', False), ("Add new child node", self.newnodechild, 'Ctrl+A', False), ("Add new brother node", self.newnodebrother, 'Ctrl+Z', False), None, ("Open form", self.popform, 'Ctrl+F', False), ("Open view", self.openSubTree, 'Ctrl+W', False), ("Open view on linked-to file", self.openLkTree, 'Ctrl+O', lknode), None, ("Load node data in memory", self.dataLoad, 'Ctrl+L', not lznode), ("Release memory node data", self.dataRelease, 'Ctrl+R', lznode), None, ("Copy", self.mcopy, 'Ctrl+C', False), ("Cut", self.mcut, 'Ctrl+X', False), ("Paste as brother", self.mpasteasbrother, 'Ctrl+V', False), ("Paste as child", self.mpasteaschild, 'Ctrl+Y', False), None, ("Cut all selected", self.mcutselected, 'Ctrl+Shift+X', False), ("Paste as brother for each selected", self.mpasteasbrotherselected, 'Ctrl+Shift+V', False), ("Paste as child for each selected", self.mpasteaschildselected, 'Ctrl+Shift+Y', False), ("Load nodes data in memory for each selected", self.dataLoadSelected, 'Ctrl+Shift+L', False), ("Release memory node data for each selected", self.dataReleaseSelected, 'Ctrl+Shift+R', False), ) self.popupmenu.clear() self.popupmenu.setTitle('Node menu') for aparam in actlist: if aparam is None: self.popupmenu.addSeparator() else: a = QAction(aparam[0], self) a.triggered.connect(aparam[1]) if aparam[2] is not None: a.setShortcut(aparam[2]) self.popupmenu.addAction(a) a.setDisabled(aparam[3]) return True def setLastEntered(self, nix=None): self._lastEntered = None def getLastEntered(self): return self._lastEntered def clearLastEntered(self): self._lastEntered = None self.treeview.selectionModel().clearSelection() return None def clickedNode(self, index): pass def expandNode(self, *args): self.resizeAll() def collapseNode(self, *args): pass def resizeAll(self): for n in range(NMT.COLUMN_LAST + 1): self.treeviewA.resizeColumnToContents(n) self.treeviewB.resizeColumnToContents(n) def show(self): super(Q7Diff, self).show() def closeAlone(self): pass def leave(self): self.close() def doRelease(self): pass
class Q7Tree(Q7Window, Ui_Q7TreeWindow): def __init__(self, control, path, fgprintindex): Q7Window.__init__(self, Q7Window.VIEW_TREE, control, path, fgprintindex) self._depthExpanded = 0 self._lastEntered = None self.lastdiag = None self._linkwindow = None self._querywindow = None self._vtkwindow = None self._selectwindow = None self._column = {NMT.COLUMN_SIDS: OCTXT.ShowSIDSColumn, NMT.COLUMN_FLAG_LINK: OCTXT.ShowLinkColumn, NMT.COLUMN_FLAG_SELECT: OCTXT.ShowSelectColumn, NMT.COLUMN_FLAG_CHECK: OCTXT.ShowCheckColumn, NMT.COLUMN_FLAG_USER: OCTXT.ShowUserColumn, NMT.COLUMN_SHAPE: OCTXT.ShowShapeColumn, NMT.COLUMN_DATATYPE: OCTXT.ShowDataTypeColumn} self.selectForLinkSrc = None # one link source per tree view allowed #self.treeview.expanded[QModelIndex].connect(self.expandNode) self.treeview.collapsed.connect(self.collapseNode) self.treeview.pressed[QModelIndex].connect(self.clickedPressedNode) self.treeview.customContextMenuRequested.connect(self.clickedNode) # QObject.connect(self.treeview, # SIGNAL("expanded(QModelIndex)"), # self.expandNode) # QObject.connect(self.treeview, # SIGNAL("collapsed()"), # self.collapseNode) # QObject.connect(self.treeview, # SIGNAL("pressed(QModelIndex)"), # self.clickedPressedNode) # QObject.connect(self.treeview, # SIGNAL("customContextMenuRequested(QPoint)"), # self.clickedNode) self.bSave.clicked.connect(self.savetree) self.lockable(self.bSave) self.bQueryView.clicked.connect(self.queryview) self.lockable(self.bQueryView) self.bSaveAs.clicked.connect(self.savetreeas) self.lockable(self.bSaveAs) self.bInfo.clicked.connect(self.infoTreeView) self.bZoomIn.clicked.connect(self.expandLevel) self.bZoomOut.clicked.connect(self.collapseLevel) self.bZoomAll.clicked.connect(self.expandMinMax) self.bFormView.clicked.connect(self.formview) self.bMarkAll.clicked.connect(self.markall) self.bUnmarkAll_1.clicked.connect(self.unmarkall) self.bUnmarkAll_2.clicked.connect(self.unmarkall) self.bPreviousMark.clicked.connect(self.previousmark) self.bNextMark.clicked.connect(self.nextmark) self.bSwapMarks.clicked.connect(self.swapmarks) self.bMarksAsList.clicked.connect(self.selectionlist) self.bVTKView.clicked.connect(self.vtkview) self.lockable(self.bVTKView) self.bScreenShot.clicked.connect(self.screenshot) self.bCheck.clicked.connect(self.check) self.bCheckList.clicked.connect(self.checklist) self.bClearChecks.clicked.connect(self.clearchecks) self.bLinkView.clicked.connect(self.linklist) self.bPatternView.clicked.connect(self.patternlist) self.bToolsView.clicked.connect(self.tools) self.setContextMenuPolicy(Qt.CustomContextMenu) self.popupmenu = QMenu() self.diagview = None lmodel = self.FG.model self.treeview.setModel(lmodel) self.treeview.setItemDelegate(Q7TreeItemDelegate(self.treeview, lmodel)) self.treeview.setControlWindow(self, self.FG.index) if (self._control.transientRecurse or OCTXT.RecursiveTreeDisplay): self.expandMinMax() if (self._control.transientVTK): self.vtkview() self._control.transientRecurse = False self._control.transientVTK = False self.clearchecks() # self.bCheckList.setDisabled(True) if (not OCTXT._HasProPackage): self.bToolsView.setDisabled(True) self.bCheckView.setDisabled(True) self.bPatternDB.setDisabled(True) self.bAddLink.clicked.connect(self.linkadd) self.bSelectLinkSrc.clicked.connect(self.linkselectsrc) self.bSelectLinkDst.clicked.connect(self.linkselectdst) self.bAddLink.setDisabled(True) self.lineEdit.returnPressed.connect(self.jumpToNode) # QObject.connect(self.lineEdit, # SIGNAL("returnPressed()"), # self.jumpToNode) tvh = self.treeview.header() tvh.setContextMenuPolicy(Qt.CustomContextMenu) tvh.customContextMenuRequested.connect(self.headerMenu) self._hmenu = QMenu() self._hmenu._idx = {} self._tlist = (('SIDS type', NMT.COLUMN_SIDS), ('Link flag', NMT.COLUMN_FLAG_LINK), ('Mark flag', NMT.COLUMN_FLAG_SELECT), ('Check flag', NMT.COLUMN_FLAG_CHECK), ('User flag', NMT.COLUMN_FLAG_USER), ('Shape', NMT.COLUMN_SHAPE), ('Data type', NMT.COLUMN_DATATYPE)) for (tag, idx) in self._tlist: a = QAction(tag, self._hmenu, checkable=True) self._hmenu._idx[idx] = a if (self._column[idx]): a.setChecked(True) else: a.setChecked(False) self._hmenu.addAction(a) self.treeview.setColumnHidden(idx, not self._column[idx]) self._recursiveAddNewNode = False self.updateTreeStatus() def headerMenu(self, pos): for (tag, idx) in self._tlist: self._hmenu._idx[idx].setChecked(self._column[idx]) self._hmenu.exec_(self.treeview.mapToGlobal(pos)) for (tag, idx) in self._tlist: if (self._hmenu._idx[idx].isChecked()): self._column[idx] = True else: self._column[idx] = False self.treeview.setColumnHidden(idx, not self._column[idx]) def model(self): return self.FG.model def modelIndex(self, idx): if not idx.isValid(): return -1 midx = idx if idx.model() != self.treeview.M(): midx = self.treeview.model().mapToSource(idx) return midx def modelData(self, idx): if not idx.isValid(): return None return self.modelIndex(idx).internalPointer() def savetree(self): if (not (self.FG.isSaveable() and self.FG.isModified())): return self._control.savedirect(self.FG) self.updateTreeStatus() def tools(self): from CGNS.NAV.wtools import Q7ToolsView if (self._control._toolswindow is None): self._control._toolswindow = Q7ToolsView(self._control, self.FG, self) self._control._toolswindow.show() else: self._control._toolswindow.raise_() def savetreeas(self): self._control.save(self.FG) self.updateTreeStatus() def infoTreeView(self): self._control.helpWindow('Tree') def screenshot(self): self.treeview.model().sort(0) sshot = QScreen.grabWindow(self.treeview.winId()) sshot.save('/tmp/foo.png', 'png') def expandMinMax(self): if (self._depthExpanded == self.FG.depth - 2): self._depthExpanded = -1 self.treeview.collapseAll() else: self._depthExpanded = self.FG.depth - 2 self.treeview.expandAll() self.resizeAll() def resetOptions(self): if (OCTXT.AutoExpand): self.treeview.setAutoExpandDelay(1000) else: self.treeview.setAutoExpandDelay(-1) def expandLevel(self): if (self._depthExpanded < self.FG.depth - 2): self._depthExpanded += 1 self.treeview.expandToDepth(self._depthExpanded) self.resizeAll() def collapseLevel(self): if (self._depthExpanded != -1): self._depthExpanded -= 1 if (self._depthExpanded == -1): self.treeview.collapseAll() else: self.treeview.expandToDepth(self._depthExpanded) self.resizeAll() def updateStatus(self, node): if (not self.lineEditLock.isChecked()): self.lineEdit.clear() self.lineEdit.insert(node.sidsPath()) def jumpToNode(self): path = self.lineEdit.text() self.treeview.selectByPath(path) def popform(self): self.formview() def openLkTree(self): self.busyCursor() filename = self.getLastEntered().sidsLinkFilename() if (filename is not None): self._control.loadfile(filename) self.readyCursor() def openSubTree(self): self.busyCursor() node = self.getLastEntered().sidsPath() child = Q7Tree(self._control, node, self.FG) self.readyCursor() child.show() def pop0(self): pass def newnodebrother(self): if (self.getLastEntered() is not None): self.model().newNodeBrother(self.getLastEntered()) def newnodechild(self): if (self.getLastEntered() is not None): self.model().newNodeChild(self.getLastEntered()) def marknode(self): if (self.getLastEntered() is not None): self.treeview.markNode(self.getLastEntered()) def mcopy(self): if (self.getLastEntered() is not None): self.model().copyNode(self.getLastEntered()) self.clearOtherSelections() def mcutselected(self): self.model().cutAllSelectedNodes() self.clearLastEntered() self.clearOtherSelections() def mcut(self): if (self.getLastEntered() is not None): self.model().cutNode(self.getLastEntered()) self.clearLastEntered() self.clearOtherSelections() def mpasteasbrotherselected(self): self.model().pasteAsBrotherAllSelectedNodes() def mpasteasbrother(self): if (self.getLastEntered() is not None): self.model().pasteAsBrother(self.getLastEntered()) def mpasteaschildselected(self): self.model().pasteAsChildAllSelectedNodes() def mpasteaschild(self): if (self.getLastEntered() is not None): self.model().pasteAsChild(self.getLastEntered()) def updateMenu(self, nodeidxs): nodeidx = self.modelIndex(nodeidxs) if (not nodeidx.isValid): return False if (nodeidx.internalPointer() is None): return False if (nodeidx.internalPointer().sidsPath() == '/CGNSTree'): return False self.setLastEntered(nodeidxs) if (nodeidx != -1): node = nodeidx.internalPointer() lknode = not node.sidsIsLink() lznode = node.hasLazyLoad() actlist = ( ("%s goodies" % node.sidsType(),), None, ("Expand sub-tree from this node", self.expand_sb, 'Ctrl++', False), ("Collapses sub-tree from this node", self.collapse_sb, 'Ctrl+-', False), None, ['Mark nodes...',[ ("Mark/unmark node", self.marknode, 'Space', False), None, ("Mark all nodes same SIDS type", self.marknode_t, 'Ctrl+1', False), ("Mark all nodes same name", self.marknode_n, 'Ctrl+2', False), ("Mark all nodes same value", self.marknode_v, 'Ctrl+3', False), None, ("Mark parent path", self.marknode_p, 'Ctrl+4', False)]], ("Add new child node", self.newnodechild, 'Ctrl+A', False), ("Add new brother node", self.newnodebrother, 'Ctrl+Z', False), # None, # ("Open form",self.popform,'Ctrl+F',False), # ("Open view",self.openSubTree,'Ctrl+W',False), # ("Open view on linked-to file",self.openLkTree,'Ctrl+O',lknode), None, ("Load node data in memory", self.dataLoad, 'Ctrl+L', not lznode), ("Release memory node data", self.dataRelease, 'Ctrl+R', lznode), None, ("Copy current", self.mcopy, 'Ctrl+C', False), ("Cut current", self.mcut, 'Ctrl+X', False), ("Paste as brother", self.mpasteasbrother, 'Ctrl+V', False), ("Paste as child", self.mpasteaschild, 'Ctrl+Y', False), None, ['On selected nodes...',[ ("Expand sub-tree from all selected nodes", self.sexpand_sb, 'Ctrl+Shift++', False), ("Collapses sub-tree from all selected nodes", self.scollapse_sb, 'Ctrl+Shift+-', False), None, ("Cut all selected", self.mcutselected, 'Ctrl+Shift+X', False), ("Paste as brother for each selected", self.mpasteasbrotherselected, 'Ctrl+Shift+V', False), ("Paste as child for each selected", self.mpasteaschildselected, 'Ctrl+Shift+Y', False), None, ("Load nodes data in memory for each selected", self.dataLoadSelected, 'Ctrl+Shift+L', False), ("Release memory node data for each selected", self.dataReleaseSelected, 'Ctrl+Shift+R', False)]], ) self.popupmenu.clear() self.popupmenu.setTitle('Node menu') for aparam in actlist: if (aparam is None): self.popupmenu.addSeparator() elif (len(aparam) == 1): stp = node.sidsType() tag = '_GM_{}'.format(stp) subm = self.popupmenu.addMenu('{}...'.format(stp)) a = QAction("About %s" % node.sidsType(), self, triggered=self.aboutSIDS) subm.addAction(a) patmenu = subm.addMenu('Insert pattern') self.patternMenu(patmenu, node.sidsNode()) subm.addSeparator() if (hasattr(self, tag)): getattr(self, tag)(subm, node) else: if isinstance(aparam,list): subm = self.popupmenu.addMenu(aparam[0]) for aaparam in aparam[1]: if (aaparam is None): subm.addSeparator() else: a = QAction(aaparam[0], self, triggered=aaparam[1]) if (aaparam[2] is not None): a.setShortcut(aaparam[2]) subm.addAction(a) a.setDisabled(aaparam[3]) else: a = QAction(aparam[0], self, triggered=aparam[1]) if (aparam[2] is not None): a.setShortcut(aparam[2]) self.popupmenu.addAction(a) a.setDisabled(aparam[3]) return True def _runAndSelect(self, qname, value): q = Q7Query.getQuery(qname) sl = q.run(self.FG.tree, self.FG.links, list(self.FG.lazy), False, value) self.model().markExtendToList(sl) self.model().updateSelected() self.treeview.refreshView() def patternMenu(self, menu, node): a = QAction("Recursive sub-pattern add", self, checkable=True) menu.addAction(a) a.setChecked(self._recursiveAddNewNode) menu.addSeparator() for t in [n[0] for n in CGU.getAuthChildren(node)]: def genCopyPattern(arg): def copyPattern(): self.model().copyNodeRaw(CGS.profile[arg][0]) if (self.getLastEntered() is not None): self.model().pasteAsChild(self.getLastEntered()) return copyPattern a = QAction("{}".format(t), self, triggered=genCopyPattern(t)) menu.addAction(a) def _gm_family_1(self, node): self._runAndSelect('013. FamilyName reference', "'%s'" % node.sidsName()) def _gm_family_2(self, node): self._runAndSelect('003. Node type', "'Family_t'") def _GM_Family_t(self, m, node): a = QAction('Select references to myself', self) a.triggered.connect(functools.partial(self._gm_family_1, node)) m.addAction(a) a = QAction('Select all families', self) a.triggered.connect(functools.partial(self._gm_family_2, node)) m.addAction(a) m.addSeparator() return True def _GM_IndexRange_t(self, m, node): if (node.sidsName() != CGK.ElementRange_s): v = 0 a = QAction('Range size: %d' % (v), self) m.addAction(a) else: v = node.sidsValue()[1] - node.sidsValue()[0] etp = CGU.getEnumAsString(node.sidsParent()) a = QAction('Number of elements of type [%s]: %d' % (etp, v), self) m.addAction(a) return True def _GM_Elements_t(self, m, node): etp = CGU.getEnumAsString(node.sidsNode()) npe = CGK.ElementTypeNPE[etp] a = QAction('Element type [%s] npe [%d]' % (etp, npe), self) m.addAction(a) return True def marknode_t(self): node = self.getLastEntered() self._runAndSelect('003. Node type', "'%s'" % node.sidsType()) def marknode_n(self): node = self.getLastEntered() self._runAndSelect('001. Node name', "'%s'" % node.sidsName()) def marknode_v(self): node = self.getLastEntered() value = node.sidsValue() self._runAndSelect('005. Node value', value) def marknode_p(self): node = self.getLastEntered() node.switchMarked() path = node.sidsPath() while path is not None: path = CGU.getPathAncestor(path) if (path not in ['/', None]): node = self.model().nodeFromPath('/CGNSTree' + path) node.switchMarked() self.model().updateSelected() def setLastEntered(self, nix=None): if ((nix is None) or (not nix.isValid())): nix = self.treeview.modelCurrentIndex() self._lastEntered = None if (nix.isValid()): self.treeview.exclusiveSelectRow(nix, False) self._lastEntered = self.modelData(nix) def getLastEntered(self): return self._lastEntered def clearLastEntered(self): self._lastEntered = None self.treeview.selectionModel().clearSelection() return None def clearOtherSelections(self): if (self._control._patternwindow is not None): self._control._patternwindow.clearSelection() def clickedPressedNode(self, index): self.clickedNode(index) def clickedNode(self, index): self.treeview.exclusiveSelectRow(index) if (self.treeview.lastButton == Qt.RightButton): if (self.updateMenu(index)): self.popupmenu.popup(self.treeview.lastPos) def expandNode(self, *args): self.resizeAll() def collapseNode(self, *args): pass def expand_sb(self): self.treeview.expand_sb() def collapse_sb(self): self.treeview.collapse_sb() def sexpand_sb(self): self.treeview.sexpand_sb() def scollapse_sb(self): self.treeview.scollapse_sb() def resizeAll(self): for n in range(NMT.COLUMN_LAST + 1): self.treeview.resizeColumnToContents(n) def show(self): super(Q7Tree, self).show() def linkselectsrc(self): if (self.bSelectLinkSrc.isChecked()): if (self.getLastEntered() is None): return self.bAddLink.setDisabled(False) node = self.getLastEntered() self.selectForLinkSrc = (node, node.sidsPath()) else: self.bAddLink.setDisabled(True) self.selectForLinkSrc = None def linkselectdst(self): if (self.getLastEntered() is None): return node = self.getLastEntered() if (node is None): return if (node.sidsIsLink()): return if (node.sidsType() == CGK.CGNSTree_ts): return if (self._control.selectForLinkDst is not None): bt = self._control.selectForLinkDst[-1].bSelectLinkDst bt.setChecked(Qt.Unchecked) if (self._control.selectForLinkDst[-1] == self): self._control.selectForLinkDst = None return self._control.selectForLinkDst = (node, node.sidsPath(), self.FG.filedir, self.FG.filename, self) self.bSelectLinkDst.setChecked(Qt.Checked) if (self._linkwindow is not None): n = node.sidsPath() d = self.FG.filedir f = self.FG.filename self._linkwindow.updateSelected(d, f, n) def linkadd(self): if (self._control.selectForLinkDst is None): return dst = self._control.selectForLinkDst str_dst = "%s:%s" % (dst[3], dst[1]) tpath = 'relative' newname = CGU.getPathLeaf(dst[1]) if (CGU.checkDuplicatedName(self.selectForLinkSrc[0].sidsNode(), newname, dienow=False)): str_cnm = "New child node name is <b>%s</b>" % newname else: count = 0 while (not CGU.checkDuplicatedName(self.selectForLinkSrc[0].sidsNode(), newname, dienow=False)): count += 1 newname = '{%s#%.3d}' % (dst[0].sidsType(), count) str_cnm = """As a child with this name already exists, the name <b>%s</b> is used (generated name)""" % \ newname str_src = "%s:%s/%s" % (self.FG.filename, self.selectForLinkSrc[1], newname) str_msg = "you want to create a link from <b>%s</b> to <b>%s</b><br>%s<br>Your current user options do force " \ "the link to use <b>%s</b> destination file path.""" % ( str_src, str_dst, str_cnm, tpath) reply = MSG.wQuestion(self, 231, 'Create link as a new node', str_msg) def linklist(self): if (self._linkwindow is None): self._linkwindow = Q7LinkList(self._control, self.FG.index, self) self._linkwindow.show() else: self._linkwindow.raise_() def patternlist(self): if (self._control._patternwindow is None): self._control._patternwindow = Q7PatternList(self._control, self.FG) self._control._patternwindow.show() self._control._patternwindow.raise_() def check(self): self.busyCursor() if (self.diagview is not None): self.diagview.close() self.diagview = None self.lastdiag = self.model().checkSelected() self.readyCursor() self.treeview.refreshView() self.bCheckList.setDisabled(False) def checklist(self): if (self.lastdiag is None): return self.diagview = Q7CheckList(self, self.lastdiag, self.FG.index) self.diagview.show() def clearchecks(self): self.model().checkClear() self.treeview.refreshView() self.lastdiag = None self.bCheckList.setDisabled(True) def selectionlist(self): if (self._selectwindow is not None): self._selectwindow.close() self._selectwindow = None self._selectwindow = Q7SelectionList(self, self.model(), self.FG.index) self._selectwindow.show() self._selectwindow.raise_() def previousmark(self): self.treeview.changeSelectedMark(-1) def nextmark(self): self.treeview.changeSelectedMark(+1) def markall(self): self.model().markAll() self.model().updateSelected() self.treeview.refreshView() def unmarkall(self): self.model().unmarkAll() self.model().updateSelected() self.treeview.refreshView() def swapmarks(self): self.model().swapMarks() self.model().updateSelected() self.treeview.refreshView() def formview(self): ix = self.treeview.modelCurrentIndex() node = self.modelData(ix) if (node is None): MSG.wInfo(self, 254, "Form view:", """You have to select a node to open its form view""", again=False) return if (node.sidsType() == CGK.CGNSTree_ts): return form = Q7Form(self._control, node, self.FG.index) form.show() def vtkview(self): if (not HAS_VTK): return from CGNS.NAV.wvtk import Q7VTK if (self._vtkwindow is None): self.busyCursor() ix = self.treeview.modelCurrentIndex() zlist = self.model().getSelectedZones() node = self.modelData(ix) self._vtkwindow = Q7VTK(self._control, self, node, self.FG.index, self.model(), zlist) if (self._vtkwindow._vtkstatus): self._vtkwindow.show() else: self._vtkwindow.close() self._vtkwindow = None self.readyCursor() else: self._vtkwindow.raise_() def plotview(self): return def queryview(self): if (self._querywindow is None): self._querywindow = Q7Query(self._control, self.FG.index, self) self._querywindow.show() else: self._querywindow.raise_() def aboutSIDS(self): path = self.getLastEntered().sidsPath() def dataLoadSelected(self): self.model().dataLoadSelected() def dataReleaseSelected(self): self.model().dataReleaseSelected() def dataLoad(self): node = self.getLastEntered() self.model().dataLoadSelected(single=node.sidsPath()) def dataRelease(self): node = self.getLastEntered() self.model().dataReleaseSelected(single=node.sidsPath()) def forceapply(self): pass def updateTreeStatus(self): if ((Q7FingerPrint.STATUS_MODIFIED in self.FG._status) and (Q7FingerPrint.STATUS_SAVEABLE in self.FG._status)): self.bSave.setEnabled(True) else: self.bSave.setEnabled(False) def doRelease(self): # break cyclic refs to allow garbage self.treeview.itemDelegate().doRelease() self.treeview.setItemDelegate(None) self.treeview.doRelease() self.treeview = None
class Q7Main(QW, Ui_Q7ControlWindow): verbose = False def __init__(self, parent=None): self.lastView = None self.w = None self.fdialog = None import platform QW.control_log = MSG.Q7Log() QW.__init__(self, QW.VIEW_CONTROL, self, None, None) self.versions = { 'pycgnsversion': 'pyCGNS v%s' % config.version, # 'chloneversion':'CHLone %s'%config.CHLONE_VERSION, 'vtkversion': 'VTK v%s' % config.VTK_VERSION, 'cythonversion': 'Cython v%s' % config.CYTHON_VERSION, 'hdf5version': 'HDF5 v%s' % config.HDF5_VERSION, 'numpyversion': 'numpy v%s' % config.NUMPY_VERSION, 'pythonversion': 'python v%s' % platform.python_version(), 'pyqtversion': 'PyQt v%s' % config.PYQT_VERSION, 'qtversion': 'Qt v%s' % config.QT_VERSION, } self.getHistory() self.bAbout.clicked.connect(self.about) self.bOptionView.clicked.connect(self.option) self.bTreeLoadLast.clicked.connect(self.loadlast) self.lockable(self.bTreeLoadLast) self.bTreeLoad.clicked.connect(self.load) self.bLog.clicked.connect(self.logView) self.lockable(self.bTreeLoad) self.bEditTree.clicked.connect(self.edit) self.lockable(self.bEditTree) self.bInfo.clicked.connect(self.infoControl) self.bPatternView.setDisabled(True) # self.bResetScrollBars.clicked.connect(self.resetScrolls) self.bClose.clicked.connect(self.close) # QObject.connect(self.controlTable, # SIGNAL("cellClicked(int,int)"), # self.clickedLine) self.controlTable.cellClicked.connect(self.clickedLine) self.initControlTable() self.controlTable.setItemDelegate(Q7ControlItemDelegate(self)) self.signals = Q7SignalPool() self.signals.loadFile.connect(self.loadStart) self.signals.saveFile.connect(self.saving) self.signals.cancel.connect(self.cancelUnlock) self.signals.loadCompleted.connect(self.loadCompleted) self.setContextMenuPolicy(Qt.CustomContextMenu) self.popupmenu = QMenu() self.transientRecurse = False self.transientVTK = False self.copyPasteBuffer = None self.wOption = None self.selectForLinkDst = None self.newtreecount = 1 self.help = None self._patternwindow = None self._toolswindow = None self.query = None Q7Query.loadUserQueries() Q7Query.fillQueries() Q7Query.loadUserFunctions() def clickedLine(self, *args): if self.controlTable.lastButton == Qt.LeftButton: # Q7FingerPrint.raiseView(self.getIdxFromLine(args[0])) pass if self.controlTable.lastButton == Qt.RightButton: self.updateMenu(self.controlTable.currentIndex()) self.popupmenu.popup(self.controlTable.lastPos) def closeView(self): self.updateLastView() if self.lastView is not None: fg = Q7FingerPrint.getFingerPrint(self.lastView) fg.closeView(self.lastView) self.lastView = None def raiseView(self): self.updateLastView() if self.lastView is not None: Q7FingerPrint.raiseView(self.lastView) def logView(self): self.control_log.show() def infoControl(self): self.helpWindow('Control') def helpWindowDoc(self, doc): if self.help is not None: self.help.close() self.help = Q7Help(self, doc=doc) self.help.show() def helpWindow(self, key): if self.help is not None: self.help.close() self.help = Q7Help(self, key) self.help.show() def info(self): self.updateLastView() if self.lastView is not None: (f, v, d) = Q7FingerPrint.infoView(self.lastView) if not f.isFile(): return self.w = Q7Info(self, d, f) self.w.show() def closeTree(self): self.updateLastView() if self.lastView is None: return (f, v, d) = Q7FingerPrint.infoView(self.lastView) reply = MSG.wQuestion( self, 101, 'Double check...', """Do you want to close the tree and all its views,<br> and <b>forget unsaved</b> modifications?""") if reply: f.closeAllViews() def closeAllTrees(self): reply = MSG.wQuestion( self, 101, 'Double check...', """Do you want to close all the views,<br> and <b>forget unsaved</b> modifications?""") if reply: Q7FingerPrint.closeAllTrees() def updateLastView(self): it = self.controlTable.currentItem() if it is None: self.lastView = None else: r = it.row() self.lastView = self.getIdxFromLine(r) return self.lastView def updateMenu(self, idx): lv = self.getIdxFromLine(idx.row()) if lv is not None: self.lastView = lv actlist = (("View information (Enter)", self.info), ("Raise selected view (Space)", self.raiseView), None, ("Close all trees", self.closeAllTrees), ("Close selected tree", self.closeTree), ("Close selected view (Del)", self.closeView)) self.popupmenu.clear() self.popupmenu.setTitle('Control view menu') for aparam in actlist: if aparam is None: self.popupmenu.addSeparator() else: a = QAction(aparam[0], self) a.triggered.connect(aparam[1]) self.popupmenu.addAction(a) def loadOptions(self): if self.wOption is None: self.wOption = Q7Option(self) self.wOption.reset() def option(self): if self.wOption is None: self.wOption = Q7Option(self) self.wOption.show() def about(self): MSG.wInfo(self, 100, "pyCGNS v%s" % OCTXT._ToolVersion, OCTXT._CopyrightNotice % self.versions, again=False) def closeApplication(self): reply = MSG.wQuestion( self, 101, 'Double check...', """Do you want to quit %s,<b>close all views</b> and forget unsaved modifications?""" % OCTXT._ToolName) if reply == MSG.OK: Q7FingerPrint.closeAllTrees() if self.help is not None: self.help.close() if self._patternwindow is not None: self._patternwindow.close() if self.control_log is not None: self.control_log.close() if self._toolswindow is not None: self._toolswindow.close() return True else: return False def closeEvent(self, event): if self.closeApplication(): event.accept() # return True else: event.ignore() # return False def resetScrolls(self): self.controlTable.verticalScrollBar().setSliderPosition(0) self.controlTable.horizontalScrollBar().setSliderPosition(0) def initControlTable(self): ctw = self.controlTable ctw.control = self cth = ctw.horizontalHeader() ctw.verticalHeader().hide() h = ['S', 'T', 'View', 'Dir', 'File', 'Node'] for i in range(len(h)): hi = QTableWidgetItem(h[i]) hi.setFont(OCTXT._Label_Font) ctw.setHorizontalHeaderItem(i, hi) cth.setSectionResizeMode(i, QHeaderView.ResizeToContents) cth.setSectionResizeMode(len(h) - 1, QHeaderView.Stretch) def updateViews(self): for i in self.getAllIdx(): f = Q7FingerPrint.getFingerPrint(i) v = Q7FingerPrint.getView(i) l = self.getLineFromIdx(i) self.modifiedLine(l, f._status, f) try: v.updateTreeStatus() except AttributeError: pass def modifiedLine(self, n, stat, fg): if ((Q7FingerPrint.STATUS_MODIFIED in stat) and (Q7FingerPrint.STATUS_SAVEABLE in stat)): stitem = QTableWidgetItem(self.IC(QW.I_MOD_SAV), '') stitem.setToolTip('Tree modified and saveable') if ((Q7FingerPrint.STATUS_MODIFIED in stat) and (Q7FingerPrint.STATUS_SAVEABLE not in stat)): stitem = QTableWidgetItem(self.IC(QW.I_MOD_USAV), '') stitem.setToolTip('Tree modified but NOT saveable') if ((Q7FingerPrint.STATUS_MODIFIED not in stat) and (Q7FingerPrint.STATUS_SAVEABLE not in stat)): stitem = QTableWidgetItem(self.IC(QW.I_UMOD_USAV), '') stitem.setToolTip('Tree unmodified and NOT saveable') if ((Q7FingerPrint.STATUS_MODIFIED not in stat) and (Q7FingerPrint.STATUS_SAVEABLE in stat)): stitem = QTableWidgetItem(self.IC(QW.I_UMOD_SAV), '') stitem.setToolTip('Tree unmodified and saveable') stitem.setTextAlignment(Qt.AlignCenter) self.controlTable.setItem(n, 0, stitem) self.controlTable.item(n, 3).setText(str(fg.filedir)) self.controlTable.item(n, 4).setText(str(fg.filename)) def addLine(self, l, fg): ctw = self.controlTable ctw.setRowCount(ctw.rowCount() + 1) r = ctw.rowCount() - 1 if l[1] == QW.VIEW_TREE: tpitem = QTableWidgetItem(self.IC(QW.I_TREE), '') if l[1] == QW.VIEW_FORM: tpitem = QTableWidgetItem(self.IC(QW.I_FORM), '') if l[1] == QW.VIEW_VTK: tpitem = QTableWidgetItem(self.IC(QW.I_VTK), '') if l[1] == QW.VIEW_QUERY: tpitem = QTableWidgetItem(self.IC(QW.I_QUERY), '') if l[1] == QW.VIEW_SELECT: tpitem = QTableWidgetItem(self.IC(QW.I_SELECT), '') if l[1] == QW.VIEW_DIAG: tpitem = QTableWidgetItem(self.IC(QW.I_DIAG), '') if l[1] == QW.VIEW_TOOLS: tpitem = QTableWidgetItem(self.IC(QW.I_TOOLS), '') l = l[0:2] + [None, None, None] if l[1] == QW.VIEW_LINK: tpitem = QTableWidgetItem(self.IC(QW.I_LINK), '') if l[1] == QW.VIEW_DIFF: tpitem = QTableWidgetItem(self.IC(QW.I_DIFF), '') tpitem.setTextAlignment(Qt.AlignCenter) ctw.setItem(r, 1, tpitem) for i in range(len(l) - 2): it = QTableWidgetItem('%s ' % (l[i + 2])) if i in [0]: it.setTextAlignment(Qt.AlignCenter) else: it.setTextAlignment(Qt.AlignLeft) it.setFont(OCTXT._Table_Font) ctw.setItem(r, i + 2, it) self.modifiedLine(r, l[0], fg) ctw.setColumnWidth(0, 25) ctw.setColumnWidth(1, 25) ctw.setColumnWidth(2, 50) for i in range(self.controlTable.rowCount()): ctw.resizeRowToContents(i) def selectLine(self, idx): i = int(self.getLineFromIdx(idx)) if i != -1: self.controlTable.setCurrentCell(i, 2) def delLine(self, idx): i = int(self.getLineFromIdx(idx)) if i != -1: self.controlTable.removeRow(i) def getIdxFromLine(self, l): self.controlTable.setCurrentCell(l, 2) it = self.controlTable.currentItem() return it.text() def getLineFromIdx(self, idx): found = -1 for n in range(self.controlTable.rowCount()): if int(idx) == int(self.controlTable.item(n, 2).text()): found = n return found def getAllIdx(self): all = [] for n in range(self.controlTable.rowCount()): all.append(self.controlTable.item(n, 2).text()) return all def clearOtherSelections(self): if self._patternwindow is not None: self._patternwindow.clearSelection() def cancelUnlock(self, *args): self.lockView(False) def loadStart(self, *args): self._T('loading: [%s]' % self.signals.buffer) self.busyCursor() Q7FingerPrint.treeLoad(self, self.signals.buffer) Q7FingerPrint.refreshScreen() def setDefaults(self): self.loadOptions() self._application.setStyleSheet(self.wOption._options['UserCSS']) def loadCompleted(self, *args, **kwargs): self.lockView(False) if 'dataset_name' in kwargs: filedir = kwargs['dataset_base'] filename = kwargs['dataset_name'] tree = kwargs['dataset_tree'] links = kwargs['dataset_references'] paths = kwargs['dataset_paths'] fgprint = Q7FingerPrint(self, filedir, filename, tree, links, paths, **kwargs) else: fgprint = self.signals.fgprint if len(fgprint) > 1: code = fgprint[1][0] msg0 = fgprint[1][1] msg1 = fgprint[1][2] MSG.wError(self, code, msg0, msg1) elif fgprint.tree is None: MSG.wError(self, 201, 'Load error', 'Fatal error while loading file, empty tree') else: child = self.loadQ7Tree(fgprint) child.show() self.setHistory(fgprint.filedir, fgprint.filename) self.updateViews() fgprint.getInfo(force=True) self.signals.fgprint = None Q7FingerPrint.killProxy() self.readyCursor() def saving(self, *args): self._T('saving as: [%s]' % self.signals.buffer) self.busyCursor() Q7FingerPrint.treeSave(self, self.signals.fgprint, self.signals.buffer, self.signals.saveAs) self.setHistory(self.signals.fgprint.filedir, self.signals.fgprint.filename) self.updateViews() self.signals.fgprint.getInfo(force=True) self.readyCursor() self.lockView(False) def load(self): self.fdialog = Q7File(self) self.lockView(True) self.fdialog.show() def loadlast(self): if self.getLastFile() is None: return self.signals.buffer = self.getLastFile()[0] + '/' + self.getLastFile( )[1] if self.signals.buffer is None: self.load() else: self.signals.loadFile.emit() def loadfile(self, name): self.signals.buffer = name self.signals.loadFile.emit() def save(self, fgprint): self.signals.fgprint = fgprint self.signals.saveAs = True self.fdialog = Q7File(self, 1) self.lockView(True) self.fdialog.show() def savedirect(self, fgprint): self.signals.fgprint = fgprint self.signals.saveAs = False self.signals.buffer = fgprint.filedir + '/' + fgprint.filename self.signals.saveFile.emit() def edit(self): self._T('edit new') tree = CGL.newCGNSTree() tc = self.newtreecount self.busyCursor() fgprint = Q7FingerPrint(self, '.', 'new#%.3d.hdf' % tc, tree, [], []) child = self.loadQ7Tree(fgprint) fgprint._status = [Q7FingerPrint.STATUS_MODIFIED] self.readyCursor() self.newtreecount += 1 child.show() def userFunctionFromPath(self, path, types): return Q7Query._userFunction def loadQ7Tree(self, fgprint): from CGNS.NAV.wtree import Q7Tree from CGNS.NAV.mtree import Q7TreeModel Q7TreeModel(fgprint.index) return Q7Tree(self, '/', fgprint.index)
class Q7Merge(Q7Window, Ui_Q7MergeWindow): def __init__(self, control, fgprint, diag): Q7Window.__init__(self, Q7Window.VIEW_DIFF, control, None, fgprint) self._depthExpanded = 0 self._lastEntered = None self._fgprint = fgprint (ldiag, lmerge) = self.diagAnalysis(diag) self.treeview.expanded[QModelIndex].connect(self.expandNode) self.treeview.collapsed.connect(self.collapseNode) self.treeview.clicked[QModelIndex].connect(self.clickedNode) self.treeview.customContextMenuRequested[QPoint].connect( self.clickedNode) # QObject.connect(self.treeview, # SIGNAL("expanded(QModelIndex)"), # self.expandNode) # QObject.connect(self.treeview, # SIGNAL("collapsed()"), # self.collapseNode) # QObject.connect(self.treeview, # SIGNAL("clicked(QModelIndex)"), # self.clickedNode) # QObject.connect(self.treeview, # SIGNAL("customContextMenuRequested(QPoint)"), # self.clickedNode) self.bClose.clicked.connect(self.leave) self.bInfo.clicked.connect(self.infoTreeView) self.bZoomIn.clicked.connect(self.expandLevel) self.bZoomOut.clicked.connect(self.collapseLevel) self.bZoomAll.clicked.connect(self.expandMinMax) self.bSaveDiff.clicked.connect(self.savediff) self.bSelectA.clicked.connect(self.showSelected) self.bSelectB.clicked.connect(self.showSelected) self.bSelectOrderSwap.clicked.connect(self.swapSelected) self.setContextMenuPolicy(Qt.CustomContextMenu) self.popupmenu = QMenu() self.proxyA = self._fgprint.model self.treeview.setModel(self.proxyA) self.treeview.setItemDelegate( Q7MergeItemDelegate(self.treeview, self._fgprint.model, ldiag, lmerge)) self.treeview.setControlWindow(self, self._fgprint.model) self.treeview.hideColumn(NMT.COLUMN_FLAG_LINK) self.treeview.hideColumn(NMT.COLUMN_FLAG_CHECK) self.treeview.hideColumn(NMT.COLUMN_FLAG_SELECT) self._fgprint.model.addA = True self._fgprint.model.addB = True self._A = QIcon(QPixmap(":/images/icons/user-A.png")) self._B = QIcon(QPixmap(":/images/icons/user-B.png")) self._order = 0 # A first def swapSelected(self): if not self._order: self.bSelectA.setIcon(self._B) self.bSelectB.setIcon(self._A) self._order = 1 else: self.bSelectA.setIcon(self._A) self.bSelectB.setIcon(self._B) self._order = 0 def showSelected(self): self._fgprint.model.addA = False self._fgprint.model.addB = False if self.bSelectA.isChecked(): self._fgprint.model.addA = True if self.bSelectB.isChecked(): self._fgprint.model.addB = True def diagAnalysis(self, diag): ldiag = {} lmerge = {} for k in diag: ldiag[k] = DIFF_NX for d in diag[k]: if d[0] == 'NA': ldiag[d[1]] = DIFF_NA lmerge[d[1]] = MERGE_NB if d[0] == 'ND': ldiag[d[1]] = DIFF_ND lmerge[d[1]] = MERGE_NA if d[0] in ['CT']: ldiag[k] = DIFF_CT lmerge[k] = MERGE_NA if d[0] in ['C3', 'C1', 'C2']: ldiag[k] = DIFF_CQ lmerge[k] = MERGE_NA if d[0] in ['C6', 'C7']: ldiag[k] = DIFF_CV lmerge[k] = MERGE_NA if d[0] in ['C4', 'C5']: ldiag[k] = DIFF_CS lmerge[k] = MERGE_NA return (ldiag, lmerge) def model(self): return self._fgprint.model def modelIndex(self, idx): if not idx.isValid(): return -1 midx = idx # if (idx.model() != self.treeview.M()): # midx=self.treeview.model().mapToSource(idx) return midx def modelData(self, idx): if not idx.isValid(): return None return self.modelIndex(idx).internalPointer() def infoTreeView(self): self._control.helpWindow('Tree') def savediff(self): pass def expandMinMax(self): if self._depthExpanded == self._fgprint.depth - 2: self._depthExpanded = -1 self.treeview.collapseAll() else: self._depthExpanded = self._fgprint.depth - 2 self.treeview.expandAll() self.resizeAll() def expandLevel(self): if self._depthExpanded < self._fgprint.depth - 2: self._depthExpanded += 1 self.treeview.expandToDepth(self._depthExpanded) self.resizeAll() def collapseLevel(self): if self._depthExpanded != -1: self._depthExpanded -= 1 if self._depthExpanded == -1: self.treeview.collapseAll() else: self.treeview.expandToDepth(self._depthExpanded) self.resizeAll() def updateStatus(self, node): return self.lineEdit.clear() self.lineEdit.insert(node.sidsPath()) def updateMenu(self, nodeidxs): return nodeidx = self.modelIndex(nodeidxs) if not nodeidx.isValid: return False if nodeidx.internalPointer() is None: return False if nodeidx.internalPointer().sidsPath() == '/CGNSTree': return False self.setLastEntered(nodeidxs) if nodeidx != -1: node = nodeidx.internalPointer() lknode = not node.sidsIsLink() lznode = node.hasLazyLoad() actlist = ( ("About %s" % node.sidsType(), self.aboutSIDS, None, False), None, ("Mark/unmark node", self.marknode, 'Space', False), ("Add new child node", self.newnodechild, 'Ctrl+A', False), ("Add new brother node", self.newnodebrother, 'Ctrl+Z', False), None, ("Open form", self.popform, 'Ctrl+F', False), ("Open view", self.openSubTree, 'Ctrl+W', False), ("Open view on linked-to file", self.openLkTree, 'Ctrl+O', lknode), None, ("Load node data in memory", self.dataLoad, 'Ctrl+L', not lznode), ("Release memory node data", self.dataRelease, 'Ctrl+R', lznode), None, ("Copy", self.mcopy, 'Ctrl+C', False), ("Cut", self.mcut, 'Ctrl+X', False), ("Paste as brother", self.mpasteasbrother, 'Ctrl+V', False), ("Paste as child", self.mpasteaschild, 'Ctrl+Y', False), None, ("Cut all selected", self.mcutselected, 'Ctrl+Shift+X', False), ("Paste as brother for each selected", self.mpasteasbrotherselected, 'Ctrl+Shift+V', False), ("Paste as child for each selected", self.mpasteaschildselected, 'Ctrl+Shift+Y', False), ("Load nodes data in memory for each selected", self.dataLoadSelected, 'Ctrl+Shift+L', False), ("Release memory node data for each selected", self.dataReleaseSelected, 'Ctrl+Shift+R', False), ) self.popupmenu.clear() self.popupmenu.setTitle('Node menu') for aparam in actlist: if aparam is None: self.popupmenu.addSeparator() else: a = QAction(aparam[0], self) a.triggered.connect(aparam[1]) if aparam[2] is not None: a.setShortcut(aparam[2]) self.popupmenu.addAction(a) a.setDisabled(aparam[3]) return True def setLastEntered(self, nix=None): self._lastEntered = None def getLastEntered(self): return self._lastEntered def clearLastEntered(self): self._lastEntered = None self.treeview.selectionModel().clearSelection() return None def clickedNode(self, index): pass def expandNode(self, *args): self.resizeAll() def collapseNode(self, *args): pass def resizeAll(self): for n in range(NMT.COLUMN_LAST + 1): self.treeview.resizeColumnToContents(n) def show(self): super(Q7Merge, self).show() def closeAlone(self): pass def leave(self): self.close()
class PreviewTable(QTableView): """Import wizard preview widget""" def __init__(self, parent): QTableView.__init__(self, parent) self._model = None # Setting up actions self.date_dayfirst_action = create_action(self, "dayfirst", triggered=ft_partial(self.parse_to_type, atype="date", dayfirst=True)) self.date_monthfirst_action = create_action(self, "monthfirst", triggered=ft_partial(self.parse_to_type, atype="date", dayfirst=False)) self.perc_action = create_action(self, "perc", triggered=ft_partial(self.parse_to_type, atype="perc")) self.acc_action = create_action(self, "account", triggered=ft_partial(self.parse_to_type, atype="account")) self.str_action = create_action(self, "unicode", triggered=ft_partial(self.parse_to_type, atype="unicode")) self.int_action = create_action(self, "int", triggered=ft_partial(self.parse_to_type, atype="int")) self.float_action = create_action(self, "float", triggered=ft_partial(self.parse_to_type, atype="float")) # Setting up menus self.date_menu = QMenu() self.date_menu.setTitle("Date") add_actions( self.date_menu, (self.date_dayfirst_action, self.date_monthfirst_action)) self.parse_menu = QMenu(self) self.parse_menu.addMenu(self.date_menu) add_actions( self.parse_menu, (self.perc_action, self.acc_action)) self.parse_menu.setTitle("String to") self.opt_menu = QMenu(self) self.opt_menu.addMenu(self.parse_menu) add_actions( self.opt_menu, (self.str_action, self.int_action, self.float_action)) def _shape_text(self, text, colsep=u"\t", rowsep=u"\n", transpose=False, skiprows=0, comments='#'): """Decode the shape of the given text""" assert colsep != rowsep out = [] text_rows = text.split(rowsep)[skiprows:] for row in text_rows: stripped = to_text_string(row).strip() if len(stripped) == 0 or stripped.startswith(comments): continue line = to_text_string(row).split(colsep) line = [try_to_parse(to_text_string(x)) for x in line] out.append(line) # Replace missing elements with np.nan's or None's if programs.is_module_installed('numpy'): from numpy import nan out = list(zip_longest(*out, fillvalue=nan)) else: out = list(zip_longest(*out, fillvalue=None)) # Tranpose the last result to get the expected one out = [[r[col] for r in out] for col in range(len(out[0]))] if transpose: return [[r[col] for r in out] for col in range(len(out[0]))] return out def get_data(self): """Return model data""" if self._model is None: return None return self._model.get_data() def process_data(self, text, colsep=u"\t", rowsep=u"\n", transpose=False, skiprows=0, comments='#'): """Put data into table model""" data = self._shape_text(text, colsep, rowsep, transpose, skiprows, comments) self._model = PreviewTableModel(data) self.setModel(self._model) @Slot() def parse_to_type(self,**kwargs): """Parse to a given type""" indexes = self.selectedIndexes() if not indexes: return for index in indexes: self.model().parse_data_type(index, **kwargs) def contextMenuEvent(self, event): """Reimplement Qt method""" self.opt_menu.popup(event.globalPos()) event.accept()
class PgImageViewROI(pg.ImageView): """ImageView 에 Mouse 명령을 추가 한다.""" def __init__(self, *args, **kwargs): """PgImageViewOk를 초기화한다.""" super().__init__(*args, **kwargs) self.font_family: str = "Courier New" self.font_size: str = "4" self.value_color: str = "#0581FF" self.scale_x: float = 1.0 self.scale_y: float = 1.0 self.ratio_of_rect_size_to_pixel = 0.93 self.axis_x: ndarray = array([]) self.axis_y: ndarray = array([]) self.ui.roiBtn.hide() self.ui.menuBtn.hide() # menu creation is deferred because it is expensive and often # the user will never see the menu anyway. self.menu = None self.view.mouseClickEvent = self.rightClickEvent def set_scale(self, scale_x: float, scale_y: float): """Set scale.""" self.scale_x = scale_x self.scale_y = scale_y def set_axis(self, axis_x: ndarray, axis_y: ndarray): """Set axis.""" self.axis_x = axis_x self.axis_y = axis_y def size_of_roi(self): r"""그림의 Pixel을 1로 계산 했을 때 화면에 그릴 Data Marker(ROI)의 크기를 계산한다.""" size_x = (1 - 2 * self.ratio_of_rect_size_to_pixel) * self.scale_x size_y = (1 - 2 * self.ratio_of_rect_size_to_pixel) * self.scale_y return pg.Point(size_x, size_y) def pos_of_roi(self, data_point_x: int, data_point_y: int): r"""그림의 Pixel을 1로 계산 했을 때 화면에 그릴 Data Marker(ROI)의 크기를 계산한다.""" x = (data_point_x + self.ratio_of_rect_size_to_pixel) * self.scale_x y = (data_point_y + self.ratio_of_rect_size_to_pixel) * self.scale_y return x, y def html_of_data_marker_name(self, string): r"""Data Marker의 Text에 항목을 HTML로 변환하여 반환한다.""" return f'<font size="{self.font_size}"; color="black">{string} </font>' def html_of_data_marker_value(self, string): r"""Data Marker의 Text에 값을 HTML로 변환하여 반환한다.""" return (f'<strong><font size="{self.font_size}"; color=#0581FF>' f"{string}</font></strong>") @staticmethod def contrast_color(rgb_hex: str): r"""배경색에서 잘보이는 색을 선택.""" rgb_in = array((int(rgb_hex[4:6], 16), int(rgb_hex[6:8], 16), int(rgb_hex[8:], 16))) rgb_out = array([0, 0, 0]) rgb_std = rgb_in.std() rgb_min = rgb_in.min() rgb_min_idx = argmin(rgb_in) if rgb_min < 180: rgb_out[rgb_min_idx] = 230 elif rgb_std < 20: rgb_out[0] = 230 return rgb_out[0], rgb_out[1], rgb_out[2] def keyPressEvent(self, ev): """Shift+S를 누르면 mouse Mode를 변경한다.""" key = ev.key() shift_pressed = ev.modifiers() & Qt.ShiftModifier if key == Qt.Key_S and shift_pressed: if self.view.vb.state["mouseMode"] == self.view.vb.RectMode: self.view.vb.setMouseMode(self.view.vb.PanMode) else: self.view.vb.setMouseMode(self.view.vb.RectMode) else: super().keyPressEvent(ev) def rightClickEvent(self, event): """Handle rightClick.""" if event.button() == Qt.RightButton: if self.raiseContextMenu(event): event.accept() def raiseContextMenu(self, ev): """Raise context menu.""" menu = self.getContextMenus() pos = ev.screenPos() menu.popup(QPoint(int(pos.x()), int(pos.y()))) return True def export_view_clicked(self): """Export view.""" self.scene.contextMenuItem = self.view self.scene.showExportDialog() def export_data_as_img_clicked(self): """Export data as image.""" filename = QFileDialog.getSaveFileName(self, "저장할 이미지 이름 선택", "", "PNG (*.png)") if isinstance(filename, tuple): filename = filename[0] # Qt4/5 API difference if filename == "": return if osp.splitext(filename)[1] != ".png": filename += ".png" self.export(filename) # This method will be called when this item's _children_ want to raise # a context menu that includes their parents' menus. def getContextMenus(self, event=None): """Get context menus. Args: event: DESCRIPTION. Defaults to None. """ if self.menu is None: self.menu = QMenu() self.menu.setTitle(self.name + " options..") view_all = QAction("View all", self.menu) view_all.triggered.connect(self.view_all) self.menu.addAction(view_all) self.menu.view_all = view_all toggle_aspect_mode = QAction("Locked aspect", self.menu, checkable=True) toggle_aspect_mode.triggered.connect(self.toggle_aspect_mode) toggle_aspect_mode.setChecked(True) self.menu.addAction(toggle_aspect_mode) self.menu.toggle_aspect_mode = toggle_aspect_mode toggle_click_mode = QAction( "Mouse panmode", self.menu, shortcut=QKeySequence("Shift+S"), checkable=True, ) toggle_click_mode.triggered.connect(self.toggle_mouse_mode) self.menu.addAction(toggle_click_mode) self.menu.toggle_mode = toggle_click_mode export_view = QAction("Export View", self.menu) export_view.setToolTip("Axis와 Marker를 포함한 화면을 캡쳐한다.") export_view.triggered.connect(self.export_view_clicked) self.menu.addAction(export_view) export_img = QAction("Export data as png", self.menu) export_img.setToolTip("Imagesc의 Data 원본을 Image 파일로 저장한다.") export_img.triggered.connect(self.export_data_as_img_clicked) self.menu.addAction(export_img) if self.view.vb.state["mouseMode"] == self.view.vb.PanMode: self.menu.toggle_mode.setChecked(True) else: self.menu.toggle_mode.setChecked(False) return self.menu def func_shift_left_click(self, event): """Shift를 누르고 마우스 왼쪽을 클릭하면 Data Marker를 표시한다. Args: event: Event. """ modifiers = QApplication.keyboardModifiers() if event.button() == Qt.LeftButton and modifiers == Qt.ShiftModifier: pos = event.scenePos() data_point = self.getImageItem().mapFromScene(pos) data_point_x = int(data_point.x()) data_point_y = int(data_point.y()) # view_rect = self.getImageItem().viewRect() # text_size = self.size_text(view_rect.width(), view_rect.height()) if self.image.ndim > 2: val_point = f"{self.image[data_point_y, data_point_x, :]}" else: val_point = f"{self.image[data_point_y, data_point_x]}" rgb_hex = hex(self.getImageItem().getPixmap().toImage().pixel( data_point_x, data_point_y)) rgb = (f"[{int(rgb_hex[4:6], 16)} {int(rgb_hex[6:8], 16)}" f" {int(rgb_hex[8:], 16)}]") roi = pg.ROI( pos=self.pos_of_roi(data_point_x, data_point_y), pen=self.contrast_color(rgb_hex), size=self.size_of_roi(), movable=False, removable=True, ) roi.setPen(color=self.contrast_color(rgb_hex), width=4.5) roi.setAcceptedMouseButtons(Qt.LeftButton) text = PgTextItem( html=(f'<span style="font-family: {self.font_family};">' + self.html_of_data_marker_name("PIXEL[X,Y]") + self.html_of_data_marker_value( f"[{data_point_x} {data_point_y}]") + "<br>" + self.html_of_data_marker_name("AXIS [X,Y]") + self.html_of_data_marker_value( f"[{self.axis_x[data_point_x]:6g}" f" {self.axis_y[data_point_y]:6g}]") + "<br>" + self.html_of_data_marker_name("Value") + self.html_of_data_marker_value(val_point) + "<br>" + self.html_of_data_marker_name("[R,G,B]") + self.html_of_data_marker_value(rgb) + "</span>"), border={ "color": "000000", "width": 1 }, anchor=(0, 1), fill=(250, 250, 255, 255), ) text.sig_change_font_size.connect(self.change_roi_font_size) text.setParentItem(roi) roi.sigClicked.connect(self.roi_click) roi.sigRemoveRequested.connect(self.roi_remove) self.addItem(roi) event.accept() else: event.ignore() def roi_remove(self, roi): """ROI를 제거한다.""" self.removeItem(roi) def roi_click(self, roi, event): """클릭된 ROI를 앞에 표시한다.""" for item in self.view.items: if isinstance(item, pg.ROI): item.setZValue(0) roi.setZValue(1) @Slot(int) def change_roi_font_size(self, font_size: int): """모든 ROI의 PgTextItem 글씨 크기를 변경한다.""" for roi in self.view.items: if isinstance(roi, pg.ROI) is False: continue for text_item in roi.allChildItems(): if isinstance(text_item, PgTextItem): font = text_item.textItem.font() font.setPointSize(font_size) text_item.setFont(font) def view_all(self): """이미지를 전체 뷰로 본다.""" self.view.autoRange() def mouseDoubleClickEvent(self, ev): """Double 클릭 시 이미지를 전체 뷰로 본다.""" self.view.autoRange() def toggle_mouse_mode(self): """Mouse 왼쪽 클릭 모드를 전환한다.""" if self.view.vb.state["mouseMode"] == self.view.vb.RectMode: self.view.vb.setMouseMode(self.view.vb.PanMode) else: self.view.vb.setMouseMode(self.view.vb.RectMode) def toggle_aspect_mode(self): """Toggle aspect mode.""" if self.view.vb.state["aspectLocked"] is False: self.view.vb.setAspectLocked(True) else: self.view.vb.setAspectLocked(False) def set_limit_view(self, x_axis, y_axis): """Panning과 Scale의 한계를 지정한다.""" x_range = max(x_axis) - min(x_axis) y_range = max(y_axis) - min(y_axis) max_range = max([x_range, y_range]) self.view.vb.setLimits( xMin=min(x_axis) - max_range, xMax=max(x_axis) + max_range, yMin=min(y_axis) - max_range, yMax=max(y_axis) + max_range, )
class PayloadWindow(FramelessWindow): get_build_options = Signal() start_build = Signal(str, str, list) stop_build = Signal() def __init__(self, parent): super(PayloadWindow, self).__init__(parent) self.logger = logging.getLogger(self.__class__.__name__) self.setContentsMargins(11, 11, 11, 11) self.progress_windows = [] self.content_widget = QWidget(self) self.addContentWidget(self.content_widget) self.widget_layout = QFormLayout(self.content_widget) self.content_widget.setLayout(self.widget_layout) self.spinner = WaitingSpinner(self, modality=Qt.WindowModal, roundness=70.0, fade=70.0, radius=15.0, lines=6, line_length=25.0, line_width=4.0, speed=1.0) self.build_name_label = QLabel("Name", self.content_widget) self.build_name_edit = QLineEdit(self.content_widget) self.widget_layout.addRow(self.build_name_label, self.build_name_edit) self.icon_label = QLabel("Icon", self.content_widget) self.icon_combobox = QComboBox(self.content_widget) self.widget_layout.addRow(self.icon_label, self.icon_combobox) self.generators_label = QLabel("Generators", self.content_widget) self.generators_list = QListWidget(self.content_widget) self.widget_layout.addRow(self.generators_label, self.generators_list) self.build_button = QPushButton("Build", self.content_widget) self.build_button.clicked.connect(self.on_build_button_clicked) self.widget_layout.addWidget(self.build_button) self.menu = QMenu(self) self.menu.setTitle("Payload") self.reload_action = QAction(self.menu) self.reload_action.setText("Reload options") self.reload_action.triggered.connect(self.setupUi) self.menu.addAction(self.reload_action) self.addMenu(self.menu) @Slot() def setupUi(self): self.spinner.start() self.get_build_options.emit() @Slot(dict) def process_build_message(self, message): if self.isVisible(): event = message.get("event") if event == "options": options = message.get("options") self.set_options(options.get("generators"), options.get("icons")) elif event == "started": self.set_started(message.get("generator_name")) elif event == "stopped": self.set_stopped() elif event == "progress": self.set_progress(message.get("generator_name"), message.get("progress")) elif event == "error": self.set_error(message.get("error")) elif event == "generator_finished": self.set_generator_finished(message.get("generator_name"), message.get("exit_code")) elif event == "build_finished": self.set_build_finished() @Slot(str, str) def set_progress(self, generator_name, progress): for win in self.progress_windows: if win.generator() == generator_name: win.appendProgress(progress) @Slot(str) def set_started(self, generator_name): win = ProgressWindow(self, generator_name) win.show() self.progress_windows.append(win) self.logger.info("Generator {} started!".format(generator_name)) self.reload_action.setEnabled(False) self.spinner.start() @Slot(str, int) def set_generator_finished(self, generator_name, exit_code): self.logger.info("Generator {} finished with exit code {}.".format( generator_name, exit_code)) @Slot(list, list) def set_options(self, generators, icons): self.build_name_edit.clear() self.generators_list.clear() self.icon_combobox.clear() for generator in generators: item = QListWidgetItem(generator, self.generators_list) item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsUserCheckable) item.setCheckState(Qt.Checked) self.generators_list.addItem(item) for icon in icons: name = icon.get("name") pix = QPixmap() pix.loadFromData(base64.b64decode(icon.get("ico"))) ico = QIcon() ico.addPixmap(pix) self.icon_combobox.addItem(ico, name) self.spinner.stop() @Slot() def set_stopped(self): self.on_build_finished() self.build_button.setText("Build") self.stopped_messagebox = FramelessInformationMessageBox(self) self.stopped_messagebox.setText( "Build process has been stopped successfully.") self.stopped_messagebox.setStandardButtons(QDialogButtonBox.Ok) self.stopped_messagebox.button(QDialogButtonBox.Ok).clicked.connect( self.stopped_messagebox.close) self.stopped_messagebox.show() @Slot(str) def set_error(self, error): self.on_build_finished() self.build_button.setText("Build") self.error_messagebox = FramelessCriticalMessageBox(self) self.error_messagebox.setText(error) self.error_messagebox.setStandardButtons(QDialogButtonBox.Ok) self.error_messagebox.button(QDialogButtonBox.Ok).clicked.connect( self.error_messagebox.close) self.error_messagebox.show() @Slot() def set_build_finished(self): self.on_build_finished() self.build_button.setText("Build") self.build_finished_messagebox = FramelessInformationMessageBox(self) self.build_finished_messagebox.setText( "Build process has been finished.") self.build_finished_messagebox.setStandardButtons(QDialogButtonBox.Ok) self.build_finished_messagebox.button( QDialogButtonBox.Ok).clicked.connect( self.build_finished_messagebox.close) self.build_finished_messagebox.show() @Slot() def on_build_button_clicked(self): if self.build_button.text() == "Build": generators = [] for i in range(self.generators_list.count()): item = self.generators_list.item(i) if item.checkState() == Qt.Checked: generators.append(item.text()) self.start_build.emit(self.build_name_edit.text(), self.icon_combobox.currentText(), generators) self.build_button.setText("Stop") else: self.stop_build_messagebox = FramelessQuestionMessageBox(self) self.stop_build_messagebox.setText( "Do you want to stop build process?") self.stop_build_messagebox.setStandardButtons( QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.stop_build_messagebox.button( QDialogButtonBox.Cancel).clicked.connect( self.stop_build_messagebox.close) self.stop_build_messagebox.button( QDialogButtonBox.Ok).clicked.connect(self.stop_build.emit) self.stop_build_messagebox.button( QDialogButtonBox.Ok).clicked.connect( self.stop_build_messagebox.close) self.stop_build_messagebox.show() @Slot() def on_build_finished(self): self.reload_action.setEnabled(True) self.spinner.stop() @Slot() def close(self) -> bool: for win in self.progress_windows: win.close() return super().close()
class UiLinelistsWindow(object): # this code was taken as-is from the Designer. # Cleaning it up sounds like a lower priority # task for now. def setupUi(self, MainWindow, title): MainWindow.setWindowTitle(title) MainWindow.setObjectName("MainWindow") MainWindow.resize(500, 500) MainWindow.setMinimumSize(QSize(300, 350)) self.centralWidget = QWidget(MainWindow) self.centralWidget.setObjectName("centralWidget") self.gridLayout = QGridLayout(self.centralWidget) self.gridLayout.setContentsMargins(11, 11, 11, 11) self.gridLayout.setSpacing(6) self.gridLayout.setObjectName("gridLayout") self.horizontalLayout_5 = QHBoxLayout() self.horizontalLayout_5.setContentsMargins(11, 11, 11, 11) self.horizontalLayout_5.setSpacing(6) self.horizontalLayout_5.setObjectName("horizontalLayout_5") self.lines_selected_label = QLabel(self.centralWidget) self.lines_selected_label.setObjectName("lines_selected_label") self.horizontalLayout_5.addWidget(self.lines_selected_label) self.label = QLabel(self.centralWidget) self.label.setObjectName("label") self.horizontalLayout_5.addWidget(self.label) self.draw_button = QPushButton(self.centralWidget) self.draw_button.setObjectName("draw_button") self.horizontalLayout_5.addWidget(self.draw_button) self.erase_button = QPushButton(self.centralWidget) self.erase_button.setObjectName("erase_button") self.horizontalLayout_5.addWidget(self.erase_button) self.dismiss_button = QPushButton(self.centralWidget) self.dismiss_button.setObjectName("dismiss_button") self.horizontalLayout_5.addWidget(self.dismiss_button) self.gridLayout.addLayout(self.horizontalLayout_5, 4, 0, 1, 1) self.verticalLayout_11 = QVBoxLayout() self.verticalLayout_11.setContentsMargins(11, 11, 11, 11) self.verticalLayout_11.setSpacing(6) self.verticalLayout_11.setObjectName("verticalLayout_11") self.tabWidget = QTabWidget(self.centralWidget) self.tabWidget.setObjectName("tabWidget") self.verticalLayout_11.addWidget(self.tabWidget) self.gridLayout.addLayout(self.verticalLayout_11, 0, 0, 1, 1) self.horizontalLayout_7 = QHBoxLayout() self.horizontalLayout_7.setContentsMargins(11, 11, 11, 11) self.horizontalLayout_7.setSpacing(6) self.horizontalLayout_7.setObjectName("horizontalLayout_7") self.add_set_button = QPushButton(self.centralWidget) self.add_set_button.setObjectName("add_set_button") self.horizontalLayout_7.addWidget(self.add_set_button) spacerItem = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout_7.addItem(spacerItem) self.gridLayout.addLayout(self.horizontalLayout_7, 2, 0, 2, 1) MainWindow.setCentralWidget(self.centralWidget) self.menuBar = QMenuBar(MainWindow) self.menuBar.setGeometry(QRect(0, 0, 767, 22)) self.menuBar.setObjectName("menuBar") self.menuFile = QMenu(self.menuBar) self.menuFile.setObjectName("menuFile") MainWindow.setMenuBar(self.menuBar) self.mainToolBar = QToolBar(MainWindow) self.mainToolBar.setMovable(False) self.mainToolBar.setFloatable(False) self.mainToolBar.setObjectName("mainToolBar") MainWindow.addToolBar(Qt.TopToolBarArea, self.mainToolBar) self.statusBar = QStatusBar(MainWindow) self.statusBar.setObjectName("statusBar") MainWindow.setStatusBar(self.statusBar) self.actionOpen = QAction(MainWindow) icon = QIcon() icon.addPixmap(QPixmap(":/img/Open Folder-48.png"), QIcon.Normal, QIcon.Off) self.actionOpen.setIcon(icon) self.actionOpen.setObjectName("actionOpen") self.actionExit = QAction(MainWindow) self.actionExit.setObjectName("actionExit") self.actionRemove = QAction(MainWindow) self.actionRemove.setObjectName("actionRemove") self.actionChange_Color = QAction(MainWindow) self.actionChange_Color.setObjectName("actionChange_Color") self.menuFile.addAction(self.actionOpen) self.menuFile.addSeparator() self.menuFile.addAction(self.actionExit) self.menuBar.addAction(self.menuFile.menuAction()) self.mainToolBar.addAction(self.actionOpen) self.mainToolBar.addSeparator() self.retranslateUi(MainWindow) QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): _translate = QCoreApplication.translate self.lines_selected_label.setText(_translate("MainWindow", "0")) self.label.setText(_translate("MainWindow", "lines selected")) self.draw_button.setText(_translate("MainWindow", "Draw")) self.erase_button.setText(_translate("MainWindow", "Erase")) self.dismiss_button.setText(_translate("MainWindow", "Dismiss")) self.add_set_button.setText(_translate("MainWindow", "Add set")) self.menuFile.setTitle(_translate("MainWindow", "File")) self.actionOpen.setText(_translate("MainWindow", "Open")) self.actionExit.setText(_translate("MainWindow", "Exit")) self.actionRemove.setText(_translate("MainWindow", "Remove")) self.actionRemove.setToolTip( _translate("MainWindow", "Removes the selected layer")) self.actionChange_Color.setText( _translate("MainWindow", "Change Color")) self.actionChange_Color.setToolTip( _translate("MainWindow", "Change the line color selected layer"))