class SortFilterTableView(QTableView): def __init__(self, parent=None): super().__init__(parent) self._proxy_model = QSortFilterProxyModel(self) self._proxy_model.setDynamicSortFilter(True) super().setModel(self._proxy_model) header = FilterHeader(self) header.filter_changed.connect(self.set_filter) self.setHorizontalHeader(header) self.setSortingEnabled(True) self.setSelectionMode(QAbstractItemView.ContiguousSelection) self.import_export_manager = ImportExportManager(self) self.import_export_manager.connect_custom_context_menu() def set_filter(self, section, filter_text): log.debug("set_filter(section: %s, filter: %r)", section, filter_text) self._proxy_model.setFilterWildcard(filter_text) self._proxy_model.setFilterKeyColumn(section) def setModel(self, model): self.horizontalHeader().set_filter_boxes(model.columnCount()) self._proxy_model.setSourceModel(model) self._proxy_model.sort(0, Qt.AscendingOrder) super().setModel(self._proxy_model) font = model.data(0, Qt.FontRole) if font is None: font = self.font() metrics = QFontMetrics(font) self.verticalHeader().setDefaultSectionSize(metrics.lineSpacing() * 1.5) self.horizontalHeader().setDefaultSectionSize(metrics.maxWidth() * 5)
class SortFilterTreeView(QTreeView): def __init__(self, parent=None): super().__init__(parent) self._proxy_model = QSortFilterProxyModel(self) self._proxy_model.setDynamicSortFilter(True) super().setModel(self._proxy_model) header = FilterHeader(self) header.filter_changed.connect(self.set_filter) self.setHeader(header) self.setSortingEnabled(True) def set_filter(self, section, filter_text): self._proxy_model.setFilterWildcard(filter_text) self._proxy_model.setFilterKeyColumn(section) def setModel(self, model): self.header().set_filter_boxes(model.columnCount()) self._proxy_model.setSourceModel(model) self.sortByColumn(0, Qt.AscendingOrder) super().setModel(self._proxy_model)
class OperacaoLogistica(QDialog): #TODO: Acertar formatação na listagem de items por SIMAFIC def __init__(self, parent=None): super().__init__(parent) self.setWindowFlags(Qt.WindowMinMaxButtonsHint | Qt.WindowCloseButtonHint) self.setWindowTitle('Operação Logística') self.setMinimumSize(QSize(h_size, v_size)) self.setWindowIcon(QIcon(main_icon)) verticalSpacer = QSpacerItem(40, 20, QSizePolicy.Minimum, QSizePolicy.Expanding) #Pedido Input Field self.proxy_list_result_id = QSortFilterProxyModel() self.numero_pedido = QLineEdit(self) self.numero_pedido.setPlaceholderText("Insira o Número do Pedido") self.numero_pedido.textChanged.connect( lambda wildcard: self.proxy_list_result_id.setFilterWildcard( wildcard)) #Voltar Btn self.voltar_btn = QPushButton(self) #self.voltar_btn.setStyleSheet('background-color: rgb(0,0,255); color: #fff') self.voltar_btn.setText('Voltar') self.voltar_btn.clicked.connect(self.goMainWindow) self.close() #Adicionar Cores no StyleSheet colors = ['##393318', ' ##fff'] self.pedidos = services.get_all_pedidos() self.item_result = None self.item_escolhido = None self.id_pedido_list = QListView() self.simafics_do_id = QListWidget() #self.simafics_do_id.setHidden(True) self.createPedidoIdList() self.id_pedido_list.clicked.connect( lambda id_pedido: self.createListaSimafics(id_pedido)) self.simafics_do_id.itemDoubleClicked.connect( lambda pedido: self.simaficSelecionado(pedido)) self.pedidos_label = QLabel() self.pedidos_label.setBuddy(self.id_pedido_list) self.simafic_label = QLabel() self.simafic_label.setBuddy(self.simafics_do_id) self.itensTree = PedidoItensTree() self.treeItensTV = QTreeView() self.treeItensTV.setEditTriggers(QAbstractItemView.NoEditTriggers) self.treeItensTV.setAlternatingRowColors(True) self.treeItensTV.setRootIsDecorated(True) self.treeItensTV.doubleClicked.connect(self.simaficSelecionado) self.treeItensTV.setColumnHidden(8, True) if len(self.pedidos) <= 0: self.pedidos_label.setText( "É necessário adicionar um pedido na tela de cadastro.") self.pedidos_label.setStyleSheet("QLabel { color: red; }") else: self.pedidos_label.setText("Listagem de Pedidos:") self.pedidos_label.setStyleSheet("QLabel { color: black; }") self.simafic_label.setText( "Selecione um pedido para ver a listagem de Itens por SIMAFIC:" ) self.simafic_label.setStyleSheet("QLabel { color: red; }") layout = QGridLayout() layout.setColumnStretch(0, 1) layout.setColumnStretch(1, 4) layout.addWidget(self.numero_pedido, 0, 0) layout.addWidget(self.voltar_btn, 0, 1) layout.addWidget(self.pedidos_label, 1, 0) layout.addWidget(self.simafic_label, 1, 1) layout.addWidget(self.id_pedido_list, 2, 0) layout.addWidget(self.treeItensTV, 2, 1) #layout.addWidget(self.simafics_do_id, 2,1) self.setLayout(layout) def createPedidoIdList(self): print('def createPedidoIdList(self):') onlyids = set() pedidosbyid = [] pedidosCompletos = [] self.proxy_list_result_id = QSortFilterProxyModel() for obj in self.pedidos: if obj.id_pedido not in onlyids: pedidosbyid.append(obj) onlyids.add(obj.id_pedido) self.pedidoId_model = QStringListModel(onlyids, self) self.proxy_list_result_id.setSourceModel(self.pedidoId_model) self.id_pedido_list.setModel(self.proxy_list_result_id) self.id_pedido_list.setAlternatingRowColors(True) self.id_pedido_list.setEditTriggers(QAbstractItemView.NoEditTriggers) def createListaSimafics(self, id_pedido): pedido = id_pedido.data() self.pedidosModel = self.itensTree.createPedidosModel(self.itensTree) self.treeItensTV.setModel(self.pedidosModel) print('def listaSimafics(self, id_pedido): {id_pedido}'.format( id_pedido=pedido)) self.item_result = None self.item_result = [x for x in self.pedidos if x.id_pedido == pedido] self.simafics_do_id.clear() self.pedidosModel.beginResetModel self.pedidosModel.modelReset self.pedidosModel.endResetModel for idx, item in enumerate(self.item_result): print(item) self.itensTree.addItens( self.pedidosModel, item.cod_simafic, item.desc, item.qty_scanneada, item.qty_total, item.nome_responsavel, item.id_caixa, item.time_updated.strftime("%d/%m/%y %H:%M:%S"), item.id_pedido, item) self.simafic_label.setText( "Listagem de Itens do pedido {} por SIMAFIC:".format(pedido)) self.simafic_label.setStyleSheet("QLabel { color: black; }") #self.simafics_do_id.setHidden(False) def simaficSelecionado(self, item): print(item.column(), item.row()) simafic_escolhido = self.treeItensTV.model().index(item.row(), 0).data() id_pedido = self.treeItensTV.model().index(item.row(), 7).data() self.item_escolhido = [ x for x in self.item_result if x.cod_simafic == simafic_escolhido and x.id_pedido == id_pedido ] self.cams = ItemScanner(self.item_escolhido[0]) self.cams.show() self.close() def goMainWindow(self): self.cams = mainView self.cams.show() self.close() def goScan(self): self.cams = ItemScanner("Eu sou o Pedido", "Eu sou o Simafic", "Eu sou a Descrição", "300") self.cams.show() self.close()
class CadastroPedidos(QDialog): def __init__(self, parent=None): super(CadastroPedidos, self).__init__(parent=None) self.setWindowFlags(Qt.WindowMinMaxButtonsHint | Qt.WindowCloseButtonHint) self.setMinimumSize(QSize(h_size, v_size)) self.originalPalette = QApplication.palette() self.setWindowIcon(QIcon(main_icon)) self.setWindowTitle("Cadastro de Pedidos") self.setStyleSheet(style) self.pedidos_selecionados = [] #Sempre que for iniciado criará um objeto data self.data = dict() voltar_btn = QPushButton(self) voltar_btn.setText('Voltar') voltar_btn.clicked.connect(self.goMainWindow) voltar_btn.setFocusPolicy(Qt.NoFocus) self.dadosDoPedido() self.resumoGeral() self.resumoDosItens() '''disableWidgetsCheckBox.toggled.connect( self.bottomLeftGroupBox.setHidden ) ''' topLayout = QHBoxLayout() topLayout.addWidget(voltar_btn) leftLayout = QVBoxLayout() leftLayout.addWidget(self.topLeftGroupBox, 100) #leftLayout.addWidget(self.bottomLeftGroupBox, 50) mainLayout = QGridLayout() mainLayout.addLayout(topLayout, 0, 0, 1, 2) mainLayout.addLayout(leftLayout, 1, 0) mainLayout.addWidget(self.topRightGroupBox, 1, 1) #mainLayout.addWidget(self.submitButtons, 3, 0, 1, 2) mainLayout.setRowStretch(1, 1) mainLayout.setColumnStretch(0, 1) mainLayout.setColumnStretch(1, 3) self.setLayout(mainLayout) def dadosDoPedido(self): self.topLeftGroupBox = QGroupBox("Dados do Pedido") verticalSpacer = QSpacerItem(40, 20, QSizePolicy.Minimum, QSizePolicy.Expanding) formLayout = QFormLayout() self.pedido = QLineEdit(self) self.pedido.setPlaceholderText("ex: 123.456") pedido_label = QLabel("Pedido:") self.n_simafic = QLineEdit(self) self.n_simafic.setPlaceholderText("ex: 08.04.02.507-6") n_simafic_label = QLabel("COD. SIMAFIC:") self.qtd_items = QLineEdit(self) self.qtd_items.setPlaceholderText("ex: 100") qtd_items_label = QLabel("Quantidade de Items:") '''ADD PEDIDO''' add_item = QPushButton('Adicionar Item') add_item.setObjectName('Add') add_item.setIcon(QIcon('assets/check_icon_blue2.png')) add_item.clicked.connect(self.add_items) '''CLEAR BUTTON CONFIG ''' clear_btn = QPushButton('Limpar Campos') clear_btn.setObjectName('Yellow') clear_btn.setIcon(QIcon('assets/eraser.png')) clear_btn.clicked.connect(self.limpar_pedidos) formLayout.addRow(pedido_label, self.pedido) formLayout.addRow(n_simafic_label, self.n_simafic) formLayout.addRow(qtd_items_label, self.qtd_items) formLayout.addItem(verticalSpacer) formLayout.addRow(add_item) formLayout.addRow(clear_btn) '''checkBox = QCheckBox("Tri-state check box") checkBox.setTristate(True) checkBox.setCheckState(Qt.PartiallyChecked)''' #layout.addWidget(checkBox) '''formLayout.addWidget(add_item) formLayout.addWidget(clear_btn)''' layout = QVBoxLayout() layout.addLayout(formLayout) layout.addStretch(2) self.topLeftGroupBox.setLayout(layout) def resumoGeral(self): self.topRightGroupBox = QTabWidget() self.topRightGroupBox.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Ignored) #[First Tab] Create first tab verticalSpacer = QSpacerItem(40, 20, QSizePolicy.Minimum, QSizePolicy.Expanding) tab1ListaPedidos = QWidget() layout = QVBoxLayout(self) #[First Tab] - TextFields searchPedido = QLineEdit(self) searchPedido.setPlaceholderText("Filtrar por pedido: ") searchProduto = QLineEdit(self) searchProduto.setPlaceholderText("Filtrar por produto: ") #[First Tab] - Set TableView self.tabv_pedidos = QTableView() tab2hbox = QHBoxLayout() self.modelAllPedidos = services.get_all_pedidos_pandas() #[First Tab] - Set Filters self.proxyPedidoFilter = QSortFilterProxyModel() self.proxyPedidoFilter.setSourceModel(self.modelAllPedidos) self.proxyPedidoFilter.setFilterKeyColumn(0) self.proxyPedidoFilter.setSortCaseSensitivity(Qt.CaseSensitive) self.proxyPedidoFilterSecondLayer = QSortFilterProxyModel() self.proxyPedidoFilterSecondLayer.setSourceModel( self.proxyPedidoFilter) self.proxyPedidoFilterSecondLayer.setFilterKeyColumn(1) self.proxyPedidoFilterSecondLayer.setSortCaseSensitivity( Qt.CaseSensitive) self.tabv_pedidos.resizeColumnsToContents() self.tabv_pedidos.doubleClicked.connect(self.abrirItensDoPedido) self.tabv_pedidos.setSelectionMode(QAbstractItemView.SingleSelection) self.tabv_pedidos.setSelectionBehavior(QTableView.SelectRows) self.tabv_pedidos.setColumnWidth(2, 100) self.tabv_pedidos.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) tab2hbox.addWidget(self.tabv_pedidos) #[Connect Fields] searchProduto.textChanged.connect( lambda wildcard: self.proxyPedidoFilterSecondLayer. setFilterWildcard(wildcard)) searchPedido.textChanged.connect( lambda wildcard: self.proxyPedidoFilter.setFilterWildcard(wildcard )) self.tabv_pedidos.setModel(self.proxyPedidoFilterSecondLayer) #[First Tab] - Set Layout tabItensValidos = QWidget() tableItensValidos = QTableView() #tableItensValidos.horizontalHeader().sectionClicked.connect(your_callable) model = services.get_simafic_as_dataframe() tableItensValidos.setModel(model) tab1hbox = QHBoxLayout() #tab1hbox.setContentsMargins(5, 5, 5, 5) tableItensValidos.resizeColumnsToContents() tab1hbox.addWidget(tableItensValidos) tabItensValidos.setLayout(tab1hbox) layoutText = QHBoxLayout() layoutText.addWidget(searchPedido) layoutText.addWidget(searchProduto) layout.addLayout(layoutText) layout.addWidget( QLabel( "Para abrir mais opções sobre um pedido, clique duas vezes no item." )) self.tabv_pedidos.verticalHeader() self.tabv_pedidos.resizeColumnsToContents() layout.addWidget(self.tabv_pedidos) tab1ListaPedidos.setLayout(layout) #TODO: Agrupar items por pedido (Drop Down) | Auto-resize nas cells da TView #TODO: Adicionar self.topRightGroupBox.addTab(tab1ListaPedidos, "&Lista de Pedidos: ") self.topRightGroupBox.addTab(tabItensValidos, "&Lista de Itens:") def resumoDosItens(self): self.bottomLeftGroupBox = QGroupBox("Lista de Itens do Pedido nº") self.listDataItens = list() self.listaViewItens = QListWidget() verticalSpacer = QSpacerItem(40, 20, QSizePolicy.Minimum, QSizePolicy.Expanding) self.resumoLayout = QGridLayout() self.resumoLayout.addItem(verticalSpacer) self.bottomLeftGroupBox.setLayout(self.resumoLayout) def abrirItensDoPedido(self, item): print( "[abrirIItensDoPedido] O Item foi selecionado através de um click na: {} x linha: {}" .format(item.column(), item.row())) pedido = self.tabv_pedidos.model().index(item.row(), 0).data() simafic = self.tabv_pedidos.model().index(item.row(), 1).data() print(pedido, simafic) self.pedidos_selecionados = pedido try: pedido_item = services.get_pedido_x_item(pedido, simafic) print(pedido_item) except (ValidationError, DBPedidosException) as error: error_dialog = QErrorMessage() error_dialog.setWindowTitle(error.errors) error_dialog.setWindowIcon(QIcon(main_icon)) error_dialog.showMessage(error.message) error_dialog.exec_() box = QMessageBox() box.setWindowIcon(QIcon(main_icon)) box.setWindowTitle("Pedido {} selecionado.".format( pedido_item.id_pedido)) box.setText("O que deseja fazer com o item {}?".format( pedido_item.cod_simafic)) box.setStandardButtons(QMessageBox.Open | QMessageBox.Discard | QMessageBox.Cancel) buttonOpen = box.button(QMessageBox.Open) buttonOpen.setText('Alterar') buttonDiscard = box.button(QMessageBox.Discard) buttonDiscard.setText('Excluir') buttonCancel = box.button(QMessageBox.Cancel) buttonCancel.setText('Cancelar') box.exec_() if box.clickedButton() == buttonOpen: print("Alterar...") self.cams = UpdateScreen(pedido_item, parent=self) self.cams.show() elif box.clickedButton() == buttonDiscard: print("Excluir ") self.confirmarExclusao(pedido_item) elif box.clickedButton() == buttonCancel: print("Cancelar ") def confirmarExclusao(self, pedido): box = QMessageBox() box.setWindowIcon(QIcon(main_icon)) box.setWindowTitle('Confirmação de Exclusão') box.setText( "Tem certeza que deseja excluir o item: {} do pedido {}?".format( pedido.cod_simafic, pedido.id_pedido)) box.setStandardButtons(QMessageBox.Yes | QMessageBox.No) buttonYes = box.button(QMessageBox.Yes) buttonYes.setText("Excluir") buttonNo = box.button(QMessageBox.No) buttonNo.setText("Cancelar") box.exec_() if box.clickedButton() == buttonYes: self.excluirPedido(pedido) print("Pedido excluido") else: print("Exclusão cancelada") return def excluirPedido(self, pedido): try: services.excluirPedidoItem(pedido) self.update_model_tableview() except (ValidationError, DBPedidosException) as error: error_dialog = QErrorMessage() error_dialog.setWindowTitle(error.errors) error_dialog.setWindowIcon(QIcon(main_icon)) error_dialog.showMessage(error.message) error_dialog.exec_() def add_items(self): try: pedido, n_simafic, qtd_items = self.pedido.text( ), self.n_simafic.text(), self.qtd_items.text() print("Add Pedido: {} {} {}".format(pedido, n_simafic, qtd_items)) if services.validateCadastro(pedido, n_simafic, qtd_items): print("Add Pedido: {} {} {}".format(pedido, n_simafic, qtd_items)) mb = QMessageBox() mb.setIconPixmap(QPixmap('assets/check_icon_blue2')) mb.setWindowTitle("Sucesso") mb.setText( 'O pedido: {} foi criado com sucesso!'.format(pedido)) services.add_pedido(pedido, n_simafic, qtd_items) mb.exec_() self.update_model_tableview() self.limpar_pedidos() except (ValidationError, DBPedidosException) as error: error_dialog = QErrorMessage() error_dialog.setWindowTitle(error.errors) error_dialog.setWindowIcon(QIcon(main_icon)) error_dialog.showMessage(error.message) error_dialog.exec_() pass def update_model_tableview(self): self.modelAllPedidos.setDataFrame(services.get_all_pedidos_df()) self.topRightGroupBox.setCurrentIndex(0) def limpar_pedidos(self): self.n_simafic.clear() self.qtd_items.clear() self.pedido.clear() def goMainWindow(self): self.cams = mainView self.cams.show() self.close()
class MainWindow(QMainWindow): def __init__(self): super().__init__() self.filename = None self.data_changed = False self.file_data = None self.open_file_dir = os.path.expanduser('~') self.ui = loadUi('gui/MainWindow.ui', self) self.ui.action_Open.triggered.connect(self.menu_open) self.ui.action_Save.triggered.connect(self.menu_save) self.ui.action_Close.triggered.connect(self.menu_close) self.ui.action_Exit.triggered.connect(qApp.quit) self.ui.action_ShowMap.triggered.connect(self.show_map) self.ui.action_BoltChecker.triggered.connect(self.show_boltchecker) self.datamodel = QSortFilterProxyModel() self.datamodel.setFilterCaseSensitivity(Qt.CaseInsensitive) self.datamodel.setSortCaseSensitivity(Qt.CaseInsensitive) self.ui.treeView.setSortingEnabled(False) self.ui.treeView.setModel(self.datamodel) self.ui.treeView.setSortingEnabled(True) self.ui.treeView.doubleClicked.connect(self.treeView_doubleClicked) self.ui.treeView.selectionModel().selectionChanged.connect( self.treeView_selectionChanged) self.ui.searchField.textChanged.connect(self.searchField_textChanged) def menu_open(self): fname = QFileDialog.getOpenFileName(self, 'Open file', self.open_file_dir) if fname[0]: self.open_file(fname[0]) def open_file(self, filename): self.filename = filename self.open_file_dir = os.path.dirname(self.filename) with open(filename, 'rb') as f: reader = ES2Reader(f) self.file_data = reader.read_all() self.update_tree(self.file_data) self.set_changed(False) self.ui.action_Close.setEnabled(True) def set_changed(self, changed=True): self.data_changed = changed self.ui.action_Save.setEnabled(self.data_changed) def menu_save(self): for i in range(100): backup_filename = '{}.{}'.format(self.filename, i) if not os.path.exists(backup_filename): shutil.copy2(self.filename, backup_filename) break else: raise Exception('Too many backups!') with open(self.filename, 'wb') as f: writer = ES2Writer(f) for k, v in self.file_data.items(): writer.save(k, v) writer.save_all() self.set_changed(False) def menu_close(self): self.ui.action_Save.setEnabled(False) self.ui.action_Close.setEnabled(False) self.filename = None self.file_data = None self.update_tree(None) def update_tree(self, file_data=None): self.datamodel.setSourceModel(TreeModel(file_data)) self.ui.treeView.sortByColumn(0, Qt.AscendingOrder) self.ui.treeView.resizeColumnToContents(0) def treeView_selectionChanged(self): pass # indexes = self.ui.treeView.selectionModel().selection().indexes() # if len(indexes) > 0: # index = indexes[0] # tag = self.datamodel.data(index) # print('selectionChanged') # print(self.file_data[item].header.value_type) # print(self.file_data[item].value) def treeView_doubleClicked(self): index = self.ui.treeView.selectionModel().selection().indexes()[0] self.edit_index(index) def edit_index(self, index): tag = index.data() dialog = EditDialog(tag, self.file_data[tag], self) result = dialog.exec_() if result == QDialog.Accepted: dialog_result = dialog.get_value() if self.file_data[tag].value == dialog_result: return self.set_changed() self.file_data[tag].value = dialog_result value_index = self.datamodel.index(index.row(), 2) self.datamodel.setData(value_index, dialog_result) def searchField_textChanged(self, text): self.datamodel.setFilterWildcard(text) def show_map(self): dialog = MapViewDialog(self.file_data, self) dialog.exec_() def show_boltchecker(self): dialog = BoltCheckerDialog(self.file_data, self) dialog.exec_()
class ReferenceSpectraDialog(QDialog): fits_picked = pyqtSignal(str) def __init__(self, database, main_spectrum=None): super(ReferenceSpectraDialog, self).__init__() self.main_spectrum = main_spectrum self.ui = Ui_ReferenceSpectraDialog() self.ui.setupUi(self) self.reference_catalogues = ReferenceCatalogues(database) self.full_model = QStandardItemModel() self.catalogues_model = QStandardItemModel() self.ui.catalogue.setModel(self.catalogues_model) self.ui.catalogue.currentTextChanged.connect( lambda txt: self.populate()) for catname, cat in self.reference_catalogues.catalogues.items(): row = QStandardItem(catname) row.setData(cat) self.catalogues_model.appendRow(row) self.model = QSortFilterProxyModel() self.model.setSourceModel(self.full_model) self.model.setFilterCaseSensitivity(Qt.CaseInsensitive) self.model.setFilterKeyColumn(0) self.ui.entries.setModel(self.model) self.ui.type_filter.currentTextChanged.connect( lambda txt: self.model.setFilterWildcard("{}*".format(txt))) self.ui.buttonBox.button(QDialogButtonBox.Open).setEnabled(False) self.ui.entries.selectionModel().selectionChanged.connect( lambda selected, deselected: self.ui.buttonBox.button( QDialogButtonBox.Open).setEnabled(len(selected.indexes()) > 0)) self.accepted.connect(self.load_fits) self.populate() def set_main_spectrum(self, spectrum): self.main_spectrum = spectrum def populate(self): self.full_model.clear() catalogue = self.catalogues_model.item( self.ui.catalogue.currentIndex()).data() self.full_model.setHorizontalHeaderLabels(['Spectral Type']) entries = self.reference_catalogues.spectra(catalogue['name']) self.ui.type_filter.clear() self.ui.type_filter.addItem('') self.ui.type_filter.addItems( sorted(set([i['sptype'] for i in entries]))) for entry in entries: item = QStandardItem(entry['sptype']) item.setData(entry) self.full_model.appendRow(item) def load_fits(self): original_index = self.model.mapToSource( self.ui.entries.selectionModel().selectedIndexes()[0]) entry = self.full_model.item(original_index.row()).data() self.fits_picked.emit(self.reference_catalogues.fits(entry)) def setup_menu(self, toolbar, axes, settings): self.current_line = None reference_action = QtCommons.addToolbarPopup(toolbar, "Reference") reference_action.menu().addAction("Reference library", lambda: self.show()) reference_action.menu().addAction( "Load from FITS file", lambda: open_file_sticky( 'Open Reference Profile', FITS_EXTS, lambda f: self. __open_reference(f[0], axes), settings, REFERENCE)) self.close_action = reference_action.menu().addAction( "Close", lambda: self.__close_reference(axes)) self.close_action.setEnabled(False) self.fits_picked.connect(lambda f: self.__open_reference(f, axes)) self.blackbody_menu = blackbody.BlackBodyAction( lambda bb: self.blackbody(bb, axes), reference_action.menu()) return reference_action.menu() def blackbody(self, blackbody, axes): self.__open(blackbody.spectrum(), axes) def __open_reference(self, file, axes): fits_spectrum = FitsSpectrum(fits.open(file)) self.__open(fits_spectrum.spectrum, axes) def __open(self, spectrum, axes): self.__close_reference(axes) if spectrum.dispersion() < 0.4 and spectrum.dispersion() > 0: spectrum.resample(spectrum.dispersion() / 0.4) if (self.main_spectrum): print("Cutting spectrum: {0}, {1}".format( self.main_spectrum.wavelengths[0], self.main_spectrum.wavelengths[-1])) spectrum.cut_lambda(self.main_spectrum.wavelengths[0], self.main_spectrum.wavelengths[-1]) spectrum.normalize_to_max() self.current_line = Line2D(spectrum.wavelengths, spectrum.fluxes, color='gray') axes.add_line(self.current_line) axes.figure.canvas.draw() self.close_action.setEnabled(True) def __close_reference(self, axes): self.close_action.setEnabled(False) if self.current_line: try: # TODO: verify self.current_line.remove() self.current_line = None axes.figure.canvas.draw() except: pass
class SortFilterTableView(QTableView): def __init__(self, parent=None): super().__init__(parent) self._proxy_model = QSortFilterProxyModel(self) self._proxy_model.setDynamicSortFilter(True) super().setModel(self._proxy_model) header = FilterHeader(self) header.filter_changed.connect(self.set_filter) self.setHorizontalHeader(header) self.setSortingEnabled(True) self.setSelectionMode(QAbstractItemView.ContiguousSelection) self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.show_context_menu) self.import_export_manager = ImportExportManager(self) self.copy_action = create_action( None, "Copy", self.copy_selection_to_clipboard) def show_context_menu(self, point): self.import_export_manager.set_model_index(self.indexAt(point)) context_menu = QMenu() context_menu.addAction(self.copy_action) context_menu.addAction(self.import_export_manager.export_action) context_menu.addAction(self.import_export_manager.import_action) context_menu.exec(self.mapToGlobal(point)) def keyPressEvent(self, event: QKeyEvent): if event.type() == QKeyEvent.KeyPress \ and event.matches(QKeySequence.Copy): self.copy_selection_to_clipboard() else: super().keyPressEvent(event) def copy_selection_to_clipboard(self): selected_indexes = self.selectionModel().selectedIndexes() if not selected_indexes or len(selected_indexes) == 0: return model = self.model() result = "\n".join( "\t".join(row) for row in self.selected_rows(model, selected_indexes) ) cp = QApplication.clipboard() cp.setText(result) def selected_rows(self, model, selected_indexes): row = [] last_row = selected_indexes[0].row() for current in selected_indexes: value = str(model.data(current, Qt.DisplayRole)) if last_row != current.row(): yield row row = [value, ] else: row.append(value) last_row = current.row() def set_filter(self, section, filter_text): log.debug("set_filter(section: %s, filter: %r)", section, filter_text) self._proxy_model.setFilterWildcard(filter_text) self._proxy_model.setFilterKeyColumn(section) def setModel(self, model): self.horizontalHeader().set_filter_boxes(model.columnCount()) self._proxy_model.setSourceModel(model) self._proxy_model.sort(0, Qt.AscendingOrder) super().setModel(self._proxy_model) font = model.data(0, Qt.FontRole) if font is None: font = self.font() metrics = QFontMetrics(font) self.verticalHeader().setDefaultSectionSize(metrics.lineSpacing() * 1.5) self.horizontalHeader().setDefaultSectionSize(metrics.maxWidth() * 5)
class ReferenceSpectraDialog(QDialog): fits_picked = pyqtSignal(str) def __init__(self, database, main_spectrum = None): super(ReferenceSpectraDialog, self).__init__() self.main_spectrum = main_spectrum self.ui = Ui_ReferenceSpectraDialog() self.ui.setupUi(self) self.reference_catalogues = ReferenceCatalogues(database) self.full_model = QStandardItemModel() self.catalogues_model = QStandardItemModel() self.ui.catalogue.setModel(self.catalogues_model) self.ui.catalogue.currentTextChanged.connect(lambda txt: self.populate()) for catname, cat in self.reference_catalogues.catalogues.items(): row = QStandardItem(catname) row.setData(cat) self.catalogues_model.appendRow(row) self.model = QSortFilterProxyModel() self.model.setSourceModel(self.full_model) self.model.setFilterCaseSensitivity(Qt.CaseInsensitive) self.model.setFilterKeyColumn(0) self.ui.entries.setModel(self.model) self.ui.type_filter.currentTextChanged.connect(lambda txt: self.model.setFilterWildcard("{}*".format(txt) ) ) self.ui.buttonBox.button(QDialogButtonBox.Open).setEnabled(False) self.ui.entries.selectionModel().selectionChanged.connect(lambda selected, deselected: self.ui.buttonBox.button(QDialogButtonBox.Open).setEnabled(len(selected.indexes()) > 0) ) self.accepted.connect(self.load_fits) self.populate() def set_main_spectrum(self, spectrum): self.main_spectrum = spectrum def populate(self): self.full_model.clear() catalogue = self.catalogues_model.item(self.ui.catalogue.currentIndex()).data() self.full_model.setHorizontalHeaderLabels(['Spectral Type']) entries = self.reference_catalogues.spectra(catalogue['name']) self.ui.type_filter.clear() self.ui.type_filter.addItem('') self.ui.type_filter.addItems( sorted(set([i['sptype'] for i in entries])) ) for entry in entries: item = QStandardItem(entry['sptype']) item.setData(entry) self.full_model.appendRow(item) def load_fits(self): original_index = self.model.mapToSource(self.ui.entries.selectionModel().selectedIndexes()[0]) entry = self.full_model.item(original_index.row()).data() self.fits_picked.emit(self.reference_catalogues.fits(entry)) def setup_menu(self, toolbar, axes, settings): self.current_line = None reference_action = QtCommons.addToolbarPopup(toolbar, "Reference") reference_action.menu().addAction("Reference library", lambda: self.show()) reference_action.menu().addAction("Load from FITS file", lambda: open_file_sticky('Open Reference Profile', FITS_EXTS, lambda f: self.__open_reference(f[0], axes), settings, REFERENCE )) self.close_action = reference_action.menu().addAction("Close", lambda: self.__close_reference(axes)) self.close_action.setEnabled(False) self.fits_picked.connect(lambda f: self.__open_reference(f, axes)) self.blackbody_menu = blackbody.BlackBodyAction(lambda bb: self.blackbody(bb, axes), reference_action.menu()) return reference_action.menu() def blackbody(self, blackbody, axes): self.__open(blackbody.spectrum(), axes) def __open_reference(self, file, axes): fits_spectrum = FitsSpectrum(fits.open(file)) self.__open(fits_spectrum.spectrum, axes) def __open(self, spectrum, axes): self.__close_reference(axes) if spectrum.dispersion() < 0.4 and spectrum.dispersion() > 0: spectrum.resample(spectrum.dispersion() /0.4) if(self.main_spectrum): print("Cutting spectrum: {0}, {1}".format(self.main_spectrum.wavelengths[0], self.main_spectrum.wavelengths[-1])) spectrum.cut_lambda(self.main_spectrum.wavelengths[0], self.main_spectrum.wavelengths[-1]) spectrum.normalize_to_max() self.current_line = Line2D(spectrum.wavelengths, spectrum.fluxes, color='gray') axes.add_line(self.current_line) axes.figure.canvas.draw() self.close_action.setEnabled(True) def __close_reference(self, axes): self.close_action.setEnabled(False) if self.current_line: try: # TODO: verify self.current_line.remove() self.current_line = None axes.figure.canvas.draw() except: pass