def _ask_overwrite(self): msg = QDialog() msg.setWindowTitle('Load overwrite') layout = QGridLayout() layout.addWidget( QLabel('Instrument %s already exists in memory. Overwrite this?'), 0, 0, 1, -1) buttons = [ QPushButton(label) for label in ['Load and overwrite', 'Cancel Load', 'Load and rename to'] ] locations = [[1, 0], [1, 1], [2, 0]] self.overwrite_flag = 1 def overwriteCB(idx): self.overwrite_flag = idx msg.accept() for idx, button in enumerate(buttons): button.clicked.connect(lambda _, idx=idx: overwriteCB(idx)) layout.addWidget(button, locations[idx][0], locations[idx][1]) newname = QLineEdit() newname.editingFinished.connect(lambda: overwriteCB(2)) layout.addWidget(newname, 2, 1) msg.setLayout(layout) msg.exec_() newname = str(newname.text()) if not newname or newname in self.instruments: self.errormessage('Invalid instrument name. Cancelling load.') self.overwrite_flag = 1 return self.overwrite_flag, newname
def _ask_overwrite(self): msg = QDialog() msg.setWindowTitle('Load overwrite') layout = QGridLayout() layout.addWidget(QLabel('Instrument %s already exists in memory. Overwrite this?'), 0, 0, 1, -1) buttons = [QPushButton(label) for label in ['Load and overwrite', 'Cancel Load', 'Load and rename to']] locations = [[1, 0], [1, 1], [2, 0]] self.overwrite_flag = 1 def overwriteCB(idx): self.overwrite_flag = idx msg.accept() for idx, button in enumerate(buttons): button.clicked.connect(lambda _, idx=idx: overwriteCB(idx)) layout.addWidget(button, locations[idx][0], locations[idx][1]) newname = QLineEdit() newname.editingFinished.connect(lambda: overwriteCB(2)) layout.addWidget(newname, 2, 1) msg.setLayout(layout) msg.exec_() newname = str(newname.text()) if not newname or newname in self.instruments: self.errormessage('Invalid instrument name. Cancelling load.') self.overwrite_flag = 1 return self.overwrite_flag, newname
def on_edit_ports(self): from pmgwidgets import PMGPanel from qtpy.QtWidgets import QDialog, QVBoxLayout dlg = QDialog(self.base_rect.scene().flow_widget) sp = PMGPanel() p: 'CustomPort' = None input_ids, output_ids = [], [] input_texts, output_texts = [], [] self._last_var = 0 def new_id_input(): node_id = self.id max_val = 0 for p in self.input_ports: n, t, p = p.parse_id() if max_val < int(p): max_val = int(p) self._last_var += 1 return '%s:input:%d' % (node_id, max_val + self._last_var) def new_id_output(): node_id = self.id max_val = 0 for p in self.output_ports: n, t, p = p.parse_id() if max_val < int(p): max_val = int(p) self._last_var += 1 return '%s:output:%d' % (node_id, max_val + self._last_var) for p in self.input_ports: input_ids.append(p.id) input_texts.append(p.text) for p in self.output_ports: output_ids.append(p.id) output_texts.append(p.text) views = [] # views += self.content.get_settings_params() views += [ ('line_ctrl', 'text', 'Node Text', self.text), ] if self.content.ports_changable[0]: views.append(('list_ctrl', 'inputs', 'Set Inputs', [input_ids, input_texts], new_id_input)) if self.content.ports_changable[1]: views.append(('list_ctrl', 'outputs', 'Set Outputs', [output_ids, output_texts], new_id_output)) sp.set_items(views) dlg.setLayout(QVBoxLayout()) dlg.layout().addWidget(sp) dlg.exec_() dic = sp.get_value() self.change_ports_property(dic)
def on_value_show_requested(self): from qtpy.QtWidgets import QDialog, QVBoxLayout val_dlg = QDialog() val_dlg.setLayout(QVBoxLayout()) text_show = QTextEdit() text = 'inputs:\n' + repr( self.node.content.input_args) + '\n' + 'results:\n' + repr( self.node.content.results) text_show.setText(text) val_dlg.layout().addWidget(text_show) val_dlg.exec_()
def show_about_dialog(parent: QWidget = None) -> None: label = QLabel() label.setText("Digital pathology for local <i>in vivo</i> drug delivery.") layout = QHBoxLayout() layout.addWidget(label) dialog = QDialog(parent=parent) dialog.setWindowModality(Qt.ApplicationModal) dialog.setLayout(layout) dialog.setWindowTitle("About") dialog.exec_()
def ProxyDialog(self): def SetProxy(): self.use_proxy = bool(self.checkUseProxy.isChecked()) self.proxy_config = self.textProxyConfig.text() if os.environ['QT_API'] == 'pyqt': self.settings.setValue("use_proxy", self.use_proxy) self.settings.setValue("proxy_config", str(self.proxy_config)) elif os.environ['QT_API'] == 'pyqt5': self.settings.setValue("use_proxy", QtCore.QVariant(self.use_proxy)) self.settings.setValue("proxy_config", QtCore.QVariant(str(self.proxy_config))) d.done(0) d = QDialog() box = QVBoxLayout() hBox_proxy = QHBoxLayout() hBox_proxy.setSpacing(5) label = QLabel('Proxy') hBox_proxy.addWidget(label) self.textProxyConfig = QLineEdit() try: self.textProxyConfig.setText( self.settings.value('proxy_config', str)) except: self.textProxyConfig.setText(bombo.PROXY_DATA) self.textProxyConfig.setMinimumWidth(200) hBox_proxy.addWidget(self.textProxyConfig) box.addLayout(hBox_proxy) self.checkUseProxy = QCheckBox("Use proxy") try: self.checkUseProxy.setChecked( self.settings.value('use_proxy', bool)) except: self.checkUseProxy.setChecked(bool(bombo.USE_PROXY)) box.addWidget(self.checkUseProxy) button = QPushButton("Save configuration") button.clicked.connect(SetProxy) box.addWidget(button) d.setWindowTitle("Proxy configuration") d.setLayout(box) d.setWindowModality(QtCore.Qt.ApplicationModal) d.exec_()
def verify(): try: text = input_widget.document().toPlainText() l = eval(text) if isinstance(l, list): dialog2 = QDialog(dialog) sp2 = PMGPanel(parent=None, views=l) dialog2.setLayout(QHBoxLayout()) dialog2.layout().addWidget(sp2) dialog2.layout().addLayout(edit_layout) dialog2.exec_() except: import traceback traceback.print_exc()
def _build_waverange_dialog(self, wave_range, line_list): dialog = QDialog(parent=self.centralWidget) loadUi(os.path.join(os.path.dirname(__file__), "ui", "linelists_waverange.ui"), dialog) dialog.min_text.setText("%.2f" % wave_range[0].value) dialog.max_text.setText("%.2f" % wave_range[1].value) validator = QDoubleValidator() validator.setBottom(0.0) validator.setDecimals(2) dialog.min_text.setValidator(validator) dialog.max_text.setValidator(validator) dialog.nlines_label = self._compute_nlines_in_waverange(line_list, dialog.min_text, dialog.max_text, dialog.nlines_label) dialog.min_text.editingFinished.connect(lambda: self._compute_nlines_in_waverange(line_list, dialog.min_text, dialog.max_text, dialog.nlines_label)) dialog.max_text.editingFinished.connect(lambda: self._compute_nlines_in_waverange(line_list, dialog.min_text, dialog.max_text, dialog.nlines_label)) accepted = dialog.exec_() > 0 amin = amax = None if accepted: return self._get_range_from_textfields(dialog.min_text, dialog.max_text) return (amin, amax)
class AnswerWindow: def __init__(self, parent=None, numTab=5): self.w = QDialog() self.parent = parent self.tables = [] self.numTab = numTab self.initUI() def closeWindow(self): self.w.close() def show(self): self.setData() self.w.exec_() def setData(self, data=None): horHeaders = [u'条件', u'値'] condNames = [ u'線材種', u'回転方向', u'回転速度', u'送り速度', u'切り込み量', u'突き出し量', u'乗せ率', u'パス回数', u'摩耗量' ] for i in range(self.numTab): table = self.tables[i] table.setHorizontalHeaderLabels(horHeaders) for m in condNames: item = QTableWidgetItem(m) table.setItem(condNames.index(m), 0, item) def initUI(self): self.w.setWindowTitle(u'回答結果') vbox = QVBoxLayout() ansBtn = QPushButton(u"閉じる") ansBtn.clicked.connect(self.closeWindow) self.tabs = QTabWidget() for i in range(self.numTab): tab = QTableWidget() tab.setRowCount(9) # あとで9のところは変更してください。 tab.setColumnCount(2) self.tabs.addTab(tab, "第" + str(i + 1) + "候補") self.tables.append(tab) vbox.addWidget(self.tabs) vbox.addWidget(ansBtn) self.w.setLayout(vbox)
def _show_plugin_list(self, plugin_manager=None): """Show dialog with a table of installed plugins and metadata.""" if not plugin_manager: from ..plugins import plugin_manager dialog = QDialog(self._qt_window) dialog.setMaximumHeight(800) dialog.setMaximumWidth(1280) layout = QVBoxLayout() # maybe someday add a search bar here? title = QLabel("Installed Plugins") title.setObjectName("h2") layout.addWidget(title) # get metadata for successfully registered plugins plugin_manager.discover() data = plugin_manager.list_plugin_metadata() data = list(filter(lambda x: x['plugin_name'] != 'builtins', data)) # create a table for it dialog.table = QtDictTable( self._qt_window, data, headers=[ 'plugin_name', 'package', 'version', 'url', 'author', 'license', ], min_section_width=60, ) dialog.table.setObjectName("pluginTable") dialog.table.horizontalHeader().setObjectName("pluginTableHeader") dialog.table.verticalHeader().setObjectName("pluginTableHeader") dialog.table.setGridStyle(Qt.NoPen) # prevent editing of table dialog.table.setEditTriggers(QAbstractItemView.NoEditTriggers) layout.addWidget(dialog.table) dialog.setLayout(layout) dialog.setAttribute(Qt.WA_DeleteOnClose) self._plugin_list = dialog dialog.exec_()
def set_bounds(self): dialog = QDialog() loadUi(os.path.join(UI_PATH, "roi_bounds_dialog.ui"), dialog) dialog.min_line_edit.setText("{:g}".format(self.getRegion()[0])) dialog.max_line_edit.setText("{:g}".format(self.getRegion()[-1])) if dialog.exec_(): self.setRegion([ float(dialog.min_line_edit.text()), float(dialog.max_line_edit.text()) ])
def exec_(self, files, force_remove=False, heading='Delete the following files?', title='Delete Files?'): ui = self.ui enable = not force_remove ui.checkbox_res.setEnabled(enable) ui.checkbox_spx.setEnabled(enable) ui.checkbox_vtk.setEnabled(enable) ui.checkbox_monitor.setEnabled(True) ui.checkbox_other.setEnabled(enable) ui.label_heading.setText(heading) self.setWindowTitle(title) self.sort_files(files) return QDialog.exec_(self)
def _open_matrix_sel(self): wid = QDialog(self) wid.setObjectName(self._csorb.acc + 'App') wid.setLayout(QVBoxLayout()) cbbox = QComboBox(wid) cbbox.setEditable(True) cbbox.setMaxVisibleItems(10) corrnames = self._csorb.ch_names + self._csorb.cv_names if self._csorb.acc in {'SI', 'BO'}: corrnames.append('RF') cbbox.addItems(corrnames) wid.layout().addWidget(QLabel('Choose the corrector:', wid)) wid.layout().addWidget(cbbox) ledit = QDoubleSpinBoxPlus(wid) ledit.setMinimum(float('-inf')) ledit.setMaximum(float('inf')) ledit.setValue(1.0) wid.layout().addWidget(QLabel('Choose the Kick [urad]:', wid)) wid.layout().addWidget(ledit) ledit.valueChanged.connect(_part(self._accept_mat_sel, ledit, cbbox)) cbbox.currentIndexChanged.connect( _part(self._accept_mat_sel, ledit, cbbox)) hlay = QHBoxLayout() cancel = QPushButton('Cancel', wid) confirm = QPushButton('Ok', wid) cancel.clicked.connect(wid.reject) confirm.clicked.connect(wid.accept) confirm.clicked.connect(_part(self._accept_mat_sel, ledit, cbbox)) confirm.setDefault(True) hlay.addStretch() hlay.addWidget(cancel) hlay.addStretch() hlay.addWidget(confirm) hlay.addStretch() wid.layout().addItem(hlay) res = wid.exec_() if res != QDialog.Accepted: self._reset_orbit()
class PMGFilesTreeview(QTreeView): """ 文件树 """ open_signal = Signal(str) open_folder_signal = Signal(str) new_file_signal = Signal(str) new_folder_signal = Signal(str) delete_file_signal = Signal(str) rename_file_signal = Signal(str, str) signal_ext_filter_adapt = Signal(bool) signal_ext_filter_changed = Signal(dict) def __init__(self, initial_dir: str = '', parent=None): super().__init__(parent) self.initial_dir = initial_dir self.setup_ui() self.bind_events() self.filter_exts = True self.exts_to_filter = { 'Program Scripts': { '.pyx': True, '.py': True, '.c': True, '.pyi': True, '.dll': True, '.h': True, '.cpp': True, '.ipynb': True, '.sh': True, '.cmd': True, '.bat': True }, 'Documents': { '.txt': True, '.md': True, '.doc': True, '.docx': True, '.ppt': True, '.pptx': True, '.html': True }, 'Data Files': { '.csv': True, '.xls': True, '.xlsx': True, '.tab': True, '.dat': True, '.tsv': True, '.sav': True, '.zsav': True, '.sas7bdat': True, '.pkl': True, '.json': True, '.mat': True, '.pmjson': True, '.pmd': True }, 'Medias': { '.mp3': False, '.mp4': False, '.avi': False, '.wma': False, '.png': True, '.jpg': True, '.svg': True }, 'Resources': { '.qm': True, '.ts': True } } def setup_ui(self): """ 界面初始化 :return: """ self.translator = create_translator(path=os.path.join( os.path.dirname(__file__), 'translations', 'qt_{0}.qm'.format(QLocale.system().name()))) # translator self.setTabKeyNavigation(True) self.setDragEnabled(True) self.setDragDropOverwriteMode(True) self.setAlternatingRowColors(False) self.setUniformRowHeights(True) self.setSortingEnabled(True) self.setAnimated(True) self.setAllColumnsShowFocus(False) self.setWordWrap(False) self.setHeaderHidden(False) self.setObjectName("treeView_files") self.header().setSortIndicatorShown(True) self.model = PMFileSystemModel() self.model.setRootPath(self.initial_dir) self.setModel(self.model) self.setRootIndex(self.model.index(self.initial_dir)) self.setAnimated(False) self.setSortingEnabled(True) # 启用排序 self.header().setSortIndicatorShown(True) # 启用标题排序 self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.show_context_menu) self.init_context_menu() def bind_events(self): """ 回调、事件与信号初始化 :return: """ self.doubleClicked.connect(lambda index: self.on_open()) self.openAction.triggered.connect(self.on_open) self.importAction.triggered.connect(self.on_import) self.renameAction.triggered.connect(self.on_rename) self.deleteAction.triggered.connect(self.on_delete) self.copyAction.triggered.connect(self.on_copy) self.pasteAction.triggered.connect(self.on_paste) self.filterAction.triggered.connect( self.show_ext_filter_selection_dialog) self.copyPathAction.triggered.connect(self.copy_path) self.new_file_action.triggered.connect(lambda: self.on_new_file('')) self.new_python_file_action.triggered.connect( lambda: self.on_new_file('py')) self.new_folder_action.triggered.connect(self.on_new_folder) self.open_file_manager_action.triggered.connect( self.on_open_file_manager) self.rename_shortcut.activated.connect(self.on_rename) self.paste_shortcut.activated.connect(self.on_paste) self.copy_shortcut.activated.connect(self.on_copy) self.open_shortcut.activated.connect(self.on_open) self.delete_shortcut.activated.connect(self.on_delete) self.goto_parent_path_shortcut.activated.connect( self.slot_goto_parent_path) self.customContextMenuRequested.connect(self.show_context_menu) def init_context_menu(self): """ 初始化右键菜单 :return: """ self.contextMenu = QMenu(self) self.openAction = self.contextMenu.addAction(self.tr('Open')) self.importAction = self.contextMenu.addAction(self.tr('Import')) self.importAction.setEnabled(False) self.new_file_or_folder_menu = QMenu(self.tr('New..')) self.contextMenu.addMenu(self.new_file_or_folder_menu) self.new_file_action = self.new_file_or_folder_menu.addAction( self.tr('File..')) self.new_python_file_action = self.new_file_or_folder_menu.addAction( self.tr('Python File')) self.new_folder_action = self.new_file_or_folder_menu.addAction( self.tr('Folder')) self.new_file_or_folder_menu.addSeparator() self.copyAction = self.contextMenu.addAction(self.tr("Copy")) self.pasteAction = self.contextMenu.addAction(self.tr("Paste")) self.pasteAction.setEnabled(False) self.renameAction = self.contextMenu.addAction(self.tr('Rename')) self.deleteAction = self.contextMenu.addAction(self.tr('Delete')) self.filterAction = self.contextMenu.addAction(self.tr('Filter')) self.copyPathAction = self.contextMenu.addAction(self.tr('Copy Path')) self.open_file_manager_action = self.contextMenu.addAction( self.tr('Open Explorer')) self.renameAction.setShortcut(QKeySequence('F2')) self.copyAction.setShortcut(QKeySequence('Ctrl+C')) self.pasteAction.setShortcut(QKeySequence('Ctrl+V')) self.deleteAction.setShortcut(QKeySequence('Delete')) self.rename_shortcut = QShortcut(QKeySequence('F2'), self, context=Qt.WidgetShortcut) self.copy_shortcut = QShortcut(QKeySequence.Copy, self, context=Qt.WidgetShortcut) self.paste_shortcut = QShortcut(QKeySequence.Paste, self, context=Qt.WidgetShortcut) self.delete_shortcut = QShortcut(QKeySequence('Delete'), self, context=Qt.WidgetShortcut) self.open_shortcut = QShortcut(QKeySequence('Return'), self, context=Qt.WidgetShortcut) self.goto_parent_path_shortcut = QShortcut(QKeySequence('Backspace'), self, context=Qt.WidgetShortcut) def show_context_menu(self): """ 显示上下文右键菜单 :return: """ self.contextMenu.popup(QCursor.pos()) self.contextMenu.show() def get_current_file_path(self): """ 获取当前选中文件的路径。 如果当前没有选中的文件,就返回根路径。 :return: """ if len(self.selectedIndexes()) > 0: index = self.currentIndex() file_info = self.model.fileInfo(index) return file_info.absoluteFilePath() else: return self.get_root_path() def get_root_path(self): """ 获取根路径 :return: """ return self.model.rootPath() def set_item_focus(self, file_path: str): """ set item focus in TreeView :param file_path: File or Dir :return: """ self.setCurrentIndex(self.model.index(file_path)) def on_open_file_manager(self): path = self.get_current_file_path() print(path) if os.path.isdir(path): open_file_manager(path) else: open_file_manager(os.path.dirname(path)) # if os.path.exists(new_folder_path): # self.set_item_focus(new_folder_path) # 设置focus liugang 200923 # QMessageBox.critical(self, self.tr('Error'), # self.tr('Folder %s already exists!' % name)) # return # else: # os.mkdir(new_folder_path) # self.new_folder_signal[str].emit(new_folder_path) # self.set_item_focus(new_folder_path) # 设置focus liugang 200923 def on_new_folder(self): """ 新建文件夹时出发的回调 :return: """ path = self.get_current_file_path() name, stat = QInputDialog.getText(self, self.tr('Please Input folder name'), '', QLineEdit.Normal, '') if name.find('.') != -1: QMessageBox.critical(self, self.tr('Error'), self.tr('Folder name %s is illeagal!' % name)) return if stat: if os.path.isdir(path): new_folder_path = os.path.join(path, name) else: new_folder_path = os.path.join(os.path.dirname(path), name) if os.path.exists(new_folder_path): self.set_item_focus(new_folder_path) # 设置focus liugang 200923 QMessageBox.critical( self, self.tr('Error'), self.tr('Folder %s already exists!' % name)) return else: os.mkdir(new_folder_path) self.new_folder_signal[str].emit(new_folder_path) self.set_item_focus(new_folder_path) # 设置focus liugang 200923 def on_new_file(self, ext: str = ''): """ 新建文件时触发的回调 :return: """ path = self.get_current_file_path() dlg = InputFilenameDialog(parent=self, title=self.tr('Please input file name'), ext=ext) dlg.exec_() name = dlg.name_input.text() stat = dlg.status if stat: if os.path.isdir(path): new_file_path = os.path.join(path, name) else: new_file_path = os.path.join(os.path.dirname(path), name) if os.path.exists(new_file_path): self.set_item_focus(new_file_path) # 设置focus liugang 200923 QMessageBox.critical(self, self.tr('Error'), self.tr('File %s already exists!' % name)) return with open(new_file_path, 'wb') as f: f.close() self.new_file_signal[str].emit(new_file_path) self.set_item_focus(new_file_path) self.on_open() # 创建文件后打开 liugang 200923 def on_open(self): """ 点击‘open’时候触发的回调, 等效的方式还有双击以及按下回车键。 :return: """ path = self.get_current_file_path() if os.path.isdir(path): self.open_folder_signal.emit(path) else: self.open_signal[str].emit(path) def on_import(self): """ :return: """ pass def on_rename(self): """ 点击’重命名‘时候的回调。 :return: """ from pmgwidgets import rename_file path = self.get_current_file_path() basename = os.path.basename(path) dir_name = os.path.dirname(path) name, stat = QInputDialog.getText(self, self.tr('Please Input file name'), '', QLineEdit.Normal, basename) if stat: new_absolute_path = os.path.join(dir_name, name) rename_result = rename_file(path, new_absolute_path) if not rename_result: QMessageBox.critical(self, self.tr('Error'), self.tr('Unable to Rename this file.')) else: self.rename_file_signal[str, str].emit(path, new_absolute_path) def on_delete(self): """ 点击’删除‘时的回调 :return: """ from pmgwidgets import move_to_trash path = self.get_current_file_path() moved_successful = move_to_trash(path) if not moved_successful: QMessageBox.critical( self, self.tr('Error'), self.tr('Unable to Move this file to recycle bin.')) else: self.delete_file_signal[str].emit(path) def on_copy(self): """ copy file or dir , save path in pasteAction data. :return: """ path = self.get_current_file_path() self.pasteAction.setEnabled(True) self.pasteAction.setData(path) data = QMimeData() data.setUrls([QUrl.fromLocalFile(path)]) # 复制到系统剪贴板 clip = QApplication.clipboard() clip.setMimeData(data) def on_paste(self): """ Paste file or dir in pasteAction data :return: """ from pmgwidgets import copy_paste path = self.get_current_file_path() target_dir_name = path if os.path.isdir(path) else os.path.dirname( path) url: QUrl = None mimedata = QApplication.clipboard().mimeData(mode=QClipboard.Clipboard) print(mimedata) urls: List[QUrl] = mimedata.urls() for url in urls: source_path = url.toLocalFile() # self.pasteAction.data() # File if os.path.isfile(source_path): source_file_name = os.path.basename(source_path) # if exist ,rename to copy_xxx if os.path.isfile( os.path.join(target_dir_name, source_file_name)): target_file_name = "copy_{0}".format(source_file_name) else: target_file_name = source_file_name target_path = os.path.join(target_dir_name, target_file_name) # Directory else: last_dir_name = os.path.split(source_path)[-1] # if exist , rename dir copy_xxxx if os.path.isdir(os.path.join(target_dir_name, last_dir_name)): target_name = "copy_{0}".format(last_dir_name) else: target_name = last_dir_name target_path = os.path.join(target_dir_name, target_name) copy_succ = copy_paste(source_path, target_path) if not copy_succ: QMessageBox.critical(self, self.tr('Error'), self.tr('Copy File or Directory Error.')) else: self.set_item_focus(target_path) def show_ext_filter_selection_dialog(self): self.dlg = QDialog(self) self.dlg.setWindowTitle(self.tr('Extension Name To Show')) self.dlg.setLayout(QVBoxLayout()) self.dlg.layout().addWidget(QLabel('过滤文件名')) check_box = QCheckBox() self.dlg.check_box = check_box check_box.setChecked(self.filter_exts) self.dlg.layout().addWidget(check_box) check_box.stateChanged.connect( lambda stat: self.signal_ext_filter_adapt.emit(stat)) check_widget = PMCheckTree(data=self.exts_to_filter) self.dlg.check_widget = check_widget self.dlg.layout().addWidget(check_widget) buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) buttonBox.accepted.connect(self.on_ext_filter_changed) buttonBox.rejected.connect(self.dlg.deleteLater) # 清除选择功能不完善目前禁用 # button_clear = buttonBox.addButton(self.tr('Clear Filter'), QDialogButtonBox.ApplyRole) # button_clear.clicked.connect(self.clear_ext_filter) self.dlg.layout().addWidget(buttonBox) self.dlg.exec_() def on_ext_filter_changed(self): """ 当扩展名过滤改变的时候。 :return: """ self.exts_to_filter = self.dlg.check_widget.get_data() self.filter_exts = self.dlg.check_box.isChecked() self.update_ext_filter() self.dlg.deleteLater() self.signal_ext_filter_changed.emit(self.exts_to_filter) def clear_ext_filter(self): self.set_ext_filter(None) self.dlg.deleteLater() def update_ext_filter(self): """ 刷新扩展名过滤。 :return: """ ext_list = [] for key in self.exts_to_filter.keys(): for name in self.exts_to_filter[key].keys(): if self.exts_to_filter[key][name]: ext_list.append('*' + name) self.set_ext_filter(ext_list) def set_ext_filter(self, ext_names: List[str]): """ 文件名过滤 例如要过滤出.py和.pyx文件,就是ext_names=['*.py','*.pyx'] discard功能不太完善,目前先禁用。 :param ext_names: :return: """ if ext_names is not None and self.filter_exts: self.model.setNameFilterDisables(False) self.model.setNameFilters(ext_names) else: self.model.setNameFilterDisables(True) self.model.setNameFilters(["*"]) def slot_goto_parent_path(self): """ Returns: """ root = self.get_root_path() parent = os.path.dirname(root) if os.path.exists(parent): pass self.open_folder_signal.emit(parent) def copy_path(self): """ 复制当前文件的路径的回调 Returns: """ path = self.get_current_file_path() # data = QMimeData() clipboard = QApplication.clipboard() clipboard.setText(path)
def _build_waverange_dialog(self, wave_range, line_list): dialog = QDialog(parent=self.centralWidget) dialog.setWindowTitle("Wavelength range") dialog.setWindowModality(Qt.ApplicationModal) dialog.resize(370, 250) button_ok = QPushButton("OK") button_ok.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) button_cancel = QPushButton("Cancel") button_cancel.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) button_ok.clicked.connect(dialog.accept) button_cancel.clicked.connect(dialog.reject) min_text = QLineEdit("%.2f" % wave_range[0].value) max_text = QLineEdit("%.2f" % wave_range[1].value) validator = QDoubleValidator() validator.setBottom(0.0) validator.setDecimals(2) min_text.setValidator(validator) max_text.setValidator(validator) min_text.setFixedWidth(150) max_text.setFixedWidth(150) min_text.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) max_text.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) min_text.setToolTip("Minimum wavelength to read from list.") max_text.setToolTip("Maximum wavelength to read from list.") nlines_label = self._compute_nlines_in_waverange( line_list, min_text, max_text) min_text.editingFinished.connect( lambda: self._compute_nlines_in_waverange( line_list, min_text, max_text, label=nlines_label)) max_text.editingFinished.connect( lambda: self._compute_nlines_in_waverange( line_list, min_text, max_text, label=nlines_label)) # set up layouts and widgets for the dialog. text_pane = QWidget() text_layout = QGridLayout() text_layout.addWidget(min_text, 1, 0) text_layout.addWidget(QLabel("Minimum wavelength"), 0, 0) text_layout.addWidget(max_text, 1, 1) text_layout.addWidget(QLabel("Maximum wavelength"), 0, 1) spacerItem = QSpacerItem(40, 10, QSizePolicy.Expanding, QSizePolicy.Minimum) text_layout.addItem(spacerItem, 1, 2) text_pane.setLayout(text_layout) label_pane = QWidget() label_layout = QHBoxLayout() label_layout.addWidget(nlines_label) label_layout.addWidget(QLabel(" lines included in range.")) label_layout.addStretch() label_pane.setLayout(label_layout) button_pane = QWidget() button_layout = QHBoxLayout() button_layout.addStretch() button_layout.addWidget(button_cancel) button_layout.addWidget(button_ok) button_pane.setLayout(button_layout) dialog_layout = QVBoxLayout() dialog_layout.setSizeConstraint(QLayout.SetMaximumSize) dialog_layout.addWidget(text_pane) dialog_layout.addWidget(label_pane) dialog_layout.addStretch() dialog_layout.addWidget(button_pane) dialog.setLayout(dialog_layout) button_ok.setDefault(True) button_cancel.setDefault(False) accepted = dialog.exec_() > 0 amin = amax = None if accepted: return self._get_range_from_textfields(min_text, max_text) return (amin, amax)
def on_edit(self): list_widget = self.toolbox.currentWidget() curr_row = list_widget.currentRow() if curr_row >= 0: group_name = self.toolbox.itemText(self.toolbox.currentIndex()) curr_text = list_widget.currentItem().text() dic = self.node_info_dic[group_name][curr_text] edit_layout = QHBoxLayout() input_widget = QTextEdit() edit_layout.addWidget(input_widget) check_button = QPushButton(text='check') edit_layout.addWidget(check_button) input_widget.setText(repr(dic['params'])) views = [('line_ctrl', 'text', 'Node Text', dic['text']), ('check_ctrl', 'inputs_changeable', 'Input Ports Changeable', dic['ports_changeable'][0]), ('check_ctrl', 'outputs_changeable', 'Output Ports Changeble', dic['ports_changeable'][1]), ('editor_ctrl', 'code', 'Input Python Code', dic['code'], 'python'), ('list_ctrl', 'inputs', 'Set Inputs', [[None] * len(dic['inputs']), dic['inputs']], lambda: None), ('list_ctrl', 'outputs', 'Set Outputs', [[None] * len(dic['outputs']), dic['outputs']], lambda: None), ('file_ctrl', 'icon', 'Set Icon', dic['icon']), ('combo_ctrl', 'group', 'Group Name', dic['group'], self.groups)] sp = PMGPanel(parent=None, views=views) dialog = QDialog(self) def verify(): try: text = input_widget.document().toPlainText() l = eval(text) if isinstance(l, list): dialog2 = QDialog(dialog) sp2 = PMGPanel(parent=None, views=l) dialog2.setLayout(QHBoxLayout()) dialog2.layout().addWidget(sp2) dialog2.layout().addLayout(edit_layout) dialog2.exec_() except: import traceback traceback.print_exc() check_button.clicked.connect(verify) dialog.setLayout(QVBoxLayout()) dialog.layout().addWidget(sp) dialog.layout().addLayout(edit_layout) dialog.exec_() dic = sp.get_value() params = None try: params = eval(input_widget.document().toPlainText()) except: import traceback traceback.print_exc() group = self.get_current_list_widget_group() if isinstance(params, list): self.node_info_dic[group][curr_text]['params'] = params self.node_info_dic[group][curr_text]['text'] = dic['text'] self.node_info_dic[group][curr_text]['icon'] = dic['icon'] self.node_info_dic[group][curr_text]['code'] = dic['code'] self.node_info_dic[group][curr_text]['inputs'] = dic['inputs'][1] self.node_info_dic[group][curr_text]['outputs'] = dic['outputs'][1] self.node_info_dic[group][curr_text]['group'] = dic['group'] self.node_info_dic[group][curr_text]['ports_changeable'] = [ dic['inputs_changeable'], dic['outputs_changeable'] ] list_widget.item(curr_row).setText(dic['text']) self.save_node_templetes() self.load_nodes() else: return
def PlotSpecificAreaDialog(self): def PlotSpecificArea(): # Save coordinates for the next time if os.environ['QT_API'] == 'pyqt': self.settings.setValue("last_point_coord_lat", self.spinboxLatDec.value()) self.settings.setValue("last_point_coord_lon", self.spinboxLonDec.value()) elif os.environ['QT_API'] == 'pyqt5': self.settings.setValue( "last_point_coord_lat", QtCore.QVariant(self.spinboxLatDec.value())) self.settings.setValue( "last_point_coord_lon", QtCore.QVariant(self.spinboxLonDec.value())) # Select the 3D Map tab self.tab.setCurrentIndex(2) # Plot if self.check3DMapSelection.isChecked(): tile_selection = 'auto' else: tile_selection = self.text3DMapName.text() terrain, track, warnings = bombo.Generate3DMap( [self.spinboxLatDec.value()], [self.spinboxLonDec.value()], tile_selection=tile_selection, margin=self.spinbox3DMargin.value(), elevation_scale=self.spinbox3DElevationScale.value(), mapping='coords', use_osm_texture=True, texture_type='osm', texture_zoom=self.spinbox3DOSMZoom.value(), texture_invert=self.check3DOSMInvert.isChecked(), use_proxy=self.use_proxy, proxy_data=self.proxy_config, verbose=False) self.textWarningConsole.append(warnings) if terrain is not None: self.map3d.update_plot(terrain, track) d.done(0) def Convert(): try: dd = bombo.parse_dms(self.textLatLonGMS.text()) self.spinboxLatDec.setValue(dd[0]) self.spinboxLonDec.setValue(dd[1]) except: pass d = QDialog() grid = QGridLayout() hBox_coordsGMS = QHBoxLayout() hBox_coordsGMS.setSpacing(5) label = QLabel('Coordinates (gms)') grid.addWidget(label, 0, 0) self.textLatLonGMS = QLineEdit() self.textLatLonGMS.setText("") grid.addWidget(self.textLatLonGMS, 0, 1, 1, 2) button1 = QPushButton("Convert to decimal") button1.clicked.connect(Convert) grid.addWidget(button1, 0, 3) label = QLabel('Coordinates (decimal)') grid.addWidget(label, 1, 0) self.spinboxLatDec = QDoubleSpinBox() self.spinboxLatDec.setRange(-90, +90) self.spinboxLatDec.setSingleStep(0.0000001) self.spinboxLatDec.setDecimals(7) grid.addWidget(self.spinboxLatDec, 1, 1) self.spinboxLonDec = QDoubleSpinBox() self.spinboxLonDec.setRange(-180, +180) self.spinboxLonDec.setSingleStep(0.0000001) self.spinboxLonDec.setDecimals(7) grid.addWidget(self.spinboxLonDec, 1, 2) # Try to recover the last used points try: old_lat = self.settings.value("last_point_coord_lat", type=float) old_lon = self.settings.value("last_point_coord_lon", type=float) self.spinboxLatDec.setValue(old_lat) self.spinboxLonDec.setValue(old_lon) except: # Coordinates of Mt. Rinjani in Indonesia self.spinboxLatDec.setValue(-8.4166000) self.spinboxLonDec.setValue(116.4666000) button2 = QPushButton("Show 3D map") button2.clicked.connect(PlotSpecificArea) grid.addWidget(button2, 1, 3) d.setWindowTitle("Show point on 3D map") d.setLayout(grid) d.setWindowModality(QtCore.Qt.ApplicationModal) d.exec_()
def _create_bump(self): def _add_entry(index): cbox = self.sender() text = cbox.itemText(index) if not text.startswith('other'): return win = LoadConfigDialog(self._config_type, self) confname, status = win.exec_() if not status: cbox.setCurrentIndex(0) return cbox.insertItem(index, confname) cbox.setCurrentIndex(index) wid = QDialog(self) wid.setObjectName(self._csorb.acc + 'App') lay = QGridLayout() wid.setLayout(lay) row = 0 lay.addWidget(QLabel('Base Orbit ', wid), row, 0) orbcombo = QComboBox(wid) orbcombo.addItems(['Register', 'ref_orb', 'bba_orb', 'other...']) orbcombo.setCurrentIndex(1) orbcombo.activated.connect(_add_entry) lay.addWidget(orbcombo, row, 1) row += 1 lay.addWidget(QLabel('Subsection', wid), row, 0) sscombo = QComboBox(wid) sub = ['SA', 'SB', 'SP', 'SB'] ssnames = [f'{d+1:02d}{sub[d%len(sub)]}' for d in range(20)] bcnames = [f'{d+1:02d}BC' for d in range(20)] names = [] for aaa, bbb in zip(ssnames, bcnames): names.extend([aaa, bbb]) sscombo.addItems(names) lay.addWidget(sscombo, row, 1) row += 1 lay.addWidget(QLabel('\u03B8<sub>x</sub> [urad]', wid), row, 0) angx = QLineEdit(wid) angx.setValidator(QDoubleValidator()) angx.setText('0.0') angx.setAlignment(Qt.AlignCenter) angx.setStyleSheet('max-width:5em;') lay.addWidget(angx, row, 1) row += 1 lay.addWidget(QLabel('X [um] ', wid), row, 0) posx = QLineEdit(wid) posx.setValidator(QDoubleValidator()) posx.setText('0.0') posx.setAlignment(Qt.AlignCenter) posx.setStyleSheet('max-width:5em;') lay.addWidget(posx, row, 1) row += 1 lay.addWidget(QLabel('\u03B8<sub>y</sub> [urad]', wid), row, 0) angy = QLineEdit(wid) angy.setValidator(QDoubleValidator()) angy.setText('0.0') angy.setAlignment(Qt.AlignCenter) angy.setStyleSheet('max-width:5em;') lay.addWidget(angy, row, 1) row += 1 lay.addWidget(QLabel('Y [um] ', wid), row, 0) posy = QLineEdit(wid) posy.setValidator(QDoubleValidator()) posy.setText('0.0') posy.setAlignment(Qt.AlignCenter) posy.setStyleSheet('max-width:5em;') lay.addWidget(posy, row, 1) row += 1 hlay = QHBoxLayout() cancel = QPushButton('Cancel', wid) confirm = QPushButton('Ok', wid) confirm.setDefault(True) cancel.clicked.connect(wid.reject) confirm.clicked.connect(wid.accept) hlay.addStretch() hlay.addWidget(cancel) hlay.addStretch() hlay.addWidget(confirm) hlay.addStretch() wid.layout().addItem(hlay, row, 0, 1, 2) res = wid.exec_() if res != QDialog.Accepted: return index = orbcombo.currentIndex() confname = orbcombo.itemText(index) if not index: orbx = _np.array(self.orbx) orby = _np.array(self.orby) elif index == orbcombo.count() - 1: return else: orbs = self._client.get_config_value(confname) orbx = _np.array(orbs['x']) orby = _np.array(orbs['y']) agx = float(angx.text()) agy = float(angy.text()) psx = float(posx.text()) psy = float(posy.text()) sub = sscombo.currentText() orbx, orby = _calculate_bump(orbx, orby, sub, agx, agy, psx, psy) txt = f'Bump@{sub}: ref={confname}\n' txt += f'ax={agx:.1f} ay={agy:.1f} dx={psx:.1f} dy={psy:.1f}' self._update_and_emit(txt, orbx, orby)
def _edit_orbit(self): orbx = self.orbx orby = self.orby wid = QDialog(self) wid.setObjectName(self._csorb.acc + 'App') wid.setLayout(QVBoxLayout()) hbl = QHBoxLayout() wid.layout().addItem(hbl) hbl.addWidget(QLabel('X = ', wid)) multx = QLineEdit(wid) multx.setValidator(QDoubleValidator()) multx.setText('1.0') # multx.setAlignment(Qt.AlignVCenter | Qt.AlignRight) multx.setAlignment(Qt.AlignCenter) multx.setStyleSheet('max-width:5em;') hbl.addWidget(multx) hbl.addWidget(QLabel('*X + ', wid)) addx = QLineEdit(wid) addx.setValidator(QDoubleValidator()) addx.setText('0.0') addx.setAlignment(Qt.AlignCenter) addx.setStyleSheet('max-width:5em;') hbl.addWidget(addx) hbl.addWidget(QLabel(' [um]', wid)) hbl = QHBoxLayout() wid.layout().addItem(hbl) hbl.addWidget(QLabel('Y = ', wid)) multy = QLineEdit(wid) multy.setValidator(QDoubleValidator()) multy.setText('1.0') # multy.setAlignment(Qt.AlignVCenter | Qt.AlignRight) multy.setAlignment(Qt.AlignCenter) multy.setStyleSheet('max-width:5em;') hbl.addWidget(multy) hbl.addWidget(QLabel('*Y + ', wid)) addy = QLineEdit(wid) addy.setValidator(QDoubleValidator()) addy.setText('0.0') addy.setAlignment(Qt.AlignCenter) addy.setStyleSheet('max-width:5em;') hbl.addWidget(addy) hbl.addWidget(QLabel(' [um]', wid)) hlay = QHBoxLayout() cancel = QPushButton('Cancel', wid) confirm = QPushButton('Ok', wid) confirm.setDefault(True) cancel.clicked.connect(wid.reject) confirm.clicked.connect(wid.accept) hlay.addStretch() hlay.addWidget(cancel) hlay.addStretch() hlay.addWidget(confirm) hlay.addStretch() wid.layout().addItem(hlay) res = wid.exec_() if res != QDialog.Accepted: return mltx = float(multx.text()) mlty = float(multy.text()) plusx = float(addx.text()) plusy = float(addy.text()) orbx = mltx * orbx + plusx orby = mlty * orby + plusy txt = '' txt += f'multx = {mltx:5.1f} offx = {plusx:7.1f}\n' txt += f'multy = {mlty:5.1f} offy = {plusy:7.1f}' self._update_and_emit(txt, orbx, orby)
def create_fitted_linemap(self): def threadable_function(data, tracker): from astropy.modeling.fitting import LevMarLSQFitter out = np.empty(shape=data.shape) mask = self.active_window.get_roi_mask(layer=self.current_layer) spectral_axis = data.spectral_axis model = self._current_model # TODO: this is a temporary solution to handle the astropy 3.0.1 # regression concerning compound models and units class ModelWrapper(model.__class__): @property def _supports_unit_fitting(self): return True model = ModelWrapper() for x in range(data.shape[1]): for y in range(data.shape[2]): flux = data[:, x, y] fitter = LevMarLSQFitter() fit_model = fitter(model, spectral_axis[mask], flux[mask]) new_data = fit_model(spectral_axis[mask]) out[:, x, y] = np.sum(new_data) tracker() return out if self._current_model is None: dialog = QDialog() loadUi( os.path.join(os.path.dirname(__file__), "no_model_error_dialog.ui"), dialog) dialog.exec_() return spectral_operation = SpectralOperationHandler( data=self.data, function=threadable_function, operation_name="Fitted Linemap", component_id=self.component_id, layout=self.layout, ui_settings={ 'title': "Fitted Linemap Operation", 'group_box_title': "Choose the component to use for linemap " "generation", 'description': "Fits the current model to the values of the " "chosen component in the range of the current " "ROI in the spectral view for each spectrum in " "the data cube." }) spectral_operation.exec_()
def _build_waverange_dialog(self, wave_range, line_list): dialog = QDialog() loadUi(os.path.join(os.path.dirname(__file__), "ui", "linelists_waverange.ui"), dialog) # convert from line list native units to whatever units # are currently being displayed in the spectral axis. linelist_units = wave_range[0].unit spectral_axis_unit = self.hub.plot_widget.spectral_axis_unit w0 = wave_range[0].to(spectral_axis_unit, equivalencies=u.spectral()) w1 = wave_range[1].to(spectral_axis_unit, equivalencies=u.spectral()) # populate labels with correct physical quantity name dispersion_unit = u.Unit(spectral_axis_unit or "") if dispersion_unit.physical_type == 'length': dialog.minwave_label.setText("Minimum wavelength") dialog.maxwave_label.setText("Maximum wavelength") elif dispersion_unit.physical_type == 'frequency': dialog.minwave_label.setText("Minimum frequency") dialog.maxwave_label.setText("Maximum frequency") elif dispersion_unit.physical_type == 'energy': dialog.minwave_label.setText("Minimum energy") dialog.maxwave_label.setText("Maximum energy") else: dialog.minwave_label.setText("Minimum disp. var.") dialog.maxwave_label.setText("Maximum disp. var.") # pick a good format to display values represented # in the currently selected plot units. if str(w0.unit) in units_formats: fmt = units_formats[str(w0.unit)] else: # use generic formatting for weirder units fmt = "%.6g" dialog.min_text.setText(fmt % w0.value) dialog.max_text.setText(fmt % w1.value) validator = QDoubleValidator() validator.setBottom(0.0) dialog.min_text.setValidator(validator) dialog.max_text.setValidator(validator) dialog.nlines_label = self._compute_nlines_in_waverange(line_list, dialog.min_text, dialog.max_text, dialog.nlines_label, linelist_units, spectral_axis_unit) dialog.min_text.editingFinished.connect(lambda: self._compute_nlines_in_waverange(line_list, dialog.min_text, dialog.max_text, dialog.nlines_label, linelist_units, spectral_axis_unit)) dialog.max_text.editingFinished.connect(lambda: self._compute_nlines_in_waverange(line_list, dialog.min_text, dialog.max_text, dialog.nlines_label, linelist_units, spectral_axis_unit)) accepted = dialog.exec_() > 0 amin = amax = None if accepted: return self._get_range_from_textfields(dialog.min_text, dialog.max_text, linelist_units, spectral_axis_unit) return (amin, amax)
def on_edit_properties_requested(self): """ Show Settings Panel. If It was customized node,it will call the function of the content. Or the default settings parameters will be got. Returns: """ from pmgwidgets import PMGPanel from qtpy.QtWidgets import QDialog, QVBoxLayout if isinstance(self.content, FlowContentForFunction): dlg = QDialog(self.base_rect.scene().flow_widget) sp = PMGPanel() p: 'CustomPort' = None input_ids, output_ids = [], [] input_texts, output_texts = [], [] self._last_var = 0 def new_id_input(): node_id = self.id max_val = 0 for p in self.input_ports: n, t, p = p.parse_id() if max_val < int(p): max_val = int(p) self._last_var += 1 return '%s:input:%d' % (node_id, max_val + self._last_var) def new_id_output(): node_id = self.id max_val = 0 for p in self.output_ports: n, t, p = p.parse_id() if max_val < int(p): max_val = int(p) self._last_var += 1 return '%s:output:%d' % (node_id, max_val + self._last_var) for p in self.input_ports: input_ids.append(p.id) input_texts.append(p.text) for p in self.output_ports: output_ids.append(p.id) output_texts.append(p.text) views = [] views += self.content.get_settings_params() views += [ ('line_ctrl', 'text', 'Node Text', self.text), ] if self.content.ports_changable[0]: views.append(('list_ctrl', 'inputs', 'Set Inputs', [input_ids, input_texts], new_id_input)) if self.content.ports_changable[1]: views.append(('list_ctrl', 'outputs', 'Set Outputs', [output_ids, output_texts], new_id_output)) sp.set_items(views) dlg.setLayout(QVBoxLayout()) dlg.layout().addWidget(sp) dlg.exec_() dic = sp.get_value() self.change_property(dic) else: try: self.content.settings_window_requested(self.canvas.flow_widget) except Exception as e: import traceback exc = traceback.format_exc() print(exc) QMessageBox.warning(self.canvas.flow_widget, 'Error', str(e))