class SchemeWidget(QWidget): def __init__(self, parent, schemes): QWidget.__init__(self) self._parent = parent self._schemes = schemes vbox = QVBoxLayout(self) self._table = QTableWidget(1, 2) self._table.removeRow(0) vbox.addWidget(self._table) set_data(self._schemes, self._table) btnUninstall = QPushButton('Download') btnUninstall.setMaximumWidth(100) vbox.addWidget(btnUninstall) self.connect(btnUninstall, SIGNAL("clicked()"), self._download_scheme) def _download_scheme(self): rows = self._table.rowCount() pos = rows - 1 schemes = [] for i in xrange(rows): if self._table.item(pos - i, 0) is not None and \ self._table.item(pos - i, 0).checkState() == Qt.Checked: schemes.append(self._schemes.pop(pos - i)) self._table.removeRow(pos - i) self._parent.download_scheme(schemes)
def add_new_table(self, rel, name): import itertools table = QTableWidget() table.setRowCount(0) table.setColumnCount(0) data = itertools.chain([rel.fields], rel.content) for row_data in data: row = table.rowCount() table.setColumnCount(len(row_data)) for col, text in enumerate(row_data): item = QTableWidgetItem() item.setText(text) if row == 0: table.setHorizontalHeaderItem(col, item) else: table.setItem(row - 1, col, item) table.insertRow(row) table.removeRow(table.rowCount() - 1) self.stacked.addWidget(table) self.stacked.setCurrentIndex(self.stacked.count() - 1) lateral = Pireal.get_service("lateral") lateral.add_item_list([name])
class UpdatesWidget(QWidget): """ This widget show the availables plugins to update """ def __init__(self, parent, updates): QWidget.__init__(self, parent) self._parent = parent self._updates = updates vbox = QVBoxLayout(self) self._table = QTableWidget(1, 5) self._table.removeRow(0) self._headers = ('Name', 'Version', 'Description', 'Authors', 'Web') vbox.addWidget(self._table) ui_tools.load_table(self._table, self._headers, _format_for_table(updates)) self._table.setColumnWidth(0, 200) btnUpdate = QPushButton(self.tr("Update")) btnUpdate.setMaximumWidth(100) vbox.addWidget(btnUpdate) self.connect(btnUpdate, SIGNAL("clicked()"), self._update_plugins) def _update_plugins(self): data = _format_for_table(self._updates) plugins = ui_tools.remove_get_selected_items(self._table, data) #get the download link of each plugin for p_row in plugins: #search the plugin for p_dict in self._updates: if unicode(p_dict["name"]) == unicode(p_row[0]): p_data = p_dict break #append the downlod link p_row.append(p_data["download"]) self._parent.update_plugin(plugins)
class UpdatesWidget(QWidget): def __init__(self, parent, updates): QWidget.__init__(self) self._parent = parent self._updates = updates vbox = QVBoxLayout(self) self._table = QTableWidget(1, 3) self._table.removeRow(0) vbox.addWidget(self._table) set_data(updates, self._table) btnUpdate = QPushButton('Update') btnUpdate.setMaximumWidth(100) vbox.addWidget(btnUpdate) self.connect(btnUpdate, SIGNAL("clicked()"), self._update_plugins) def _update_plugins(self): rows = self._table.rowCount() pos = rows - 1 plugins = [] for i in xrange(rows): if self._table.item(pos-i, 0) is not None and \ self._table.item(pos-i, 0).checkState() == Qt.Checked: plugins.append(self._updates.pop(pos-i)) self._table.removeRow(pos-i) self._parent.update_plugin(plugins)
class UpdatesWidget(QWidget): """ This widget show the availables plugins to update """ def __init__(self, parent, updates): QWidget.__init__(self, parent) self._parent = parent self._updates = updates vbox = QVBoxLayout(self) self._table = QTableWidget(1, 5) self._table.removeRow(0) self._headers = ("Name", "Version", "Description", "Authors", "Web") vbox.addWidget(self._table) ui_tools.load_table(self._table, self._headers, _format_for_table(updates)) self._table.setColumnWidth(0, 200) btnUpdate = QPushButton(self.tr("Update")) btnUpdate.setMaximumWidth(100) vbox.addWidget(btnUpdate) self.connect(btnUpdate, SIGNAL("clicked()"), self._update_plugins) def _update_plugins(self): data = _format_for_table(self._updates) plugins = ui_tools.remove_get_selected_items(self._table, data) # get the download link of each plugin for p_row in plugins: # search the plugin for p_dict in self._updates: if unicode(p_dict["name"]) == unicode(p_row[0]): p_data = p_dict break # append the downlod link p_row.append(p_data["download"]) self._parent.update_plugin(plugins)
class AvailableWidget(QWidget): def __init__(self, parent, available): QWidget.__init__(self) self._parent = parent self._available = available vbox = QVBoxLayout(self) self._table = QTableWidget(1, 3) self._table.removeRow(0) vbox.addWidget(self._table) set_data(available, self._table) btnInstall = QPushButton('Install') btnInstall.setMaximumWidth(100) vbox.addWidget(btnInstall) hbox = QHBoxLayout() hbox.addWidget(QLabel('Add an external Plugin. URL Zip File:')) self.link = QLineEdit() hbox.addWidget(self.link) btnAdd = QPushButton('Add') hbox.addWidget(btnAdd) vbox.addLayout(hbox) lblExternalPlugin = QLabel('(Write the URL of the Plugin and press "Add")') lblExternalPlugin.setAlignment(Qt.AlignRight) vbox.addWidget(lblExternalPlugin) self.connect(btnInstall, SIGNAL("clicked()"), self._install_plugins) self.connect(btnAdd, SIGNAL("clicked()"), self._install_external) def _install_plugins(self): rows = self._table.rowCount() pos = rows - 1 plugins = [] for i in xrange(rows): if self._table.item(pos-i, 0) is not None and \ self._table.item(pos-i, 0).checkState() == Qt.Checked: plugins.append(self._available.pop(pos-i)) self._table.removeRow(pos-i) self._parent.download_plugins(plugins) def _install_external(self): if self.link.text().isEmpty(): QMessageBox.information(self, 'External Plugins', 'URL from Plugin missing...') return plug = [ manage_files.get_module_name(str(self.link.text())), 'External Plugin', '1.0', str(self.link.text()) ] self._parent.download_plugins(plug) self.link.setText('') def add_table_items(self, plugs): self._available += plugs set_data(self._available, self._table)
class InstalledWidget(QWidget): """ This widget show the installed plugins """ def __init__(self, parent, installed): QWidget.__init__(self, parent) self._parent = parent self._installed = installed vbox = QVBoxLayout(self) self._table = QTableWidget(1, 2) self._table.setSelectionMode(QTableWidget.SingleSelection) self._table.removeRow(0) vbox.addWidget(self._table) ui_tools.load_table(self._table, (self.tr('Name'), self.tr('Version')), _format_for_table(installed)) self._table.setColumnWidth(0, 500) self._table.setSortingEnabled(True) self._table.setAlternatingRowColors(True) btnUninstall = QPushButton(self.tr("Uninstall")) btnUninstall.setMaximumWidth(100) vbox.addWidget(btnUninstall) self.connect(btnUninstall, SIGNAL("clicked()"), self._uninstall_plugins) self.connect(self._table, SIGNAL("itemSelectionChanged()"), self._show_item_description) def _show_item_description(self): item = self._table.currentItem() if item is not None: data = list(item.data(Qt.UserRole)) self._parent.show_plugin_info(data) def remove_item(self, plugin_name): plugin = _get_plugin(plugin_name, self._installed) self._installed.remove(plugin) def add_table_items(self, plugs): self._installed += plugs data = _format_for_table(self._installed) ui_tools.load_table(self._table, (self.tr('Name'), self.tr('Version')), data) def _uninstall_plugins(self): data = _format_for_table(self._installed) plugins = ui_tools.remove_get_selected_items(self._table, data) self._parent.mark_as_available(plugins) def reset_table(self, installed): self._installed = installed while self._table.rowCount() > 0: self._table.removeRow(0) ui_tools.load_table(self._table, (self.tr('Name'), self.tr('Version')), self._installed)
class InstalledWidget(QWidget): """ This widget show the installed plugins """ def __init__(self, parent, installed): QWidget.__init__(self, parent) self._parent = parent self._installed = installed vbox = QVBoxLayout(self) self._table = QTableWidget(1, 2) self._table.setSelectionMode(QTableWidget.SingleSelection) self._table.removeRow(0) vbox.addWidget(self._table) ui_tools.load_table(self._table, (self.tr('Name'), self.tr('Version')), _format_for_table(installed)) self._table.setColumnWidth(0, 500) btnUninstall = QPushButton(self.tr("Uninstall")) btnUninstall.setMaximumWidth(100) vbox.addWidget(btnUninstall) self.connect(btnUninstall, SIGNAL("clicked()"), self._uninstall_plugins) self.connect(self._table, SIGNAL("itemSelectionChanged()"), self._show_item_description) def _show_item_description(self): item = self._table.currentItem() if item is not None: data = list(item.data(Qt.UserRole)) self._parent.show_plugin_info(data) def remove_item(self, plugin_name): plugin = _get_plugin(plugin_name, self._installed) self._installed.remove(plugin) def add_table_items(self, plugs): self._installed += plugs data = _format_for_table(self._installed) ui_tools.load_table(self._table, (self.tr('Name'), self.tr('Version')), data) def _uninstall_plugins(self): data = _format_for_table(self._installed) plugins = ui_tools.remove_get_selected_items(self._table, data) self._parent.mark_as_available(plugins) def reset_table(self, installed): self._installed = installed while self._table.rowCount() > 0: self._table.removeRow(0) ui_tools.load_table(self._table, (self.tr('Name'), self.tr('Version')), self._installed)
class AccountManagerDialog(QDialog): def __init__(self, emails, types, parent): self.emails, self.types = emails, types QDialog.__init__(self, parent) self.resize(560, 350) self.gridLayout = QGridLayout(self) self.tableWidget = QTableWidget(0, 2, self) self.tableWidget.setAlternatingRowColors(True) self.tableWidget.setSelectionBehavior(1) # Rows self.tableWidget.setSelectionMode(1) # Single self.tableWidget.horizontalHeader().setResizeMode(0, 1) # 1 = Stretch self.tableWidget.setHorizontalHeaderLabels(['Email', 'Type']) self.addBtn = QPushButton('+', self) self.removeBtn = QPushButton('-', self) self.closeBtn = QPushButton('Close', self) self.spacer = QWidget(self) self.spacer.setSizePolicy(1 | 2 | 4, 1 | 4) self.gridLayout.addWidget(self.tableWidget, 0, 0, 1, 4) self.gridLayout.addWidget(self.addBtn, 1, 0, 1, 1) self.gridLayout.addWidget(self.removeBtn, 1, 1, 1, 1) self.gridLayout.addWidget(self.spacer, 1, 2, 1, 1) self.gridLayout.addWidget(self.closeBtn, 1, 3, 1, 1) self.addBtn.clicked.connect(self.addAccount) self.removeBtn.clicked.connect(self.removeAccount) self.closeBtn.clicked.connect(self.accept) for i in range(len(self.emails)): self.tableWidget.insertRow(i) self.tableWidget.setItem(i, 0, QTableWidgetItem(emails[i])) self.tableWidget.setItem(i, 1, QTableWidgetItem(types[i])) def addAccount(self): dialog = AddAccountDialog(self) if dialog.exec_() != QDialog.Accepted: return email = unicode(dialog.emailEdit.text()) passwd = unicode(dialog.passwordEdit.text()) ac_type = unicode(dialog.typeCombo.currentText()) self.tableWidget.insertRow(0) self.tableWidget.setItem(0, 0, QTableWidgetItem(email)) self.tableWidget.setItem(0, 1, QTableWidgetItem(ac_type)) self.emails.insert(0, email) self.types.insert(0, ac_type) kr = Keyring() kr.setPassword(email, passwd) def removeAccount(self): row = self.tableWidget.selectionModel().selectedRows()[0].row() email = self.tableWidget.item(row, 0).text() kr = Keyring() kr.deletePassword(email) self.tableWidget.removeRow(row) self.emails.pop(row) self.types.pop(row)
class AvailableWidget(QWidget): def __init__(self, parent, available): QWidget.__init__(self) self._parent = parent self._available = available vbox = QVBoxLayout(self) self._table = QTableWidget(1, 3) self._table.removeRow(0) vbox.addWidget(self._table) set_data(available, self._table) btnInstall = QPushButton('Install') btnInstall.setMaximumWidth(100) vbox.addWidget(btnInstall) hbox = QHBoxLayout() hbox.addWidget(QLabel('Add an external Plugin. URL Zip File:')) self.link = QLineEdit() hbox.addWidget(self.link) btnAdd = QPushButton('Add') hbox.addWidget(btnAdd) vbox.addLayout(hbox) self.connect(btnInstall, SIGNAL("clicked()"), self._install_plugins) self.connect(btnAdd, SIGNAL("clicked()"), self._install_external) def _install_plugins(self): rows = self._table.rowCount() pos = rows - 1 plugins = [] for i in xrange(rows): if self._table.item(pos-i, 0) is not None and \ self._table.item(pos-i, 0).checkState() == Qt.Checked: plugins.append(self._available.pop(pos-i)) self._table.removeRow(pos-i) self._parent.download_plugins(plugins) def _install_external(self): plug = [ manage_files.get_module_name(str(self.link.text())), 'External Plugin', '1.0', str(self.link.text()) ] self._parent.download_plugins(plug) self.link.setText('') def add_table_items(self, plugs): self._available += plugs set_data(self._available, self._table)
class AvailableWidget(QWidget): def __init__(self, parent, available): QWidget.__init__(self) self._parent = parent self._available = available vbox = QVBoxLayout(self) self._table = QTableWidget(1, 3) self._table.removeRow(0) vbox.addWidget(self._table) set_data(available, self._table) btnInstall = QPushButton("Install") btnInstall.setMaximumWidth(100) vbox.addWidget(btnInstall) hbox = QHBoxLayout() hbox.addWidget(QLabel("Add an external Plugin. URL Zip File:")) self.link = QLineEdit() hbox.addWidget(self.link) btnAdd = QPushButton("Add") hbox.addWidget(btnAdd) vbox.addLayout(hbox) lblExternalPlugin = QLabel('(Write the URL of the Plugin and press "Add")') lblExternalPlugin.setAlignment(Qt.AlignRight) vbox.addWidget(lblExternalPlugin) self.connect(btnInstall, SIGNAL("clicked()"), self._install_plugins) self.connect(btnAdd, SIGNAL("clicked()"), self._install_external) def _install_plugins(self): rows = self._table.rowCount() pos = rows - 1 plugins = [] for i in xrange(rows): if self._table.item(pos - i, 0) is not None and self._table.item(pos - i, 0).checkState() == Qt.Checked: plugins.append(self._available.pop(pos - i)) self._table.removeRow(pos - i) self._parent.download_plugins(plugins) def _install_external(self): if self.link.text().isEmpty(): QMessageBox.information(self, "External Plugins", "URL from Plugin missing...") return plug = [manage_files.get_module_name(str(self.link.text())), "External Plugin", "1.0", str(self.link.text())] self._parent.download_plugins(plug) self.link.setText("") def add_table_items(self, plugs): self._available += plugs set_data(self._available, self._table)
class UpdatesWidget(QWidget): """ This widget show the availables plugins to update """ def __init__(self, parent, updates): QWidget.__init__(self, parent) self._parent = parent self._updates = updates vbox = QVBoxLayout(self) self._table = QTableWidget(1, 2) self._table.removeRow(0) self._table.setSelectionMode(QTableWidget.SingleSelection) self._table.setColumnWidth(0, 500) self._table.setSortingEnabled(True) self._table.setAlternatingRowColors(True) vbox.addWidget(self._table) ui_tools.load_table(self._table, (self.tr('Name'), self.tr('Version')), _format_for_table(updates)) btnUpdate = QPushButton(self.tr("Update")) btnUpdate.setMaximumWidth(100) vbox.addWidget(btnUpdate) self.connect(btnUpdate, SIGNAL("clicked()"), self._update_plugins) self.connect(self._table, SIGNAL("itemSelectionChanged()"), self._show_item_description) def _show_item_description(self): item = self._table.currentItem() if item is not None: data = list(item.data(Qt.UserRole)) self._parent.show_plugin_info(data) def _update_plugins(self): data = _format_for_table(self._updates) plugins = ui_tools.remove_get_selected_items(self._table, data) #get the download link of each plugin for p_row in plugins: #search the plugin for p_dict in self._updates: if p_dict["name"] == p_row[0]: p_data = p_dict break #append the downlod link p_row.append(p_data["download"]) self._parent.update_plugin(plugins)
def load_relation(self, filenames=[]): """ Load relation from file """ import csv from PyQt4.QtGui import QTableWidgetItem, QTableWidget from src.core import relation if not filenames: native_dialog = QFileDialog.DontUseNativeDialog directory = os.path.expanduser("~") ffilter = settings.RFILES.split(';;')[-1] filenames = QFileDialog.getOpenFileNames(self, self.tr("Abrir Archivo"), directory, ffilter, native_dialog) if not filenames: return lateral = Pireal.get_service("lateral") for filename in filenames: rel = relation.Relation(filename) relation_name = os.path.splitext(os.path.basename(filename))[0] self.table_widget.relations[relation_name] = rel table = QTableWidget() with open(filename, newline='') as f: table.setRowCount(0) table.setColumnCount(0) csv_reader = csv.reader(f) for row_data in csv_reader: row = table.rowCount() table.setColumnCount(len(row_data)) for column, data in enumerate(row_data): item = QTableWidgetItem() item.setText(data) if row == 0: table.setHorizontalHeaderItem(column, item) else: table.setItem(row - 1, column, item) table.insertRow(row) table.removeRow(table.rowCount() - 1) self.table_widget.stacked.addWidget(table) #FIXME: names names = [os.path.splitext(os.path.basename(i))[0] for i in filenames] lateral.add_item_list(names) lateral.show()
class UpdatesWidget(QWidget): """ This widget show the availables plugins to update """ def __init__(self, parent, updates): QWidget.__init__(self, parent) self._parent = parent self._updates = updates vbox = QVBoxLayout(self) self._table = QTableWidget(1, 2) self._table.removeRow(0) self._table.setSelectionMode(QTableWidget.SingleSelection) self._table.setColumnWidth(0, 500) vbox.addWidget(self._table) ui_tools.load_table(self._table, TABLE_HEADER, _format_for_table(updates)) btnUpdate = QPushButton(self.tr("Update")) btnUpdate.setMaximumWidth(100) vbox.addWidget(btnUpdate) self.connect(btnUpdate, SIGNAL("clicked()"), self._update_plugins) self.connect(self._table, SIGNAL("itemSelectionChanged()"), self._show_item_description) def _show_item_description(self): item = self._table.currentItem() if item is not None: data = list(item.data(Qt.UserRole)) self._parent.show_plugin_info(data) def _update_plugins(self): data = _format_for_table(self._updates) plugins = ui_tools.remove_get_selected_items(self._table, data) #get the download link of each plugin for p_row in plugins: #search the plugin for p_dict in self._updates: if p_dict["name"] == p_row[0]: p_data = p_dict break #append the downlod link p_row.append(p_data["download"]) self._parent.update_plugin(plugins)
class InstalledWidget(QWidget): """ This widget show the installed plugins """ def __init__(self, parent, installed): QWidget.__init__(self, parent) self._parent = parent self._installed = installed vbox = QVBoxLayout(self) self._table = QTableWidget(1, 5) self._table.removeRow(0) self._headers = ('Name', 'Version', 'Description', "Authors", "Web") vbox.addWidget(self._table) ui_tools.load_table(self._table, self._headers, _format_for_table(installed)) self._table.setColumnWidth(0, 200) btnUninstall = QPushButton(self.tr("Uninstall")) btnUninstall.setMaximumWidth(100) vbox.addWidget(btnUninstall) self.connect(btnUninstall, SIGNAL("clicked()"), self._uninstall_plugins) def remove_item(self, plugin_name): plugin = _get_plugin(plugin_name, self._installed) self._installed.remove(plugin) def add_table_items(self, plugs): self._installed += plugs data = _format_for_table(self._installed) ui_tools.load_table(self._table, self._headers, data) def _uninstall_plugins(self): data = _format_for_table(self._installed) plugins = ui_tools.remove_get_selected_items(self._table, data) self._parent.mark_as_available(plugins) def reset_table(self, installed): self._installed = installed while self._table.rowCount() > 0: self._table.removeRow(0) ui_tools.load_table(self._table, self._headers, self._installed)
class SchemeWidget(QWidget): def __init__(self, parent, schemes): QWidget.__init__(self, parent) self._parent = parent self._schemes = schemes vbox = QVBoxLayout(self) self._table = QTableWidget(1, 2) self._table.removeRow(0) vbox.addWidget(self._table) ui_tools.load_table(self._table, ['Name', 'URL'], self._schemes) btnUninstall = QPushButton('Download') btnUninstall.setMaximumWidth(100) vbox.addWidget(btnUninstall) self._table.setColumnWidth(0, 200) self.connect(btnUninstall, SIGNAL("clicked()"), self._download_scheme) def _download_scheme(self): schemes = ui_tools.remove_get_selected_items(self._table, self._schemes) self._parent.download_scheme(schemes)
class InstalledWidget(QWidget): def __init__(self, parent, installed): QWidget.__init__(self) self._parent = parent self._installed = installed vbox = QVBoxLayout(self) self._table = QTableWidget(1, 3) self._table.removeRow(0) vbox.addWidget(self._table) set_data(self._installed, self._table) btnUninstall = QPushButton('Uninstall') btnUninstall.setMaximumWidth(100) vbox.addWidget(btnUninstall) self.connect(btnUninstall, SIGNAL("clicked()"), self._uninstall_plugins) def add_table_items(self, plugs): self._installed += plugs set_data(self._installed, self._table) def _uninstall_plugins(self): rows = self._table.rowCount() pos = rows - 1 for i in xrange(rows): if self._table.item(pos-i, 0) is not None and \ self._table.item(pos-i, 0).checkState() == Qt.Checked: self._parent.mark_as_available(self._installed.pop(pos-i)) self._table.removeRow(pos-i) def reset_table(self, installed): self._installed = installed while self._table.rowCount() > 0: self._table.removeRow(0) set_data(self._installed, self._table)
class LanguageWidget(QWidget): def __init__(self, parent, languages): QWidget.__init__(self, parent) self._parent = parent self._languages = languages vbox = QVBoxLayout(self) self._table = QTableWidget(1, 2) self._table.removeRow(0) vbox.addWidget(self._table) ui_tools.load_table(self._table, [self.tr('Language'), self.tr('URL')], self._languages) btnUninstall = QPushButton(self.tr('Download')) btnUninstall.setMaximumWidth(100) vbox.addWidget(btnUninstall) self._table.setColumnWidth(0, 200) self.connect(btnUninstall, SIGNAL("clicked()"), self._download_language) def _download_language(self): languages = ui_tools.remove_get_selected_items(self._table, self._languages) self._parent.download_language(languages)
class LanguageWidget(QWidget): def __init__(self, parent, languages): QWidget.__init__(self, parent) self._parent = parent self._languages = languages vbox = QVBoxLayout(self) self._table = QTableWidget(1, 2) self._table.removeRow(0) vbox.addWidget(self._table) ui_tools.load_table( self._table, [self.tr('Language'), self.tr('URL')], self._languages) btnUninstall = QPushButton(self.tr('Download')) btnUninstall.setMaximumWidth(100) vbox.addWidget(btnUninstall) self._table.setColumnWidth(0, 200) self.connect(btnUninstall, SIGNAL("clicked()"), self._download_language) def _download_language(self): languages = ui_tools.remove_get_selected_items(self._table, self._languages) self._parent.download_language(languages)
class OWxsh_waviness(widget.OWWidget): name = "xsh_waviness" id = "orange.widgets.preprocessor.xsh_waviness" description = "xoppy application to compute..." icon = "icons/waviness.png" author = "Luca Rebuffi" maintainer_email = "[email protected]; [email protected]" priority = 10 category = "" keywords = ["xoppy", "xsh_waviness"] outputs = [{"name": "PreProcessor_Data", "type": ShadowPreProcessorData, "doc": "PreProcessor Data", "id": "PreProcessor_Data"}] want_main_area = 1 want_control_area = 1 WIDGET_WIDTH = 1100 WIDGET_HEIGHT = 650 xx = None yy = None zz = None number_of_points_x = Setting(10) number_of_points_y = Setting(100) dimension_x = Setting(20.1) dimension_y = Setting(113.1) estimated_slope_error = Setting(0.9) montecarlo_seed = Setting(2387427) waviness_file_name = Setting('waviness.dat') harmonic_maximum_index = Setting(60) data = Setting({'c': ['0.3', '0.1', '0.1', '0.0', '0.0', '0.0', '0.3', '0.0', '0.0', '0.3', '0.0', '0.0', '0.5', '0.0', '0.0', '0.2', '0.2', '0.2', '0.9', '0.0', '0.0', '0.0', '0.0', '0.0', '0.4', '0.0', '0.0', '0.4', '0.0', '0.0', '0.0', '0.6', '0.6', '0.0', '0.4', '0.4', '0.0', '0.4', '0.4', '0.1', '0.4', '0.4', '0.1', '0.2', '0.2', '0.0', '0.2', '0.2', '0.0', '0.3', '0.3', '0.0', '0.0', '0.0', '0.0', '0.0', '0.0', '0.0', '0.0', '0.0', '0.0'], 'y': ['0.0', '-0.1', '-0.1', '0.0', '0.0', '0.0', '0.03', '0.0', '0.0', '0.2', '0.0', '0.0', '0.2', '0.0', '0.0', '0.1', '0.1', '0.1', '0.1', '0.0', '0.0', '0.0', '0.0', '0.0', '0.01', '0.0', '0.0', '0.03', '0.0', '0.0', '0.0', '0.02', '0.02', '0.0', '0.1', '0.1', '0.0', '0.1', '0.1', '0.0', '0.1', '0.1', '0.0', '0.0', '0.0', '0.0', '0.3', '0.3', '0.0', '0.2', '0.2', '0.0', '0.2', '0.2', '0.0', '0.2', '0.2', '0.0', '0.0', '0.0', '0.0'], 'g': ['0.0', '0.3', '0.3', '0.0', '0.0', '0.0', '0.05', '0.0', '0.0', '0.05', '0.0', '0.0', '0.1', '0.0', '0.0', '0.05', '0.05', '0.05', '0.2', '0.0', '0.0', '0.0', '0.0', '0.0', '0.1', '0.0', '0.0', '0.1', '0.0', '0.0', '0.0', '0.2', '0.2', '0.0', '0.1', '0.1', '0.0', '0.1', '0.1', '0.0', '0.1', '0.1', '0.0', '0.0', '0.0', '0.0', '0.1', '0.1', '0.0', '0.2', '0.2', '0.0', '0.1', '0.1', '0.0', '0.1', '0.1', '0.0', '0.0', '0.0', '0.0']}) def __init__(self): super().__init__() geom = QApplication.desktop().availableGeometry() self.setGeometry(QRect(round(geom.width() * 0.05), round(geom.height() * 0.05), round(min(geom.width() * 0.98, self.WIDGET_WIDTH)), round(min(geom.height() * 0.95, self.WIDGET_HEIGHT)))) gen_box = ShadowGui.widgetBox(self.controlArea, "Waviness Parameters", addSpace=True, orientation="horizontal", width=500) tabs_setting = gui.tabWidget(gen_box) tab_input = ShadowGui.createTabPage(tabs_setting, "Input Parameter") tab_harmonics = ShadowGui.createTabPage(tabs_setting, "Harmonics") tab_out = ShadowGui.createTabPage(tabs_setting, "Output") self.input_box = ShadowGui.widgetBox(tab_input, "Inputs", addSpace=True, orientation="vertical", width=470) gui.button(self.input_box, self, "Load xsh_waviness input file ...", callback=self.load_inp_file) gui.separator(self.input_box) ShadowGui.lineEdit(self.input_box, self, "number_of_points_x", "Number of Points (<201) X (width)", labelWidth=300, valueType=int, orientation="horizontal") ShadowGui.lineEdit(self.input_box, self, "number_of_points_y", " Y (length)", labelWidth=300, valueType=int, orientation="horizontal") gui.separator(self.input_box) ShadowGui.lineEdit(self.input_box, self, "dimension_x", "Dimensions [cm] X (width)", labelWidth=300, valueType=float, orientation="horizontal") ShadowGui.lineEdit(self.input_box, self, "dimension_y", " Y (length)", labelWidth=300, valueType=float, orientation="horizontal") gui.separator(self.input_box) ShadowGui.lineEdit(self.input_box, self, "estimated_slope_error", "Estimated slope error [arcsec]", labelWidth=300, valueType=float, orientation="horizontal") ShadowGui.lineEdit(self.input_box, self, "montecarlo_seed", "Monte Carlo initial seed", labelWidth=300, valueType=int, orientation="horizontal") self.output_box = ShadowGui.widgetBox(tab_input, "Outputs", addSpace=True, orientation="vertical", width=470) self.select_file_box = ShadowGui.widgetBox(self.output_box, "", addSpace=True, orientation="horizontal") gui.separator(self.output_box) gui.button(self.output_box, self, "Write xsh_waviness input file (optional) ...", callback=self.write_inp_file) ShadowGui.lineEdit(self.select_file_box, self, "waviness_file_name", "Output File Name", labelWidth=120, valueType=str, orientation="horizontal") self.harmonics_box = ShadowGui.widgetBox(tab_harmonics, "Harmonics", addSpace=True, orientation="vertical", width=470, height=690) ShadowGui.lineEdit(self.harmonics_box, self, "harmonic_maximum_index", "Harmonic Maximum Index", labelWidth=300, valueType=int, orientation="horizontal", callback=self.set_harmonics) gui.separator(self.harmonics_box) self.scrollarea = QScrollArea() self.scrollarea.setMaximumWidth(400) self.harmonics_box.layout().addWidget(self.scrollarea, alignment=Qt.AlignHCenter) self.shadow_output = QTextEdit() self.shadow_output.setReadOnly(True) out_box = ShadowGui.widgetBox(tab_out, "System Output", addSpace=True, orientation="horizontal", height=600) out_box.layout().addWidget(self.shadow_output) button_box = ShadowGui.widgetBox(self.controlArea, "", addSpace=False, orientation="horizontal") button = gui.button(button_box, self, "Calculate Waviness", callback=self.calculate_waviness) button.setFixedHeight(45) button.setFixedWidth(170) button = gui.button(button_box, self, "Generate Waviness File", callback=self.generate_waviness_file) font = QFont(button.font()) font.setBold(True) button.setFont(font) palette = QPalette(button.palette()) # make a copy of the palette palette.setColor(QPalette.ButtonText, QColor('Dark Blue')) button.setPalette(palette) # assign new palette button.setFixedHeight(45) button.setFixedWidth(200) button = gui.button(button_box, self, "Reset Fields", callback=self.call_reset_settings) font = QFont(button.font()) font.setItalic(True) button.setFont(font) palette = QPalette(button.palette()) # make a copy of the palette palette.setColor(QPalette.ButtonText, QColor('Dark Red')) button.setPalette(palette) # assign new palette button.setFixedHeight(45) button.setFixedWidth(120) gui.rubber(self.controlArea) self.figure = Figure(figsize=(600, 600)) self.figure.patch.set_facecolor('white') self.axis = self.figure.add_subplot(111, projection='3d') self.axis.set_xlabel("X (cm)") self.axis.set_ylabel("Y (cm)") self.axis.set_zlabel("Z (µm)") self.figure_canvas = FigureCanvasQTAgg(self.figure) self.mainArea.layout().addWidget(self.figure_canvas) gui.rubber(self.mainArea) def restoreWidgetPosition(self): super().restoreWidgetPosition() self.table = QTableWidget(self.harmonic_maximum_index + 1, 3) self.table.setAlternatingRowColors(True) self.table.horizontalHeader().setResizeMode(QHeaderView.Fixed) for i in range(0, 3): self.table.setColumnWidth(i, 70) horHeaders = [] verHeaders = [] for n, key in enumerate(sorted(self.data.keys())): horHeaders.append(key) for m, item in enumerate(self.data[key]): table_item = QTableWidgetItem(str(item)) table_item.setTextAlignment(Qt.AlignRight) self.table.setItem(m, n, table_item) verHeaders.append(str(m)) self.table.setHorizontalHeaderLabels(horHeaders) self.table.setVerticalHeaderLabels(verHeaders) self.table.resizeRowsToContents() self.table.itemChanged.connect(self.table_item_changed) self.scrollarea.setWidget(self.table) self.scrollarea.setWidgetResizable(1) gui.rubber(self.controlArea) def reload_harmonics_table(self): horHeaders = [] verHeaders = [] self.table.itemChanged.disconnect(self.table_item_changed) self.table.clear() row_count = self.table.rowCount() for n in range(0, row_count): self.table.removeRow(0) for index in range(0, self.harmonic_maximum_index + 1): self.table.insertRow(0) for n, key in enumerate(sorted(self.data.keys())): horHeaders.append(key) for m, item in enumerate(self.data[key]): table_item = QTableWidgetItem(str(item)) table_item.setTextAlignment(Qt.AlignRight) self.table.setItem(m, n, table_item) verHeaders.append(str(m)) self.table.setHorizontalHeaderLabels(horHeaders) self.table.setVerticalHeaderLabels(verHeaders) self.table.resizeRowsToContents() for i in range(0, 3): self.table.setColumnWidth(i, 70) self.table.itemChanged.connect(self.table_item_changed) def table_item_changed(self): dict = {} message = "" error_row_index = -1 error_column_index = -1 previous_value = "" try: row_count = self.harmonic_maximum_index + 1 for column_index in range(0, self.table.columnCount()): column_name = self.table.horizontalHeaderItem(column_index).data(0) row_content = [] for row_index in range(0, row_count): if not self.table.item(row_index, column_index) is None: message = "Value at row " + str( row_index) + " and column \'" + column_name + "\' is not numeric" error_row_index = row_index error_column_index = column_index previous_value = self.data[column_name][row_index] value = float(self.table.item(row_index, column_index).data(0)) # to raise exception row_content.append(str(value)) dict[column_name] = row_content self.data = dict except ValueError: QMessageBox.critical(self, "QMessageBox.critical()", message + "\nValue is reset to previous value", QMessageBox.Ok) table_item = QTableWidgetItem(previous_value) table_item.setTextAlignment(Qt.AlignRight) self.table.setItem(error_row_index, error_column_index, table_item) self.table.setCurrentCell(error_row_index, error_column_index) except Exception as exception: QMessageBox.critical(self, "QMessageBox.critical()", exception.args[0], QMessageBox.Ok) def set_harmonics(self): if self.harmonic_maximum_index < 0: QMessageBox.critical(self, "QMessageBox.critical()", "Harmonic Maximum Index should be a positive integer number", QMessageBox.Ok) else: row_count = len(self.data["c"]) if self.harmonic_maximum_index + 1 > row_count: for n, key in enumerate(sorted(self.data.keys())): for m in range(row_count, self.harmonic_maximum_index + 1): self.data[key].append('0.0') else: for n, key in enumerate(sorted(self.data.keys())): self.data[key] = copy.deepcopy(self.data[key][0: self.harmonic_maximum_index + 1]) self.reload_harmonics_table() def load_inp_file(self): file_name = QFileDialog.getOpenFileName(self, "Select a input file for XSH_WAVINESS", ".", "*.inp") if not file_name is None: sys.stdout = EmittingStream(textWritten=self.writeStdOut) if not file_name.strip() == "": dict = ST.waviness_read(file=file_name) self.number_of_points_x = dict["npointx"] self.number_of_points_y = dict["npointy"] self.dimension_y = dict["xlength"] self.dimension_x = dict["width"] self.estimated_slope_error = dict["slp"] self.montecarlo_seed = dict["iseed"] self.waviness_file_name = dict["file"].strip('\n\r').strip() self.harmonic_maximum_index = dict["nharmonics"] self.data["c"] = self.to_str_array(dict["c"]) self.data["y"] = self.to_str_array(dict["y"]) self.data["g"] = self.to_str_array(dict["g"]) self.reload_harmonics_table() def write_inp_file(self): try: sys.stdout = EmittingStream(textWritten=self.writeStdOut) self.check_fields() file_name = self.waviness_file_name.strip().split(sep=".dat")[0] + ".inp" dict = {} dict["npointx"] = self.number_of_points_x dict["npointy"] = self.number_of_points_y dict["xlength"] = self.dimension_y dict["width"] = self.dimension_x dict["slp"] = self.estimated_slope_error dict["iseed"] = self.montecarlo_seed dict["file"] = self.waviness_file_name.strip('\n\r') dict["nharmonics"] = self.harmonic_maximum_index dict["c"] = self.to_float_array(self.data["c"]) dict["y"] = self.to_float_array(self.data["y"]) dict["g"] = self.to_float_array(self.data["g"]) ST.waviness_write(dict, file=file_name) QMessageBox.information(self, "QMessageBox.information()", "File \'" + file_name + "\' written to disk", QMessageBox.Ok) except Exception as exception: QMessageBox.critical(self, "QMessageBox.critical()", exception.args[0], QMessageBox.Ok) def calculate_waviness(self): try: sys.stdout = EmittingStream(textWritten=self.writeStdOut) self.check_fields() xx, yy, zz = ST.waviness_calc(npointx=self.number_of_points_x, npointy=self.number_of_points_y, width=self.dimension_x, xlength=self.dimension_y, slp=self.estimated_slope_error, nharmonics=self.harmonic_maximum_index, iseed=self.montecarlo_seed, c=self.to_float_array(self.data["c"]), y=self.to_float_array(self.data["y"]), g=self.to_float_array(self.data["g"])) self.xx = xx self.yy = yy self.zz = zz self.axis.clear() x_to_plot, y_to_plot = numpy.meshgrid(xx, yy) z_to_plot = [] for y_index in range(0, len(yy)): z_array = [] for x_index in range(0, len(xx)): z_array.append(1e4 * float(zz[x_index][y_index])) # to micron z_to_plot.append(z_array) z_to_plot = numpy.array(z_to_plot) self.axis.plot_surface(x_to_plot, y_to_plot, z_to_plot, rstride=1, cstride=1, cmap=cm.autumn, linewidth=0.5, antialiased=True) slope, sloperms = ST.slopes(zz, xx, yy) title = ' Slope error rms in X direction: %f arcsec' % (sloperms[0]) + '\n' + \ ' : %f urad' % (sloperms[2]) + '\n' + \ ' Slope error rms in Y direction: %f arcsec' % (sloperms[1]) + '\n' + \ ' : %f urad' % (sloperms[3]) self.axis.set_xlabel("X (cm)") self.axis.set_ylabel("Y (cm)") self.axis.set_zlabel("Z (µm)") self.axis.set_title(title) self.axis.mouse_init() self.figure_canvas.draw() QMessageBox.information(self, "QMessageBox.information()", "Waviness calculated: if the result is satisfactory,\nclick \'Generate Waviness File\' to complete the operation ", QMessageBox.Ok) except Exception as exception: QMessageBox.critical(self, "QMessageBox.critical()", exception.args[0], QMessageBox.Ok) def generate_waviness_file(self): if not self.zz is None and not self.yy is None and not self.xx is None: if not self.waviness_file_name is None: self.waviness_file_name = self.waviness_file_name.strip() if self.waviness_file_name == "": raise Exception("Output File Name missing") else: raise Exception("Output File Name missing") sys.stdout = EmittingStream(textWritten=self.writeStdOut) ST.write_shadow_surface(self.zz.T, self.xx, self.yy, outFile=self.waviness_file_name) QMessageBox.information(self, "QMessageBox.information()", "Waviness file " + self.waviness_file_name + " written on disk", QMessageBox.Ok) self.send("PreProcessor_Data", ShadowPreProcessorData(waviness_data_file=self.waviness_file_name)) def call_reset_settings(self): if ConfirmDialog.confirmed(parent=self, message="Confirm Reset of the Fields?"): try: self.resetSettings() self.reload_harmonics_table() except: pass def check_fields(self): self.number_of_points_x = ShadowGui.checkStrictlyPositiveNumber(self.number_of_points_x, "Number of Points X") self.number_of_points_y = ShadowGui.checkStrictlyPositiveNumber(self.number_of_points_y, "Number of Points Y") self.dimension_x = ShadowGui.checkStrictlyPositiveNumber(self.dimension_x, "Dimension X") self.dimension_y = ShadowGui.checkStrictlyPositiveNumber(self.dimension_y, "Dimension Y") self.estimated_slope_error = ShadowGui.checkPositiveNumber(self.estimated_slope_error, "Estimated slope error") self.montecarlo_seed = ShadowGui.checkPositiveNumber(self.montecarlo_seed, "Monte Carlo initial seed") self.harmonic_maximum_index = ShadowGui.checkPositiveNumber(self.harmonic_maximum_index, "Harmonic Maximum Index") if not self.waviness_file_name is None: self.waviness_file_name = self.waviness_file_name.strip() if self.waviness_file_name == "": raise Exception("Output File Name missing") else: raise Exception("Output File Name missing") def to_float_array(self, string_array): float_array = [] for index in range(len(string_array)): float_array.append(float(string_array[index])) return float_array def to_str_array(self, float_array): string_array = [] for index in range(len(float_array)): string_array.append(str(float_array[index])) return string_array def writeStdOut(self, text): cursor = self.shadow_output.textCursor() cursor.movePosition(QTextCursor.End) cursor.insertText(text) self.shadow_output.setTextCursor(cursor) self.shadow_output.ensureCursorVisible()
class NewRelationDialog(QDialog): def __init__(self, parent=None): QDialog.__init__(self, parent) self.setWindowTitle(self.tr("Nueva Relación")) vbox = QVBoxLayout(self) hbox = QHBoxLayout() self._line_relation_name = QLineEdit() hbox.addWidget(QLabel(self.tr("Nombre:"))) hbox.addWidget(self._line_relation_name) vbox.addLayout(hbox) vbox.addWidget(QLabel( self.tr("La primera fila corresponde a los campos"))) hbox = QHBoxLayout() btn_add_column = QPushButton(self.tr("Agregar Columna")) hbox.addWidget(btn_add_column) btn_add_tuple = QPushButton(self.tr("Agregar Tupla")) hbox.addWidget(btn_add_tuple) btn_remove_column = QPushButton(self.tr("Eliminar Columna")) hbox.addWidget(btn_remove_column) btn_remove_tuple = QPushButton(self.tr("Eliminar Tupla")) hbox.addWidget(btn_remove_tuple) vbox.addLayout(hbox) self._table = QTableWidget() vbox.addWidget(self._table) self._table.setRowCount(1) self._table.setColumnCount(2) self._table.setItem(0, 0, QTableWidgetItem("Campo 1")) self._table.setItem(0, 1, QTableWidgetItem("Campo 2")) hbox = QHBoxLayout() hbox.addItem(QSpacerItem(1, 0, QSizePolicy.Expanding)) btn_ok = QPushButton(self.tr("Aceptar")) hbox.addWidget(btn_ok) btn_cancel = QPushButton(self.tr("Cancelar")) hbox.addWidget(btn_cancel) vbox.addLayout(hbox) # Connections self.connect(btn_add_column, SIGNAL("clicked()"), self.__add_column) self.connect(btn_remove_column, SIGNAL("clicked()"), self.__remove_column) self.connect(btn_add_tuple, SIGNAL("clicked()"), self.__add_tuple) self.connect(btn_remove_tuple, SIGNAL("clicked()"), self.__remove_tuple) self.connect(btn_ok, SIGNAL("clicked()"), self.__create_table) self.connect(btn_cancel, SIGNAL("clicked()"), self.close) def __add_column(self): columns = self._table.columnCount() self._table.insertColumn(columns) def __remove_column(self): current = self._table.currentColumn() self._table.removeColumn(current) def __add_tuple(self): tuples = self._table.rowCount() self._table.insertRow(tuples) def __remove_tuple(self): current = self._table.currentRow() self._table.removeRow(current) def __create_table(self): name = self._line_relation_name.text() rows = self._table.rowCount() columns = self._table.columnCount() rel = relation.Relation() fields = [self._table.item(0, i).text() for i in range(columns)] rel.fields = fields data = {} for row in range(1, rows): reg = [] for column in range(columns): reg.append(self._table.item(row, column).text()) data[row, column] = self._table.item(row, column).text() rel.insert(reg) table_widget = Pireal.get_service("container").table_widget table_widget.add_table(rows - 1, columns, name, data) #table_widget.relations[name] = rel self.close()
class KeywordTable(HelpedWidget): """Shows a table of key/value pairs. The data structure expected and sent to the getter and setter is a dictionary of values.""" def __init__(self, model, table_label="", help_link=""): HelpedWidget.__init__(self, table_label, help_link) self.table = QTableWidget(self) self.table.setColumnCount(2) self.setColumnHeaders() self.table.verticalHeader().setHidden(True) self.table.setColumnWidth(0, 150) self.table.horizontalHeader().setStretchLastSection(True) self.table.setMinimumHeight(110) self.table.setSelectionMode(QAbstractItemView.SingleSelection) self.table.setSelectionBehavior(QAbstractItemView.SelectRows) self.addWidget(self.table) self.addWidget(AddRemoveWidget(self.addItem, self.removeItem)) self.connect(self.table, SIGNAL('cellChanged(int,int)'), self.tableChanged) assert isinstance(model, DictionaryModelMixin) self.model = model model.observable().attach(DictionaryModelMixin.DICTIONARY_CHANGED_EVENT, self.modelChanged) self.modelChanged() def setColumnHeaders(self, keyword_name="Keyword", value_name="Value"): self.headers = [keyword_name, value_name] self.table.setHorizontalHeaderLabels(self.headers) def addItem(self): """Called by the add button to insert a new keyword""" title = "New %s" % self.headers[0] description = "Enter new %s:" % self.headers[0] (new_keyword, ok) = QInputDialog.getText(self, title, description, QLineEdit.Normal) if ok: new_keyword = str(new_keyword).strip() self.model.addKey(new_keyword) def removeItem(self): """Called by the remove button to remove a selected keyword""" current_row = self.table.currentRow() if current_row >= 0: do_delete = QMessageBox.question(self, "Delete row?", "Are you sure you want to delete the key/value pair?", QMessageBox.Yes | QMessageBox.No ) if do_delete: key_item = self.table.item(current_row, 0) if key_item is not None: key = str(key_item.text()).strip() self.model.removeKey(key) def tableChanged(self, row, column): """Called whenever the contents of a cell changes.""" key_item = self.table.item(row, 0) if key_item is not None: key = str(key_item.text()).strip() value_item = self.table.item(row, 1) if value_item is not None: value = str(value_item.text()).strip() self.model.setValueForKey(key, value) def modelChanged(self): """Retrieves data from the model and inserts it into the table.""" values = self.model.getDictionary() blocked = self.table.blockSignals(True) for row in reversed(range(self.table.rowCount())): self.table.removeRow(row) row = 0 for key in values: key_item = QTableWidgetItem(str(key)) key_item.setFlags(key_item.flags() ^ Qt.ItemIsEditable) value_item = QTableWidgetItem(str(values[key])) self.table.insertRow(row) self.table.setItem(row, 0, key_item) self.table.setItem(row, 1, value_item) row += 1 self.table.blockSignals(blocked)
class WellMarkerDialog(QDialog): def __init__(self, well): super(WellMarkerDialog, self).__init__() self.well = well self.setupUi() self.initUI() self.button_box.accepted.connect(self.save_markers) self.button_box.rejected.connect(self.close) self.add_Button.clicked.connect(self.add_row) self.del_Button.clicked.connect(self.del_row) self.export_Button.clicked.connect(self.export_markers) self.import_Button.clicked.connect(self.import_markers) def setupUi(self): self.resize(568, 411) self.setWindowIcon(QIcon(':/icon/layer_icon')) self.setWindowTitle("Edit Markers") self.gridLayout = QGridLayout(self) # table widget self.tableWidget = QTableWidget(self) self.tableWidget.setColumnCount(4) self.tableWidget.setRowCount(0) self.tableWidget.setHorizontalHeaderItem(0, QTableWidgetItem("Name")) self.tableWidget.setHorizontalHeaderItem(1, QTableWidgetItem("TVD (m)")) self.tableWidget.setHorizontalHeaderItem(2, QTableWidgetItem("TVDSS (m)")) self.tableWidget.setHorizontalHeaderItem(3, QTableWidgetItem("Color")) self.gridLayout.addWidget(self.tableWidget, 0, 0, 1, 1) # button box self.button_box = QDialogButtonBox(self) self.export_Button = self.button_box.addButton( "Export", QDialogButtonBox.ResetRole) self.import_Button = self.button_box.addButton( "Import", QDialogButtonBox.ResetRole) self.add_Button = self.button_box.addButton("Add", QDialogButtonBox.ResetRole) self.del_Button = self.button_box.addButton("Del", QDialogButtonBox.ResetRole) self.button_box.setStandardButtons(QDialogButtonBox.Save | QDialogButtonBox.Cancel) self.gridLayout.addWidget(self.button_box, 1, 0, 1, 1) def initUI(self): self.populate_marker_table() def populate_marker_table(self): try: markers_dict = self.well.params["horizon"] for mark in markers_dict.keys(): self.tableWidget.insertRow(0) self.tableWidget.setItem(0, 0, QTableWidgetItem(mark)) self.tableWidget.setItem( 0, 1, QTableWidgetItem(str(markers_dict[mark]))) self.tableWidget.setItem( 0, 2, QTableWidgetItem(str(markers_dict[mark]))) self.tableWidget.sortItems(0, Qt.AscendingOrder) except KeyError: pass def add_row(self): self.tableWidget.insertRow(self.tableWidget.rowCount()) def del_row(self): self.tableWidget.removeRow(self.tableWidget.currentRow()) def save_markers(self): l_names = [str(self.tableWidget.item(irow, 0).text()) \ for irow in range(self.tableWidget.rowCount())] l_md = [float(self.tableWidget.item(irow, 1).text()) \ for irow in range(self.tableWidget.rowCount())] new_dict = OrderedDict([(a, b) for a, b in zip(l_names, l_md)]) if self.well.params['horizon'] != new_dict: respond = QMessageBox.question( self, "Save Markers", "Sure to save changes?", QMessageBox.Save | QMessageBox.Cancel) if respond == QMessageBox.Save: self.well.params['horizon'] = new_dict self.well.save_params() self.close() def export_markers(self): file_path = str(QFileDialog.getSaveFileName(self, "Save Markers")) l_names = [str(self.tableWidget.item(irow, 0).text()) \ for irow in range(self.tableWidget.rowCount())] l_md = [float(self.tableWidget.item(irow, 1).text()) \ for irow in range(self.tableWidget.rowCount())] df = pd.DataFrame({"name": l_names, "MD(m)": l_md}) df.to_csv(file_path, sep='\t', columns=["name", "MD(m)"], index=False) QMessageBox.information(self, "Export Markers", "Succeed!") def import_markers(self): read_csv_dialog = ReadCsvDialog() read_csv_dialog.setWindowIcon(QIcon(':/icon/layer_icon')) read_csv_dialog.setWindowTitle("Open Markers File") read_csv_dialog.label.setText("Read Makers from File") read_csv_dialog.exec_()
class wavListDialog(QDialog): def __init__(self, parent): QDialog.__init__(self, parent) self.prm = self.parent().parent().prm self.audioManager = audioManager(self) self.currLocale = self.parent().parent().prm['currentLocale'] self.currLocale.setNumberOptions(self.currLocale.OmitGroupSeparator | self.currLocale.RejectGroupSeparator) self.isPlaying = False self.sizer = QGridLayout() self.v1Sizer = QVBoxLayout() self.wavsTableWidget = QTableWidget() self.wavsTableWidget.setColumnCount(4) self.wavsTableWidget.setSelectionBehavior(QAbstractItemView.SelectRows) self.wavsTableWidget.setSelectionMode(QAbstractItemView.ExtendedSelection) self.wavsTableWidget.setHorizontalHeaderLabels([self.tr("File"), self.tr('Use'), self.tr("RMS Level"), 'id']) self.quidColumn = 3 self.wavsTableWidget.hideColumn(self.quidColumn) self.wavsTableWidget.cellDoubleClicked[int,int].connect(self.onCellDoubleClicked) #ADD wav BUTTON self.addWavButton = QPushButton(self.tr("Add Wav"), self) self.addWavButton.clicked.connect(self.onClickAddWavButton) #REMOVE wav BUTTON self.removeWavButton = QPushButton(self.tr("Remove Wav"), self) self.removeWavButton.clicked.connect(self.onClickRemoveWavButton) #PLAY wav BUTTON self.playWavButton = QPushButton(self.tr("Play Wav"), self) self.playWavButton.clicked.connect(self.onClickPlayWavButton) #STOP wav BUTTON self.stopWavButton = QPushButton(self.tr("Stop Playing"), self) self.stopWavButton.clicked.connect(self.onClickStopWavButton) self.v1Sizer.addWidget(self.addWavButton) self.v1Sizer.addWidget(self.removeWavButton) self.v1Sizer.addWidget(self.playWavButton) self.v1Sizer.addWidget(self.stopWavButton) self.v1Sizer.addStretch() self.wavsList = {} for i in range(len(self.parent().wavsPref['endMessageFiles'])): currCount = i+1 thisID = self.parent().wavsPref['endMessageFilesID'][i] self.wavsList[thisID] = {} self.wavsList[thisID]['file'] = self.parent().wavsPref['endMessageFiles'][i] self.wavsList[thisID]['use'] = self.parent().wavsPref['endMessageFilesUse'][i] self.wavsList[thisID]['level'] = self.parent().wavsPref['endMessageLevels'][i] self.wavsTableWidget.setRowCount(currCount) n = 0 newItem = QTableWidgetItem(self.wavsList[thisID]['file']) newItem.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) self.wavsTableWidget.setItem(currCount-1, n, newItem) n = n+1 newItem = QTableWidgetItem(self.wavsList[thisID]['use']) newItem.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) self.wavsTableWidget.setItem(currCount-1, n, newItem) n = n+1 newItem = QTableWidgetItem(self.currLocale.toString(self.wavsList[thisID]['level'])) newItem.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) self.wavsTableWidget.setItem(currCount-1, n, newItem) n = n+1 self.wavsList[thisID]['qid'] = QTableWidgetItem(thisID) self.wavsTableWidget.setItem(currCount-1, n, self.wavsList[thisID]['qid']) buttonBox = QDialogButtonBox(QDialogButtonBox.Apply|QDialogButtonBox.Ok|QDialogButtonBox.Cancel) buttonBox.accepted.connect(self.accept) buttonBox.rejected.connect(self.reject) self.sizer.addLayout(self.v1Sizer, 0, 0) self.sizer.addWidget(self.wavsTableWidget,0,1) self.sizer.addWidget(buttonBox, 1,1) self.setLayout(self.sizer) self.setWindowTitle(self.tr("Edit Wavs")) self.show() def onCellDoubleClicked(self, row, col): if col == 0: pass elif col == 1: self.onEditUse() elif col == 2: self.onEditLevel() def onEditLevel(self): ids = self.findSelectedItemIds() if len(ids) > 1: QMessageBox.warning(self, self.tr('Warning'), self.tr('Only one item can be edited at a time')) elif len(ids) < 1: pass else: selectedSound = ids[0] msg = self.tr('RMS Level:') text, ok = QInputDialog.getDouble(self, self.tr('Input Dialog'), msg, self.wavsList[selectedSound]['level']) if ok: self.wavsTableWidget.item(self.wavsList[selectedSound]['qid'].row(), 2).setText(self.currLocale.toString(text)) self.wavsList[selectedSound]['level'] = text def onEditUse(self): ids = self.findSelectedItemIds() if len(ids) > 1: QMessageBox.warning(self, self.tr('Warning'), self.tr('Only one item can be edited at a time')) elif len(ids) < 1: pass else: selectedSound = ids[0] if self.wavsTableWidget.item(self.wavsList[selectedSound]['qid'].row(), 1).text() == "\u2012": self.wavsTableWidget.item(self.wavsList[selectedSound]['qid'].row(), 1).setText("\u2713") self.wavsList[selectedSound]['use'] = "\u2713" else: self.wavsTableWidget.item(self.wavsList[selectedSound]['qid'].row(), 1).setText("\u2012") self.wavsList[selectedSound]['use'] = "\u2012" def findSelectedItemIds(self): selItems = self.wavsTableWidget.selectedItems() selItemsRows = [] for i in range(len(selItems)): selItemsRows.append(selItems[i].row()) selItemsRows = unique(selItemsRows) selItemsIds = [] for i in range(len(selItemsRows)): selItemsIds.append(str(self.wavsTableWidget.item(selItemsRows[i], self.quidColumn).text())) return selItemsIds def permanentApply(self): self.wavListToPass = {} self.wavListToPass['endMessageFiles'] = [] self.wavListToPass['endMessageFilesUse'] = [] self.wavListToPass['endMessageFilesID'] = [] self.wavListToPass['endMessageLevels'] = [] keys = sorted(self.wavsList.keys()) for key in keys: self.wavListToPass['endMessageFiles'].append(str(self.wavsList[key]['file'])) self.wavListToPass['endMessageFilesUse'].append(self.wavsList[key]['use']) self.wavListToPass['endMessageLevels'].append(self.wavsList[key]['level']) self.wavListToPass['endMessageFilesID'].append(key) def onClickAddWavButton(self): fName = QFileDialog.getOpenFileName(self, self.tr("Choose wav file to load"), '', self.tr("wav files (*.wav);;All Files (*)"))[0] if len(fName) > 0: #if the user didn't press cancel if len(self.wavsList.keys()) > 0: keys = sorted(self.wavsList.keys()) thisID = str(int(keys[-1])+1) else: thisID = "1" currCount = self.wavsTableWidget.rowCount() + 1 self.wavsList[thisID] = {} self.wavsList[thisID]['file'] = fName self.wavsList[thisID]['use'] = "\u2713" self.wavsList[thisID]['level'] = 60 self.wavsTableWidget.setRowCount(currCount) n = 0 newItem = QTableWidgetItem(self.wavsList[thisID]['file']) newItem.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) self.wavsTableWidget.setItem(currCount-1, n, newItem) n = n+1 newItem = QTableWidgetItem(self.wavsList[thisID]['use']) newItem.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) self.wavsTableWidget.setItem(currCount-1, n, newItem) n = n+1 newItem = QTableWidgetItem(self.currLocale.toString(self.wavsList[thisID]['level'])) newItem.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) self.wavsTableWidget.setItem(currCount-1, n, newItem) n = n+1 self.wavsList[thisID]['qid'] = QTableWidgetItem(thisID) self.wavsTableWidget.setItem(currCount-1, n, self.wavsList[thisID]['qid']) def onClickRemoveWavButton(self): ids = self.findSelectedItemIds() for i in range(len(ids)): selectedWavs = ids[i] self.wavsTableWidget.removeRow(self.wavsList[selectedWavs]['qid'].row()) del self.wavsList[selectedWavs] def onClickPlayWavButton(self): ids = self.findSelectedItemIds() if len(ids) < 1: QMessageBox.warning(self, self.tr('Warning'), self.tr('No files selected for playing')) else: if len(ids) > 1: pass #maybe say on the status bar that only the first one will be played selectedWav = ids[0] fName = self.wavsList[selectedWav]['file'] level = self.wavsList[selectedWav]['level'] nBits = self.currLocale.toInt(self.parent().parent().nBitsChooser.currentText())[0] maxLevel = float(self.prm['phones']['phonesMaxLevel'][self.parent().parent().phonesChooser.currentIndex()]) msgSnd, fs = self.audioManager.loadWavFile(fName, level, maxLevel, 'Both') self.isPlaying = True if self.prm['pref']['sound']['playCommand'] in ["alsaaudio","pyaudio"]: self.playThread = threadedAudioPlayer(self.parent().parent()) else: self.playThread = threadedExternalAudioPlayer(self.parent().parent()) self.playThread.playThreadedSound(msgSnd, fs, nBits, self.prm['pref']['sound']['playCommand'], False, 'tmp.wav') if self.playThread.isFinished == True: self.isPlaying = False def onClickStopWavButton(self): if self.isPlaying == True: self.playThread.terminate() def closeEvent(self, event): if self.isPlaying == True: self.playThread.terminate() event.accept() def accept(self): #reimplement accept (i.e. ok button) if self.isPlaying == True: self.playThread.terminate() QDialog.accept(self) def reject(self): #reimplement reject if self.isPlaying == True: self.playThread.terminate() QDialog.reject(self)
class AvailableWidget(QWidget): def __init__(self, parent, available): QWidget.__init__(self, parent) self._parent = parent self._available = available vbox = QVBoxLayout(self) self._table = QTableWidget(1, 5) self._table.removeRow(0) vbox.addWidget(self._table) self._headers = ('Name', 'Version', 'Description', "Authors", "Web") ui_tools.load_table(self._table, self._headers, _format_for_table(available)) self._table.setColumnWidth(0, 200) hbox = QHBoxLayout() btnInstall = QPushButton('Install') btnInstall.setMaximumWidth(100) hbox.addWidget(btnInstall) hbox.addWidget(QLabel(self.tr("NINJA needs to be restarted for " \ "changes to take effect."))) vbox.addLayout(hbox) # hbox = QHBoxLayout() # hbox.addWidget(QLabel( # self.tr("Add an external Plugin. URL Zip File:"))) # self._link = QLineEdit() # hbox.addWidget(self._link) # btnAdd = QPushButton(self.tr("Add")) # hbox.addWidget(btnAdd) # vbox.addLayout(hbox) # lblExternalPlugin = QLabel( # self.tr("(Write the URL of the Plugin and press 'Add')")) # lblExternalPlugin.setAlignment(Qt.AlignRight) # vbox.addWidget(lblExternalPlugin) self.connect(btnInstall, SIGNAL("clicked()"), self._install_plugins) # self.connect(btnAdd, SIGNAL("clicked()"), self._install_external) def _install_plugins(self): data = _format_for_table(self._available) plugins = ui_tools.remove_get_selected_items(self._table, data) #get the download link of each plugin for p_row in plugins: #search the plugin for p_dict in self._available: if unicode(p_dict["name"]) == unicode(p_row[0]): p_data = p_dict break #append the downlod link p_row.append(p_data["download"]) #download self._parent.download_plugins(plugins) def remove_item(self, plugin_name): plugin = _get_plugin(plugin_name, self._available) self._available.remove(plugin) def _install_external(self): if self._link.text().isEmpty(): QMessageBox.information(self, self.tr("External Plugins"), self.tr("URL from Plugin missing...")) return plug = [ file_manager.get_module_name(str(self._link.text())), 'External Plugin', '1.0', str(self._link.text()) ] self.parent().download_plugins(plug) self._link.setText('') def add_table_items(self, plugs): self._available += plugs data = _format_for_table(self._available) ui_tools.load_table(self._table, self._headers, data)
class DataItemWidget(QWidget): __EXTRA_COLUMN_WIDTH = 20 def __init__(self, me_cls, data): QWidget.__init__(self) self.__me_cls = me_cls self.__setup_ui() self.__data = data self.__init_data() self.__connect_slot() def __setup_ui(self): v_layout = QVBoxLayout() self.__tool_widget = ToolWidget() self.__tool_widget.setMaximumHeight(40) self.__data_table_widget = QTableWidget() self.__data_table_widget.horizontalHeader().setStretchLastSection(True) self.__data_table_widget.horizontalHeader().setResizeMode( 0, QHeaderView.Fixed) v_layout.setSpacing(0) v_layout.setContentsMargins(0, 0, 0, 0) v_layout.addWidget(self.__tool_widget, 0) v_layout.addWidget(self.__data_table_widget, 1) self.setLayout(v_layout) def __connect_slot(self): pass #self.connect(self.__tool_widget,SIGNAL('refresh_btn_clicked()'), self ,SLOT('__on_refresh_signal()')) def __init_data(self): self.__data_table_widget.clearContents() # init header #self.__colume_names = yt_connection.get_table_colume_names(self.__table_name) self.__colume_names = [x.field.name for x in self.__me_cls.attributes] #self.__colume_names.insert(0,'entity_id') #print self.__colume_names self.__data_table_widget.setColumnCount(len(self.__colume_names)) head_list = QStringList() for colume in self.__colume_names: head_list << colume self.__data_table_widget.setHorizontalHeaderLabels(head_list) # default the header column both sides are coverd, these codes add __EXTRA_COLUMN_WIDTH to the header column width # and reise column width in function self.__adjust_table_colume() self.__data_table_widget.horizontalHeader().setResizeMode( QHeaderView.ResizeToContents) self.__record_colume_header_width() self.__data_table_widget.horizontalHeader().setResizeMode( QHeaderView.Interactive) self.__record_colume_header_width() show_data = [] for entity_id, value in self.__data.items(): item = value.obj_data.copy() item['managed_entity_id'] = entity_id show_data.append(item) self.__update_table(show_data) # init data # data = yt_connection.get_table_data(self.__table_name) # # self.__update_table(data) self.__adjust_table_colume() def __record_colume_header_width(self): count = self.__data_table_widget.columnCount() self.__column_widths = [] for i in range(count): self.__column_widths.append( self.__data_table_widget.columnWidth(i) + self.__EXTRA_COLUMN_WIDTH) ''' data like this [ {u'direction': 'to-lport', u'name': '[]', u'priority': '100', u'log': 'true', u'action': 'drop', u'external_ids': '{"neutron:lport"="5fb77332-2035-4f72-8e57-7415b02489c9"}', u'match': '"outport==\\"inside-vm2\\""', u'severity': '[]', 'uuid': '2890a832-1c83-4b8e-8b40-2928817012cc'} ] ''' def __update_table(self, data): self.__data_table_widget.clearContents() row_num = 0 for row in data: self.__data_table_widget.insertRow(row_num) colume_num = 0 for colume in self.__colume_names: if row.has_key(colume): item_str = str(row[colume]) else: item_str = 'None' table_wid_item = QTableWidgetItem(item_str) table_wid_item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable) self.__data_table_widget.setItem(row_num, colume_num, table_wid_item) colume_num += 1 row_num += 1 def __clear_table_data(self): row_count = self.__data_table_widget.rowCount() rev = [i for i in range(row_count)] rev.reverse() for i in rev: self.__data_table_widget.removeRow(i) def __adjust_table_colume(self): self.__data_table_widget.resizeColumnsToContents() count = self.__data_table_widget.columnCount() for i in range(count): col_wid = self.__data_table_widget.columnWidth(i) if col_wid < self.__column_widths[i]: self.__data_table_widget.setColumnWidth( i, self.__column_widths[i])
class ElemCompDialog(QtGui.QDialog): def __init__(self,mz, mass,xp,parent=None): QtGui.QDialog.__init__(self, parent) settings = QSettings() size = settings.value("MainWindow/Size",QVariant(QSize(1024,650))).toSize() self.resize(size) self.setWindowTitle('Elenmental Composition') self.xp=xp self.mass=mass self.mz=mz print mz self.initControls() # self.initPlots() def initControls(self): self.plot1 = Qwt.QwtPlot(self) self.plot1.setCanvasBackground(Qt.white) self.plot2 = Qwt.QwtPlot(self) self.plot2.setCanvasBackground(Qt.white) self.list = QTreeWidget() self.list.setColumnCount(11) self.list.setColumnWidth(0,80) self.list.setColumnWidth(1,80) self.list.setColumnWidth(2,60) self.list.setColumnWidth(3,60) self.list.setColumnWidth(4,60) self.list.setColumnWidth(5,150) self.list.setColumnWidth(7,30) self.list.setColumnWidth(8,30) self.list.setColumnWidth(9,30) self.list.setColumnWidth(10,30) self.list.setHeaderLabels(['Mass','Calc.Mass','mDa','PPM','DBE','Formula','Fit Conf %','C','H','N','O']) self.list.setSortingEnabled(True) self.table = QTableWidget(1,11) self.table.setColumnWidth(0,80) self.table.setColumnWidth(1,80) self.table.setColumnWidth(2,60) self.table.setColumnWidth(3,60) self.table.setColumnWidth(4,60) self.table.setColumnWidth(5,150) self.table.setColumnWidth(7,30) self.table.setColumnWidth(8,30) self.table.setColumnWidth(9,30) self.table.setColumnWidth(10,30) self.table.setHorizontalHeaderLabels(['Mass','Calc.Mass','mDa','PPM','DBE','Formula','Fit Conf %','C','H','N','O']) self.table.setEditTriggers(QTableWidget.NoEditTriggers) self.table.setSelectionBehavior(QTableWidget.SelectRows) self.table.setSelectionMode(QTableWidget.SingleSelection) self.table.setAlternatingRowColors(True) print self.connect(self.table, SIGNAL("itemActivated(QTableWidgetItem*)"), self.tableClicked) # self.connect(self.library_list, SIGNAL("itemSelectionChanged()"), self.libraryListClicked) up_hbox=QVBoxLayout() up_hbox.addWidget(self.table) down_hbox = QVBoxLayout() down_hbox.addWidget(self.plot1) down_hbox.addWidget(self.plot2) hbox = QVBoxLayout() hbox.addLayout(up_hbox, 3.5) hbox.addLayout(down_hbox, 3.5) self.setLayout(hbox) self.cal_mass() def tableClicked(self,item): self.C=self.table.item(item.row(),7).text() self.H=self.table.item(item.row(),8).text() self.N=self.table.item(item.row(),9).text() self.O=self.table.item(item.row(),10).text() self.cal_isotopic() self.initPlots() def initPlots(self): self.plot1.clear() # self.plot1.setTitle("Observed Isotope Distribution") # self.plot1.setAxisTitle(Qwt.QwtPlot.xBottom, 'Raman shift (cm-1)') # self.plot1.setAxisTitle(Qwt.QwtPlot.yLeft, 'Intensity') # grid = Qwt.QwtPlotGrid() pen = QPen(Qt.DotLine) pen.setColor(Qt.black) pen.setWidth(0) # grid.setPen(pen) # grid.attach(self.plot1) self.mass1=self.mass/self.massy*100 self.plot1.setAxisScale(self.plot1.xBottom,self.x_min,self.x_max) self.plot1.setAxisScale(self.plot1.yLeft,0,1.1*100) color = QColor('black') curve = Qwt.QwtPlotCurve("test1") pen = QPen(color) pen.setWidth(1) curve.setPen(pen) curve.setData(self.mass_x,self.mass_y) curve.setStyle(Qwt.QwtPlotCurve.Sticks) curve.attach(self.plot1) self.plot1.replot() self.plot2.clear() # self.plot2.setTitle("Theoretical Isotope Distribution") # self.plot2.setAxisTitle(Qwt.QwtPlot.xBottom, 'Raman shift (cm-1)') # self.plot2.setAxisTitle(Qwt.QwtPlot.yLeft, 'Intensity') # grid = Qwt.QwtPlotGrid() pen = QPen(Qt.DotLine) pen.setColor(Qt.blue) self.plot2.setAxisScale(self.plot1.xBottom,self.x_min,self.x_max) self.plot2.setAxisScale(self.plot1.yLeft,0,1.1*100) color = QColor('blue') curve = Qwt.QwtPlotCurve("test1") pen = QPen(color) pen.setWidth(1) curve.setPen(pen) # self.axis= np.arange(len(self.mass)) curve.setData(self.x,self.y) curve.setStyle(Qwt.QwtPlotCurve.Sticks) curve.attach(self.plot2) pen.setWidth(0) # grid.setPen(pen) # grid.attach(self.plot2) self.plot2.replot() def cal_mass(self): # charge=0.0 tol = 10.0 # electron=0.000549 measured_mass=np.round(self.xp) limit_lo = measured_mass - (tol/1000.0) limit_hi = measured_mass + (tol/1000.0) mass=[] mass.append((12.000000000,2.0,"C")) #mass.append((78.9183376,-1.0,"Br")) #mass.append((34.96885271,-1.0,"Cl")) #mass.append((31.97207069,0.0,"S")) #mass.append((30.97376151,1.0,"P")) #mass.append((27.9769265327,2.0,"Si")) #mass.append((22.98976967,-1.0,"Na")) #mass.append((18.99840320,-1.0,"F")) mass.append((15.9949146221,0.0,"O")) mass.append((14.0030740052,1.0,"N")) mass.append((1.0078250321,-1.0,"H")) print range(1,10) print mass[0][0] print mass[1][0] print mass[2][0] calc_mass=[] for i in range(1,int(floor(measured_mass/mass[0][0]))+1): for j in range(0,int(floor((measured_mass-mass[0][0]*i)/mass[1][0]))+1): for k in range(0,int(floor((measured_mass-mass[0][0]*i-mass[1][0]*j)/mass[2][0]))+1): # rr=(measured_mass-mass[0][0]*i-mass[1][0]*j-mass[2][0]*k)/mass[3][0] # rrr=round((measured_mass-mass[0][0]*i-mass[1][0]*j-mass[2][0]*k)/mass[3][0]) # rrrr=int(round((measured_mass-mass[0][0]*i-mass[1][0]*j-mass[2][0]*k)/mass[3][0])) # print "rr:%s"%rr+" rrr:%s"%rrr+" rrrr:%s"%rrrr r=int(round((measured_mass-mass[0][0]*i-mass[1][0]*j-mass[2][0]*k)/mass[3][0])) calmass=mass[0][0]*i+mass[1][0]*j+mass[2][0]*k+mass[3][0]*r if (mass[0][1]*i+mass[2][1]*k+mass[3][1]*r)>=-1 and calmass>limit_lo and calmass<limit_hi: calc_mass.append((calmass,i,j,k,r)) print len(calc_mass) for ii in range(0,len(calc_mass)): mda=(measured_mass-calc_mass[ii][0])*1000 ppm=(measured_mass-calc_mass[ii][0])/measured_mass*1000000 DBE=(calc_mass[ii][1]*2+calc_mass[ii][3]-calc_mass[ii][4]+2)/2.0 self.calmass="%.4f"%calc_mass[ii][0] self.mda="%.1f"%mda self.ppm="%.1f"%ppm self.DBE="%.1f"%DBE self.C="%s"%calc_mass[ii][1] self.H="%s"%calc_mass[ii][4] self.N="%s"%calc_mass[ii][3] self.O="%s"%calc_mass[ii][2] self.Formula="C%2s"%self.C+" H%2s"%self.H+" N%2s"%self.N+" O%2s"%self.O mass=str(self.xp) # if not(ii==0): # mass="" self.cal_isotopic() self.initPlots() self.conf="%.1f"%self.mass_diff self.table.insertRow(ii) self.table.setRowHeight(ii,20) self.table.setItem(ii, 0,QTableWidgetItem(mass)) self.table.setItem(ii, 1,QTableWidgetItem(self.calmass)) self.table.setItem(ii, 2,QTableWidgetItem(self.mda)) self.table.setItem(ii, 3,QTableWidgetItem(self.ppm)) self.table.setItem(ii, 4,QTableWidgetItem(self.DBE)) self.table.setItem(ii, 5,QTableWidgetItem(self.Formula)) self.table.setItem(ii, 6,QTableWidgetItem(self.conf)) self.table.setItem(ii, 7,QTableWidgetItem(self.C)) self.table.setItem(ii, 8,QTableWidgetItem(self.H)) self.table.setItem(ii, 9,QTableWidgetItem(self.N)) self.table.setItem(ii, 10,QTableWidgetItem(self.O)) item=QTreeWidgetItem([mass,str(self.calmass),str(self.mda),str(self.ppm),str(self.DBE),self.Formula,str(self.conf),str(self.C),str(self.H),str(self.N),str(self.O)]) self.list.addTopLevelItem(item) self.table.removeRow(len(calc_mass)) self.table.setSortingEnabled(True) # self.table.sortByColumn(1,Qt.DescendingOrder) def next2pow(self): return 2**int(np.ceil(np.log(float(self.xx))/np.log(2.0))) def cal_isotopic(self): MAX_ELEMENTS=5+1 # add 1 due to mass correction 'element' MAX_ISOTOPES=4 # maxiumum # of isotopes for one element CUTOFF=1e-4 # relative intensity cutoff for plotting WINDOW_SIZE = 500 #WINDOW_SIZE=input('Window size (in Da) ---> '); #RESOLUTION=input('Resolution (in Da) ----> '); % mass unit used in vectors RESOLUTION = 1 if RESOLUTION < 0.00001:# % minimal mass step allowed RESOLUTION = 0.00001 elif RESOLUTION > 0.5: # maximal mass step allowed RESOLUTION = 0.5 R=0.00001/RESOLUTION# % R is used to scale nuclide masses (see below) WINDOW_SIZE=WINDOW_SIZE/RESOLUTION; self.xx=WINDOW_SIZE # convert window size to new mass units WINDOW_SIZE=self.next2pow(); # fast radix-2 fast-Fourier transform algorithm if WINDOW_SIZE < np.round(496708*R)+1: WINDOW_SIZE = self.next2pow(np.round(496708*R)+1) # just to make sure window is big enough #H378 C254 N65 O75 S6 M=np.array([int(self.H),int(self.C),int(self.N),int(self.O),0,0]) #% empiric formula, e.g. bovine insulin # isotopic abundances stored in matrix A (one row for each element) A=np.zeros((MAX_ELEMENTS,MAX_ISOTOPES,2)); A[0][0,:] = [100783,0.9998443]# % 1H A[0][1,:] = [201410,0.0001557]# % 2H A[1][0,:] = [100000,0.98889]# % 12C A[1][1,:] = [200336,0.01111]# % 13C A[2][0,:] = [100307,0.99634]# % 14N A[2][1,:] = [200011,0.00366]# % 15N A[3][0,:] = [99492,0.997628]# % 16O A[3][1,:] = [199913,0.000372]# % 17O A[3][2,:] = [299916,0.002000]# % 18O A[4][0,:] = [97207,0.95018]# % 32S A[4][1,:] = [197146,0.00750]# % 33S A[4][2,:] = [296787,0.04215]# % 34S A[4][3,:] = [496708,0.00017]# % 36S A[5][0,:] = [100000,1.00000]# % for shifting mass so that Mmi is # % near left limit of window Mmi=np.array([np.round(100783*R), np.round(100000*R),\ np.round(100307*R),np.round(99492*R), np.round(97207*R), 0])*M# % (Virtual) monoisotopic mass in new units Mmi = Mmi.sum() #% mass shift so Mmi is in left limit of window: FOLDED=np.floor(Mmi/(WINDOW_SIZE-1))+1# % folded FOLDED times (always one folding due to shift below) #% shift distribution to 1 Da from lower window limit: M[MAX_ELEMENTS-1]=np.ceil(((WINDOW_SIZE-1)-np.mod(Mmi,WINDOW_SIZE-1)+np.round(100000*R))*RESOLUTION) MASS_REMOVED=np.array([0,11,13,15,31,-1])*M#% correction for 'virtual' elements and mass shift begin=WINDOW_SIZE*RESOLUTION+MASS_REMOVED.sum() end=2*(WINDOW_SIZE-1)*RESOLUTION+MASS_REMOVED.sum() ptA=np.ones(WINDOW_SIZE); t_fft=0 t_mult=0 for i in xrange(MAX_ELEMENTS): tA=np.zeros(WINDOW_SIZE) for j in xrange(MAX_ISOTOPES): if A[i][j,0] != 0: #removed +1 after R)+1 --we're using python tA[np.round(A[i][j,0]*R)]=A[i][j,1]#; % put isotopic distribution in tA t0 = time.clock() tA=F.fft(tA) # FFT along elements isotopic distribution O(nlogn) t_fft = time.clock()-t0 t0 = time.clock() tA=tA**M[i]# % O(n) ################# ptA = ptA*tA# % O(n)#this is where it is messing UP ################# t1 = time.clock() t_mult=t1-t0 t0=time.clock() ptA=F.ifft(ptA).real#; % O(nlogn) t0=time.clock() MA=np.linspace(begin,end,WINDOW_SIZE-1) ind=np.where(ptA>CUTOFF)[0] self.x = MA[ind] self.y = ptA[ind] self.x_min=int(np.min(self.x)-(np.max(self.x)-np.min(self.x))) self.x_max=int(np.min(self.x)+(np.max(self.x)-np.min(self.x))) self.mass_y=np.ones(len(self.x)) mass_diff=np.ones(len(self.x)) mzInd= np.logical_and((self.mz>=self.x_min),(self.mz<=self.x_max)) self.mass_y=self.mass[mzInd] self.mass_x=self.mz[mzInd] # for i in range(len(self.x)): # self.mass_y[i]=self.mass[int(self.x[i])] self.massy=np.max(self.mass_y) print self.massy self.mass_y=self.mass_y/max(self.mass_y)*100 self.y=self.y/max(self.y)*100 # k=(self.mass_y*self.y).sum()/(self.mass_y*self.mass_y).sum() # self.fit=((k*self.mass_y-self.y)*(k*self.mass_y-self.y)).sum()/(self.y*self.y).sum() for i in range(len(self.y)): mass_diff[i]=np.abs(self.mass_y[i]-self.y[i])/(self.mass_y[i]+self.y[i]) self.mass_diff=(1-mass_diff.sum()/len(mass_diff))*100
class ProfileDlg(QDialog): def __init__(self): QDialog.__init__(self) self.__setup_ui() self.__connect_slot() self.__settings = QSettings('__cyt', '__yt_ovs') #print self.__settings.fileName() set_str = to_python_str(self.__settings.value('__profile_record', '').toString()) set_str = set_str if set_str is not '' else "[]" self.__record_list = json.loads(set_str)#[{'ip':'1.1.1.1','port':6641,'schema':'xxxx'},{...}] self.__list_to_table_item() self.click_ip = '' self.click_port = 0 self.click_schema = '' def __setup_ui(self): self.setMaximumSize(500, 400) self.setMinimumSize(500, 400) v_layout = QVBoxLayout() #init table widget self.__profile_table = QTableWidget() self.__profile_table.setColumnCount(3) header_list = QStringList() header_list << 'ip' << 'port' << 'schema' self.__profile_table.setHorizontalHeaderLabels(header_list) self.__profile_table.horizontalHeader().setResizeMode(QHeaderView.Stretch) self.__profile_table.setSelectionBehavior(QAbstractItemView.SelectRows) #init tool widget self.__tool_wid = QWidget() h_layout = QHBoxLayout() h_layout.setContentsMargins(0,0,0,0) self.__puls_btn = QPushButton() self.__puls_btn.setIcon(QIcon(ICON_IDR + 'arrow_plus.png')) self.__puls_btn.setIconSize(QSize(15, 15)) self.__puls_btn.setMaximumSize(20, 20) self.__minus_btn = QPushButton() self.__minus_btn.setIcon(QIcon(ICON_IDR + 'arrow_minus.png')) self.__minus_btn.setIconSize(QSize(15, 15)) self.__minus_btn.setMaximumSize(20, 20) h_layout.addWidget(self.__puls_btn,0) h_layout.addWidget(self.__minus_btn,0) h_layout.addStretch(1) self.__tool_wid.setLayout(h_layout) #v layout v_layout.addWidget(self.__profile_table,1) v_layout.addWidget(self.__tool_wid,0) v_layout.setSpacing(1) self.setLayout(v_layout) def __connect_slot(self): self.connect(self.__puls_btn, SIGNAL('clicked()'), self, SLOT('__on_plus_btn()')) self.connect(self.__minus_btn, SIGNAL('clicked()'), self, SLOT('__on_minus_btn()')) self.connect(self.__profile_table, SIGNAL('cellDoubleClicked (int,int)'), self, SLOT('__on_profile_double_click(int,int)')) def __add_record(self, ip, port, schema): count = self.__profile_table.rowCount() self.__profile_table.insertRow(count) ip_item = QTableWidgetItem(ip) ip_item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable) item_font = ip_item.font() item_font.setPointSizeF(12) ip_item.setFont(item_font) port_item = QTableWidgetItem(port) port_item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable) port_item.setFont(item_font) schema_item = QTableWidgetItem(schema) schema_item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable) schema_item.setFont(item_font) self.__profile_table.setItem(count, 0, ip_item) self.__profile_table.setItem(count, 1, port_item) self.__profile_table.setItem(count, 2, schema_item) def __clear_table_data(self): row_count = self.__profile_table.rowCount() rev = [i for i in range(row_count)] rev.reverse() for i in rev: self.__profile_table.removeRow(i) def __list_to_table_item(self): self.__clear_table_data() for record in self.__record_list: self.__add_record(record['ip'], str(record['port']), record['schema']) #print record def __table_item_to_list(self): row_count = self.__profile_table.rowCount() self.__record_list = [] for i in range(row_count): record = {} ip = to_python_str( self.__profile_table.item(i, 0).text() ) port = int( self.__profile_table.item(i, 1).text() ) schema = to_python_str(self.__profile_table.item(i, 2).text()) record["ip"] = ip record["port"] = port record["schema"] = schema self.__record_list.append(record) print self.__record_list def __check_existed(self, ip, port, schema): has_code = con_has_code(ip, port, schema) for record in self.__record_list: exist_code = con_has_code(record["ip"], record["port"], record["schema"]) if exist_code == has_code: return True return False def __record_to_settings(self): self.__settings.setValue('__profile_record', json.dumps(self.__record_list)) @pyqtSlot() def __on_plus_btn(self): new_dlg = NewConnectionDlg() if new_dlg.exec_(): # add to table_widget if self.__check_existed(new_dlg.host, new_dlg.port, new_dlg.schema): return self.__add_record(new_dlg.host, str(new_dlg.port), new_dlg.schema) self.__table_item_to_list() self.__record_to_settings() @pyqtSlot() def __on_minus_btn(self): select_row = self.__profile_table.currentRow() self.__profile_table.removeRow(select_row) self.__table_item_to_list() self.__record_to_settings() @pyqtSlot('int','int') def __on_profile_double_click(self, row, column): ip_item = self.__profile_table.item(row, 0) port_item = self.__profile_table.item(row, 1) schema_item = self.__profile_table.item(row, 2) self.click_ip = to_python_str(ip_item.text()) self.click_port = int(port_item.text()) self.click_schema = to_python_str(schema_item.text()) self.accept()
class phonesDialog(QDialog): def __init__(self, parent): QDialog.__init__(self, parent) self.prm = self.parent().prm self.currLocale = self.parent().prm['currentLocale'] self.currLocale.setNumberOptions( self.currLocale.OmitGroupSeparator | self.currLocale.RejectGroupSeparator) screen = QDesktopWidget().screenGeometry() self.resize(screen.width() / 2.5, screen.height() / 3) self.isPlaying = False #self.audioManager = audioManager(self) #self.playThread = threadedPlayer(self) self.sizer = QGridLayout() self.v1Sizer = QVBoxLayout() self.v2Sizer = QVBoxLayout() self.calibSizer = QGridLayout() self.phonesTableWidget = QTableWidget() self.phonesTableWidget.setColumnCount(4) self.phonesTableWidget.setSelectionBehavior( QAbstractItemView.SelectRows) self.phonesTableWidget.setSelectionMode( QAbstractItemView.ExtendedSelection) self.phonesTableWidget.setHorizontalHeaderLabels([ self.tr('Phones'), self.tr('Max Level'), self.tr('Default'), 'id' ]) self.phonesTableWidget.hideColumn(3) self.phonesTableWidget.cellDoubleClicked[int, int].connect( self.onCellDoubleClicked) #RENAME Phones BUTTON self.renamePhonesButton = QPushButton(self.tr("Rename Phones"), self) self.renamePhonesButton.clicked.connect(self.onEditLabel) #Change Level Phones BUTTON self.changeLevelPhonesButton = QPushButton(self.tr("Change Max Level"), self) self.changeLevelPhonesButton.clicked.connect(self.onEditMaxLevel) #ADD Phones BUTTON self.addPhonesButton = QPushButton(self.tr("Add Phones"), self) self.addPhonesButton.clicked.connect(self.onClickAddPhonesButton) #REMOVE Phones BUTTON self.removePhonesButton = QPushButton(self.tr("Remove Phones"), self) self.removePhonesButton.clicked.connect(self.onClickRemovePhonesButton) #Set Default Phones BUTTON self.setDefaultPhonesButton = QPushButton(self.tr("Set Default"), self) self.setDefaultPhonesButton.clicked.connect(self.onEditDefault) self.v1Sizer.addWidget(self.renamePhonesButton) self.v1Sizer.addWidget(self.changeLevelPhonesButton) self.v1Sizer.addWidget(self.addPhonesButton) self.v1Sizer.addWidget(self.removePhonesButton) self.v1Sizer.addWidget(self.setDefaultPhonesButton) self.v1Sizer.addStretch() self.phonesList = {} for i in range(len(self.prm['phones']['phonesChoices'])): currCount = i + 1 thisID = self.prm['phones']['phonesID'][i] self.phonesList[thisID] = {} self.phonesList[thisID]['label'] = self.prm['phones'][ 'phonesChoices'][i] self.phonesList[thisID]['maxLevel'] = self.prm['phones'][ 'phonesMaxLevel'][i] self.phonesList[thisID]['default'] = self.prm['phones'][ 'defaultPhones'][i] self.phonesTableWidget.setRowCount(currCount) newItem = QTableWidgetItem(self.phonesList[thisID]['label']) newItem.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) self.phonesTableWidget.setItem(currCount - 1, 0, newItem) newItem = QTableWidgetItem( self.currLocale.toString(self.phonesList[thisID]['maxLevel'])) newItem.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) self.phonesTableWidget.setItem(currCount - 1, 1, newItem) newItem = QTableWidgetItem(self.phonesList[thisID]['default']) newItem.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) self.phonesTableWidget.setItem(currCount - 1, 2, newItem) self.phonesList[thisID]['qid'] = QTableWidgetItem(thisID) self.phonesTableWidget.setItem(currCount - 1, 3, self.phonesList[thisID]['qid']) ##CALIBRATION TONE n = 0 self.calLabel = QLabel(self.tr('Calibration Tone:'), self) self.calibSizer.addWidget(self.calLabel, n, 0, 1, 2) n = n + 1 self.toneFreqLabel = QLabel(self.tr('Frequency (Hz)'), self) self.toneFreqTF = QLineEdit("1000") self.toneFreqTF.setValidator(QDoubleValidator(self)) self.calibSizer.addWidget(self.toneFreqLabel, n, 0) self.calibSizer.addWidget(self.toneFreqTF, n, 1) n = n + 1 self.toneLevLabel = QLabel(self.tr('Level (dB)'), self) self.toneLevTF = QLineEdit("60") self.toneLevTF.setValidator(QDoubleValidator(self)) self.calibSizer.addWidget(self.toneLevLabel, n, 0) self.calibSizer.addWidget(self.toneLevTF, n, 1) n = n + 1 self.toneDurLabel = QLabel(self.tr('Duration (ms)'), self) self.toneDurTF = QLineEdit("980") self.toneDurTF.setValidator(QDoubleValidator(self)) self.calibSizer.addWidget(self.toneDurLabel, n, 0) self.calibSizer.addWidget(self.toneDurTF, n, 1) n = n + 1 self.toneRampsLabel = QLabel(self.tr('Ramps (ms)'), self) self.toneRampsTF = QLineEdit("10") self.toneRampsTF.setValidator(QDoubleValidator(self)) self.calibSizer.addWidget(self.toneRampsLabel, n, 0) self.calibSizer.addWidget(self.toneRampsTF, n, 1) n = n + 1 self.earLabel = QLabel(self.tr('Ear:'), self) self.earChooser = QComboBox() self.earChooser.addItems( [self.tr("Right"), self.tr("Left"), self.tr("Both")]) self.calibSizer.addWidget(self.earLabel, n, 0) self.calibSizer.addWidget(self.earChooser, n, 1) n = n + 1 self.playCalibButton = QPushButton(self.tr("Play"), self) self.playCalibButton.clicked.connect(self.onClickPlayCalibButton) self.playCalibButton.setIcon( QIcon.fromTheme("media-playback-start", QIcon(":/media-playback-start"))) self.calibSizer.addWidget(self.playCalibButton, n, 0, 1, 2) n = n + 1 self.stopCalibButton = QPushButton(self.tr("Stop"), self) self.stopCalibButton.clicked.connect(self.onClickStopCalibButton) self.stopCalibButton.setIcon( QIcon.fromTheme("media-playback-stop", QIcon(":/media-playback-stop"))) self.calibSizer.addWidget(self.stopCalibButton, n, 0, 1, 2) if self.prm['pref']['sound']['playCommand'] in [ "alsaaudio", "pyaudio" ]: self.stopCalibButton.show() else: self.stopCalibButton.hide() buttonBox = QDialogButtonBox(QDialogButtonBox.Apply | QDialogButtonBox.Ok | QDialogButtonBox.Cancel) buttonBox.accepted.connect(self.accept) buttonBox.rejected.connect(self.reject) buttonBox.button(QDialogButtonBox.Apply).clicked.connect( self.permanentApply) self.sizer.addLayout(self.v1Sizer, 0, 0) self.v2Sizer.addLayout(self.calibSizer) self.v2Sizer.addStretch() self.sizer.addWidget(self.phonesTableWidget, 0, 1) self.sizer.addLayout(self.v2Sizer, 0, 2) self.sizer.addWidget(buttonBox, 1, 1, 1, 2) self.sizer.setColumnStretch(1, 2) self.setLayout(self.sizer) self.setWindowTitle(self.tr("Edit Phones")) self.show() def onCellDoubleClicked(self, row, col): if col == 0: self.onEditLabel() elif col == 1: self.onEditMaxLevel() elif col == 2: self.onEditDefault() def onEditLabel(self): ids = self.findSelectedItemIds() if len(ids) > 1: QMessageBox.warning( self, self.tr('Warning'), self.tr('Only one label can be renamed at a time')) elif len(ids) < 1: pass else: selectedSound = ids[0] msg = self.tr('New name:') text, ok = QInputDialog.getText(self, self.tr('Input Dialog'), msg) if ok: self.phonesTableWidget.item( self.phonesList[selectedSound]['qid'].row(), 0).setText(text) self.phonesList[selectedSound]['label'] = text def onEditMaxLevel(self): ids = self.findSelectedItemIds() if len(ids) > 1: QMessageBox.warning( self, self.tr('Warning'), self.tr('Only one item can be edited at a time')) elif len(ids) < 1: pass else: selectedSound = ids[0] msg = self.tr('Level:') text, ok = QInputDialog.getDouble( self, self.tr('Input Dialog'), msg, self.phonesList[selectedSound]['maxLevel']) if ok: self.phonesTableWidget.item( self.phonesList[selectedSound]['qid'].row(), 1).setText(self.currLocale.toString(text)) self.phonesList[selectedSound]['maxLevel'] = text def onEditDefault(self): ids = self.findSelectedItemIds() if len(ids) > 1: QMessageBox.warning( self, self.tr('Warning'), self.tr('Only one item can be edited at a time')) elif len(ids) < 1: pass else: selectedSound = ids[0] for i in range(self.phonesTableWidget.rowCount()): self.phonesTableWidget.item(i, 2).setText("\u2012") self.phonesList[str(self.phonesTableWidget.item( i, 3).text())]['default'] = "\u2012" self.phonesTableWidget.item( self.phonesList[selectedSound]['qid'].row(), 2).setText("\u2713") self.phonesList[selectedSound]['default'] = "\u2713" def findSelectedItemIds(self): selItems = self.phonesTableWidget.selectedItems() selItemsRows = [] for i in range(len(selItems)): selItemsRows.append(selItems[i].row()) selItemsRows = unique(selItemsRows) selItemsIds = [] for i in range(len(selItemsRows)): selItemsIds.append( str(self.phonesTableWidget.item(selItemsRows[i], 3).text())) return selItemsIds def permanentApply(self): self.prm['phones']['phonesChoices'] = [] self.prm['phones']['phonesMaxLevel'] = [] self.prm['phones']['defaultPhones'] = [] self.prm['phones']['phonesID'] = [] keys = sorted(self.phonesList.keys()) for key in keys: self.prm['phones']['phonesChoices'].append( str(self.phonesList[key]['label'])) self.prm['phones']['phonesMaxLevel'].append( self.phonesList[key]['maxLevel']) self.prm['phones']['defaultPhones'].append( self.phonesList[key]['default']) self.prm['phones']['phonesID'].append(key) f = open(self.parent().prm['phonesPrefFile'], 'wb') pickle.dump(self.parent().prm['phones'], f) f.close() for i in range(self.parent().phonesChooser.count()): self.parent().phonesChooser.removeItem(0) self.parent().phonesChooser.addItems( self.prm['phones']['phonesChoices']) def onClickAddPhonesButton(self): keys = sorted(self.phonesList.keys()) thisID = str(int(keys[-1]) + 1) currCount = self.phonesTableWidget.rowCount() + 1 self.phonesList[thisID] = {} self.phonesList[thisID]['label'] = 'Phones' + ' ' + str(currCount) self.phonesList[thisID]['maxLevel'] = 100 self.phonesList[thisID]['default'] = "\u2012" self.phonesTableWidget.setRowCount(currCount) newItem = QTableWidgetItem(self.phonesList[thisID]['label']) newItem.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) self.phonesTableWidget.setItem(currCount - 1, 0, newItem) newItem = QTableWidgetItem( self.currLocale.toString(self.phonesList[thisID]['maxLevel'])) newItem.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) self.phonesTableWidget.setItem(currCount - 1, 1, newItem) newItem = QTableWidgetItem(self.phonesList[thisID]['default']) newItem.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) self.phonesTableWidget.setItem(currCount - 1, 2, newItem) self.phonesList[thisID]['qid'] = QTableWidgetItem(thisID) self.phonesTableWidget.setItem(currCount - 1, 3, self.phonesList[thisID]['qid']) def onClickRemovePhonesButton(self): if self.phonesTableWidget.rowCount() == 1: ret = QMessageBox.warning( self, self.tr("Warning"), self.tr("Only one phone left. Cannot remove!"), QMessageBox.Ok) else: ids = self.findSelectedItemIds() wasDefault = False for i in range(len(ids)): selectedPhones = ids[i] if self.phonesTableWidget.item( self.phonesList[selectedPhones]['qid'].row(), 2).text() == "\u2713": wasDefault = True self.phonesTableWidget.removeRow( self.phonesList[selectedPhones]['qid'].row()) del self.phonesList[selectedPhones] if wasDefault == True: self.phonesTableWidget.item(0, 2).setText("\u2713") self.phonesList[str(self.phonesTableWidget.item( 0, 3).text())]['default'] = "\u2713" def onClickPlayCalibButton(self): ids = self.findSelectedItemIds() if len(ids) > 1: QMessageBox.warning( self, self.tr('Warning'), self.tr('Only one label can be renamed at a time')) return elif len(ids) < 1: QMessageBox.warning(self, self.tr('Warning'), self.tr('Please, select a phone in the table')) return else: selectedSound = ids[0] calMaxLev = self.phonesList[selectedSound]['maxLevel'] frequency = self.currLocale.toDouble(self.toneFreqTF.text())[0] level = self.currLocale.toDouble(self.toneLevTF.text())[0] duration = self.currLocale.toDouble(self.toneDurTF.text())[0] ramp = self.currLocale.toDouble(self.toneRampsTF.text())[0] channel = self.earChooser.currentText() fs = self.currLocale.toInt(self.parent().sampRateTF.text())[0] nBits = self.currLocale.toInt( self.parent().nBitsChooser.currentText())[0] calTone = pureTone(frequency, 0, level, duration, ramp, channel, fs, calMaxLev) self.isPlaying = True if self.prm['pref']['sound']['playCommand'] in [ "alsaaudio", "pyaudio" ]: self.playThread = threadedAudioPlayer(self.parent()) else: self.playThread = threadedExternalAudioPlayer(self.parent()) self.playThread.playThreadedSound( calTone, fs, nBits, self.prm['pref']['sound']['playCommand'], True, 'calibrationTone.wav') if self.playThread.isFinished() == True: self.isPlaying = False def onClickStopCalibButton(self): if self.isPlaying == True: self.playThread.terminate() #self.playThread.__del__() def closeEvent(self, event): if self.isPlaying == True: #self.playThread.__del__() self.playThread.terminate() event.accept() def accept(self): #reimplement accept (i.e. ok button) if self.isPlaying == True: #self.playThread.__del__() self.playThread.terminate() QDialog.accept(self) def reject(self): #reimplement reject if self.isPlaying == True: #self.playThread.__del__() self.playThread.terminate() QDialog.reject(self)
class TableCatalogOTF(QObject): runCatalog = pyqtSignal(str) def __init__(self): def initGui(): self.tableWidget.setWindowTitle("Catalog OTF") self.tableWidget.setSortingEnabled(False) msgtrans = QCoreApplication.translate("CatalogOTF", "Layer,Total") headers = msgtrans.split(',') self.tableWidget.setColumnCount(len(headers)) self.tableWidget.setHorizontalHeaderLabels(headers) self.tableWidget.resizeColumnsToContents() super(TableCatalogOTF, self).__init__() self.tableWidget = QTableWidget() initGui() def _getRowLayerID(self, layerID): for row in range(self.tableWidget.rowCount()): if layerID == self.tableWidget.cellWidget(row, 0).objectName(): return row return -1 def _changedText(self, layerID, name, column): row = self._getRowLayerID(layerID) if row != -1: wgt = self.tableWidget.cellWidget( row, column) if column == 0 else self.tableWidget.item( row, column) wgt.setText(name) wgt.setToolTip(name) self.tableWidget.resizeColumnsToContents() @pyqtSlot() def _onRunCatalog(self): btn = self.sender() icon = QIcon(joinPath(dirname(__file__), 'cancel_red.svg')) btn.setIcon(icon) layerID = btn.objectName() self.runCatalog.emit(layerID) @pyqtSlot() def _onSelectionChanged(self): layer = self.sender() row = self._getRowLayerID(layer.id()) if row != -1: wgt = self.tableWidget.cellWidget(row, 0) nameIcon = 'check_green.svg' if layer.selectedFeatureCount( ) == 0 else 'check_yellow.svg' icon = QIcon(joinPath(dirname(__file__), nameIcon)) wgt.setIcon(icon) @pyqtSlot("QgsVectorLayer") def insertRow(self, layer): row = self.tableWidget.rowCount() self.tableWidget.insertRow(row) column = 0 # Layer layerName = layer.name() nameIcon = 'check_green.svg' if layer.selectedFeatureCount( ) == 0 else 'check_yellow.svg' icon = QIcon(joinPath(dirname(__file__), nameIcon)) btn = QPushButton(icon, layerName, self.tableWidget) btn.setObjectName(layer.id()) btn.setToolTip(layerName) btn.clicked.connect(self._onRunCatalog) layer.selectionChanged.connect(self._onSelectionChanged) self.tableWidget.setCellWidget(row, column, btn) column = 1 # Total msgtrans = QCoreApplication.translate("CatalogOTF", "None") item = QTableWidgetItem(msgtrans) item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) self.tableWidget.setItem(row, column, item) self.tableWidget.resizeColumnsToContents() @pyqtSlot(str) def removeRow(self, layerID): row = self._getRowLayerID(layerID) if row != -1: self.tableWidget.removeRow(row) @pyqtSlot(str, str) def changedNameLayer(self, layerID, name): self._changedText(layerID, name, 0) @pyqtSlot(str, str) def changedTotal(self, layerID, value): self._changedText(layerID, value, 1) @pyqtSlot(str, bool) def changedIconRun(self, layerID, selected): row = self._getRowLayerID(layerID) if row != -1: btn = self.tableWidget.cellWidget(row, 0) nameIcon = 'check_green.svg' if not selected else 'check_yellow.svg' icon = QIcon(joinPath(dirname(__file__), nameIcon)) btn.setIcon(icon) btn.setEnabled(True) @pyqtSlot(str) def killed(self, layerID): row = self._getRowLayerID(layerID) if row != -1: btn = self.tableWidget.cellWidget(row, 0) btn.setEnabled(False) def widget(self): return self.tableWidget
class AvailableWidget(QWidget): def __init__(self, parent, available): QWidget.__init__(self, parent) self._parent = parent self._available = available vbox = QVBoxLayout(self) self._table = QTableWidget(1, 5) self._table.removeRow(0) vbox.addWidget(self._table) self._headers = ('Name', 'Version', 'Description', "Authors", "Web") ui_tools.load_table(self._table, self._headers, _format_for_table(available)) self._table.setColumnWidth(0, 200) hbox = QHBoxLayout() btnInstall = QPushButton('Install') btnInstall.setMaximumWidth(100) hbox.addWidget(btnInstall) hbox.addWidget(QLabel(self.tr("NINJA needs to be restarted for " \ "changes to take effect."))) vbox.addLayout(hbox) # hbox = QHBoxLayout() # hbox.addWidget(QLabel( # self.tr("Add an external Plugin. URL Zip File:"))) # self._link = QLineEdit() # hbox.addWidget(self._link) # btnAdd = QPushButton(self.tr("Add")) # hbox.addWidget(btnAdd) # vbox.addLayout(hbox) # lblExternalPlugin = QLabel( # self.tr("(Write the URL of the Plugin and press 'Add')")) # lblExternalPlugin.setAlignment(Qt.AlignRight) # vbox.addWidget(lblExternalPlugin) self.connect(btnInstall, SIGNAL("clicked()"), self._install_plugins) # self.connect(btnAdd, SIGNAL("clicked()"), self._install_external) def _install_plugins(self): data = _format_for_table(self._available) plugins = ui_tools.remove_get_selected_items(self._table, data) #get the download link of each plugin for p_row in plugins: #search the plugin for p_dict in self._available: if unicode(p_dict["name"]) == unicode(p_row[0]): p_data = p_dict break #append the downlod link p_row.append(p_data["download"]) #download self._parent.download_plugins(plugins) def remove_item(self, plugin_name): plugin = _get_plugin(plugin_name, self._available) self._available.remove(plugin) def _install_external(self): if self._link.text().isEmpty(): QMessageBox.information(self, self.tr("External Plugins"), self.tr("URL from Plugin missing...")) return plug = [ file_manager.get_module_name(str(self._link.text())), 'External Plugin', '1.0', str(self._link.text())] self.parent().download_plugins(plug) self._link.setText('') def add_table_items(self, plugs): self._available += plugs data = _format_for_table(self._available) ui_tools.load_table(self._table, self._headers, data)
class FilesUIManager(QWidget): def __init__(self, winged, pref): QWidget.__init__(self) self.winged = winged self.pref = pref self._vbox = QVBoxLayout(self) self._hbox = QHBoxLayout() self._table = QTableWidget(1, 3) self._table.setHorizontalHeaderLabels(['Access', 'File Name', 'Size']) self._table.setSelectionBehavior(QAbstractItemView.SelectRows) self._table.verticalHeader().hide() self._table.removeRow(0) self._table.setColumnWidth(0, 80) self._table.setColumnWidth(1, 480) self._hbox.addWidget(self._table) self._btnDownload = QPushButton(QIcon(config.images['download']), '') self._btnDownload.setToolTip('Download') self._btnFacebook = QPushButton(QIcon(config.images['facebook']), '') self._btnFacebook.setToolTip('Share on Facebook') self._btnTwitter = QPushButton(QIcon(config.images['twitter']), '') self._btnTwitter.setToolTip('Share on Twitter') self._btnLink = QPushButton(QIcon(config.images['link']), '') self._btnLink.setToolTip('Copy Link') self.connect(self._btnDownload, SIGNAL("clicked()"), self._save) self.connect(self._btnFacebook, SIGNAL("clicked()"), self._facebook) self.connect(self._btnTwitter, SIGNAL("clicked()"), self._twitter) self.connect(self._btnLink, SIGNAL("clicked()"), self._copy_link) def _save(self): file_ = self._files[self._table.currentRow()] if file_['accesibility'] == '2': if self.pref.get('ask', True): folderName = str(QFileDialog.getExistingDirectory(self, 'Save File in...')) else: folderName = self.pref.get('folder', '') if folderName != '': self.winged.save_file(file_, folderName) else: QMessageBox.information(self, 'Download Fail', 'You can only download public files\nwith WingedBox-Client.') def _facebook(self): file_ = self._files[self._table.currentRow()] self.winged.thread.api.facebook(file_) def _twitter(self): file_ = self._files[self._table.currentRow()] self.winged.thread.api.twitter(file_) def _copy_link(self): clipboard = QApplication.clipboard() file = self._files[self._table.currentRow()] clipboard.setText('http://wingedbox.com/downloads/' + file['id'] + "-" + file['file-name']) def find(self, text): items = self._table.findItems(text, Qt.MatchContains) rows = [i.row() for i in items] rowsCount = range(self._table.rowCount()) rowsCount.reverse() for i in rowsCount: if i not in rows: self._table.removeRow(i) def load_table(self, files): self._files = files r = 0 for file in files: self._table.insertRow(r) if len(file['name']) > 0: item = QTableWidgetItem(file['name']) else: item = QTableWidgetItem(file['file-name']) item.setFlags( Qt.ItemIsSelectable | Qt.ItemIsEnabled ) self._table.setItem(r, 1, item) item = QTableWidgetItem(str(file['file-size'] / 1024) + ' kb') item.setFlags( Qt.ItemIsSelectable | Qt.ItemIsEnabled ) self._table.setItem(r, 2, item) imageFile = config.type.get(file['type'], config.typeBlank) access = config.access[file['accesibility']] item = QTableWidgetItem(QIcon(imageFile), access[3]) item.setBackgroundColor(QColor(access[0], access[1], access[2])) item.setFlags( Qt.ItemIsSelectable | Qt.ItemIsEnabled ) self._table.setItem(r, 0, item) r += 1 self._table.resizeRowsToContents() self._table.resizeColumnsToContents() self._table.horizontalHeader().setStretchLastSection(True)
class CameraWindow(PyDialog): def __init__(self, data, win_parent=None): """ +--------+ | Camera | +--------+---------------+ | Camera Name | | +-------------------+ | | | | | | | | | | | | | | | | | | | | | | +-------------------+ | | | | Name xxx Save | | Delete Set | | | | Apply OK Cancel | +--------+---------------+ """ PyDialog.__init__(self, data, win_parent) self.setWindowTitle('Camera Views') #self.setWindowIcon(view_icon) self._default_name = 'Camera' self.out_data['clicked_ok'] = False self.cameras = deepcopy(data['cameras']) self.names = sorted(self.cameras.keys()) self.name = QLabel("Name:") self.name_edit = QLineEdit(str(self._default_name)) self.delete_button = QPushButton("Delete") self.set_button = QPushButton("Set") self.save_button = QPushButton("Save") # closing self.apply_button = QPushButton("Apply") #self.ok_button = QPushButton("OK") self.close_button = QPushButton("Close") self.cancel_button = QPushButton("Cancel") self.table = QTableWidget() names_text = [] for iname, name in enumerate(self.names): name_text = QTableWidgetItem(str(name)) names_text.append(name_text) self.create_layout(names_text) self.set_connections() def create_layout(self, names_text): nrows = len(self.names) table = self.table table.setRowCount(nrows) table.setColumnCount(1) headers = [QString('Camera Name')] table.setHorizontalHeaderLabels(headers) header = table.horizontalHeader() header.setStretchLastSection(True) for iname, name_text in enumerate(names_text): # row, col, value table.setItem(iname, 0, name_text) table.resizeRowsToContents() ok_cancel_box = QHBoxLayout() ok_cancel_box.addWidget(self.apply_button) #ok_cancel_box.addWidget(self.ok_button) ok_cancel_box.addWidget(self.close_button) ok_cancel_box.addWidget(self.cancel_button) grid = QGridLayout() irow = 0 grid.addWidget(self.name, irow, 0) grid.addWidget(self.name_edit, irow, 1) grid.addWidget(self.save_button, irow, 2) irow += 1 grid.addWidget(self.delete_button, irow, 0) grid.addWidget(self.set_button, irow, 1) irow += 1 vbox = QVBoxLayout() vbox.addWidget(self.table) vbox.addLayout(grid) vbox.addStretch() vbox.addLayout(ok_cancel_box) self.setLayout(vbox) def set_connections(self): if qt_version == 4: self.connect(self.set_button, QtCore.SIGNAL('clicked()'), self.on_set) self.connect(self.save_button, QtCore.SIGNAL('clicked()'), self.on_save) self.connect(self.delete_button, QtCore.SIGNAL('clicked()'), self.on_delete) self.connect(self.apply_button, QtCore.SIGNAL('clicked()'), self.on_apply) #self.connect(self.ok_button, QtCore.SIGNAL('clicked()'), self.on_ok) self.connect(self.close_button, QtCore.SIGNAL('clicked()'), self.on_close) self.connect(self.cancel_button, QtCore.SIGNAL('clicked()'), self.on_cancel) else: self.set_button.clicked.connect(self.on_set) self.save_button.clicked.connect(self.on_save) self.delete_button.clicked.connect(self.on_delete) self.apply_button.clicked.connect(self.on_apply) self.close_button.clicked.connect(self.on_close) self.cancel_button.clicked.connect(self.on_cancel) def on_set(self): objs = self.table.selectedIndexes() if len(objs) == 1: obj = objs[0] irow = obj.row() name = self.names[irow] #print('name =', name) self.set_camera(name) return True return False def on_save(self): name = str(self.name_edit.text()).strip() if name in self.cameras: return irow = self.nrows if len(name): self.table.insertRow(irow) name_text = QTableWidgetItem(str(name)) self.table.setItem(irow, 0, name_text) self.name_edit.setText('') self.save_camera(name) def set_camera(self, name): camera_data = self.cameras[name] if self.win_parent is None: return self.win_parent.on_set_camera_data(camera_data) def save_camera(self, name): self.names.append(name) if self.win_parent is None: self.cameras[name] = None return self.cameras[name] = self.win_parent.get_camera_data() #@property #def camera(self): @property def nrows(self): return self.table.rowCount() def on_delete(self): irows = [] for obj in self.table.selectedIndexes(): irow = obj.row() irows.append(irow) irows.sort() for irow in reversed(irows): self.table.removeRow(irow) #print('delete', self.names) name = self.names.pop(irow) del self.cameras[name] #print(' removing irow=%s name=%r' % (irow, name)) def closeEvent(self, event): event.accept() @staticmethod def check_name(cell): text = str(cell.text()).strip() if len(text): cell.setStyleSheet("QLineEdit{background: white;}") return text, True else: cell.setStyleSheet("QLineEdit{background: red;}") return None, False #def on_validate(self): #name_value, flag0 = self.check_name(self.name_edit) #if flag0: #self.out_data['cameras'] = self.cameras #self.out_data['clicked_ok'] = True #return True #return False def on_apply(self): passed = self.on_set() #if passed: # self.win_parent.create_plane(self.out_data) return passed def on_close(self): self.out_data['clicked_ok'] = True self.out_data['cameras'] = self.cameras self.close() def on_ok(self): passed = self.on_apply() if passed: name = str(self.name_edit.text()).strip() self.out_data['name'] = name self.out_data['cameras'] = self.cameras self.out_data['clicked_ok'] = True self.close() #self.destroy() def on_cancel(self): self.close()
class AvailableWidget(QWidget): def __init__(self, parent, available): QWidget.__init__(self, parent) self._parent = parent self._available = available vbox = QVBoxLayout(self) self._table = QTableWidget(1, 2) self._table.setSelectionMode(QTableWidget.SingleSelection) self._table.removeRow(0) vbox.addWidget(self._table) ui_tools.load_table(self._table, TABLE_HEADER, _format_for_table(available)) self._table.setColumnWidth(0, 500) hbox = QHBoxLayout() btnInstall = QPushButton('Install') btnInstall.setMaximumWidth(100) hbox.addWidget(btnInstall) hbox.addWidget(QLabel(self.tr("NINJA needs to be restarted for " "changes to take effect."))) vbox.addLayout(hbox) self.connect(btnInstall, SIGNAL("clicked()"), self._install_plugins) self.connect(self._table, SIGNAL("itemSelectionChanged()"), self._show_item_description) def _show_item_description(self): item = self._table.currentItem() if item is not None: data = list(item.data(Qt.UserRole)) self._parent.show_plugin_info(data) def _install_plugins(self): data = _format_for_table(self._available) plugins = ui_tools.remove_get_selected_items(self._table, data) #get the download link of each plugin for p_row in plugins: #search the plugin for p_dict in self._available: if p_dict["name"] == p_row[0]: p_data = p_dict break #append the downlod link p_row.append(p_data["download"]) #download self._parent.download_plugins(plugins) def remove_item(self, plugin_name): plugin = _get_plugin(plugin_name, self._available) self._available.remove(plugin) def _install_external(self): if self._link.text().isEmpty(): QMessageBox.information(self, self.tr("External Plugins"), self.tr("URL from Plugin missing...")) return plug = [ file_manager.get_module_name(str(self._link.text())), 'External Plugin', '1.0', str(self._link.text())] self.parent().download_plugins(plug) self._link.setText('') def add_table_items(self, plugs): self._available += plugs data = _format_for_table(self._available) ui_tools.load_table(self._table, TABLE_HEADER, data)
class daq_window(QMainWindow): """Window to control and visualise DAQ measurements. Set up the desired channels with a given sampling rate. Start an acquisition after a trigger. Display the acquired data on a trace, and accumulated data on a graph. Arguments: n -- run number for synchronisation rate -- max sample rate in samples / second dt -- desired acquisition period in seconds config_file -- path to file storing default settings port -- the port number to open for TCP connections """ def __init__(self, n=0, rate=250, dt=500, config_file='monitor\\daqconfig.dat', port=8622): super().__init__() self.types = OrderedDict([('n', int), ('config_file', str), ('trace_file', str), ('graph_file', str), ('save_dir', str), ('Sample Rate (kS/s)',float), ('Duration (ms)', float), ('Trigger Channel', str), ('Trigger Level (V)', float), ('Trigger Edge', str), ('channels',channel_stats)]) self.stats = OrderedDict([('n', n), ('config_file', config_file), ('trace_file', 'DAQtrace.csv'), ('graph_file', 'DAQgraph.csv'),('save_dir', '.'), ('Sample Rate (kS/s)', rate), ('Duration (ms)', dt), ('Trigger Channel', 'Dev2/ai1'), # /Dev2/PFI0 ('Trigger Level (V)', 1.0), ('Trigger Edge', 'rising'), ('channels', channel_stats("[['Dev2/ai0', '0', '1.0', '0.0', '5', '1', '1']]"))]) self.trigger_toggle = True # whether to trigger acquisition or just take a measurement self.slave = worker(rate*1e3, dt/1e3, self.stats['Trigger Channel'], self.stats['Trigger Level (V)'], self.stats['Trigger Edge'], list(self.stats['channels'].keys()), [ch['range'] for ch in self.stats['channels'].values()]) # this controls the DAQ self.dc = daqCollection(param=[], channels=list(self.stats['channels'].keys())) self.init_UI() self.load_config(config_file) # load default settings self.n_samples = int(self.stats['Duration (ms)'] * self.stats['Sample Rate (kS/s)']) # number of samples per acquisition self.last_path = './' self.x = [] # run numbers for graphing collections of acquired data self.y = [] # average voltages in slice of acquired trace self.slave.acquired.connect(self.update_graph) # take average of slices self.slave.acquired.connect(self.update_trace) # plot new data when it arrives self.tcp = PyClient(port=port) remove_slot(self.tcp.dxnum, self.set_n, True) remove_slot(self.tcp.textin, self.respond, True) self.tcp.start() def init_UI(self): """Produce the widgets and buttons.""" self.centre_widget = QWidget() self.tabs = QTabWidget() # make tabs for each main display self.centre_widget.layout = QVBoxLayout() self.centre_widget.layout.addWidget(self.tabs) self.centre_widget.setLayout(self.centre_widget.layout) self.setCentralWidget(self.centre_widget) # change font size font = QFont() font.setPixelSize(18) #### menubar at top gives options #### menubar = self.menuBar() # file menubar allows you to save/load data file_menu = menubar.addMenu('File') for label, function in [['Load Config', self.load_config], ['Save Config', self.save_config], ['Load Trace', self.load_trace], ['Save Trace', self.save_trace], ['Save Graph', self.save_graph]]: action = QAction(label, self) action.triggered.connect(function) file_menu.addAction(action) #### tab for settings #### settings_tab = QWidget() settings_grid = QGridLayout() settings_tab.setLayout(settings_grid) self.tabs.addTab(settings_tab, "Settings") self.settings = QTableWidget(1, 6) self.settings.setHorizontalHeaderLabels(['Duration (ms)', 'Sample Rate (kS/s)', 'Trigger Channel', 'Trigger Level (V)', 'Trigger Edge', 'Use Trigger?']) settings_grid.addWidget(self.settings, 0,0, 1,1) defaults = [str(self.stats['Duration (ms)']), str(self.stats['Sample Rate (kS/s)']), self.stats['Trigger Channel'], str(self.stats['Trigger Level (V)']), self.stats['Trigger Edge'], '1'] validators = [double_validator, double_validator, None, double_validator, None, bool_validator] for i in range(6): table_item = QLineEdit(defaults[i]) # user can edit text to change the setting if defaults[i] == 'Sample Rate (kS/s)': table_item.setEnabled(False) table_item.setValidator(validators[i]) # validator limits the values that can be entered self.settings.setCellWidget(0,i, table_item) self.settings.resizeColumnToContents(1) self.settings.setFixedHeight(70) # make it take up less space self.settings.cellWidget(0,0).textChanged.connect(self.check_slice_duration) # start/stop: start waiting for a trigger or taking an acquisition self.toggle = QPushButton('Start', self) self.toggle.setCheckable(True) self.toggle.clicked.connect(self.activate) settings_grid.addWidget(self.toggle, 1,0, 1,1) # channels self.channels = QTableWidget(8, 7) # make table self.channels.setHorizontalHeaderLabels(['Channel', 'Label', 'Scale (X/V)', 'Offset (V)', 'Range', 'Acquire?', 'Plot?']) settings_grid.addWidget(self.channels, 2,0, 1,1) validators = [None, double_validator, double_validator, None, bool_validator, bool_validator] for i in range(8): chan = 'Dev2/ai'+str(i) # name of virtual channel table_item = QLabel(chan) self.channels.setCellWidget(i,0, table_item) if chan in self.stats['channels']: # load values from previous defaults = self.stats['channels'][chan] else: # default values when none are loaded defaults = channel_stats("[dummy, "+str(i)+", 1.0, 0.0, 5.0, 0, 0]")['dummy'] for j, key in zip([0,1,2,4,5], ['label', 'scale', 'offset', 'acquire', 'plot']): table_item = QLineEdit(str(defaults[key])) if 'acquire' in key: table_item.textChanged.connect(self.check_slice_channels) elif 'plot' in key: table_item.textChanged.connect(self.set_acquire) table_item.setValidator(validators[j]) self.channels.setCellWidget(i,j+1, table_item) vrange = QComboBox() # only allow certain values for voltage range vrange.text = vrange.currentText # overload function so it's same as QLabel vrange.addItems(['%.1f'%x for x in self.slave.vrs]) try: vrange.setCurrentIndex(self.slave.vrs.index(defaults['range'])) except Exception as e: logger.error('Invalid channel voltage range\n'+str(e)) self.channels.setCellWidget(i,4, vrange) #### Plot for most recently acquired trace #### trace_tab = QWidget() trace_grid = QGridLayout() trace_tab.setLayout(trace_grid) self.tabs.addTab(trace_tab, "Trace") # button activates horizontal line self.hline_toggle = QPushButton('Horizontal line', self, checkable=True) self.hline_toggle.clicked.connect(self.add_horizontal) trace_grid.addWidget(self.hline_toggle, 0,0, 1,1) self.hline_label = QLabel() trace_grid.addWidget(self.hline_label, 0,1, 1,1) fadeline_button = QPushButton('Persist', self) fadeline_button.clicked.connect(self.set_fadelines) trace_grid.addWidget(fadeline_button, 0,2, 1,1) # plot the trace self.trace_canvas = pg.PlotWidget() self.trace_legend = self.trace_canvas.addLegend() self.trace_canvas.getAxis('bottom').tickFont = font self.trace_canvas.getAxis('left').tickFont = font self.trace_canvas.setLabel('bottom', 'Time', 's', **{'font-size':'18pt'}) self.trace_canvas.setLabel('left', 'Voltage', 'V', **{'font-size':'18pt'}) self.lines = [] # handles for lines plotting the last measurement self.fadelines = [] # handles for previous measurement lines for i in range(8): chan = self.channels.cellWidget(i,1).text() self.lines.append(self.trace_canvas.plot([1], name=chan, pen=pg.mkPen(pg.intColor(i), width=3))) self.lines[i].hide() self.fadelines.append(self.trace_canvas.plot([1], pen=pg.mkPen(pg.intColor(i, alpha=50), width=2))) self.fadelines[i].hide() self.hline = pg.InfiniteLine(1., angle=0, pen='k', movable=True) self.trace_canvas.addItem(self.hline) self.hline.sigPositionChanged.connect(self.update_hline) self.hline.hide() trace_grid.addWidget(self.trace_canvas, 1,0, 1,3) #### Settings for slices of the trace accumulating into the graph #### slice_tab = QWidget() slice_grid = QGridLayout() slice_tab.setLayout(slice_grid) self.tabs.addTab(slice_tab, "Slice") # Buttons to add/remove slices and reset graph for i, (label, func) in enumerate([['Add slice', self.add_slice], ['Remove slice', self.del_slice], ['Reset graph', self.reset_graph]]): button = QPushButton(label, self) button.clicked.connect(func) slice_grid.addWidget(button, 0,i, 1,1) # parameters for slices self.slices = QTableWidget(0, 4) # make table self.slices.setHorizontalHeaderLabels(['Slice name', 'Start (ms)', 'End (ms)', 'Channels']) slice_grid.addWidget(self.slices, 1,0, 1,3) #### Plot for graph of accumulated data #### graph_tab = QWidget() graph_grid = QGridLayout() graph_tab.setLayout(graph_grid) self.tabs.addTab(graph_tab, "Graph") self.mean_graph = pg.PlotWidget() # for plotting means self.stdv_graph = pg.PlotWidget() # for plotting standard deviations self.graph_legends = [] for i, g in enumerate([self.mean_graph, self.stdv_graph]): g.getAxis('bottom').tickFont = font g.getAxis('bottom').setFont(font) g.getAxis('left').tickFont = font g.getAxis('left').setFont(font) graph_grid.addWidget(g, i,0, 1,1) self.reset_lines() # make a line for every slice channel self.stdv_graph.setLabel('bottom', 'Shot', '', **{'font-size':'18pt'}) self.stdv_graph.setLabel('left', 'Standard Deviation', 'V', **{'font-size':'18pt'}) self.mean_graph.setLabel('left', 'Mean', 'V', **{'font-size':'18pt'}) #### tab for TCP message settings #### tcp_tab = QWidget() tcp_grid = QGridLayout() tcp_tab.setLayout(tcp_grid) self.tabs.addTab(tcp_tab, "Sync") label = QLabel('Run number: ') tcp_grid.addWidget(label, 0,0, 1,1) self.n_edit = QLineEdit(str(self.stats['n'])) self.n_edit.setValidator(int_validator) self.n_edit.textEdited[str].connect(self.set_n) tcp_grid.addWidget(self.n_edit, 0,1, 1,1) label = QLabel('Save directory: ') tcp_grid.addWidget(label, 1,0, 1,1) self.save_edit = QLineEdit(self.stats['save_dir']) self.save_edit.textEdited[str].connect(self.set_save_dir) tcp_grid.addWidget(self.save_edit, 1,1, 1,1) label = QLabel('Trace file name: ') tcp_grid.addWidget(label, 2,0, 1,1) self.trace_edit = QLineEdit(self.stats['trace_file']) self.trace_edit.textEdited[str].connect(self.set_trace_file) tcp_grid.addWidget(self.trace_edit, 2,1, 1,1) label = QLabel('Graph file name: ') tcp_grid.addWidget(label, 3,0, 1,1) self.graph_edit = QLineEdit(self.stats['graph_file']) self.graph_edit.textEdited[str].connect(self.set_graph_file) tcp_grid.addWidget(self.graph_edit, 3,1, 1,1) reset = QPushButton('Reset TCP client', self) reset.clicked.connect(self.reset_client) tcp_grid.addWidget(reset, 4,0, 1,1) #### Title and icon #### self.setWindowTitle('- NI DAQ Controller -') self.setWindowIcon(QIcon('docs/daqicon.png')) self.setGeometry(200, 200, 800, 600) #### user input functions #### def set_acquire(self): """If the user chooses to plot, set the same channel to acquire.""" for i in range(self.channels.rowCount()): if BOOL(self.channels.cellWidget(i,6).text()): # plot self.channels.cellWidget(i,5).setText('1') # only plot if acquiring def check_settings(self): """Coerce the settings into allowed values.""" statstr = "[[" # dictionary of channel names and properties for i in range(self.channels.rowCount()): self.trace_legend.items[i][1].setText(self.channels.cellWidget(i,1).text()) # label if BOOL(self.channels.cellWidget(i,5).text()): # acquire statstr += ', '.join([self.channels.cellWidget(i,j).text() for j in range(self.channels.columnCount())]) + '],[' self.stats['channels'] = channel_stats(statstr[:-2] + ']') self.dc.channels = self.stats['channels'].keys() # acquisition settings self.stats['Duration (ms)'] = float(self.settings.cellWidget(0,0).text()) # check that the requested rate is valid rate = float(self.settings.cellWidget(0,1).text()) if len(self.stats['channels']) > 1 and rate > 245 / len(self.stats['channels']): rate = 245 / len(self.stats['channels']) elif len(self.stats['channels']) < 2 and rate > 250: rate = 250 self.stats['Sample Rate (kS/s)'] = rate self.settings.cellWidget(0,1).setText('%.2f'%(rate)) self.n_samples = int(self.stats['Duration (ms)'] * self.stats['Sample Rate (kS/s)']) # check the trigger channel is valid trig_chan = self.settings.cellWidget(0,2).text() if 'Dev2/PFI' in trig_chan or 'Dev2/ai' in trig_chan: self.stats['Trigger Channel'] = trig_chan else: self.stats['Trigger Channel'] = 'Dev2/ai0' self.settings.cellWidget(0,2).setText(str(self.stats['Trigger Channel'])) self.stats['Trigger Level (V)'] = float(self.settings.cellWidget(0,3).text()) self.stats['Trigger Edge'] = self.settings.cellWidget(0,4).text() self.trigger_toggle = BOOL(self.settings.cellWidget(0,5).text()) def set_table(self): """Display the acquisition and channel settings in the table.""" x = self.stats.copy() # prevent it getting overwritten for i in range(5): self.settings.cellWidget(0,i).setText(str(x[ self.settings.horizontalHeaderItem(i).text()])) for i in range(8): ch = self.channels.cellWidget(i,0).text() if ch in x['channels']: for j, key in zip([0,1,2,4,5], ['label', 'scale', 'offset', 'acquire', 'plot']): self.channels.cellWidget(i,j+1).setText(str(x['channels'][ch][key])) self.channels.cellWidget(i,4).setCurrentText('%.1f'%x['channels'][ch]['range']) else: self.channels.cellWidget(i,5).setText('0') # don't acquire self.channels.cellWidget(i,6).setText('0') # don't plot #### slice settings functions #### def add_slice(self, param=[]): """Add a row to the slice table and append it to the daqCollection instance for analysis. param -- [name, start (ms), end (ms), channels]""" try: name, start, end, channels = param except TypeError: name = 'Slice' + str(self.slices.rowCount()) start = 0 end = self.stats['Duration (ms)'] channels = list(self.stats['channels'].keys()) i = self.slices.rowCount() # index to add row at self.slices.insertRow(i) # add row to table validator = QDoubleValidator(0.,float(self.stats['Duration (ms)']),3) for j, text in enumerate([name, str(start), str(end)]): item = QLineEdit(text) item.pos = (i, j) if j > 0: item.setValidator(validator) item.textChanged.connect(self.update_slices) self.slices.setCellWidget(i, j, item) chanbox = QListWidget(self) chanbox.setSelectionMode(3) # extended selection, allows multiple selection chanbox.itemSelectionChanged.connect(self.update_slices) chanbox.pos = (i, 3) chanbox.text = chanbox.objectName chanlist = list(self.stats['channels'].keys()) chanbox.addItems(chanlist) self.slices.setCellWidget(i, j+1, chanbox) self.slices.resizeRowToContents(i) # add to the dc list of slices t = np.linspace(0, self.stats['Duration (ms)']/1000, self.n_samples) self.dc.add_slice(name, np.argmin(np.abs(t-start)), np.argmin(np.abs(t-end)), OrderedDict([(chan, chanlist.index(chan)) for chan in channels])) self.reset_lines() def del_slice(self, toggle=True): """Remove the slice at the selected row of the slice table.""" index = self.slices.currentRow() self.slices.removeRow(index) if index >= 0: self.dc.slices.pop(index) def check_slice_duration(self, newtxt): """If the acquisition duration is changed, make sure the slices can't use times beyond this.""" self.check_settings() # update DAQ acquisition settings first for i in range(self.slices.rowCount()): for j in [1,2]: # force slice to be within max duration validator = QDoubleValidator(0.,float(self.stats['Duration (ms)']),3) self.slices.cellWidget(i, j).setValidator(validator) def check_slice_channels(self, newtxt): """If the channels that can be used for the acquisition are changed, change the list widgets in the slice settings to match.""" self.check_settings() # update DAQ acquisition settings first for i in range(self.slices.rowCount()): w = self.slices.cellWidget(i, 3) # widget shorthand selected = [w.row(x) for x in w.selectedItems()] # make record of selected channels w.clear() w.addItems(list(self.stats['channels'].keys())) for r in selected: try: w.setCurrentRow(r, QItemSelectionModel.SelectCurrent) except Exception as e: pass def update_slices(self, newtxt=''): """Use the current item from the table to update the parameter for the slices.""" try: w = self.sender() i, j = w.pos t = np.linspace(0, self.stats['Duration (ms)'], self.n_samples) x = self.dc.slices[i] # shorthand if j == 0: # name x.name = w.text() elif j == 1: # start (ms) x.i0 = np.argmin(np.abs(t-float(w.text()))) elif j == 2: # end (ms) x.i1 = np.argmin(np.abs(t-float(w.text()))) elif j == 3: x.channels = OrderedDict([(x.text(), w.row(x)) for x in w.selectedItems()]) x.stats = OrderedDict([(chan, OrderedDict([ ('mean',[]), ('stdv',[])])) for chan in x.channels.keys()]) self.reset_lines() self.reset_graph() x.inds = slice(x.i0, x.i1+1) x.size = x.i1 - x.i0 except IndexError as e: pass # logger.error("Couldn't update slice.\n"+str(e)) #### TCP functions #### def set_n(self, num): """Receive the new run number to update to""" self.stats['n'] = int(num) self.n_edit.setText(str(num)) def set_save_dir(self, directory): """Set the directory to save results to""" self.stats['save_dir'] = directory self.save_edit.setText(directory) def set_trace_file(self, fname): """Set the default name for trace files when they're saved.""" self.stats['trace_file'] = fname self.trace_edit.setText(fname) def set_graph_file(self, fname): """Set the default name for graph files when they're saved.""" self.stats['graph_file'] = fname self.graph_edit.setText(fname) def reset_client(self, toggle=True): """Stop the TCP client thread then restart it.""" self.tcp.stop = True for i in range(100): # wait til it's stopped if not self.tcp.isRunning(): break else: time.sleep(0.001) self.tcp.start() # restart def respond(self, msg=''): """Interpret a TCP message. For setting properties, the syntax is: value=property. E.g. 'Z:\Tweezer=save_dir'.""" if 'save_dir' in msg: self.set_save_dir(msg.split('=')[0]) elif 'trace_file' in msg: self.set_trace_file(msg.split('=')[0]) elif 'graph_file' in msg: self.set_graph_file(msg.split('=')[0]) elif 'start' in msg and not self.toggle.isChecked(): self.toggle.setChecked(True) self.activate() elif 'stop' in msg and self.toggle.isChecked(): self.toggle.setChecked(False) self.activate() elif 'save trace' in msg: self.save_trace(os.path.join(self.stats['save_dir'], self.stats['trace_file'])) elif 'save graph' in msg: self.save_graph(os.path.join(self.stats['save_dir'], self.stats['graph_file'])) elif 'set fadelines' in msg: self.set_fadelines() #### acquisition functions #### def activate(self, toggle=0): """Prime the DAQ task for acquisition if it isn't already running. Otherwise, stop the task running.""" if self.toggle.isChecked(): self.check_settings() self.slave = worker(self.stats['Sample Rate (kS/s)']*1e3, self.stats['Duration (ms)']/1e3, self.stats['Trigger Channel'], self.stats['Trigger Level (V)'], self.stats['Trigger Edge'], list(self.stats['channels'].keys()), [ch['range'] for ch in self.stats['channels'].values()]) remove_slot(self.slave.acquired, self.update_trace, True) remove_slot(self.slave.acquired, self.update_graph, True) if self.trigger_toggle: # remove_slot(self.slave.finished, self.activate, True) self.slave.start() self.toggle.setText('Stop') else: self.toggle.setChecked(False) self.slave.analogue_acquisition() else: # remove_slot(self.slave.finished, self.activate, False) self.slave.stop = True self.slave.quit() self.toggle.setText('Start') #### plotting functions #### def update_trace(self, data): """Plot the supplied data with labels on the trace canvas.""" t = np.linspace(0, self.stats['Duration (ms)']/1000, self.n_samples) i = 0 # index to keep track of which channels have been plotted for j in range(8): ch = self.channels.cellWidget(j,0).text() l = self.lines[j] # shorthand if ch in self.stats['channels'] and self.stats['channels'][ch]['plot']: try: l.setData(t, data[i]) except Exception as e: logger.error('DAQ trace could not be plotted.\n'+str(e)) self.fadelines[j].show() l.show() self.trace_legend.items[j][0].show() self.trace_legend.items[j][1].show() i += 1 else: l.hide() self.fadelines[j].hide() self.trace_legend.items[j][0].hide() self.trace_legend.items[j][1].hide() self.trace_legend.resize(0,0) def set_fadelines(self): """Take the data from the current lines and sets it to the fadelines.""" for j in range(8): ch = self.channels.cellWidget(j,0).text() l = self.lines[j] # shorthand if ch in self.stats['channels'] and self.stats['channels'][ch]['plot']: try: self.fadelines[j].setData(l.xData, l.yData) except Exception as e: logger.error('DAQ trace could not be plotted.\n'+str(e)) self.fadelines[j].show() else: self.fadelines[j].hide() def reset_lines(self): """Clear the mean and stdv graphs, reset the legends, then make new lines for each of the slice channels.""" for legend in self.graph_legends: # reset the legends try: legend.scene().removeItem(legend) except AttributeError: pass for g in [self.mean_graph, self.stdv_graph]: g.clear() g.lines = OrderedDict([]) self.graph_legends.append(g.addLegend()) i = 0 for s in self.dc.slices: for chan, val in s.stats.items(): g.lines[s.name+'/'+chan] = g.plot([1], name=s.name+'/'+chan, pen=None, symbol='o', symbolPen=pg.mkPen(pg.intColor(i)), symbolBrush=pg.intColor(i)) i += 1 def reset_graph(self): """Reset the collection of slice data, then replot the graph.""" self.dc.reset_arrays() self.update_graph() def update_graph(self, data=[]): """Extract averages from slices of the data. Replot the stored data accumulated from averages in slices of the measurements.""" if np.size(data): self.dc.process(data, self.stats['n']) for s in self.dc.slices: for chan, val in s.stats.items(): self.mean_graph.lines[s.name+'/'+chan].setData(self.dc.runs, val['mean']) self.stdv_graph.lines[s.name+'/'+chan].setData(self.dc.runs, val['stdv']) def add_horizontal(self, toggle=True): """Display a horizontal line on the trace""" if toggle: self.hline.show() else: self.hline.hide() self.hline_label.setText('') def update_hline(self): """Display the value of the horizontal line in the label""" self.hline_label.setText(str(self.hline.value())) #### save/load functions #### def try_browse(self, title='Select a File', file_type='all (*)', open_func=QFileDialog.getOpenFileName, default_path=''): """Open a file dialog and retrieve a file name from the browser. title: String to display at the top of the file browser window default_path: directory to open first file_type: types of files that can be selected open_func: the function to use to open the file browser""" default_path = default_path if default_path else os.path.dirname(self.last_path) try: if 'PyQt4' in sys.modules: file_name = open_func(self, title, default_path, file_type) elif 'PyQt5' in sys.modules: file_name, _ = open_func(self, title, default_path, file_type) if type(file_name) == str: self.last_path = file_name return file_name except OSError: return '' # probably user cancelled def save_config(self, file_name='daqconfig.dat'): """Save the current acquisition settings to the config file.""" self.stats['config_file'] = file_name if file_name else self.try_browse( 'Save Config File', 'dat (*.dat);;all (*)', QFileDialog.getSaveFileName) try: with open(self.stats['config_file'], 'w+') as f: for key, val in self.stats.items(): if key == 'channels': f.write(key+'='+channel_str(val)+'\n') else: f.write(key+'='+str(val)+'\n') logger.info('DAQ config saved to '+self.stats['config_file']) except Exception as e: logger.error('DAQ settings could not be saved to config file.\n'+str(e)) def load_config(self, file_name='daqconfig.dat'): """Load the acquisition settings from the config file.""" self.stats['config_file'] = file_name if file_name else self.try_browse(file_type='dat (*.dat);;all (*)') try: with open(self.stats['config_file'], 'r') as f: for line in f: if len(line.split('=')) == 2: key, val = line.replace('\n','').split('=') # there should only be one = per line try: self.stats[key] = self.types[key](val) except KeyError as e: logger.warning('Failed to load DAQ default config line: '+line+'\n'+str(e)) self.set_table() # make sure the updates are displayed self.set_n(self.stats['n']) self.set_save_dir(self.stats['save_dir']) self.set_trace_file(self.stats['trace_file']) self.set_graph_file(self.stats['graph_file']) self.dc.channels = list(self.stats['channels'].keys()) logger.info('DAQ config loaded from '+self.stats['config_file']) except FileNotFoundError as e: logger.warning('DAQ settings could not find the config file.\n'+str(e)) def save_trace(self, file_name=''): """Save the data currently displayed on the trace to a csv file.""" file_name = file_name if file_name else self.try_browse( 'Save File', 'csv (*.csv);;all (*)', QFileDialog.getSaveFileName) if file_name: # metadata header = ', '.join(list(self.stats.keys())) + '\n' header += ', '.join(list(map(str, self.stats.values()))[:-1] ) + ', ' + channel_str(self.stats['channels']) + '\n' # determine which channels are in the plot header += 'Time (s)' data = [] for key, d in self.stats['channels'].items(): if d['plot']: header += ', ' + key # column headings if len(data) == 0: # time (s) data.append(self.lines[int(key[-1])].xData) data.append(self.lines[int(key[-1])].yData) # voltage # data converted to the correct type out_arr = np.array(data).T try: np.savetxt(file_name, out_arr, fmt='%s', delimiter=',', header=header) logger.info('DAQ trace saved to '+file_name) except (PermissionError, FileNotFoundError) as e: logger.error('DAQ controller denied permission to save file: \n'+str(e)) def load_trace(self, file_name=''): """Load data for the current trace from a csv file.""" file_name = file_name if file_name else self.try_browse(file_type='csv(*.csv);;all (*)') if file_name: head = [[],[],[]] # get metadata with open(file_name, 'r') as f: for i in range(3): row = f.readline() if row[:2] == '# ': head[i] = row[2:].replace('\n','').split(', ') # apply the acquisition settings from the file labels = [self.settings.horizontalHeaderItem(i).text() for i in range(self.settings.columnCount())] for i in range(len(head[0])): try: j = labels.index(head[0][i]) self.settings.cellWidget(0,j).setText(head[1][i]) except ValueError: pass self.stats['channels'] = channel_stats(', '.join(head[1][7:])) for i in range(8): # whether to plot or not ch = self.channels.cellWidget(i,0).text() if ch in head[2]: self.channels.cellWidget(i,6).setText('1') self.channels.cellWidget(i,1).setText(self.stats['channels'][ch]['label']) else: self.channels.cellWidget(i,6).setText('0') self.check_settings() # plot the data data = np.genfromtxt(file_name, delimiter=',', dtype=float) if np.size(data) < 2: return 0 # insufficient data to load self.update_trace(data.T[1:]) def save_graph(self, file_name=''): """Save the data accumulated from several runs that's displayed in the graph into a csv file.""" file_name = file_name if file_name else self.try_browse( 'Save File', 'csv (*.csv);;all (*)', QFileDialog.getSaveFileName) if file_name: self.dc.save(file_name, list(self.stats.keys()), list(map(str, self.stats.values()))[:-1] + [channel_str(self.stats['channels'])]) logger.info('DAQ graph saved to '+file_name) def closeEvent(self, event): """Before closing, try to save the config settings to file.""" statstr = "[[" # dictionary of channel names and properties for i in range(self.channels.rowCount()): statstr += ', '.join([self.channels.cellWidget(i,j).text() for j in range(self.channels.columnCount())]) + '],[' self.stats['channels'] = channel_stats(statstr[:-2] + ']') # add all channels to stats self.save_config(self.stats['config_file']) event.accept()
def make_widget(main, show=True): id = main.persistant['id'] table = QTableWidget() table.controller = ROITableController(table, main) table.setGeometry(QRect(20, 33, 496, 296)) table.setWindowTitle('ceilingfaan - ROI Table - Work in progress') analysis = s.query(Analysis).order_by(Analysis.date.desc()).all() table.setRowCount(len(analysis)) table.setColumnCount(4) table.setHorizontalHeaderLabels( QString('CONTROL,DATE,MOUSE,FILENAME').split(',')) current_analysis = None on_render = table.controller.on('render') on_import = table.controller.on('import') for nrow, entity in enumerate(analysis): if entity.id == id: print 'Found matching analysis data', id, 'at nrow:', nrow current_analysis = entity current_nrow = nrow continue for ncol, attr in enumerate('date mouse_id filename'.split()): field = getattr(entity, attr) item = QTableWidgetItem(str(field)) item.setFlags(Qt.ItemIsEnabled) table.setItem(nrow, ncol + 1, item) render_btn = QPushButton('Render', checkable=True) render_btn.setStyleSheet('font-size: 9px; background-color: skyblue;') import_btn = QPushButton('Import') import_btn.setStyleSheet('font-size: 9px;') btn_layout = QHBoxLayout() btn_layout.setContentsMargins(5, 0, 5, 0) btn_layout.addWidget(render_btn) btn_layout.addWidget(import_btn) btn_widget = QWidget() btn_widget.nrow = nrow btn_widget.analysis_id = entity.id btn_widget.ext_roi_set = None btn_widget.setLayout(btn_layout) table.setCellWidget(nrow, 0, btn_widget) render_btn.clicked.connect(on_render) import_btn.clicked.connect(on_import) if current_analysis: table.removeRow(current_nrow) table.insertRow(0) item = QTableWidgetItem('Current Analysis') item.setFlags(Qt.ItemIsEnabled) item.setTextAlignment(Qt.AlignCenter) table.setItem(0, 0, item) for ncol, attr in enumerate('date mouse_id filename'.split()): field = getattr(current_analysis, attr) item = QTableWidgetItem(str(field)) item.setFlags(Qt.ItemIsEnabled) table.setItem(0, ncol + 1, item) # debug.enter() table.setSelectionBehavior(QTableWidget.SelectRows) table.setSelectionMode(QTableWidget.NoSelection) table.resizeColumnsToContents() table.horizontalHeader().setStretchLastSection(True) if show: table.show() return table
class AccessFrontend(ScrollArea): COMPONENT = 'access' LABEL = tr('Access to services') REQUIREMENTS = ('access',) STYLE_ALLOW = "color: white; background-color: white; border: none;" STYLE_DISALLOW = "color: lightGray; background-color: lightGray; border: none;" ICON = ':/icons/Acl.png' def __init__(self, client, parent): ScrollArea.__init__(self) self.client = client self.mainwindow = parent self._modified = False self.__disabled = False self.net_object = QNetObject.getInitializedInstance(self.client) if EDENWALL: self.vpn_object = QOpenVpnObject.getInstance() self.setupWidgets() self.getConfigs() self.getNetworks() # vpn_config is used to check if the VPN config changed or not self.vpn_config = self.getVPNConfig() self.fillTable() self.net_object.registerCallbacks(self.validateNetCfg, self.updateWithNetCfg) if EDENWALL: self.vpn_object.registerCallbacks(self.validateVpnCfg, self.updateWithVpnCfg) self.mainwindow.addToInfoArea(tr("Access interface enabled")) @staticmethod def get_calls(): """ services called at startup (self.mainwindow.init_call) """ return (('access', 'getConfig'),) def getVPNConfig(self): if not EDENWALL: return None vpn = self.vpn_object.getCfg() if not vpn: return None return (vpn.enabled, vpn.protocol, vpn.port, vpn.client_network) def setupWidgets(self): layout = QVBoxLayout(self) self.setLayout(layout) self.icon = QIcon() ALLOW = QPixmap(":/icons-20/status_on.png") self.icon.addPixmap(ALLOW, QIcon.Normal, QIcon.On) DISALLOW = QPixmap(":/icons-20/status_off.png") self.icon.addPixmap(DISALLOW, QIcon.Normal, QIcon.Off) title = QLabel(u"<H1>%s</H1>" % tr("Access to services")) layout.addWidget(title) self.table = QTableWidget() self.table.setSelectionMode(QAbstractItemView.NoSelection) layout.addWidget(self.table) def isModified(self): return self._modified def isValid(self): if self.__disabled: return True valid, errmsg = self.access_cfg.isValidWithMsg() if not valid: self.error_message = errmsg return valid def setModified(self, modif=True): if self.__disabled: self._modified = False return self._modified = modif if modif: self.mainwindow.setModified(self, True) def resetConf(self): if self.__disabled: return self.getConfigs() self.getNetworks() self.fillTable() def __disable(self, reason): if self.__disabled: return self.__disabled = True self.mainwindow.addToInfoArea( tr("The Access to services interface is disabled."), COLOR_ERROR) self.mainwindow.addToInfoArea(reason, COLOR_ERROR) self.close() raise NuConfModuleDisabled(reason) def getConfigs(self): if self.__disabled: return try: data = self.mainwindow.init_call('access', 'getConfig') except RpcdError: self.__disable(tr("Could not get Access to services configuration.")) return if data is None: self.access_cfg = AccessConf.defaultConf() else: self.access_cfg = AccessConf.deserialize(data) def _getNetworks(self, netcfg): return [(interface.system_name, network) for interface, network in netcfg.iterKnownNetworks()] def getNetworks(self): if self.__disabled: return netcfg = QNetObject.getInstance().netcfg if netcfg is None: self.networks = () self.mainwindow.addToInfoArea( tr("The access interface could not load the network configuration"), COLOR_ERROR ) return # list of (interface, network) where interface (str) is the system # name, and network (IPy.IP object) is the network address # (eg. IP('192.168.0.0/24') self.networks = self._getNetworks(netcfg) self.networks += list(self.access_cfg.custom_networks) self.networks.sort() def fillTable(self): if self.__disabled: self.table.clear() return services = list(self.access_cfg.permissions) self.table.clear() # (interface (str), network (IPy), ip version (int)) => row (int) # Don't use (interface, network) because of a bug in IPy < 0.70: # IP('0.0.0.0/0') and IP('::/0') are considered as equal self.net_to_row = {} component_to_name = ComponentToName() self.table.setSortingEnabled(False) self.table.setRowCount(len(self.networks)) self.setVerticalHeaders() self.table.setColumnCount(len(services)) self.table.setHorizontalHeaderLabels([component_to_name.display_name(service) for service in services]) self.table.horizontalHeader().setResizeMode(QHeaderView.ResizeToContents) for irow, interface_network in enumerate(self.networks): self.setRow(interface_network, irow) for icol, service in enumerate(self.access_cfg.permissions): allow = interface_network in self.access_cfg.permissions[service] self.createService(irow, icol, service, interface_network, allow) def getRow(self, interface_network, pop=False): interface, network = interface_network key = (interface, network, network.version()) if pop: return self.net_to_row.pop(key) else: return self.net_to_row[key] def setRow(self, interface_network, row): interface, network = interface_network key = (interface, network, network.version()) self.net_to_row[key] = row def setVerticalHeaders(self): labels = [self.netLabel(interface, network) for interface, network in self.networks] self.table.setVerticalHeaderLabels(labels) def saveConf(self, message): data = self.access_cfg.serialize(downgrade=True) self.client.call("access", 'setConfig', message, data) self.setModified(False) def changeService(self, col, service, interface_network): row = self.getRow(interface_network) self.setModified(True) button = self.table.cellWidget(row, col) if button.isChecked(): self.access_cfg.permissions[service].add(interface_network) button.setStyleSheet(self.STYLE_ALLOW) else: try: self.access_cfg.permissions[service].remove(interface_network) except KeyError: pass button.setStyleSheet(self.STYLE_DISALLOW) def appendNetwork(self, interface_network, close_all_ports=False): row = self.table.rowCount() self.table.insertRow(row) self.networks.append(interface_network) self.setRow(interface_network, row) interface, network = interface_network for icol, service in enumerate(self.access_cfg.permissions): if (not close_all_ports) \ and (service in OPEN_BY_DEFAULT) \ and (network not in CLOSED_NETWORKS): allow = True self.access_cfg.permissions[service].add(interface_network) else: allow = interface_network in self.access_cfg.permissions[service] self.createService(row, icol, service, interface_network, allow) def removeNetwork(self, interface_network): index = self.getRow(interface_network, pop=True) self.table.removeRow(index) network = self.networks[index] for service, networks in self.access_cfg.permissions.iteritems(): try: networks.remove(network) except KeyError: pass del self.networks[index] for key, row in self.net_to_row.iteritems(): if row > index: self.net_to_row[key] -= 1 # callback used to update the table on network modification def updateWithNetCfg(self, deleted_nets, added_nets): if not(deleted_nets or added_nets): return # delete for key in deleted_nets: self.removeNetwork(key) # add new for interface_network in added_nets: self.appendNetwork(interface_network, close_all_ports=True) # modify and update self.setVerticalHeaders() self.setModified(True) def createService(self, row, col, service, interface_network, allow): button = QPushButton(self.icon, u'') button.setCheckable(True) button.setFlat(True) button.setAutoFillBackground(True) if allow: style = self.STYLE_ALLOW else: style = self.STYLE_DISALLOW button.setStyleSheet(style) button.setFocusPolicy(Qt.NoFocus) self.mainwindow.writeAccessNeeded(button) self.connect(button, SIGNAL('clicked()'), partial(self.changeService, col, service, interface_network)) self.table.setCellWidget(row, col, button) # with PyQt 4.4.2, table.setCellWidget(button) changes # the button's state (bug fixed in PyQt 4.4.4) button.setChecked(allow) # callback used when the networks are modified def validateNetCfg(self): netcfg = QNetObject.getInstance().netcfg previous_nets = set(self.networks) - set(self.access_cfg.custom_networks) new_networks = self._getNetworks(netcfg) new_networks = set(new_networks) not_in_both = previous_nets ^ new_networks deleted_nets = not_in_both & previous_nets added_nets = not_in_both & new_networks return True, deleted_nets, added_nets def validateVpnCfg(self): """ always accept modifications """ return True, self.getVPNConfig() def updateWithVpnCfg(self, new_config): if self.vpn_config == new_config: return # anything changed, access has to reapply the new config self.setModified() self.vpn_config = new_config # get old/new key config = self.vpn_object.getCfg() if self.access_cfg.custom_networks: old_key = self.access_cfg.custom_networks[0] else: old_key = None if config.enabled: network = config.client_network try: network = IP(network) except ValueError: # ignore invalid network: vpn check will raise an error return new_key = (OPENVPN_INTERFACE, network) else: new_key = None # no change? exit if old_key == new_key: return # create/delete vpn custom network if old_key: self.removeNetwork(old_key) if new_key: self.access_cfg.custom_networks = [new_key] self.appendNetwork(new_key) else: self.access_cfg.custom_networks = [] self.setVerticalHeaders() def netLabel(self, interface, network): """ return label for network """ interface_label = interface network_label = str(network) network = IP(network) netcfg = QNetObject.getInstance().netcfg try: interface = netcfg.getInterfaceBySystemName(interface) interface_label = interface.user_label network = netcfg.getNet(network) network_label = network.displayName() except NoMatch: pass return tr("%s: %s") % (interface_label, network_label)
class NewRelationDialog(QDialog): def __init__(self, parent=None): QDialog.__init__(self, parent) self.setWindowTitle(self.tr("Nueva Relación")) vbox = QVBoxLayout(self) hbox = QHBoxLayout() self._line_relation_name = QLineEdit() hbox.addWidget(QLabel(self.tr("Nombre:"))) hbox.addWidget(self._line_relation_name) vbox.addLayout(hbox) vbox.addWidget(QLabel( self.tr("La primera fila corresponde a los campos"))) hbox = QHBoxLayout() btn_add_column = QPushButton(self.tr("Agregar Columna")) hbox.addWidget(btn_add_column) btn_add_tuple = QPushButton(self.tr("Agregar Tupla")) hbox.addWidget(btn_add_tuple) btn_remove_column = QPushButton(self.tr("Eliminar Columna")) hbox.addWidget(btn_remove_column) btn_remove_tuple = QPushButton(self.tr("Eliminar Tupla")) hbox.addWidget(btn_remove_tuple) vbox.addLayout(hbox) self._table = QTableWidget() vbox.addWidget(self._table) self._table.setRowCount(1) self._table.setColumnCount(2) self._table.setItem(0, 0, QTableWidgetItem("Campo 1")) self._table.setItem(0, 1, QTableWidgetItem("Campo 2")) hbox = QHBoxLayout() hbox.addItem(QSpacerItem(1, 0, QSizePolicy.Expanding)) btn_ok = QPushButton(self.tr("Aceptar")) hbox.addWidget(btn_ok) btn_cancel = QPushButton(self.tr("Cancelar")) hbox.addWidget(btn_cancel) vbox.addLayout(hbox) # Connections self.connect(btn_add_column, SIGNAL("clicked()"), self.__add_column) self.connect(btn_remove_column, SIGNAL("clicked()"), self.__remove_column) self.connect(btn_add_tuple, SIGNAL("clicked()"), self.__add_tuple) self.connect(btn_remove_tuple, SIGNAL("clicked()"), self.__remove_tuple) self.connect(btn_ok, SIGNAL("clicked()"), self.__create_table) self.connect(btn_cancel, SIGNAL("clicked()"), self.close) def __add_column(self): columns = self._table.columnCount() self._table.insertColumn(columns) def __remove_column(self): current = self._table.currentColumn() self._table.removeColumn(current) def __add_tuple(self): tuples = self._table.rowCount() self._table.insertRow(tuples) def __remove_tuple(self): current = self._table.currentRow() self._table.removeRow(current) def __create_table(self): # Name of relation name = self._line_relation_name.text() if not name.strip(): QMessageBox.critical(self, self.tr("Error"), self.tr("Nombre de relación no especificado")) return rows = self._table.rowCount() columns = self._table.columnCount() rel = relation.Relation() # Header of relation fields = [] for i in range(columns): text = self._table.item(0, i).text() if not text.strip(): QMessageBox.critical(self, self.tr("Error"), self.tr("Nombre de campo inválido")) return fields.append(text) rel.fields = fields # Data data = {} for row in range(1, rows): reg = [] for column in range(columns): item = self._table.item(row, column) if item is None or not item.text().strip(): QMessageBox.critical(self, self.tr("Campo vacío"), self.tr("El campo {0}:{1} está " "vacío").format(row + 1, column + 1)) return reg.append(self._table.item(row, column).text()) data[row, column] = self._table.item(row, column).text() rel.insert(reg) # Add table and relation table_widget = Pireal.get_service("container").table_widget table_widget.add_table(rows - 1, columns, name, data, fields) table_widget.relations[name] = rel self.close()
class phonesDialog(QDialog): def __init__(self, parent): QDialog.__init__(self, parent) self.prm = self.parent().prm self.currLocale = self.parent().prm['currentLocale'] self.currLocale.setNumberOptions(self.currLocale.OmitGroupSeparator | self.currLocale.RejectGroupSeparator) screen = QDesktopWidget().screenGeometry() self.resize(screen.width()/2.5,screen.height()/3) self.isPlaying = False #self.audioManager = audioManager(self) #self.playThread = threadedPlayer(self) self.sizer = QGridLayout() self.v1Sizer = QVBoxLayout() self.v2Sizer = QVBoxLayout() self.calibSizer = QGridLayout() self.phonesTableWidget = QTableWidget() self.phonesTableWidget.setColumnCount(4) self.phonesTableWidget.setSelectionBehavior(QAbstractItemView.SelectRows) self.phonesTableWidget.setSelectionMode(QAbstractItemView.ExtendedSelection) self.phonesTableWidget.setHorizontalHeaderLabels([self.tr('Phones'), self.tr('Max Level'), self.tr('Default'), 'id']) self.phonesTableWidget.hideColumn(3) self.phonesTableWidget.cellDoubleClicked[int,int].connect(self.onCellDoubleClicked) #RENAME Phones BUTTON self.renamePhonesButton = QPushButton(self.tr("Rename Phones"), self) self.renamePhonesButton.clicked.connect(self.onEditLabel) #Change Level Phones BUTTON self.changeLevelPhonesButton = QPushButton(self.tr("Change Max Level"), self) self.changeLevelPhonesButton.clicked.connect(self.onEditMaxLevel) #ADD Phones BUTTON self.addPhonesButton = QPushButton(self.tr("Add Phones"), self) self.addPhonesButton.clicked.connect(self.onClickAddPhonesButton) #REMOVE Phones BUTTON self.removePhonesButton = QPushButton(self.tr("Remove Phones"), self) self.removePhonesButton.clicked.connect(self.onClickRemovePhonesButton) #Set Default Phones BUTTON self.setDefaultPhonesButton = QPushButton(self.tr("Set Default"), self) self.setDefaultPhonesButton.clicked.connect(self.onEditDefault) self.v1Sizer.addWidget(self.renamePhonesButton) self.v1Sizer.addWidget(self.changeLevelPhonesButton) self.v1Sizer.addWidget(self.addPhonesButton) self.v1Sizer.addWidget(self.removePhonesButton) self.v1Sizer.addWidget(self.setDefaultPhonesButton) self.v1Sizer.addStretch() self.phonesList = {} for i in range(len(self.prm['phones']['phonesChoices'])): currCount = i+1 thisID = self.prm['phones']['phonesID'][i] self.phonesList[thisID] = {} self.phonesList[thisID]['label'] = self.prm['phones']['phonesChoices'][i] self.phonesList[thisID]['maxLevel'] = self.prm['phones']['phonesMaxLevel'][i] self.phonesList[thisID]['default'] = self.prm['phones']['defaultPhones'][i] self.phonesTableWidget.setRowCount(currCount) newItem = QTableWidgetItem(self.phonesList[thisID]['label']) newItem.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) self.phonesTableWidget.setItem(currCount-1, 0, newItem) newItem = QTableWidgetItem(self.currLocale.toString(self.phonesList[thisID]['maxLevel'])) newItem.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) self.phonesTableWidget.setItem(currCount-1, 1, newItem) newItem = QTableWidgetItem(self.phonesList[thisID]['default']) newItem.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) self.phonesTableWidget.setItem(currCount-1, 2, newItem) self.phonesList[thisID]['qid'] = QTableWidgetItem(thisID) self.phonesTableWidget.setItem(currCount-1, 3, self.phonesList[thisID]['qid']) ##CALIBRATION TONE n = 0 self.calLabel = QLabel(self.tr('Calibration Tone:'), self) self.calibSizer.addWidget(self.calLabel, n, 0, 1, 2) n = n+1 self.toneFreqLabel = QLabel(self.tr('Frequency (Hz)'), self) self.toneFreqTF = QLineEdit("1000") self.toneFreqTF.setValidator(QDoubleValidator(self)) self.calibSizer.addWidget(self.toneFreqLabel, n, 0) self.calibSizer.addWidget(self.toneFreqTF, n, 1) n = n+1 self.toneLevLabel = QLabel(self.tr('Level (dB)'), self) self.toneLevTF = QLineEdit("60") self.toneLevTF.setValidator(QDoubleValidator(self)) self.calibSizer.addWidget(self.toneLevLabel, n, 0) self.calibSizer.addWidget(self.toneLevTF, n, 1) n = n+1 self.toneDurLabel = QLabel(self.tr('Duration (ms)'), self) self.toneDurTF = QLineEdit("4980") self.toneDurTF.setValidator(QDoubleValidator(self)) self.calibSizer.addWidget(self.toneDurLabel, n, 0) self.calibSizer.addWidget(self.toneDurTF, n, 1) n = n+1 self.toneRampsLabel = QLabel(self.tr('Ramps (ms)'), self) self.toneRampsTF = QLineEdit("10") self.toneRampsTF.setValidator(QDoubleValidator(self)) self.calibSizer.addWidget(self.toneRampsLabel, n, 0) self.calibSizer.addWidget(self.toneRampsTF, n, 1) n = n+1 self.earLabel = QLabel(self.tr('Ear:'), self) self.earChooser = QComboBox() self.earChooser.addItems([self.tr("Right"), self.tr("Left"), self.tr("Both")]) self.calibSizer.addWidget(self.earLabel, n, 0) self.calibSizer.addWidget(self.earChooser, n, 1) n = n+1 self.playCalibButton = QPushButton(self.tr("Play"), self) self.playCalibButton.clicked.connect(self.onClickPlayCalibButton) self.playCalibButton.setIcon(QIcon.fromTheme("media-playback-start", QIcon(":/media-playback-start"))) self.calibSizer.addWidget(self.playCalibButton, n, 0, 1, 2) n = n+1 self.stopCalibButton = QPushButton(self.tr("Stop"), self) self.stopCalibButton.clicked.connect(self.onClickStopCalibButton) self.stopCalibButton.setIcon(QIcon.fromTheme("media-playback-stop", QIcon(":/media-playback-stop"))) self.calibSizer.addWidget(self.stopCalibButton, n, 0, 1, 2) if self.prm['pref']['sound']['playCommand'] in ["alsaaudio","pyaudio"]: self.stopCalibButton.show() else: self.stopCalibButton.hide() buttonBox = QDialogButtonBox(QDialogButtonBox.Apply|QDialogButtonBox.Ok|QDialogButtonBox.Cancel) buttonBox.accepted.connect(self.accept) buttonBox.rejected.connect(self.reject) buttonBox.button(QDialogButtonBox.Apply).clicked.connect(self.permanentApply) self.sizer.addLayout(self.v1Sizer, 0, 0) self.v2Sizer.addLayout(self.calibSizer) self.v2Sizer.addStretch() self.sizer.addWidget(self.phonesTableWidget, 0, 1) self.sizer.addLayout(self.v2Sizer, 0, 2) self.sizer.addWidget(buttonBox, 1,1,1,2) self.sizer.setColumnStretch(1,2) self.setLayout(self.sizer) self.setWindowTitle(self.tr("Edit Phones")) self.show() def onCellDoubleClicked(self, row, col): if col == 0: self.onEditLabel() elif col == 1: self.onEditMaxLevel() elif col == 2: self.onEditDefault() def onEditLabel(self): ids = self.findSelectedItemIds() if len(ids) > 1: QMessageBox.warning(self, self.tr('Warning'), self.tr('Only one label can be renamed at a time')) elif len(ids) < 1: pass else: selectedSound = ids[0] msg = self.tr('New name:') text, ok = QInputDialog.getText(self, self.tr('Input Dialog'), msg) if ok: self.phonesTableWidget.item(self.phonesList[selectedSound]['qid'].row(), 0).setText(text) self.phonesList[selectedSound]['label'] = text def onEditMaxLevel(self): ids = self.findSelectedItemIds() if len(ids) > 1: QMessageBox.warning(self, self.tr('Warning'), self.tr('Only one item can be edited at a time')) elif len(ids) < 1: pass else: selectedSound = ids[0] msg = self.tr('Level:') text, ok = QInputDialog.getDouble(self, self.tr('Input Dialog'), msg, self.phonesList[selectedSound]['maxLevel']) if ok: self.phonesTableWidget.item(self.phonesList[selectedSound]['qid'].row(), 1).setText(self.currLocale.toString(text)) self.phonesList[selectedSound]['maxLevel'] = text def onEditDefault(self): ids = self.findSelectedItemIds() if len(ids) > 1: QMessageBox.warning(self, self.tr('Warning'), self.tr('Only one item can be edited at a time')) elif len(ids) < 1: pass else: selectedSound = ids[0] for i in range(self.phonesTableWidget.rowCount()): self.phonesTableWidget.item(i, 2).setText("\u2012") self.phonesList[str(self.phonesTableWidget.item(i, 3).text())]['default'] = "\u2012" self.phonesTableWidget.item(self.phonesList[selectedSound]['qid'].row(), 2).setText("\u2713") self.phonesList[selectedSound]['default'] = "\u2713" def findSelectedItemIds(self): selItems = self.phonesTableWidget.selectedItems() selItemsRows = [] for i in range(len(selItems)): selItemsRows.append(selItems[i].row()) selItemsRows = unique(selItemsRows) selItemsIds = [] for i in range(len(selItemsRows)): selItemsIds.append(str(self.phonesTableWidget.item(selItemsRows[i], 3).text())) return selItemsIds def permanentApply(self): self.prm['phones']['phonesChoices'] = [] self.prm['phones']['phonesMaxLevel'] = [] self.prm['phones']['defaultPhones'] = [] self.prm['phones']['phonesID'] = [] keys = sorted(self.phonesList.keys()) for key in keys: self.prm['phones']['phonesChoices'].append(str(self.phonesList[key]['label'])) self.prm['phones']['phonesMaxLevel'].append(self.phonesList[key]['maxLevel']) self.prm['phones']['defaultPhones'].append(self.phonesList[key]['default']) self.prm['phones']['phonesID'].append(key) f = open(self.parent().prm['phonesPrefFile'], 'wb') pickle.dump(self.parent().prm['phones'], f) f.close() for i in range(self.parent().phonesChooser.count()): self.parent().phonesChooser.removeItem(0) self.parent().phonesChooser.addItems(self.prm['phones']['phonesChoices']) def onClickAddPhonesButton(self): keys = sorted(self.phonesList.keys()) thisID = str(int(keys[-1])+1) currCount = self.phonesTableWidget.rowCount() + 1 self.phonesList[thisID] = {} self.phonesList[thisID]['label'] = 'Phones' + ' ' + str(currCount) self.phonesList[thisID]['maxLevel'] = 100 self.phonesList[thisID]['default'] = "\u2012" self.phonesTableWidget.setRowCount(currCount) newItem = QTableWidgetItem(self.phonesList[thisID]['label']) newItem.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) self.phonesTableWidget.setItem(currCount-1, 0, newItem) newItem = QTableWidgetItem(self.currLocale.toString(self.phonesList[thisID]['maxLevel'])) newItem.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) self.phonesTableWidget.setItem(currCount-1, 1, newItem) newItem = QTableWidgetItem(self.phonesList[thisID]['default']) newItem.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) self.phonesTableWidget.setItem(currCount-1, 2, newItem) self.phonesList[thisID]['qid'] = QTableWidgetItem(thisID) self.phonesTableWidget.setItem(currCount-1, 3, self.phonesList[thisID]['qid']) def onClickRemovePhonesButton(self): if self.phonesTableWidget.rowCount() == 1: ret = QMessageBox.warning(self, self.tr("Warning"), self.tr("Only one phone left. Cannot remove!"), QMessageBox.Ok) else: ids = self.findSelectedItemIds() wasDefault = False for i in range(len(ids)): selectedPhones = ids[i] if self.phonesTableWidget.item(self.phonesList[selectedPhones]['qid'].row(), 2).text() == "\u2713": wasDefault = True self.phonesTableWidget.removeRow(self.phonesList[selectedPhones]['qid'].row()) del self.phonesList[selectedPhones] if wasDefault == True: self.phonesTableWidget.item(0, 2).setText("\u2713") self.phonesList[str(self.phonesTableWidget.item(0, 3).text())]['default'] = "\u2713" def onClickPlayCalibButton(self): ids = self.findSelectedItemIds() if len(ids) > 1: QMessageBox.warning(self, self.tr('Warning'), self.tr('Only one label can be renamed at a time')) return elif len(ids) < 1: QMessageBox.warning(self, self.tr('Warning'), self.tr('Please, select a phone in the table')) return else: selectedSound = ids[0] calMaxLev = self.phonesList[selectedSound]['maxLevel'] frequency = self.currLocale.toDouble(self.toneFreqTF.text())[0] level = self.currLocale.toDouble(self.toneLevTF.text())[0] duration = self.currLocale.toDouble(self.toneDurTF.text())[0] ramp = self.currLocale.toDouble(self. toneRampsTF.text())[0] channel = self.earChooser.currentText() fs = self.currLocale.toInt(self.parent().sampRateTF.text())[0] nBits = self.currLocale.toInt(self.parent().nBitsChooser.currentText())[0] calTone = pureTone(frequency, 0, level, duration, ramp, channel, fs, calMaxLev) self.isPlaying = True if self.prm['pref']['sound']['playCommand'] in ["alsaaudio","pyaudio"]: self.playThread = threadedAudioPlayer(self.parent()) else: self.playThread = threadedExternalAudioPlayer(self.parent()) self.playThread.playThreadedSound(calTone, fs, nBits, self.prm['pref']['sound']['playCommand'], True, 'calibrationTone.wav') if self.playThread.isFinished() == True: self.isPlaying = False def onClickStopCalibButton(self): if self.isPlaying == True: self.playThread.terminate() #self.playThread.__del__() def closeEvent(self, event): if self.isPlaying == True: #self.playThread.__del__() self.playThread.terminate() event.accept() def accept(self): #reimplement accept (i.e. ok button) if self.isPlaying == True: #self.playThread.__del__() self.playThread.terminate() QDialog.accept(self) def reject(self): #reimplement reject if self.isPlaying == True: #self.playThread.__del__() self.playThread.terminate() QDialog.reject(self)
class ThirdPart(QWizardPage): def __init__(self): super(ThirdPart, self).__init__() self.completed = False self.setTitle(u'第三方库设置') self.setSubTitle(u'需要设置的第三方库') rootLayout = QVBoxLayout() rootLayout.setContentsMargins(14, 20, 10, 20) self.tw_interface = QTableWidget(0, 3) headerLabels = QStringList() headerLabels.append(u'库名') headerLabels.append(u'库路径') headerLabels.append(u'打开') self.tw_interface.setHorizontalHeaderLabels(headerLabels) self.tw_interface.setSelectionBehavior(1) self.tw_interface.setRowCount(0) self.tw_interface.setColumnWidth(0, 200) self.tw_interface.setColumnWidth(1, 280) self.tw_interface.horizontalHeader().setStretchLastSection(True) self.mhlayout = QHBoxLayout() on_new_btn = QPushButton() on_new_btn.setText(u'添加类库') on_new_btn.clicked.connect(self.on_new) on_delete_btn = QPushButton() on_delete_btn.setText(u'删除类库') on_delete_btn.clicked.connect(self.on_delete) space = QSpacerItem(40, 28, QSizePolicy.Expanding) self.mhlayout.addSpacerItem(space) self.mhlayout.addWidget(on_new_btn) self.mhlayout.addWidget(on_delete_btn) rootLayout.addWidget(self.tw_interface) rootLayout.addLayout(self.mhlayout) self.setLayout(rootLayout) self.setStyleSheet(sheetstyle) self.alloneEnv = os.getenv('ALLONEDIR', '../..').replace('\\', '/') def on_new(self): rowIndex = self.tw_interface.rowCount() self.tw_interface.setRowCount(rowIndex + 1) ptn = self.add_button(rowIndex) self.tw_interface.setCellWidget(rowIndex, 2, ptn) def on_delete(self): rowIndex = self.tw_interface.currentRow() if rowIndex != -1: self.tw_interface.removeRow(rowIndex) def updateTable(self, id): filePath = QFileDialog.getOpenFileName(self, "请选择库", self.alloneEnv, "Library(*.lib)") if filePath.isEmpty(): return fileinfo = QFileInfo(filePath) libPath = fileinfo.absoluteDir().absolutePath() libName = fileinfo.baseName() # 支持选择文件后与系统ALLONEDIR比较一下变成相对路径 # 并且能够手动输入相对路径或包含$(ALLONEDIR)的相对路径 env = QString(os.getenv('ALLONEDIR', '../..').replace('\\', '/')) if env.endsWith('/'): env.remove(env.lastIndexOf('/'), 1) if libPath.contains(env): libPath.replace(env, QString('$$ALLONEDIR')) self.tw_interface.setItem(id, 1, QTableWidgetItem(libPath)) self.tw_interface.setItem(id, 0, QTableWidgetItem(libName)) def add_button(self, id): widget = QWidget() fileBtn = QPushButton() fileBtn.setText(u'浏览...') fileBtn.clicked.connect(lambda: self.updateTable(id)) hLayout = QHBoxLayout() hLayout.addWidget(fileBtn) hLayout.setAlignment(Qt.AlignHCenter) hLayout.setContentsMargins(0, 0, 0, 0) widget.setLayout(hLayout) return widget def initializePage(self): super(ThirdPart, self).initializePage() self.tw_interface.setRowCount(len(app.g_configurations.thirdpart_lib)) row = 0 for libinfo in app.g_configurations.thirdpart_lib: twitem0 = QTableWidgetItem(QString(libinfo["libname"])) twitem1 = QTableWidgetItem(QString(libinfo["libpath"])) self.tw_interface.setItem(row, 0, twitem0) self.tw_interface.setItem(row, 1, twitem1) ptn = self.add_button(row) self.tw_interface.setCellWidget(row, 2, ptn) row += 1 def validatePage(self): thirdpart_libs = [] if self.tw_interface.rowCount() > 0: for i in range(self.tw_interface.rowCount()): libinfo = {"libname": "", "libpath": ""} libname = self.tw_interface.item(i, 0).text() libpath = self.tw_interface.item(i, 1).text() #print unicode(libname) #print unicode(libpath) libinfo["libname"] = unicode(libname) libinfo["libpath"] = unicode(libpath) thirdpart_libs.append(libinfo) print thirdpart_libs app.g_configurations.thirdpart_lib = thirdpart_libs return True
class wavListDialog(QDialog): def __init__(self, parent): QDialog.__init__(self, parent) self.prm = self.parent().parent().prm self.audioManager = audioManager(self) self.currLocale = self.parent().parent().prm['currentLocale'] self.currLocale.setNumberOptions( self.currLocale.OmitGroupSeparator | self.currLocale.RejectGroupSeparator) self.isPlaying = False self.sizer = QGridLayout() self.v1Sizer = QVBoxLayout() self.wavsTableWidget = QTableWidget() self.wavsTableWidget.setColumnCount(4) self.wavsTableWidget.setSelectionBehavior(QAbstractItemView.SelectRows) self.wavsTableWidget.setSelectionMode( QAbstractItemView.ExtendedSelection) self.wavsTableWidget.setHorizontalHeaderLabels( [self.tr("File"), self.tr('Use'), self.tr("RMS Level"), 'id']) self.quidColumn = 3 self.wavsTableWidget.hideColumn(self.quidColumn) self.wavsTableWidget.cellDoubleClicked[int, int].connect( self.onCellDoubleClicked) #ADD wav BUTTON self.addWavButton = QPushButton(self.tr("Add Wav"), self) self.addWavButton.clicked.connect(self.onClickAddWavButton) #REMOVE wav BUTTON self.removeWavButton = QPushButton(self.tr("Remove Wav"), self) self.removeWavButton.clicked.connect(self.onClickRemoveWavButton) #PLAY wav BUTTON self.playWavButton = QPushButton(self.tr("Play Wav"), self) self.playWavButton.clicked.connect(self.onClickPlayWavButton) #STOP wav BUTTON self.stopWavButton = QPushButton(self.tr("Stop Playing"), self) self.stopWavButton.clicked.connect(self.onClickStopWavButton) self.v1Sizer.addWidget(self.addWavButton) self.v1Sizer.addWidget(self.removeWavButton) self.v1Sizer.addWidget(self.playWavButton) self.v1Sizer.addWidget(self.stopWavButton) self.v1Sizer.addStretch() self.wavsList = {} for i in range(len(self.parent().wavsPref['endMessageFiles'])): currCount = i + 1 thisID = self.parent().wavsPref['endMessageFilesID'][i] self.wavsList[thisID] = {} self.wavsList[thisID]['file'] = self.parent( ).wavsPref['endMessageFiles'][i] self.wavsList[thisID]['use'] = self.parent( ).wavsPref['endMessageFilesUse'][i] self.wavsList[thisID]['level'] = self.parent( ).wavsPref['endMessageLevels'][i] self.wavsTableWidget.setRowCount(currCount) n = 0 newItem = QTableWidgetItem(self.wavsList[thisID]['file']) newItem.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) self.wavsTableWidget.setItem(currCount - 1, n, newItem) n = n + 1 newItem = QTableWidgetItem(self.wavsList[thisID]['use']) newItem.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) self.wavsTableWidget.setItem(currCount - 1, n, newItem) n = n + 1 newItem = QTableWidgetItem( self.currLocale.toString(self.wavsList[thisID]['level'])) newItem.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) self.wavsTableWidget.setItem(currCount - 1, n, newItem) n = n + 1 self.wavsList[thisID]['qid'] = QTableWidgetItem(thisID) self.wavsTableWidget.setItem(currCount - 1, n, self.wavsList[thisID]['qid']) buttonBox = QDialogButtonBox(QDialogButtonBox.Apply | QDialogButtonBox.Ok | QDialogButtonBox.Cancel) buttonBox.accepted.connect(self.accept) buttonBox.rejected.connect(self.reject) self.sizer.addLayout(self.v1Sizer, 0, 0) self.sizer.addWidget(self.wavsTableWidget, 0, 1) self.sizer.addWidget(buttonBox, 1, 1) self.setLayout(self.sizer) self.setWindowTitle(self.tr("Edit Wavs")) self.show() def onCellDoubleClicked(self, row, col): if col == 0: pass elif col == 1: self.onEditUse() elif col == 2: self.onEditLevel() def onEditLevel(self): ids = self.findSelectedItemIds() if len(ids) > 1: QMessageBox.warning( self, self.tr('Warning'), self.tr('Only one item can be edited at a time')) elif len(ids) < 1: pass else: selectedSound = ids[0] msg = self.tr('RMS Level:') text, ok = QInputDialog.getDouble( self, self.tr('Input Dialog'), msg, self.wavsList[selectedSound]['level']) if ok: self.wavsTableWidget.item( self.wavsList[selectedSound]['qid'].row(), 2).setText(self.currLocale.toString(text)) self.wavsList[selectedSound]['level'] = text def onEditUse(self): ids = self.findSelectedItemIds() if len(ids) > 1: QMessageBox.warning( self, self.tr('Warning'), self.tr('Only one item can be edited at a time')) elif len(ids) < 1: pass else: selectedSound = ids[0] if self.wavsTableWidget.item( self.wavsList[selectedSound]['qid'].row(), 1).text() == "\u2012": self.wavsTableWidget.item( self.wavsList[selectedSound]['qid'].row(), 1).setText("\u2713") self.wavsList[selectedSound]['use'] = "\u2713" else: self.wavsTableWidget.item( self.wavsList[selectedSound]['qid'].row(), 1).setText("\u2012") self.wavsList[selectedSound]['use'] = "\u2012" def findSelectedItemIds(self): selItems = self.wavsTableWidget.selectedItems() selItemsRows = [] for i in range(len(selItems)): selItemsRows.append(selItems[i].row()) selItemsRows = unique(selItemsRows) selItemsIds = [] for i in range(len(selItemsRows)): selItemsIds.append( str( self.wavsTableWidget.item(selItemsRows[i], self.quidColumn).text())) return selItemsIds def permanentApply(self): self.wavListToPass = {} self.wavListToPass['endMessageFiles'] = [] self.wavListToPass['endMessageFilesUse'] = [] self.wavListToPass['endMessageFilesID'] = [] self.wavListToPass['endMessageLevels'] = [] keys = sorted(self.wavsList.keys()) for key in keys: self.wavListToPass['endMessageFiles'].append( str(self.wavsList[key]['file'])) self.wavListToPass['endMessageFilesUse'].append( self.wavsList[key]['use']) self.wavListToPass['endMessageLevels'].append( self.wavsList[key]['level']) self.wavListToPass['endMessageFilesID'].append(key) def onClickAddWavButton(self): fName = QFileDialog.getOpenFileName( self, self.tr("Choose wav file to load"), '', self.tr("wav files (*.wav);;All Files (*)"))[0] if len(fName) > 0: #if the user didn't press cancel if len(self.wavsList.keys()) > 0: keys = sorted(self.wavsList.keys()) thisID = str(int(keys[-1]) + 1) else: thisID = "1" currCount = self.wavsTableWidget.rowCount() + 1 self.wavsList[thisID] = {} self.wavsList[thisID]['file'] = fName self.wavsList[thisID]['use'] = "\u2713" self.wavsList[thisID]['level'] = 60 self.wavsTableWidget.setRowCount(currCount) n = 0 newItem = QTableWidgetItem(self.wavsList[thisID]['file']) newItem.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) self.wavsTableWidget.setItem(currCount - 1, n, newItem) n = n + 1 newItem = QTableWidgetItem(self.wavsList[thisID]['use']) newItem.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) self.wavsTableWidget.setItem(currCount - 1, n, newItem) n = n + 1 newItem = QTableWidgetItem( self.currLocale.toString(self.wavsList[thisID]['level'])) newItem.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) self.wavsTableWidget.setItem(currCount - 1, n, newItem) n = n + 1 self.wavsList[thisID]['qid'] = QTableWidgetItem(thisID) self.wavsTableWidget.setItem(currCount - 1, n, self.wavsList[thisID]['qid']) def onClickRemoveWavButton(self): ids = self.findSelectedItemIds() for i in range(len(ids)): selectedWavs = ids[i] self.wavsTableWidget.removeRow( self.wavsList[selectedWavs]['qid'].row()) del self.wavsList[selectedWavs] def onClickPlayWavButton(self): ids = self.findSelectedItemIds() if len(ids) < 1: QMessageBox.warning(self, self.tr('Warning'), self.tr('No files selected for playing')) else: if len(ids) > 1: pass #maybe say on the status bar that only the first one will be played selectedWav = ids[0] fName = self.wavsList[selectedWav]['file'] level = self.wavsList[selectedWav]['level'] nBits = self.currLocale.toInt( self.parent().parent().nBitsChooser.currentText())[0] maxLevel = float(self.prm['phones']['phonesMaxLevel'][ self.parent().parent().phonesChooser.currentIndex()]) msgSnd, fs = self.audioManager.loadWavFile(fName, level, maxLevel, 'Both') self.isPlaying = True if self.prm['pref']['sound']['playCommand'] in [ "alsaaudio", "pyaudio" ]: self.playThread = threadedAudioPlayer(self.parent().parent()) else: self.playThread = threadedExternalAudioPlayer( self.parent().parent()) self.playThread.playThreadedSound( msgSnd, fs, nBits, self.prm['pref']['sound']['playCommand'], False, 'tmp.wav') if self.playThread.isFinished == True: self.isPlaying = False def onClickStopWavButton(self): if self.isPlaying == True: self.playThread.terminate() def closeEvent(self, event): if self.isPlaying == True: self.playThread.terminate() event.accept() def accept(self): #reimplement accept (i.e. ok button) if self.isPlaying == True: self.playThread.terminate() QDialog.accept(self) def reject(self): #reimplement reject if self.isPlaying == True: self.playThread.terminate() QDialog.reject(self)
class OWdabam_height_profile(OWWidget): name = "DABAM Height Profile" id = "dabam_height_profile" description = "Calculation of mirror surface error profile" icon = "icons/dabam.png" author = "Luca Rebuffi" maintainer_email = "[email protected]; [email protected]" priority = 6 category = "" keywords = ["dabam_height_profile"] outputs = [{"name": "PreProcessor_Data", "type": ShadowPreProcessorData, "doc": "PreProcessor Data", "id": "PreProcessor_Data"}] want_main_area = 1 want_control_area = 1 MAX_WIDTH = 1320 MAX_HEIGHT = 700 IMAGE_WIDTH = 860 IMAGE_HEIGHT = 645 CONTROL_AREA_WIDTH = 405 TABS_AREA_HEIGHT = 618 xx = None yy = None zz = None entry_number = Setting(1) shape=Setting(0) slope_error_from = Setting(0.0) slope_error_to = Setting(1.5) dimension_y_from = Setting(0.0) dimension_y_to = Setting(200.0) use_undetrended = Setting(0) step_x = Setting(1.0) dimension_x = Setting(10.0) center_y = Setting(1) modify_y = Setting(0) new_length = Setting(200.0) filler_value = Setting(0.0) scale_factor_y = Setting(1.0) renormalize_y = Setting(1) error_type_y = Setting(0) rms_y = Setting(0.9) dabam_profile_index = Setting(1) heigth_profile_file_name = Setting('mirror.dat') tab=[] def __init__(self): super().__init__() self.runaction = widget.OWAction("Calculate Height Profile", self) self.runaction.triggered.connect(self.calculate_heigth_profile_ni) self.addAction(self.runaction) self.runaction = widget.OWAction("Generate Height Profile File", self) self.runaction.triggered.connect(self.generate_heigth_profile_file_ni) self.addAction(self.runaction) geom = QApplication.desktop().availableGeometry() self.setGeometry(QRect(round(geom.width() * 0.05), round(geom.height() * 0.05), round(min(geom.width() * 0.98, self.MAX_WIDTH)), round(min(geom.height() * 0.95, self.MAX_HEIGHT)))) self.setMaximumHeight(self.geometry().height()) self.setMaximumWidth(self.geometry().width()) # DABAM INITIALIZATION self.server = dabam.dabam() self.server.set_input_silent(True) gui.separator(self.controlArea) button_box = oasysgui.widgetBox(self.controlArea, "", addSpace=False, orientation="horizontal") button = gui.button(button_box, self, "Calculate Height\nProfile", callback=self.calculate_heigth_profile) button.setFixedHeight(45) button = gui.button(button_box, self, "Generate Height\nProfile File", callback=self.generate_heigth_profile_file) font = QFont(button.font()) font.setBold(True) button.setFont(font) palette = QPalette(button.palette()) # make a copy of the palette palette.setColor(QPalette.ButtonText, QColor('Dark Blue')) button.setPalette(palette) # assign new palette button.setFixedHeight(45) button.setFixedWidth(150) button = gui.button(button_box, self, "Reset Fields", callback=self.call_reset_settings) font = QFont(button.font()) font.setItalic(True) button.setFont(font) palette = QPalette(button.palette()) # make a copy of the palette palette.setColor(QPalette.ButtonText, QColor('Dark Red')) button.setPalette(palette) # assign new palette button.setFixedHeight(45) gui.separator(self.controlArea) tabs_setting = gui.tabWidget(self.controlArea) tabs_setting.setFixedHeight(self.TABS_AREA_HEIGHT) tabs_setting.setFixedWidth(self.CONTROL_AREA_WIDTH-5) tab_input = oasysgui.createTabPage(tabs_setting, "DABAM Search Setting") tab_gener = oasysgui.createTabPage(tabs_setting, "DABAM Generation Setting") tab_out = oasysgui.createTabPage(tabs_setting, "Output") manual_box = oasysgui.widgetBox(tab_input, "Manual Entry", addSpace=True, orientation="vertical") oasysgui.lineEdit(manual_box, self, "entry_number", "Entry Number", labelWidth=300, valueType=int, orientation="horizontal") gui.separator(manual_box) button = gui.button(manual_box, self, "Retrieve Profile", callback=self.retrieve_profile) button.setFixedHeight(35) button.setFixedWidth(self.CONTROL_AREA_WIDTH-35) input_box = oasysgui.widgetBox(tab_input, "Search Parameters", addSpace=True, orientation="vertical") gui.comboBox(input_box, self, "shape", label="Mirror Shape", labelWidth=300, items=["All", "Plane", "Cylindrical", "Elliptical", "Toroidal", "Spherical"], sendSelectedValue=False, orientation="horizontal") gui.separator(input_box) input_box_1 = oasysgui.widgetBox(input_box, "", addSpace=True, orientation="horizontal") oasysgui.lineEdit(input_box_1, self, "slope_error_from", "Slope Error From (" + u"\u03BC" + "rad)", labelWidth=150, valueType=float, orientation="horizontal") oasysgui.lineEdit(input_box_1, self, "slope_error_to", "To (" + u"\u03BC" + "rad)", labelWidth=60, valueType=float, orientation="horizontal") input_box_2 = oasysgui.widgetBox(input_box, "", addSpace=True, orientation="horizontal") self.le_dimension_y_from = oasysgui.lineEdit(input_box_2, self, "dimension_y_from", "Mirror Length From", labelWidth=150, valueType=float, orientation="horizontal") self.le_dimension_y_to = oasysgui.lineEdit(input_box_2, self, "dimension_y_to", "To", labelWidth=60, valueType=float, orientation="horizontal") table_box = oasysgui.widgetBox(tab_input, "Search Results", addSpace=True, orientation="vertical", height=290) self.overlay_search = Overlay(table_box, self.search_profiles) self.overlay_search.hide() button = gui.button(input_box, self, "Search", callback=self.overlay_search.show) button.setFixedHeight(35) button.setFixedWidth(self.CONTROL_AREA_WIDTH-35) gui.comboBox(table_box, self, "use_undetrended", label="Use Undetrended Profile", labelWidth=300, items=["No", "Yes"], callback=self.table_item_clicked, sendSelectedValue=False, orientation="horizontal") gui.separator(table_box) self.scrollarea = QScrollArea() self.scrollarea.setMinimumWidth(self.CONTROL_AREA_WIDTH-35) table_box.layout().addWidget(self.scrollarea, alignment=Qt.AlignHCenter) self.table = QTableWidget(1, 5) self.table.setAlternatingRowColors(True) self.table.horizontalHeader().setResizeMode(QHeaderView.Fixed) self.table.verticalHeader().setVisible(False) self.table.setColumnWidth(0, 40) self.table.setColumnWidth(1, 70) self.table.setColumnWidth(2, 70) self.table.setColumnWidth(3, 85) self.table.setColumnWidth(4, 80) self.table.resizeRowsToContents() self.table.setSelectionBehavior(QAbstractItemView.SelectRows) self.table.itemClicked.connect(self.table_item_clicked) self.scrollarea.setWidget(self.table) self.scrollarea.setWidgetResizable(1) output_profile_box = oasysgui.widgetBox(tab_gener, "Surface Generation Parameters", addSpace=True, orientation="vertical", height=270) self.le_dimension_x = oasysgui.lineEdit(output_profile_box, self, "dimension_x", "Width", labelWidth=300, valueType=float, orientation="horizontal") self.le_step_x = oasysgui.lineEdit(output_profile_box, self, "step_x", "Step Width", labelWidth=300, valueType=float, orientation="horizontal") gui.comboBox(output_profile_box, self, "center_y", label="Center Profile in the middle of O.E.", labelWidth=300, items=["No", "Yes"], sendSelectedValue=False, orientation="horizontal") gui.comboBox(output_profile_box, self, "modify_y", label="Modify Length?", labelWidth=240, items=["No", "Rescale to new length", "Fit to new length (fill or cut)"], callback=self.set_ModifyY, sendSelectedValue=False, orientation="horizontal") self.modify_box_1 = oasysgui.widgetBox(output_profile_box, "", addSpace=False, orientation="vertical", height=50) self.modify_box_2 = oasysgui.widgetBox(output_profile_box, "", addSpace=False, orientation="vertical", height=50) oasysgui.lineEdit(self.modify_box_2, self, "scale_factor_y", "Scale Factor", labelWidth=300, valueType=float, orientation="horizontal") self.modify_box_3 = oasysgui.widgetBox(output_profile_box, "", addSpace=False, orientation="vertical", height=50) self.le_new_length = oasysgui.lineEdit(self.modify_box_3, self, "new_length", "New Length", labelWidth=300, valueType=float, orientation="horizontal") oasysgui.lineEdit(self.modify_box_3, self, "filler_value", "Filler Value (if new length > profile length) [nm]", labelWidth=300, valueType=float, orientation="horizontal") self.set_ModifyY() gui.comboBox(output_profile_box, self, "renormalize_y", label="Renormalize Length Profile to different RMS", labelWidth=300, items=["No", "Yes"], callback=self.set_RenormalizeY, sendSelectedValue=False, orientation="horizontal") self.output_profile_box_1 = oasysgui.widgetBox(output_profile_box, "", addSpace=True, orientation="vertical") gui.comboBox(self.output_profile_box_1, self, "error_type_y", label="Normalization to", labelWidth=270, items=["Figure Error (nm)", "Slope Error (" + u"\u03BC" + "rad)"], sendSelectedValue=False, orientation="horizontal") oasysgui.lineEdit(self.output_profile_box_1, self, "rms_y", "Rms Value", labelWidth=300, valueType=float, orientation="horizontal") self.set_RenormalizeY() output_box = oasysgui.widgetBox(tab_gener, "Outputs", addSpace=True, orientation="vertical") select_file_box = oasysgui.widgetBox(output_box, "", addSpace=True, orientation="horizontal") self.le_heigth_profile_file_name = oasysgui.lineEdit(select_file_box, self, "heigth_profile_file_name", "Output File Name", labelWidth=120, valueType=str, orientation="horizontal") gui.button(select_file_box, self, "...", callback=self.selectFile) self.shadow_output = QTextEdit() self.shadow_output.setReadOnly(True) out_box = oasysgui.widgetBox(tab_out, "System Output", addSpace=True, orientation="horizontal", height=500) out_box.layout().addWidget(self.shadow_output) gui.rubber(self.controlArea) self.initializeTabs() gui.rubber(self.mainArea) self.overlay_search.raise_() def resizeEvent(self, event): self.overlay_search.resize(self.CONTROL_AREA_WIDTH - 15, 290) event.accept() def after_change_workspace_units(self): self.si_to_user_units = 1e2 / self.workspace_units_to_cm self.horHeaders = ["Entry", "Shape", "Length\n[" + self.workspace_units_label + "]", "Heights St.Dev.\n[nm]", "Slopes St.Dev.\n[" + u"\u03BC" + "rad]"] self.table.setHorizontalHeaderLabels(self.horHeaders) self.plot_canvas[0].setGraphXLabel("Y [" + self.workspace_units_label + "]") self.plot_canvas[1].setGraphXLabel("Y [" + self.workspace_units_label + "]") self.axis.set_xlabel("X [" + self.workspace_units_label + "]") self.axis.set_ylabel("Y [" + self.workspace_units_label + "]") label = self.le_dimension_y_from.parent().layout().itemAt(0).widget() label.setText(label.text() + " [" + self.workspace_units_label + "]") label = self.le_dimension_y_to.parent().layout().itemAt(0).widget() label.setText(label.text() + " [" + self.workspace_units_label + "]") label = self.le_dimension_x.parent().layout().itemAt(0).widget() label.setText(label.text() + " [" + self.workspace_units_label + "]") label = self.le_step_x.parent().layout().itemAt(0).widget() label.setText(label.text() + " [" + self.workspace_units_label + "]") label = self.le_new_length.parent().layout().itemAt(0).widget() label.setText(label.text() + " [" + self.workspace_units_label + "]") def initializeTabs(self): self.tabs = gui.tabWidget(self.mainArea) self.tab = [gui.createTabPage(self.tabs, "Info"), gui.createTabPage(self.tabs, "Heights Profile"), gui.createTabPage(self.tabs, "Slopes Profile"), gui.createTabPage(self.tabs, "PSD Heights"), gui.createTabPage(self.tabs, "CSD Heights"), gui.createTabPage(self.tabs, "ACF"), gui.createTabPage(self.tabs, "Generated 2D Profile"), ] for tab in self.tab: tab.setFixedHeight(self.IMAGE_HEIGHT) tab.setFixedWidth(self.IMAGE_WIDTH) self.plot_canvas = [None, None, None, None, None, None] self.plot_canvas[0] = PlotWindow(roi=False, control=False, position=True, plugins=False) self.plot_canvas[0].setDefaultPlotLines(True) self.plot_canvas[0].setActiveCurveColor(color='darkblue') self.plot_canvas[0].setGraphYLabel("Z [nm]") self.plot_canvas[0].setGraphTitle("Heights Profile") self.plot_canvas[0].setDrawModeEnabled(True, 'rectangle') self.plot_canvas[0].setZoomModeEnabled(True) self.plot_canvas[1] = PlotWindow(roi=False, control=False, position=True, plugins=False) self.plot_canvas[1].setDefaultPlotLines(True) self.plot_canvas[1].setActiveCurveColor(color='darkblue') self.plot_canvas[1].setGraphYLabel("Zp [$\mu$rad]") self.plot_canvas[1].setGraphTitle("Slopes Profile") self.plot_canvas[1].setDrawModeEnabled(True, 'rectangle') self.plot_canvas[1].setZoomModeEnabled(True) self.plot_canvas[2] = PlotWindow(roi=False, control=False, position=True, plugins=False) self.plot_canvas[2].setDefaultPlotLines(True) self.plot_canvas[2].setActiveCurveColor(color='darkblue') self.plot_canvas[2].setGraphXLabel("f [m^-1]") self.plot_canvas[2].setGraphYLabel("PSD [m^3]") self.plot_canvas[2].setGraphTitle("Power Spectral Density of Heights Profile") self.plot_canvas[2].setDrawModeEnabled(True, 'rectangle') self.plot_canvas[2].setZoomModeEnabled(True) self.plot_canvas[2].setXAxisLogarithmic(True) self.plot_canvas[2].setYAxisLogarithmic(True) self.plot_canvas[3] = PlotWindow(roi=False, control=False, position=True, plugins=False) self.plot_canvas[3].setDefaultPlotLines(True) self.plot_canvas[3].setActiveCurveColor(color='darkblue') self.plot_canvas[3].setGraphXLabel("f [m^-1]") self.plot_canvas[3].setGraphYLabel("CSD [m^3]") self.plot_canvas[3].setGraphTitle("Cumulative Spectral Density of Heights Profile") self.plot_canvas[3].setDrawModeEnabled(True, 'rectangle') self.plot_canvas[3].setZoomModeEnabled(True) self.plot_canvas[3].setXAxisLogarithmic(True) self.plot_canvas[4] = PlotWindow(roi=False, control=False, position=True, plugins=False) self.plot_canvas[4].setDefaultPlotLines(True) self.plot_canvas[4].setActiveCurveColor(color='darkblue') self.plot_canvas[4].setGraphXLabel("Length [m]") self.plot_canvas[4].setGraphYLabel("ACF") self.plot_canvas[4].setGraphTitle("Autocovariance Function of Heights Profile") self.plot_canvas[4].setDrawModeEnabled(True, 'rectangle') self.plot_canvas[4].setZoomModeEnabled(True) self.figure = Figure(figsize=(self.IMAGE_HEIGHT, self.IMAGE_HEIGHT)) # QUADRATA! self.figure.patch.set_facecolor('white') self.axis = self.figure.add_subplot(111, projection='3d') self.axis.set_zlabel("Z [nm]") self.plot_canvas[5] = FigureCanvasQTAgg(self.figure) self.profileInfo = QTextEdit() self.profileInfo.setReadOnly(True) self.profileInfo.setMinimumHeight(self.IMAGE_HEIGHT-5) self.profileInfo.setMaximumHeight(self.IMAGE_HEIGHT-5) self.profileInfo.setMinimumWidth(310) self.profileInfo.setMaximumWidth(310) profile_box = oasysgui.widgetBox(self.tab[0], "", addSpace=True, orientation="horizontal", height = self.IMAGE_HEIGHT, width=320) profile_box.layout().addWidget(self.profileInfo) for index in range(0, 6): self.tab[index+1].layout().addWidget(self.plot_canvas[index]) self.tabs.setCurrentIndex(1) def plot_dabam_graph(self, plot_canvas_index, curve_name, x_values, y_values, xtitle, ytitle, color='blue', replace=True): self.plot_canvas[plot_canvas_index].addCurve(x_values, y_values, curve_name, symbol='', color=color, replace=replace) #'+', '^', ',' self.plot_canvas[plot_canvas_index].setGraphXLabel(xtitle) self.plot_canvas[plot_canvas_index].setGraphYLabel(ytitle) self.plot_canvas[plot_canvas_index].replot() def set_ModifyY(self): self.modify_box_1.setVisible(self.modify_y == 0) self.modify_box_2.setVisible(self.modify_y == 1) self.modify_box_3.setVisible(self.modify_y == 2) def set_RenormalizeY(self): self.output_profile_box_1.setVisible(self.renormalize_y==1) def table_item_clicked(self): if self.table.selectionModel().hasSelection(): if not self.table.rowCount() == 0: if not self.table.item(0, 0) is None: row = self.table.selectionModel().selectedRows()[0].row() self.entry_number = int(self.table.item(row, 0).text()) self.retrieve_profile() def retrieve_profile(self): try: if self.entry_number is None or self.entry_number <= 0: raise Exception("Entry number should be a strictly positive integer number") self.server.load(self.entry_number) self.profileInfo.setText(self.server.info_profiles()) self.plot_canvas[0].setGraphTitle( "Heights Profile. St.Dev.=%.3f nm" % (self.server.stdev_profile_heights() * 1e9)) self.plot_canvas[1].setGraphTitle( "Slopes Profile. St.Dev.=%.3f $\mu$rad" % (self.server.stdev_profile_slopes() * 1e6)) if self.use_undetrended == 0: self.plot_dabam_graph(0, "heights_profile", self.si_to_user_units * self.server.y, 1e9 * self.server.zHeights, "Y [" + self.workspace_units_label + "]", "Z [nm]") self.plot_dabam_graph(1, "slopes_profile", self.si_to_user_units * self.server.y, 1e6 * self.server.zSlopes, "Y [" + self.workspace_units_label + "]", "Zp [$\mu$rad]") else: self.plot_dabam_graph(0, "heights_profile", self.si_to_user_units * self.server.y, 1e9 * self.server.zHeightsUndetrended, "Y [" + self.workspace_units_label + "]", "Z [nm]") self.plot_dabam_graph(1, "slopes_profile", self.si_to_user_units * self.server.y, 1e6 * self.server.zSlopesUndetrended, "Y [" + self.workspace_units_label + "]", "Zp [$\mu$rad]") y = self.server.f ** (self.server.powerlaw["hgt_pendent"]) * 10 ** self.server.powerlaw["hgt_shift"] i0 = self.server.powerlaw["index_from"] i1 = self.server.powerlaw["index_to"] beta = -self.server.powerlaw["hgt_pendent"] self.plot_canvas[2].setGraphTitle( "Power Spectral Density of Heights Profile (beta=%.2f,Df=%.2f)" % (beta, (5 - beta) / 2)) self.plot_dabam_graph(2, "psd_heights_2", self.server.f, self.server.psdHeights, "f [m^-1]", "PSD [m^3]") self.plot_dabam_graph(2, "psd_heights_1", self.server.f, y, "f [m^-1]", "PSD [m^3]", color='green', replace=False) self.plot_dabam_graph(2, "psd_heights_3", self.server.f[i0:i1], y[i0:i1], "f [m^-1]", "PSD [m^3]", color='red', replace=False) self.plot_dabam_graph(3, "csd", self.server.f, self.server.csd_heights(), "f [m^-1]", "CSD [m^3]") c1, c2, c3 = dabam.autocorrelationfunction(self.server.y, self.server.zHeights) self.plot_canvas[4].setGraphTitle( "Autocovariance Function of Heights Profile.\nAutocorrelation Length (ACF=0.5)=%.3f m" % (c3)) self.plot_dabam_graph(4, "acf", c1[0:-1], c2, "Length [m]", "Heights Autocovariance") # surface error removal if not self.zz is None and not self.yy is None and not self.xx is None: self.xx = None self.yy = None self.zz = None self.axis.set_title("") self.axis.clear() self.plot_canvas[5].draw() if (self.tabs.currentIndex()==6): self.tabs.setCurrentIndex(1) except Exception as exception: QMessageBox.critical(self, "Error", exception.args[0], QMessageBox.Ok) #raise exception def search_profiles(self): try: self.table.itemClicked.disconnect(self.table_item_clicked) self.table.clear() row_count = self.table.rowCount() for n in range(0, row_count): self.table.removeRow(0) self.table.setHorizontalHeaderLabels(self.horHeaders) profiles = dabam.dabam_summary_dictionary(surface=self.get_dabam_shape(), slp_err_from=self.slope_error_from*1e-6, slp_err_to=self.slope_error_to*1e-6, length_from=self.dimension_y_from / self.si_to_user_units, length_to=self.dimension_y_to / self.si_to_user_units) for index in range(0, len(profiles)): self.table.insertRow(0) for index in range(0, len(profiles)): table_item = QTableWidgetItem(str(profiles[index]["entry"])) table_item.setTextAlignment(Qt.AlignCenter) self.table.setItem(index, 0, table_item) table_item = QTableWidgetItem(str(profiles[index]["surface"])) table_item.setTextAlignment(Qt.AlignLeft) self.table.setItem(index, 1, table_item) table_item = QTableWidgetItem(str(numpy.round(profiles[index]["length"]*self.si_to_user_units, 3))) table_item.setTextAlignment(Qt.AlignRight) self.table.setItem(index, 2, table_item) table_item = QTableWidgetItem(str(numpy.round(profiles[index]["hgt_err"]*1e9, 3))) table_item.setTextAlignment(Qt.AlignRight) self.table.setItem(index, 3, table_item) table_item = QTableWidgetItem(str(numpy.round(profiles[index]["slp_err"]*1e6, 3))) table_item.setTextAlignment(Qt.AlignRight) self.table.setItem(index, 4, table_item) self.table.setHorizontalHeaderLabels(self.horHeaders) self.table.resizeRowsToContents() self.table.setSelectionBehavior(QAbstractItemView.SelectRows) self.table.itemClicked.connect(self.table_item_clicked) self.overlay_search.hide() except Exception as exception: self.overlay_search.hide() QMessageBox.critical(self, "Error", exception.args[0], QMessageBox.Ok) def get_dabam_shape(self): if self.shape == 0: return None elif self.shape == 1: return "plane" elif self.shape == 2: return "cylindrical" elif self.shape == 3: return "elliptical" elif self.shape == 4: return "toroidal" elif self.shape == 5: return "spherical" def calculate_heigth_profile_ni(self): self.calculate_heigth_profile(not_interactive_mode=True) def calculate_heigth_profile(self, not_interactive_mode=False): try: if self.server.y is None: raise Exception("No Profile Selected") sys.stdout = EmittingStream(textWritten=self.writeStdOut) self.check_fields() combination = "EF" if self.modify_y == 2: profile_1D_y_x_temp = self.si_to_user_units * self.server.y if self.use_undetrended == 0: profile_1D_y_y_temp = self.si_to_user_units * self.server.zHeights else: profile_1D_y_y_temp = self.si_to_user_units * self.server.zHeightsUndetrended first_coord = profile_1D_y_x_temp[0] second_coord = profile_1D_y_x_temp[1] last_coord = profile_1D_y_x_temp[-1] step = numpy.abs(second_coord - first_coord) length = numpy.abs(last_coord - first_coord) n_points_old = len(profile_1D_y_x_temp) if self.new_length > length: difference = self.new_length - length n_added_points = int(difference/step) if difference % step == 0: n_added_points += 1 if n_added_points % 2 != 0: n_added_points += 1 profile_1D_y_x = numpy.arange(n_added_points + n_points_old) * step profile_1D_y_y = numpy.ones(n_added_points + n_points_old) * self.filler_value * 1e-9 * self.si_to_user_units profile_1D_y_y[int(n_added_points/2) : n_points_old + int(n_added_points/2)] = profile_1D_y_y_temp elif self.new_length < length: difference = length - self.new_length n_removed_points = int(difference/step) if difference % step == 0: n_removed_points -= 1 if n_removed_points % 2 != 0: n_removed_points -= 1 if n_removed_points >= 2: profile_1D_y_x = profile_1D_y_x_temp[0 : (n_points_old - n_removed_points)] profile_1D_y_y = profile_1D_y_y_temp[(int(n_removed_points/2) - 1) : (n_points_old - int(n_removed_points/2) - 1)] else: profile_1D_y_x = profile_1D_y_x_temp profile_1D_y_y = profile_1D_y_y_temp else: profile_1D_y_x = profile_1D_y_x_temp profile_1D_y_y = profile_1D_y_y_temp else: if self.modify_y == 0: profile_1D_y_x = self.si_to_user_units * self.server.y elif self.modify_y == 1: profile_1D_y_x = self.si_to_user_units * self.server.y * self.scale_factor_y if self.use_undetrended == 0: profile_1D_y_y = self.si_to_user_units * self.server.zHeights else: profile_1D_y_y = self.si_to_user_units * self.server.zHeightsUndetrended if self.center_y: first_coord = profile_1D_y_x[0] last_coord = profile_1D_y_x[-1] length = numpy.abs(last_coord - first_coord) profile_1D_y_x_temp = numpy.linspace(-length/2, length/2, len(profile_1D_y_x)) profile_1D_y_x = profile_1D_y_x_temp if self.renormalize_y == 0: rms_y = None else: if self.error_type_y == profiles_simulation.FIGURE_ERROR: rms_y = self.si_to_user_units * self.rms_y * 1e-9 # from nm to user units else: rms_y = self.rms_y * 1e-6 # from urad to rad xx, yy, zz = profiles_simulation.simulate_profile_2D(combination = combination, error_type_l = self.error_type_y, rms_l = rms_y, x_l = profile_1D_y_x, y_l = profile_1D_y_y, mirror_width = self.dimension_x, step_w = self.step_x, rms_w = 0.0) self.xx = xx self.yy = yy self.zz = zz # in user units self.axis.clear() x_to_plot, y_to_plot = numpy.meshgrid(xx, yy) z_to_plot = zz * 1e9 / self.si_to_user_units #nm self.axis.plot_surface(x_to_plot, y_to_plot, z_to_plot, rstride=1, cstride=1, cmap=cm.autumn, linewidth=0.5, antialiased=True) sloperms = profiles_simulation.slopes(zz.T, xx, yy, return_only_rms=1) title = ' Slope error rms in X direction: %f $\mu$rad' % (sloperms[0]*1e6) + '\n' + \ ' Slope error rms in Y direction: %f $\mu$rad' % (sloperms[1]*1e6) self.axis.set_xlabel("X [" + self.workspace_units_label + "]") self.axis.set_ylabel("Y [" + self.workspace_units_label + "]") self.axis.set_zlabel("Z [nm]") self.axis.set_title(title) self.axis.mouse_init() if not not_interactive_mode: try: self.plot_canvas[5].draw() except: pass self.tabs.setCurrentIndex(6) QMessageBox.information(self, "QMessageBox.information()", "Height Profile calculated: if the result is satisfactory,\nclick \'Generate Height Profile File\' to complete the operation ", QMessageBox.Ok) except Exception as exception: QMessageBox.critical(self, "Error", exception.args[0], QMessageBox.Ok) #raise exception def generate_heigth_profile_file_ni(self): self.generate_heigth_profile_file(not_interactive_mode=True) def generate_heigth_profile_file(self, not_interactive_mode=False): if not self.zz is None and not self.yy is None and not self.xx is None: try: congruence.checkDir(self.heigth_profile_file_name) sys.stdout = EmittingStream(textWritten=self.writeStdOut) ST.write_shadow_surface(self.zz, self.xx, self.yy, outFile=congruence.checkFileName(self.heigth_profile_file_name)) if not not_interactive_mode: QMessageBox.information(self, "QMessageBox.information()", "Height Profile file " + self.heigth_profile_file_name + " written on disk", QMessageBox.Ok) if self.modify_y == 0: dimension_y = self.si_to_user_units * (self.server.y[-1] - self.server.y[0]) if self.modify_y == 1: dimension_y = self.si_to_user_units * (self.server.y[-1] - self.server.y[0]) * self.scale_factor_y elif self.modify_y == 2: dimension_y = self.new_length self.send("PreProcessor_Data", ShadowPreProcessorData(error_profile_data_file=self.heigth_profile_file_name, error_profile_x_dim=self.dimension_x, error_profile_y_dim=dimension_y)) except Exception as exception: QMessageBox.critical(self, "Error", exception.args[0], QMessageBox.Ok) def call_reset_settings(self): if ConfirmDialog.confirmed(parent=self, message="Confirm Reset of the Fields?"): try: self.resetSettings() except: pass def check_fields(self): self.dimension_x = congruence.checkStrictlyPositiveNumber(self.dimension_x, "Dimension X") self.step_x = congruence.checkStrictlyPositiveNumber(self.step_x, "Step X") if self.step_x > self.dimension_x/2: raise Exception("Step Width should be smaller than or equal to Width/2") if self.modify_y == 1: self.scale_factor_y = congruence.checkStrictlyPositiveNumber(self.scale_factor_y, "Scale Factor") elif self.modify_y == 2: self.new_length = congruence.checkStrictlyPositiveNumber(self.new_length, "New Length") if self.renormalize_y == 1: self.rms_y = congruence.checkPositiveNumber(self.rms_y, "Rms Y") congruence.checkDir(self.heigth_profile_file_name) def writeStdOut(self, text): cursor = self.shadow_output.textCursor() cursor.movePosition(QTextCursor.End) cursor.insertText(text) self.shadow_output.setTextCursor(cursor) self.shadow_output.ensureCursorVisible() def selectFile(self): self.le_heigth_profile_file_name.setText(oasysgui.selectFileFromDialog(self, self.heigth_profile_file_name, "Select Output File", file_extension_filter="Data Files (*.dat)"))
class CameraWindow(PyDialog): def __init__(self, data, win_parent=None): """ +--------+ | Camera | +--------+---------------+ | Camera Name | | +-------------------+ | | | | | | | | | | | | | | | | | | | | | | +-------------------+ | | | | Name xxx Save | | Delete Set | | | | Apply OK Cancel | +--------+---------------+ """ PyDialog.__init__(self, data, win_parent) self.setWindowTitle('Camera Views') #self.setWindowIcon(view_icon) self._default_name = 'Camera' self.out_data['clicked_ok'] = False self.cameras = deepcopy(data['cameras']) self.names = sorted(self.cameras.keys()) self.name = QLabel("Name:") self.name_edit = QLineEdit(str(self._default_name)) self.delete_button = QPushButton("Delete") self.set_button = QPushButton("Set") self.save_button = QPushButton("Save") # closing self.apply_button = QPushButton("Apply") #self.ok_button = QPushButton("OK") self.close_button = QPushButton("Close") self.cancel_button = QPushButton("Cancel") self.table = QTableWidget() names_text = [] for iname, name in enumerate(self.names): name_text = QTableWidgetItem(str(name)) names_text.append(name_text) self.create_layout(names_text) self.set_connections() def create_layout(self, names_text): nrows = len(self.names) table = self.table table.setRowCount(nrows) table.setColumnCount(1) headers = [QString('Camera Name')] table.setHorizontalHeaderLabels(headers) header = table.horizontalHeader() header.setStretchLastSection(True) for iname, name_text in enumerate(names_text): # row, col, value table.setItem(iname, 0, name_text) table.resizeRowsToContents() ok_cancel_box = QHBoxLayout() ok_cancel_box.addWidget(self.apply_button) #ok_cancel_box.addWidget(self.ok_button) ok_cancel_box.addWidget(self.close_button) ok_cancel_box.addWidget(self.cancel_button) grid = QGridLayout() irow = 0 grid.addWidget(self.name, irow, 0) grid.addWidget(self.name_edit, irow, 1) grid.addWidget(self.save_button, irow, 2) irow += 1 grid.addWidget(self.delete_button, irow, 0) grid.addWidget(self.set_button, irow, 1) irow += 1 vbox = QVBoxLayout() vbox.addWidget(self.table) vbox.addLayout(grid) vbox.addStretch() vbox.addLayout(ok_cancel_box) self.setLayout(vbox) def set_connections(self): #if qt_version == 4: #self.connect(self.ok_button, QtCore.SIGNAL('clicked()'), self.on_ok) self.set_button.clicked.connect(self.on_set) self.save_button.clicked.connect(self.on_save) self.delete_button.clicked.connect(self.on_delete) self.apply_button.clicked.connect(self.on_apply) self.close_button.clicked.connect(self.on_close) self.cancel_button.clicked.connect(self.on_cancel) def on_set(self): objs = self.table.selectedIndexes() if len(objs) == 1: obj = objs[0] irow = obj.row() name = self.names[irow] self.set_camera(name) return True return False def on_save(self): name = str(self.name_edit.text()).strip() if name in self.cameras: return irow = self.nrows if len(name): self.table.insertRow(irow) name_text = QTableWidgetItem(str(name)) self.table.setItem(irow, 0, name_text) self.name_edit.setText('') self.save_camera(name) def set_camera(self, name): camera_data = self.cameras[name] if self.win_parent is None: return self.win_parent.on_set_camera_data(camera_data) def save_camera(self, name): self.names.append(name) if self.win_parent is None: self.cameras[name] = None return self.cameras[name] = self.win_parent.get_camera_data() #@property #def camera(self): @property def nrows(self): return self.table.rowCount() def on_delete(self): irows = [] for obj in self.table.selectedIndexes(): irow = obj.row() irows.append(irow) irows.sort() for irow in reversed(irows): self.table.removeRow(irow) #print('delete', self.names) name = self.names.pop(irow) del self.cameras[name] #print(' removing irow=%s name=%r' % (irow, name)) def closeEvent(self, event): event.accept() @staticmethod def check_name(cell): text = str(cell.text()).strip() if len(text): cell.setStyleSheet("QLineEdit{background: white;}") return text, True else: cell.setStyleSheet("QLineEdit{background: red;}") return None, False #def on_validate(self): #name_value, flag0 = self.check_name(self.name_edit) #if flag0: #self.out_data['cameras'] = self.cameras #self.out_data['clicked_ok'] = True #return True #return False def on_apply(self): passed = self.on_set() #if passed: # self.win_parent.create_plane(self.out_data) return passed def on_close(self): self.out_data['clicked_ok'] = True self.out_data['cameras'] = self.cameras self.close() def on_ok(self): passed = self.on_apply() if passed: name = str(self.name_edit.text()).strip() self.out_data['name'] = name self.out_data['cameras'] = self.cameras self.out_data['clicked_ok'] = True self.close() #self.destroy() def on_cancel(self): self.close()