def saveFavorite(self): """ Writes the current favorite (selected in the combobox) to a file, any where in the disk that can be given to another NE1 user (i.e. as an email attachment). """ cmd = greenmsg("Save Favorite File: ") env.history.message(greenmsg("Save Favorite File:")) current_favorite = self.favoritesComboBox.currentText() favfilepath = getFavoritePathFromBasename(current_favorite) formats = \ "Favorite (*.txt);;"\ "All Files (*.*)" fn = QFileDialog.getSaveFileName( self, "Save Favorite As", # caption favfilepath, #where to save formats, # file format options QString("Favorite (*.txt)") # selectedFilter ) if not fn: env.history.message(cmd + "Cancelled") else: saveFavoriteFile(str(fn), favfilepath) return
def start_download(self, request): if not self.gui: return url = unicode(request.url().toString()) cf = self.get_cookies() filename = get_download_filename(url, cf) ext = os.path.splitext(filename)[1][1:].lower() filename = ascii_filename(filename[:60] + '.' + ext) if ext not in BOOK_EXTENSIONS: if ext == 'acsm': from calibre.gui2.dialogs.confirm_delete import confirm if not confirm( '<p>' + _('This ebook is a DRMed EPUB file. ' 'You will be prompted to save this file to your ' 'computer. Once it is saved, open it with ' '<a href="http://www.adobe.com/products/digitaleditions/">' 'Adobe Digital Editions</a> (ADE).<p>ADE, in turn ' 'will download the actual ebook, which will be a ' '.epub file. You can add this book to calibre ' 'using "Add Books" and selecting the file from ' 'the ADE library folder.'), 'acsm_download', self): return home = os.path.expanduser('~') name = QFileDialog.getSaveFileName( self, _('File is not a supported ebook type. Save to disk?'), os.path.join(home, filename), '*.*') if name: name = unicode(name) self.gui.download_ebook(url, cf, name, name, False) else: self.gui.download_ebook(url, cf, filename, tags=self.tags)
def saveFavorite(self): cmd = greenmsg("Save Favorite File: ") env.history.message(greenmsg("Save Favorite File:")) current_favorite = self.favoritesComboBox.currentText() favfilepath = getFavoritePathFromBasename(current_favorite) formats = \ "Favorite (*.txt);;"\ "All Files (*.*)" directory = self.currentWorkingDirectory saveLocation = directory + "/" + current_favorite + ".txt" fn = QFileDialog.getSaveFileName( self, "Save Favorite As", # caption favfilepath, #where to save formats, # file format options QString("Favorite (*.txt)") # selectedFilter ) if not fn: env.history.message(cmd + "Cancelled") else: dir, fil = os.path.split(str(fn)) self.setCurrentWorkingDirectory(dir) saveFavoriteFile(str(fn), favfilepath) return
def saveFavorite(self): """ Save favorite file in a user chosen location """ cmd = greenmsg("Save Favorite File: ") env.history.message(greenmsg("Save Favorite File:")) current_favorite = self.favoritesComboBox.currentText() favfilepath = getFavoritePathFromBasename(current_favorite) formats = \ "Favorite (*.txt);;"\ "All Files (*.*)" directory = self.currentWorkingDirectory saveLocation = directory + "/" + current_favorite + ".txt" fn = QFileDialog.getSaveFileName( self, "Save Favorite As", # caption favfilepath, #where to save formats, # file format options QString("Favorite (*.txt)") # selectedFilter ) if not fn: env.history.message(cmd + "Cancelled") else: dir, fil = os.path.split(str(fn)) self.setCurrentWorkingDirectory(dir) saveFavoriteFile(str(fn), favfilepath) return
def rezip_epub2(self, epub, titre_dialogue="Enregistrer l'epub détatoué sous :"): self.setLabelText('Reconstruction de l\'epub') QtGui.QApplication.processEvents() # choix du nom de l'epub epub2 = QFileDialog.getSaveFileName(None, titre_dialogue, epub, 'epub(*.epub)') if zipfile.is_zipfile(epub): try: zepub = zipfile.ZipFile(epub2, mode="w", compression=zipfile.ZIP_DEFLATED, allowZip64=True) # d'abord le mimetype non compressé. zepub.write(os.path.join(self.dirtemp.name, "mimetype"), arcname="mimetype", compress_type=zipfile.ZIP_STORED) # puis les autres fichiers exclude_files = ['.DS_Store', 'mimetype'] for root, _dirs, files in os.walk(self.dirtemp.name): for fn in files: if fn in exclude_files: continue absfn = os.path.join(root, fn) zfn = os.path.relpath(absfn, self.dirtemp.name).replace(os.sep, '/') zepub.write(absfn, zfn) zepub.close() except: log('Impossible de rezipper cet epub.') return
def start_download(self, request): if not self.gui: return url = unicode(request.url().toString()) cf = self.get_cookies() filename = get_download_filename(url, cf) ext = os.path.splitext(filename)[1][1:].lower() filename = ascii_filename(filename[:60] + '.' + ext) if ext not in BOOK_EXTENSIONS: if ext == 'acsm': from calibre.gui2.dialogs.confirm_delete import confirm if not confirm('<p>' + _('This ebook is a DRMed EPUB file. ' 'You will be prompted to save this file to your ' 'computer. Once it is saved, open it with ' '<a href="http://www.adobe.com/products/digitaleditions/">' 'Adobe Digital Editions</a> (ADE).<p>ADE, in turn ' 'will download the actual ebook, which will be a ' '.epub file. You can add this book to calibre ' 'using "Add Books" and selecting the file from ' 'the ADE library folder.'), 'acsm_download', self): return home = os.path.expanduser('~') name = QFileDialog.getSaveFileName(self, _('File is not a supported ebook type. Save to disk?'), os.path.join(home, filename), '*.*') if name: name = unicode(name) self.gui.download_ebook(url, cf, name, name, False) else: self.gui.download_ebook(url, cf, filename, tags=self.tags)
def btnCardLocation_Clicked(self): try: savePath = str(QFileDialog.getSaveFileName(self, "Save as")) tempPath = savePath if len(savePath ) > 8: #teensy requires names of less than 8 characters savePath = os.path.join(os.path.dirname(savePath), os.path.basename(savePath)[:8]) __SONGS_temp_ = { os.path.basename(tempPath): os.path.basename(savePath) } settings[0] = savePath if not os.path.exists(settings[0]): os.makedirs(settings[0]) shelfFile = shelve.open('GUIconfig') if (not '__SONGS__' in shelfFile.keys()): shelfFile['__SONGS__'] = {} __SONGS_temp_2 = shelfFile['__SONGS__'] if not list(__SONGS_temp_.keys())[0] in list( __SONGS_temp_2.keys()): __SONGS_temp_2.update(__SONGS_temp_) shelfFile['__SONGS__'] = __SONGS_temp_2 self.ui.SelectSong.addItems(list(__SONGS_temp_.keys())) else: pass # print("key exists not adding") shelfFile.close() self.ui.lineEdit.setText(os.path.basename(tempPath)) except Exception as e: pass
def export_bookmarks(self): filename = QFileDialog.getSaveFileName(self, _("Export Bookmarks"), '%s%suntitled.pickle' % (os.getcwdu(), os.sep), _("Saved Bookmarks (*.pickle)")) if filename == '': return with open(filename, 'w') as fileobj: cPickle.dump(self._model.bookmarks, fileobj)
def export_bookmarks(self): filename = QFileDialog.getSaveFileName(self, _("Export Bookmarks"), '%s%suntitled.pickle' % (os.getcwdu(), os.sep), _("Saved Bookmarks (*.pickle)")) if not filename: return with open(filename, 'w') as fileobj: cPickle.dump(self.get_bookmarks(), fileobj)
def Save(self): d = QFileDialog(self) s = d.getSaveFileName() l = len(self.mt.Images) for i in xrange(l): self.mt.Images[i].save(s+'.'+str(i)+'.png') f = open(s,"w") f.write(str(l)) f.close()
def saveParserAs(self): filename = str( QFileDialog.getSaveFileName(self, caption="%s - Save a parser" % QApplication.applicationName(), directory=str("."), filter=str("XML files (*.xml)"))) if not filename: return misc.saveAsXML(self.parser, filename) self.filename = filename self.updateStatus("Saved parser to file %s" % filename)
def saveToFile(self): fdiag = QFileDialog() selectedFilter = QString() if foundPandas: filt = self.tr("Excel Open XML Document (*.xlsx);;Portable Network Graphics (*.png)") else: filt = self.tr("Portable Network Graphics (*.png)") fileName = fdiag.getSaveFileName(self, self.tr("Save Data As"), datetime.now().strftime('%Y-%m-%d-T%H%M%S-') + self.modeAscii, filt, selectedFilter) if len(fileName) == 0: return if 'png' in selectedFilter: if fileName[-4:] == '.png': fileName = fileName[0:-4] px = QPixmap.grabWidget(self.graphGrp) px.save(fileName + '.png', "PNG") return if fileName[-5:] == '.xlsx': fileName = fileName[0:-5] data = self.excelData.getData() if len(data) == 0: mb = QMessageBox() mb.setIcon(QMessageBox.Warning) mb.setWindowTitle(self.tr('Warning')) mb.setText(self.tr('No data exists. No output file has been produced.')) mb.exec_() return if data.ndim == 1: #Bad workaround if only one line exists add = [] for idx in range(0,len(data)): add.append(0) data = np.vstack((data, np.array(add))) df = pandas.DataFrame(data, columns=['Frequency', self.modeTuple[0], self.modeTuple[1]]) df.to_excel(str(fileName) + '.xlsx', index=False)
def saveStrandSequence(self): """ Save the strand sequence entered in the Strand text edit in the specified file. """ if not self.sequenceFileName: sdir = env.prefs[workingDirectory_prefs_key] else: sdir = self.sequenceFileName fileName = QFileDialog.getSaveFileName( self, "Save Strand Sequence As ...", sdir, "Strand Sequence File (*.txt)" ) if fileName: fileName = str(fileName) if fileName[-4] != '.': fileName += '.txt' if os.path.exists(fileName): # ...and if the "Save As" file exists... # ... confirm overwrite of the existing file. ret = QMessageBox.warning( self, "Save Strand Sequence...", "The file \"" + fileName + "\" already exists.\n"\ "Do you want to overwrite the existing file or cancel?", "&Overwrite", "&Cancel", "", 0, # Enter == button 0 1 ) # Escape == button 1 if ret == 1: # The user cancelled return # write the current set of element colors into a file self._writeStrandSequenceFile( fileName, str(self.sequenceTextEdit.toPlainText())) return
def MakeGcode(self): path = QFileDialog.getSaveFileName(self, u"选择保存路径", "", " (*.nc)") if path == "": QMessageBox.warning(self, u"发生错误", u"路径错误!!") return f = open(path, 'w') f.write("M5\n") for i in range(self.resultImage.width()): flag = False #检测这一行是否有点 for j in range(self.resultImage.height()): if self.resultImage.pixelIndex(i, j) < 128: flag = True break #如果这一行都没有点则跳过这一行 if flag: f.write("G0 Y%f\n" % (i * self.pixDoubleSpinBox.value())) else: continue if (i % 2) > 0: for j in range(self.resultImage.height()): if self.resultImage.pixelIndex(i, j) < 128: f.write("G0 X%f\n" % (j * self.pixDoubleSpinBox.value())) f.write("M3\n") f.write("G4 P%f\n" % self.timeDoubleSpinBox.value()) f.write("M5\n") else: for j in range(self.resultImage.height())[::-1]: if self.resultImage.pixelIndex(i, j) < 128: f.write("G0 X%f\n" % (j * self.pixDoubleSpinBox.value())) f.write("M3\n") f.write("G4 P%f\n" % self.timeDoubleSpinBox.value()) f.write("M5\n") f.write("M5\n") f.write("G0 X0 Y0\n") f.close() QMessageBox.information(self, u"成功", u"生成G代码文件成功!!")
def write_element_rgb_table(self): """ Save the current set of element preferences into an external file -- currently only r,g,b color of each element will be saved. """ if not self.fileName: from utilities.prefs_constants import workingDirectory_prefs_key sdir = env.prefs[workingDirectory_prefs_key] else: sdir = self.fileName fn = QFileDialog.getSaveFileName(self, "Save Element Colors As ...", sdir, "Element Color File (*.txt)") if fn: fn = str(fn) if fn[-4] != '.': fn += '.txt' import os if os.path.exists(fn): # ...and if the "Save As" file exists... # ... confirm overwrite of the existing file. ret = QMessageBox.warning( self, "Save Element Colors...", "The file \"" + fn + "\" already exists.\n" "Do you want to overwrite the existing file or cancel?", "&Overwrite", "&Cancel", "", 0, # Enter == button 0 1) # Escape == button 1 if ret == 1: # The user cancelled return # write the current set of element colors into a file saveElementColors(fn, self.elemTable.getAllElements()) env.history.message("Element colors saved in file: [" + fn + "]") #After saving a file, reset the flag self.isFileSaved = True
def write_element_rgb_table(self): """ Save the current set of element preferences into an external file -- currently only r,g,b color of each element will be saved. """ if not self.fileName: from utilities.prefs_constants import workingDirectory_prefs_key sdir = env.prefs[workingDirectory_prefs_key] else: sdir = self.fileName fn = QFileDialog.getSaveFileName( self, "Save Element Colors As ...", sdir, "Element Color File (*.txt)" ) if fn: fn = str(fn) if fn[-4] != '.': fn += '.txt' import os if os.path.exists(fn): # ...and if the "Save As" file exists... # ... confirm overwrite of the existing file. ret = QMessageBox.warning( self, "Save Element Colors...", "The file \"" + fn + "\" already exists.\n" "Do you want to overwrite the existing file or cancel?", "&Overwrite", "&Cancel", "", 0, # Enter == button 0 1 ) # Escape == button 1 if ret == 1: # The user cancelled return # write the current set of element colors into a file saveElementColors(fn, self.elemTable.getAllElements()) env.history.message("Element colors saved in file: [" + fn + "]") #After saving a file, reset the flag self.isFileSaved = True
def saveFavorite(self): """ Writes the current favorite (selected in the combobox) to a file, any where in the disk that can be given to another NE1 user (i.e. as an email attachment). """ cmd = greenmsg("Save Favorite File: ") env.history.message(greenmsg("Save Favorite File:")) current_favorite = self.favoritesComboBox.currentText() favfilepath = getFavoritePathFromBasename(current_favorite) #Check to see if favfilepath exists first if not os.path.exists(favfilepath): msg = "%s does not exist" % favfilepath env.history.message(cmd + msg) return formats = \ "Favorite (*.txt);;"\ "All Files (*.*)" directory = self.currentWorkingDirectory saveLocation = directory + "/" + current_favorite + ".txt" fn = QFileDialog.getSaveFileName( self, "Save Favorite As", # caption saveLocation, #where to save formats, # file format options QString("Favorite (*.txt)") # selectedFilter ) if not fn: env.history.message(cmd + "Cancelled") else: #remember this directory dir, fil = os.path.split(str(fn)) self.setCurrentWorkingDirectory(dir) saveFavoriteFile(str(fn), favfilepath) return
def _saveImage(self): filename = QFileDialog.getSaveFileName(self, "Save FITS file", self._save_dir, "FITS files(*.fits *.FITS *fts *FTS)") filename = str(filename) if not filename: return busy = BusyIndicator() self._imgman.showMessage("""Writing FITS image %s""" % filename, 3000) QApplication.flush() try: self.image.save(filename) except Exception as exc: busy = None traceback.print_exc() self._imgman.showErrorMessage("""Error writing FITS image %s: %s""" % (filename, str(sys.exc_info()[1]))) return None self.renderControl().startSavingConfig(filename) self.setName(self.image.name) self._qa_save.setVisible(False) self._wsave.hide() busy = None
def saveAnimation(self, listOfAnimatedElements, description=""): """ TODO: Doesn't work. Implement. Serializes the animation after showing the user a dialog to choose where to do so. :param listOfAnimatedElements: The list of objects which compose this animation. :type listOfAnimatedElements: [Animation2] . :param fileName: The name of the file in which this animation should be saved. :type fileName: str :param description: (optional) Brief description for this animation. :type description: str """ filename = QFileDialog.getSaveFileName(parent=None, caption="Save animation layer", filter=("All Files (*.*)")) # print filename pass
def saveToFile(self): fileName = QFileDialog.getSaveFileName( self, "Open Points File", "", "All Files (*);;Text Files (*.txt);;Excel (*.xlsx)", "") if fileName[-4:] == ".txt": f = open(fileName, 'w') f.write(" Y X \n") for i, j in self.provisionals.iteritems(): f.write(i + ": " + " " + str(round(float(j.y), 3)) + " " + str(round(float(j.x), 3)) + "\n\n") f.close() elif fileName[-5:] == ".xlsx": fileName = str(fileName) workbook = xlsxwriter.Workbook(fileName) worksheet = workbook.add_worksheet() i = 0 for nm, j in sorted(self.provisionals.iteritems()): worksheet.write(i, 0, nm) worksheet.write(i, 1, (round(float(j.y), 3))) worksheet.write(i, 2, (round(float(j.x), 3))) i += 1 workbook.close()
def saveToFile(self): fileName = QFileDialog.getSaveFileName(self, "Open Points File", "", "All Files (*);;Text Files (*.txt);;Excel (*.xlsx)", "") if fileName[-4:]==".txt": f = open(fileName, 'w') f.write(" Y X \n") for i,j in self.provisionals.iteritems(): f.write(i +": "+" "+ str(round(float(j.y),3))+" "+ str(round(float(j.x),3))+"\n\n") f.close() elif fileName[-5:]==".xlsx": fileName=str(fileName) workbook = xlsxwriter.Workbook(fileName) worksheet = workbook.add_worksheet() i=0 for nm,j in sorted(self.provisionals.iteritems()): worksheet.write(i,0, nm) worksheet.write(i,1, (round(float(j.y),3))) worksheet.write(i,2, (round(float(j.x),3))) i+=1 workbook.close()
def saveAnimation(self, listOfAnimatedElements, description=""): """ TODO: Doesn't work. Implement. Serializes the animation after showing the user a dialog to choose where to do so. :param listOfAnimatedElements: The list of objects which compose this animation. :type listOfAnimatedElements: [Animation2] . :param fileName: The name of the file in which this animation should be saved. :type fileName: str :param description: (optional) Brief description for this animation. :type description: str """ filename = QFileDialog.getSaveFileName( parent = None, caption = "Save animation layer", filter=("All Files (*.*)")); #print filename pass
def _select_create_dialog(self): path = str(QFileDialog.getSaveFileName(self, "Create new purrlog", self.create_path)) if path: self._validate_create_filename(path)
def __init__(self, title=_('Choose Files'), filters=[], add_all_files_filter=True, parent=None, modal=True, name='', mode=QFileDialog.ExistingFiles, default_dir=u'~', no_save_dir=False, combine_file_and_saved_dir=False ): QObject.__init__(self) ftext = '' if filters: for filter in filters: text, extensions = filter extensions = ['*'+(i if i.startswith('.') else '.'+i) for i in extensions] ftext += '%s (%s);;'%(text, ' '.join(extensions)) if add_all_files_filter or not ftext: ftext += 'All files (*)' if ftext.endswith(';;'): ftext = ftext[:-2] self.dialog_name = name if name else 'dialog_' + title self.selected_files = None self.fd = None if combine_file_and_saved_dir: bn = os.path.basename(default_dir) prev = dynamic.get(self.dialog_name, expanduser(u'~')) if os.path.exists(prev): if os.path.isfile(prev): prev = os.path.dirname(prev) else: prev = expanduser(u'~') initial_dir = os.path.join(prev, bn) elif no_save_dir: initial_dir = expanduser(default_dir) else: initial_dir = dynamic.get(self.dialog_name, expanduser(default_dir)) if not isinstance(initial_dir, basestring): initial_dir = expanduser(default_dir) if not initial_dir or (not os.path.exists(initial_dir) and not ( mode == QFileDialog.AnyFile and (no_save_dir or combine_file_and_saved_dir))): initial_dir = select_initial_dir(initial_dir) self.selected_files = [] use_native_dialog = 'CALIBRE_NO_NATIVE_FILEDIALOGS' not in os.environ with SanitizeLibraryPath(): opts = QFileDialog.Option() if not use_native_dialog: opts |= QFileDialog.DontUseNativeDialog if mode == QFileDialog.AnyFile: f = unicode(QFileDialog.getSaveFileName(parent, title, initial_dir, ftext, "", opts)) if f: self.selected_files.append(f) elif mode == QFileDialog.ExistingFile: f = unicode(QFileDialog.getOpenFileName(parent, title, initial_dir, ftext, "", opts)) if f and os.path.exists(f): self.selected_files.append(f) elif mode == QFileDialog.ExistingFiles: fs = QFileDialog.getOpenFileNames(parent, title, initial_dir, ftext, "", opts) for f in fs: f = unicode(f) if not f: continue if not os.path.exists(f): # QFileDialog for some reason quotes spaces # on linux if there is more than one space in a row f = unquote(f) if f and os.path.exists(f): self.selected_files.append(f) else: if mode == QFileDialog.Directory: opts |= QFileDialog.ShowDirsOnly f = unicode(QFileDialog.getExistingDirectory(parent, title, initial_dir, opts)) if os.path.exists(f): self.selected_files.append(f) if self.selected_files: self.selected_files = [unicode(q) for q in self.selected_files] saved_loc = self.selected_files[0] if os.path.isfile(saved_loc): saved_loc = os.path.dirname(saved_loc) if not no_save_dir: dynamic[self.dialog_name] = saved_loc self.accepted = bool(self.selected_files)
class MainWidget(QWidget): def __init__(self): QWidget.__init__(self) # define periodic table widget for element selection self.periodicTableWidget = widgets.PeriodicTableDialog() # initial molecule Zmatrix (can be empty) # self.inp = [] self.inp = [['H'], ['O', 1, 0.9], ['O', 2, 1.4, 1, 105.], ['H', 3, 0.9, 2, 105., 1, 120.]] self.atomList = [] self.highList = [] self.labelList = [] self.fast = False # define & initialize ZMatModel that will contain Zmatrix data self.ZMatModel = QStandardItemModel(len(self.inp), 7, self) self.ZMatTable = QTableView(self) self.ZMatTable.setModel(self.ZMatModel) self.ZMatTable.setFixedWidth(325) #self.ZMatTable.installEventFilter(self) #self.ZMatModel.installEventFilter(self) self.ZMatModel.setHorizontalHeaderLabels(['atom','','bond','','angle','','dihedral']) for j, width in enumerate([40, 22, 65, 22, 65, 22, 65]): self.ZMatTable.setColumnWidth(j, width) # populate the ZMatModel self.populateZMatModel() #define Menu bar menus and their actions self.menuBar = QMenuBar(self) fileMenu = self.menuBar.addMenu('&File') editMenu = self.menuBar.addMenu('&Edit') viewMenu = self.menuBar.addMenu('&View') measureMenu = self.menuBar.addMenu('&Measure') helpMenu = self.menuBar.addMenu('&Help') readZmatAction = QAction('&Read &ZMat', self) readZmatAction.setShortcut('Ctrl+O') readZmatAction.setStatusTip('Read Zmat from file') readZmatAction.triggered.connect(self.readZmat) fileMenu.addAction(readZmatAction) readXYZAction = QAction('&Read &XYZ', self) readXYZAction.setShortcut('Ctrl+Shift+O') readXYZAction.setStatusTip('Read XYZ from file') readXYZAction.triggered.connect(self.readXYZ) fileMenu.addAction(readXYZAction) readGaussianAction = QAction('&Read &Gaussian log', self) readGaussianAction.setShortcut('Ctrl+G') readGaussianAction.setStatusTip('Read Gaussian log file') readGaussianAction.triggered.connect(self.readGaussian) fileMenu.addAction(readGaussianAction) writeZmatAction = QAction('&Write &ZMat', self) writeZmatAction.setShortcut('Ctrl+S') writeZmatAction.setStatusTip('Write Zmat to file') writeZmatAction.triggered.connect(self.writeZmat) fileMenu.addAction(writeZmatAction) writeXYZAction = QAction('&Write &XYZ', self) writeXYZAction.setShortcut('Ctrl+Shift+S') writeXYZAction.setStatusTip('Write XYZ from file') writeXYZAction.triggered.connect(self.writeXYZ) fileMenu.addAction(writeXYZAction) exitAction = QAction('&Exit', self) exitAction.setShortcut('Ctrl+Q') exitAction.setStatusTip('Exit application') exitAction.triggered.connect(qApp.quit) fileMenu.addAction(exitAction) addRowAction = QAction('&Add &row', self) addRowAction.setShortcut('Ctrl+R') addRowAction.setStatusTip('Add row to ZMatrix') addRowAction.triggered.connect(self.addRow) editMenu.addAction(addRowAction) deleteRowAction = QAction('&Delete &row', self) deleteRowAction.setShortcut('Ctrl+Shift+R') deleteRowAction.setStatusTip('Delete row from ZMatrix') deleteRowAction.triggered.connect(self.deleteRow) editMenu.addAction(deleteRowAction) addAtomAction = QAction('&Add &atom', self) addAtomAction.setShortcut('Ctrl+A') addAtomAction.setStatusTip('Add atom to ZMatrix') addAtomAction.triggered.connect(self.buildB) editMenu.addAction(addAtomAction) drawModeMenu = QMenu('Draw mode', self) viewMenu.addMenu(drawModeMenu) fastDrawAction = QAction('&Fast draw', self) fastDrawAction.triggered.connect(self.fastDraw) normalDrawAction = QAction('&Normal draw', self) normalDrawAction.triggered.connect(self.normalDraw) drawModeMenu.addAction(normalDrawAction) drawModeMenu.addAction(fastDrawAction) clearHighlightsAction = QAction('&Clear selection', self) clearHighlightsAction.setShortcut('Ctrl+C') clearHighlightsAction.setStatusTip('Clear highlighted atoms') clearHighlightsAction.triggered.connect(self.clearHighlights) viewMenu.addAction(clearHighlightsAction) clearLabelsAction = QAction('&Clear labels', self) clearLabelsAction.setShortcut('Ctrl+Alt+C') clearLabelsAction.setStatusTip('Clear labels') clearLabelsAction.triggered.connect(self.clearLabels) viewMenu.addAction(clearLabelsAction) clearUpdateViewAction = QAction('&Clear selection and labels', self) clearUpdateViewAction.setShortcut('Ctrl+Shift+C') clearUpdateViewAction.setStatusTip('Clear highlighted atoms and labels') clearUpdateViewAction.triggered.connect(self.clearUpdateView) viewMenu.addAction(clearUpdateViewAction) self.showGaussAction = QAction('Show &Gaussian geometry optimization', self) self.showGaussAction.setShortcut('Ctrl+G') self.showGaussAction.setStatusTip('Show Gaussian geometry optimization plots for energy, force and displacement.') self.showGaussAction.setEnabled(False) self.showGaussAction.triggered.connect(self.showGauss) viewMenu.addAction(self.showGaussAction) self.showFreqAction = QAction('Show &IR frequency plot', self) self.showFreqAction.setShortcut('Ctrl+I') self.showFreqAction.setStatusTip('Show Gaussian calculated IR frequency plot.') self.showFreqAction.setEnabled(False) self.showFreqAction.triggered.connect(self.showFreq) viewMenu.addAction(self.showFreqAction) measureDistanceAction = QAction('&Measure &distance', self) measureDistanceAction.setShortcut('Ctrl+D') measureDistanceAction.setStatusTip('Measure distance between two atoms') measureDistanceAction.triggered.connect(self.measureDistanceB) measureMenu.addAction(measureDistanceAction) measureAngleAction = QAction('&Measure &angle', self) measureAngleAction.setShortcut('Ctrl+Shift+D') measureAngleAction.setStatusTip('Measure angle between three atoms') measureAngleAction.triggered.connect(self.measureAngleB) measureMenu.addAction(measureAngleAction) aboutAction = QAction('&About', self) aboutAction.setStatusTip('About this program...') aboutAction.triggered.connect(self.about) helpMenu.addAction(aboutAction) aboutQtAction = QAction('&About Qt', self) aboutQtAction.setStatusTip('About Qt...') aboutQtAction.triggered.connect(self.aboutQt) helpMenu.addAction(aboutQtAction) # define GL widget that displays the 3D molecule model self.window = widgets.MyGLView() self.window.installEventFilter(self) self.window.setMinimumSize(500, 500) #self.window.setBackgroundColor((50, 0, 10)) self.updateView() self.gaussianPlot = GraphicsLayoutWidget() self.gaussianPlot.resize(750, 250) self.gaussianPlot.setWindowTitle('Gaussian geometry optimization') #self.gaussianPlot.setAspectLocked(True) #self.gaussianPlot.addLayout(rowspan=3, colspan=1) self.FreqModel = QStandardItemModel(1, 3, self) self.freqTable = QTableView(self) self.freqTable.setModel(self.FreqModel) self.freqTable.setMinimumWidth(240) self.freqTable.installEventFilter(self) self.FreqModel.installEventFilter(self) self.FreqModel.setHorizontalHeaderLabels(['Frequency','IR Intensity','Raman Intensity']) for j, width in enumerate([80, 80, 80]): self.freqTable.setColumnWidth(j, width) self.freqWidget = QWidget() self.freqWidget.setWindowTitle('IR frequency plot & table') self.freqWidget.resize(800, 400) self.freqWidget.layout = QHBoxLayout(self.freqWidget) self.freqWidget.layout.setSpacing(1) self.freqWidget.layout.setContentsMargins(1, 1, 1, 1) self.freqPlot = GraphicsLayoutWidget() self.freqWidget.layout.addWidget(self.freqPlot) self.freqWidget.layout.addWidget(self.freqTable) self.freqTable.clicked.connect(self.freqCellClicked) # define other application parts self.statusBar = QStatusBar(self) self.fileDialog = QFileDialog(self) # define application layout self.layout = QVBoxLayout(self) self.layout.setSpacing(1) self.layout.setContentsMargins(1, 1, 1, 1) self.layout1 = QHBoxLayout() self.layout1.setSpacing(1) self.layout1.addWidget(self.ZMatTable) self.layout1.addWidget(self.window) self.layout.addWidget(self.menuBar) self.layout.addLayout(self.layout1) self.layout.addWidget(self.statusBar) self.adjustSize() self.setWindowTitle('Moldy') iconPath = 'icon.png' icon = QIcon(iconPath) icon.addFile(iconPath, QSize(16, 16)) icon.addFile(iconPath, QSize(24, 24)) icon.addFile(iconPath, QSize(32, 32)) icon.addFile(iconPath, QSize(48, 48)) icon.addFile(iconPath, QSize(256, 256)) self.setWindowIcon(icon) # start monitoring changes in the ZMatModel self.ZMatModel.dataChanged.connect(self.clearUpdateView) # run and show the application def run(self): self.show() self.ZMatTable.clicked.connect(self.ZMatCellClicked) qt_app.instance().aboutToQuit.connect(self.deleteGLwidget) qt_app.exec_() # fill the ZMatModel with initial data from 'self.inp' def populateZMatModel(self): self.ZMatModel.removeRows(0, self.ZMatModel.rowCount()) for i, row in enumerate(self.inp): for j, cell in enumerate(row): item = QStandardItem(str(cell)) self.ZMatModel.setItem(i, j, item) # some cells should not be editable, they are disabled for i in range(min(len(self.inp), 3)): for j in range(2*i+1, 7): self.ZMatModel.setItem(i, j, QStandardItem()) self.ZMatModel.item(i, j).setBackground(QColor(150,150,150)) self.ZMatModel.item(i, j).setFlags(Qt.ItemIsEnabled) def populateFreqModel(self): self.FreqModel.removeRows(0, self.FreqModel.rowCount()) for i, row in enumerate(zip(self.vibfreqs, self.vibirs, self.vibramans)): for j, cell in enumerate(row): item = QStandardItem(str(cell)) self.FreqModel.setItem(i, j, item) # add a row to the bottom of the ZMatModel def addRow(self): # temporarily stop updating the GL window self.ZMatModel.dataChanged.disconnect(self.clearUpdateView) row = self.ZMatModel.rowCount() self.ZMatModel.insertRow(row) # some cells should not be editable if row < 3: for j in range(2*row+1, 7): self.ZMatModel.setItem(row, j, QStandardItem()) self.ZMatModel.item(row, j).setBackground(QColor(150,150,150)) self.ZMatModel.item(row, j).setFlags(Qt.ItemIsEnabled) # restart GL window updating self.ZMatModel.dataChanged.connect(self.clearUpdateView) self.statusBar.clearMessage() self.statusBar.showMessage('Added 1 row.', 3000) # delete the last row of the ZMatModel def deleteRow(self): xyz = [list(vi) for vi in list(v)] atoms = [str(elements[e]) for e in elems] oldLen = self.ZMatModel.rowCount() idxs = sorted(set(idx.row() for idx in self.ZMatTable.selectedIndexes()), reverse=True) newLen = oldLen - len(idxs) if newLen == oldLen: self.ZMatModel.removeRow(self.ZMatModel.rowCount()-1) else: self.ZMatModel.dataChanged.disconnect(self.clearUpdateView) for idx in idxs: self.ZMatModel.removeRow(idx) if idx < 3: for i in range(idx, min(3, newLen)): for j in range(2*i+1, 7): self.ZMatModel.setItem(i, j, QStandardItem()) self.ZMatModel.item(i, j).setBackground(QColor(150,150,150)) self.ZMatModel.item(i, j).setFlags(Qt.ItemIsEnabled) if len(xyz) > idx: xyz.pop(idx) atoms.pop(idx) self.inp = xyz2zmat(xyz, atoms) self.populateZMatModel() for i in reversed(self.highList): self.window.removeItem(i[1]) self.highList = [] self.ZMatModel.dataChanged.connect(self.clearUpdateView) self.updateView() self.statusBar.clearMessage() if idxs: self.statusBar.showMessage('Deleted row(s): '+str([i+1 for i in idxs]), 3000) else: self.statusBar.showMessage('Deleted last row.', 3000) # show the periodic table widget def periodicTable(self): self.statusBar.clearMessage() self.statusBar.showMessage('Select element from periodic table.') self.periodicTableWidget.exec_() selection = self.periodicTableWidget.selection() return selection # import molecule with zmatrix coordinates def readZmat(self): self.ZMatModel.dataChanged.disconnect(self.clearUpdateView) filename = self.fileDialog.getOpenFileName(self, 'Open file', expanduser('~'), '*.zmat;;*.*') self.inp = [] self.populateZMatModel() if filename: with open(filename, 'r') as f: next(f) next(f) for row in f: self.inp.append(row.split()) f.close() self.populateZMatModel() self.ZMatModel.dataChanged.connect(self.clearUpdateView) self.updateView() self.statusBar.clearMessage() self.statusBar.showMessage('Read molecule from '+filename+'.', 5000) self.showGaussAction.setEnabled(False) self.showFreqAction.setEnabled(False) # import molecule with xyz coordinates def readXYZ(self): self.ZMatModel.dataChanged.disconnect(self.clearUpdateView) filename = self.fileDialog.getOpenFileName(self, 'Open file', expanduser('~'), '*.xyz;;*.*') xyz = [] elems = [] self.inp = [] self.populateZMatModel() if filename: with open(filename, 'r') as f: next(f) next(f) for row in f: rs = row.split() if len(rs) == 4: elems.append(rs[0]) xyz.append([float(f) for f in rs[1:]]) f.close() self.inp = xyz2zmat(xyz, elems) self.populateZMatModel() #print(elems) self.ZMatModel.dataChanged.connect(self.clearUpdateView) self.updateView() self.statusBar.clearMessage() self.statusBar.showMessage('Read molecule from '+filename+'.', 5000) self.showGaussAction.setEnabled(False) self.showFreqAction.setEnabled(False) # import Gaussian log file def readGaussian(self): global vsShifted self.ZMatModel.dataChanged.disconnect(self.clearUpdateView) filename = self.fileDialog.getOpenFileName(self, 'Open file', expanduser('~'), '*.log;;*.*') if filename: self.gaussianPlot.clear() self.inp = [] self.populateZMatModel() file = ccopen(filename) data = file.parse().getattributes() self.natom = data['natom'] self.atomnos = data['atomnos'].tolist() self.atomsymbols = [ str(elements[e]) for e in self.atomnos ] self.atomcoords = data['atomcoords'].tolist() self.scfenergies = data['scfenergies'].tolist() self.geovalues = data['geovalues'].T.tolist() self.geotargets = data['geotargets'].tolist() if 'vibfreqs' in data.keys(): self.vibfreqs = data['vibfreqs'] #print(self.vibfreqs) self.vibirs = data['vibirs'] #print(self.vibirs) #print(data.keys()) if 'vibramans' in data.keys(): self.vibramans = data['vibramans'] else: self.vibramans = [''] * len(self.vibirs) self.vibdisps = data['vibdisps'] #print(self.vibdisps) self.inp = xyz2zmat(self.atomcoords[0], self.atomsymbols) self.populateZMatModel() titles = ['SCF Energies', 'RMS & Max Forces', 'RMS & Max Displacements'] for i in range(3): self.gaussianPlot.addPlot(row=1, col=i+1) plot = self.gaussianPlot.getItem(1, i+1) plot.setTitle(title=titles[i]) if i == 0: c = ['c'] x = [0] y = [self.scfenergies] else: c = ['r', 'y'] x = [0, 0] y = [self.geovalues[2*i-2], self.geovalues[2*i-1]] targety = [self.geotargets[2*i-2], self.geotargets[2*i-1]] plot.clear() plot.maxData = plot.plot(y[0], symbol='o', symbolPen=c[0], symbolBrush=c[0], pen=c[0], symbolSize=5, pxMode=True, antialias=True, autoDownsample=False) plot.highlight=plot.plot(x, [ yy[0] for yy in y ], symbol='o', symbolPen='w', symbolBrush=None, pen=None, symbolSize=15, pxMode=True, antialias=True, autoDownsample=False) plot.maxData.sigPointsClicked.connect(self.gausclicked) if i > 0: for j in range(2): plot.addLine(y=np.log10(targety[j]), pen=mkPen((255, 255*j, 0, int(255/2)), width=1)) plot.RMSData=plot.plot(y[1], symbol='o', symbolPen=c[1], symbolBrush=c[1], pen=c[1], symbolSize=5, pxMode=True, antialias=True, autoDownsample=False) plot.RMSData.sigPointsClicked.connect(self.gausclicked) plot.setLogMode(y=True) self.showGauss() self.updateView() self.statusBar.clearMessage() self.statusBar.showMessage('Read molecule from '+filename+'.', 5000) self.ZMatModel.dataChanged.connect(self.clearUpdateView) if self.natom: self.showGaussAction.setEnabled(True) if 'vibfreqs' in data.keys(): self.showFreqAction.setEnabled(True) # populate the FreqModel self.populateFreqModel() self.freqPlot.clear() irPlot = self.freqPlot.addPlot(row=1, col=1) irPlot.clear() minFreq = np.min(self.vibfreqs) maxFreq = np.max(self.vibfreqs) maxInt = np.max(self.vibirs) x = np.sort(np.concatenate([np.linspace(minFreq-100, maxFreq+100, num=1000), self.vibfreqs])) y = x*0 for f,i in zip(self.vibfreqs, self.vibirs): y += lorentzv(x, f, 2*np.pi, i) #xy = np.array([np.concatenate([x, np.array(self.vibfreqs)]), np.concatenate([y, np.array(self.vibirs)])]).T #xysort = xy[xy[:,0].argsort()] irPlot.maxData = irPlot.plot(x, y, antialias=True) markers = ErrorBarItem(x=self.vibfreqs, y=self.vibirs, top=maxInt/30, bottom=None, pen='r') irPlot.addItem(markers) self.showFreq() #self.vibdisps = np.append(self.vibdisps, [np.mean(self.vibdisps, axis=0)], axis=0) maxt = 100 vsShifted = np.array([ [ vs + self.vibdisps[i]*np.sin(t*2*np.pi/maxt)/3 for t in range(maxt) ] for i in range(len(self.vibfreqs)) ]) else: self.showFreqAction.setEnabled(False) self.freqWidget.hide() def showGauss(self): self.gaussianPlot.show() def showFreq(self): self.freqWidget.show() # export Zmatrix to csv def writeZmat(self): zm = model2list(self.ZMatModel) filename = self.fileDialog.getSaveFileName(self, 'Save file', expanduser('~')+'/'+getFormula(list(list(zip(*zm))[0]))+'.zmat', '*.zmat;;*.*') try: filename except NameError: pass else: if filename: writeOutput(zm, filename) self.statusBar.clearMessage() self.statusBar.showMessage('Wrote molecule to '+filename+'.', 5000) # export XYZ coordinates to csv def writeXYZ(self): xyz = [] zm = model2list(self.ZMatModel) for i in range(len(v)): xyz.append(np.round(v[i], 7).tolist()) xyz[i][:0] = zm[i][0] if len(v) > 0: formula = getFormula(list(list(zip(*xyz))[0])) else: formula = 'moldy_output' filename = self.fileDialog.getSaveFileName(self, 'Save file', expanduser('~')+'/'+formula+'.xyz', '*.xyz;;*.*') try: filename except NameError: pass else: if filename: writeOutput(xyz, filename) self.statusBar.clearMessage() self.statusBar.showMessage('Wrote molecule to '+filename+'.', 5000) # redraw the 3D molecule in GL widget def updateView(self): global r global c global v global vs global elems global nelems data = model2list(self.ZMatModel) try: # create a list with element coordinates v = zmat2xyz(data) except (AssertionError, IndexError, ZMError): pass else: # clear the screen before redraw for item in reversed(self.window.items): self.window.removeItem(item) # create a second coordinate list 'vs' that is centered in the GL view self.atomList = [] if len(v) > 0: shift = np.mean(v, axis=0) vs = np.add(v, -shift) elems = [ 1 + next((i for i, sublist in enumerate(colors) if row[0] in sublist), -1) for row in data ] nelems = len(elems) # define molecule radii and colors r = [] c = [] for i in elems: r.append(elements[i].covalent_radius) c.append(colors[i-1][-1]) # draw atoms for i in range(nelems): addAtom(self.window, i, r, vs, c, fast=self.fast) self.atomList.append([i, self.window.items[-1]]) #print(self.atomList) # draw bonds where appropriate combs = list(itertools.combinations(range(nelems), 2)) bonds = [] for i in combs: bonds.append(addBond(self.window, i[0], i[1], r, vs, c, fast=self.fast)) if self.fast: bondedAtoms = set(filter((None).__ne__, flatten(bonds))) for i in set(range(nelems)) - bondedAtoms: addUnbonded(self.window, i, vs, c) self.atomList[i][1]=self.window.items[-1] #print(self.atomList) for i in self.highList: self.window.addItem(i[1]) for i in self.labelList: self.window.addItem(i) if len(v) > 1: maxDim = float('-inf') for dim in v.T: span = max(dim)-min(dim) if span > maxDim: maxDim = span else: maxDim = 2 self.window.setCameraPosition(distance=maxDim*1.5+1) global index index = 0 def updateFreq(self): global vsShifted, index, r, c index += 1 index = index % len(vsShifted[0]) #print(index) #print(vsShifted[index]) for item in reversed(self.window.items): self.window.removeItem(item) for i in range(nelems): addAtom(self.window, i, r, vsShifted[self.freqIndex, index], c, fast=self.fast) self.atomList.append([i, self.window.items[-1]]) combs = itertools.combinations(range(nelems), 2) bonds = [] for i in combs: bonds.append(addBond(self.window, i[0], i[1], r, vsShifted[self.freqIndex, index], c, fast=self.fast)) if self.fast: bondedAtoms = set(filter((None).__ne__, flatten(bonds))) for i in set(range(nelems)) - bondedAtoms: addUnbonded(self.window, i, vsShifted[self.freqIndex, index], c) self.atomList[i][1]=self.window.items[-1] # detect mouse clicks in GL window and process them def eventFilter(self, obj, event): if obj == self.window: if event.type() == event.MouseButtonPress: itms = obj.itemsAt((event.pos().x()-2, event.pos().y()-2, 4, 4)) if len(itms): self.highlight(obj, [itms[0]]) elif len(self.atomList) == 0: self.build() # also do the default click action return super(MainWidget, self).eventFilter(obj, event) def ZMatCellClicked(self): idxs = sorted(set(idx.row() for idx in self.ZMatTable.selectedIndexes()), reverse=True) itms = [] if self.highList: highIdx = list(np.array(self.highList).T[0]) for idx in idxs: if self.highList and idx in highIdx: itms.append(self.highList[highIdx.index(idx)][1]) elif len(self.atomList) > idx: itms.append(self.atomList[idx][1]) self.highlight(self.window, itms) def freqCellClicked(self): global vsShifted self.timer = QTimer() self.timer.setInterval(30) self.timer.timeout.connect(self.updateFreq) idxs = [ idx.row() for idx in self.freqTable.selectedIndexes() ] if len(idxs) == 1: self.freqIndex = idxs[0] self.timer.stop() self.timer.timeout.connect(self.updateFreq) try: self.ZMatModel.dataChanged.disconnect(self.clearUpdateView) except TypeError: pass self.timer.start() if len(idxs) != 1: self.timer.stop() self.freqTable.clearSelection() self.timer.timeout.disconnect(self.updateFreq) self.ZMatModel.dataChanged.connect(self.clearUpdateView) self.clearUpdateView() def gausclicked(self, item, point): itemdata = item.scatter.data points = [ row[7] for row in itemdata ] idx = points.index(point[0]) for i in range(3): if i == 0: x = [idx] y = [self.scfenergies[idx]] else: x = [idx, idx] y = [self.geovalues[2*i-2][idx], self.geovalues[2*i-1][idx]] plot = self.gaussianPlot.getItem(1, i+1) plot.removeItem(plot.highlight) plot.highlight=plot.plot(x, y, symbol='o', symbolPen='w', symbolBrush=None, pen=None, symbolSize=15, pxMode=True, antialias=True, autoDownsample=False) self.ZMatModel.dataChanged.disconnect(self.clearUpdateView) self.inp = [] self.populateZMatModel() self.inp = xyz2zmat(self.atomcoords[min(idx, len(self.atomcoords)-1)], self.atomsymbols) self.populateZMatModel() self.ZMatModel.dataChanged.connect(self.clearUpdateView) self.updateView() def highlight(self, obj, itms): for itm in itms: idx = next((i for i, sublist in enumerate(self.atomList) if itm in sublist), -1) #print(idx) if idx != -1: addAtom(obj, idx, r, vs, c, opt='highlight', fast=self.fast) self.highList.append([idx, obj.items[-1]]) self.ZMatTable.selectRow(idx) idx = next((i for i, sublist in enumerate(self.highList) if itm in sublist), -1) if idx != -1: obj.removeItem(self.highList[idx][1]) self.highList.pop(idx) self.ZMatTable.clearSelection() self.statusBar.clearMessage() if len(self.highList) > 0: idxs = np.asarray(self.highList).T[0] selected = [] for i in idxs: selected.append(str(i+1)+str(elements[elems[i]])) self.statusBar.showMessage('Selected atoms: '+str(selected), 5000) def buildB(self): try: nelems except NameError: self.build() else: if len(self.highList) <= min(nelems, 3): diff = min(nelems, 3) - len(self.highList) if diff != 0: self.statusBar.clearMessage() self.statusBar.showMessage('Please select '+str(diff)+' more atom(s).') else: self.build() else: self.statusBar.clearMessage() self.statusBar.showMessage('Too many atoms selected.') def build(self): selection = self.periodicTable() row = self.ZMatModel.rowCount() self.addRow() self.ZMatModel.dataChanged.disconnect(self.clearUpdateView) newSymbol = selection[1] newData = [newSymbol] if len(self.highList) >= 1: newBond = round(2.1*gmean([ elements[e].covalent_radius for e in [selection[0], elems[self.highList[0][0]]] ]), 4) newData.append(self.highList[0][0]+1) newData.append(newBond) if len(self.highList) >= 2: newAngle = 109.4712 newData.append(self.highList[1][0]+1) newData.append(newAngle) if len(self.highList) == 3: newDihedral = 120. newData.append(self.highList[2][0]+1) newData.append(newDihedral) for j, cell in enumerate(newData): item = QStandardItem(str(cell)) self.ZMatModel.setItem(row, j, item) self.highList = [] self.ZMatModel.dataChanged.connect(self.clearUpdateView) self.updateView() def measureDistanceB(self): sel = len(self.highList) if sel <= 2: if sel < 2: self.statusBar.clearMessage() self.statusBar.showMessage('Please select '+str(2-sel)+' more atom(s).') else: self.measureDistance() else: self.statusBar.clearMessage() self.statusBar.showMessage('Too many atoms selected.') def measureDistance(self): pts = [] for pt in self.highList: pts.append(vs[pt[0]]) pts = np.array(pts) self.clearHighlights() line = gl.GLLinePlotItem(pos=pts, color=(0., 1., 0., 1.), width=3) self.window.addItem(line) self.labelList.append(line) q = pts[1]-pts[0] dist = round(np.sqrt(np.dot(q, q)), 4) self.window.labelPos.append(np.mean(pts[0:2], axis=0)) self.window.labelText.append(str(dist)) self.statusBar.clearMessage() self.statusBar.showMessage('Measured distance: '+str(dist)+' A.', 3000) def measureAngleB(self): sel = len(self.highList) if sel <= 3: if sel < 3: self.statusBar.clearMessage() self.statusBar.showMessage('Please select '+str(3-sel)+' more atom(s).') else: self.measureAngle() else: self.statusBar.clearMessage() self.statusBar.showMessage('Too many atoms selected.') def measureAngle(self): pts = [] for pt in self.highList: pts.append(vs[pt[0]]) pts = np.array(pts) q = pts[1]-pts[0] r = pts[2]-pts[0] q_u = q / np.sqrt(np.dot(q, q)) r_u = r / np.sqrt(np.dot(r, r)) angle = round(degrees(acos(np.dot(q_u, r_u))), 1) srange = np.array([slerp(q, r, t) for t in np.arange(0.0, 13/12, 1/12)]) self.clearHighlights() for i in range(12): mesh = gl.MeshData(np.array([[0,0,0],srange[i],srange[i+1]])) tri = gl.GLMeshItem(meshdata=mesh, smooth=False, computeNormals=False, color=(0.3, 1., 0.3, 0.5), glOptions=('translucent')) tri.translate(pts[0][0], pts[0][1], pts[0][2]) self.window.addItem(tri) self.labelList.append(tri) self.window.labelPos.append(slerp(q, r, 0.5)+pts[0]) self.window.labelText.append(str(angle)) self.statusBar.clearMessage() self.statusBar.showMessage('Measured angle: '+str(angle)+'°', 3000) def clearLabels(self): self.window.labelPos = [] self.window.labelText = [] self.labelList = [] self.updateView() def clearHighlights(self): for item in reversed(self.highList): self.window.removeItem(item[1]) self.highList = [] self.updateView() def clearUpdateView(self): self.window.labelPos = [] self.window.labelText = [] self.labelList = [] for item in reversed(self.highList): self.window.removeItem(item[1]) self.highList = [] self.updateView() #print(self.highList) def fastDraw(self): if not self.fast: self.fast = True self.updateView() def normalDraw(self): if self.fast: self.fast = False self.updateView() def about(self): QMessageBox.about(self, 'About moldy', 'moldy beta 15. 9. 2015') def aboutQt(self): QMessageBox.aboutQt(self, 'About Qt') def deleteGLwidget(self): self.window.setParent(None) del self.window
def SaveAction(self): #Filename zum Speichern vom Benutzer erfragen filename = QFileDialog.getSaveFileName(self, 'Messung Speichern') if not filename == '': self.MainProgramm.SaveFile(filename)
def ExportAction(self): filename = QFileDialog.getSaveFileName(self, 'Messung Exportieren') if not filename == '': self.MainProgramm.Export(filename) return
def saveToFileBowditch(self): ''' the bowditch needs to be setup such that the final coordinate is a known point, a single letter, then the reference will be in the next 2 rows, with a dash next to the single letter''' fileName = QFileDialog.getSaveFileName(self, "Open Points File", "", "Excel (*.xlsx)", "") dX, dY = bowditchAdjust(self.provisionals, self.control, self.obsOrder[-1][4:]) self.bowditch.setText("not completed yet.") sumDistance = 0 for i, j in self.obs1.iteritems(): for p, t in j.iteritems(): if self.provisionals.has_key(p): sumDistance = sumDistance + t.distance dX = dX / sumDistance dY = dY / sumDistance fileName = str(fileName) workbook = xlsxwriter.Workbook(fileName) worksheet = workbook.add_worksheet() i = 0 worksheet.write(0, 0, 'Leg') worksheet.write(0, 1, 'Dir/OrCorr./Dis') worksheet.write(0, 2, 'Name') worksheet.write(0, 3, 'Y') worksheet.write(0, 4, 'X') worksheet.write(2, 2, self.control[self.stationsOrder[0]].name) worksheet.write(2, 3, self.control[self.stationsOrder[0]].y) worksheet.write(2, 4, self.control[self.stationsOrder[0]].x) i += 4 temp = self.stationsOrder[0] soFar = 0 format = workbook.add_format() format.set_underline() for nm3 in self.stationsOrder: for nm, ob in self.obs1[nm3].iteritems(): if self.provisionals.has_key(nm): worksheet.write(i, 0, nm3 + "-" + nm) worksheet.write(i, 1, rad2dms(self.obs1[nm3][nm].direction)) worksheet.write(i, 2, nm) worksheet.write(i, 3, round(self.provisionals[nm].y, 3)) worksheet.write(i, 4, round(self.provisionals[nm].x, 3)) i += 1 ldist = self.obs1[nm3][nm].distance soFar += ldist worksheet.write(i, 3, soFar * dY) worksheet.write(i, 4, soFar * dX) i += 1 worksheet.write( i, 1, str(round(self.obs1[nm3][nm].distance, 2)) + "m") worksheet.write(i, 2, nm, format) worksheet.write( i, 3, round(self.provisionals[nm].y + soFar * dY, 2), format) worksheet.write( i, 4, round(self.provisionals[nm].x + soFar * dX, 2), format) i += 2 temp = nm workbook.close()
def writeOut(self): fileName = QFileDialog.getSaveFileName(self, "Open Points File", "", "Text File (*.txt);;", "") file = open(fileName, "w") file.write("________CONTROL POINTS________\n\n") for i, j in self.control.iteritems(): file.write(i + ":\n" + str(j) + "\n") file.write("________UNKNOWNS________\n\n") file.write(str(self.unknowns) + '\n\n') file.write( "_______________________________________ CALCULATIONS _______________________________________ \n\n\n\n" ) k = 0 for i in range(self.iterations): k += 1 provis = adjustProvisional(self.Xdict, self.provis, self.obs, self.unknowns) A, Xdict, provis, obs, control, unknowns, L = Iterate( provis, self.obs, self.control, self.unknowns, self.P) X = ((A.T * self.P * A)**-1) * A.T * self.P * L Xdict = Points("Solutions Dictionary") j = 0 for i in unknowns: Xdict[i] = X[j] j += 1 V, posteriori, covarience_mat, precisi = precisions( A, X, self.P, L, obs, unknowns) file.write("________ITERATION: " + str(k) + " ________\n\n") if float(round(float((A.T * self.P * V).T * (A.T * self.P * V)), 6)) == 0.: file.write( "____________________________________________________\n\nCalculation check 'A.tPV' successful\n---------------------------------------------\n" ) else: file.write( "Calculation check 'A.tPV' unsuccessful to 6 dec places\n\n" ) # V,posteriori,covarience_mat,precisions file.write("________'V.TPV'________\n\n") file.write(str(V.T * self.P * V) + '\n\n') file.write("________Posteriori________\n\n") file.write(str(posteriori) + '\n\n') # file.write("________Covarience Matrix________\n\n") # COVARIENCE MATRIX # file.write(str(covarience_mat)+'\n\n') file.write("________Precisions of Unknowns ________\n\n") for i, j in precisi.iteritems(): file.write(i + ":\n" + str(round(float(j), 3)) + "\n\n") check = globalCheck(provis, control, V, obs, unknowns, Xdict) file.write("________Global Check________\n\n") for i, j in check.iteritems(): file.write(i + ":\n" + str(j) + "\n") file.write("________________---- END OF ITERATION " + str(k) + " ----____________\n\n") file.write( "_______________________________________________________________________\n\n" ) # showGraph(N,provisionals,control) file.write("________FINAL COORDINATES________\n\n") for i, j in provis.iteritems(): file.write(i + ":\n" + str(j) + "\n\n") file.write( "________X Solution Vector, With distances in meters and directions in seconds ________\n\n" ) for i, j in Xdict.iteritems(): file.write(i + ":\n" + str(round(float(j), 3)) + "\n\n")
def __init__(self, title=_('Choose Files'), filters=[], add_all_files_filter=True, parent=None, modal=True, name='', mode=QFileDialog.ExistingFiles, default_dir='~'): QObject.__init__(self) ftext = '' if filters: for filter in filters: text, extensions = filter extensions = [ '*' + (i if i.startswith('.') else '.' + i) for i in extensions ] ftext += '%s (%s);;' % (text, ' '.join(extensions)) if add_all_files_filter or not ftext: ftext += 'All files (*)' if ftext.endswith(';;'): ftext = ftext[:-2] self.dialog_name = name if name else 'dialog_' + title self.selected_files = None self.fd = None initial_dir = dynamic.get(self.dialog_name, os.path.expanduser(default_dir)) if not isinstance(initial_dir, basestring): initial_dir = os.path.expanduser(default_dir) self.selected_files = [] with SanitizeLibraryPath(): if mode == QFileDialog.AnyFile: f = unicode( QFileDialog.getSaveFileName(parent, title, initial_dir, ftext, "")) if f: self.selected_files.append(f) elif mode == QFileDialog.ExistingFile: f = unicode( QFileDialog.getOpenFileName(parent, title, initial_dir, ftext, "")) if f and os.path.exists(f): self.selected_files.append(f) elif mode == QFileDialog.ExistingFiles: fs = QFileDialog.getOpenFileNames(parent, title, initial_dir, ftext, "") for f in fs: f = unicode(f) if not f: continue if not os.path.exists(f): # QFileDialog for some reason quotes spaces # on linux if there is more than one space in a row f = unquote(f) if f and os.path.exists(f): self.selected_files.append(f) else: opts = QFileDialog.ShowDirsOnly if mode == QFileDialog.Directory else QFileDialog.Option( ) f = unicode( QFileDialog.getExistingDirectory(parent, title, initial_dir, opts)) if os.path.exists(f): self.selected_files.append(f) if self.selected_files: self.selected_files = [unicode(q) for q in self.selected_files] saved_loc = self.selected_files[0] if os.path.isfile(saved_loc): saved_loc = os.path.dirname(saved_loc) dynamic[self.dialog_name] = saved_loc self.accepted = bool(self.selected_files)
def __init__( self, title=_("Choose Files"), filters=[], add_all_files_filter=True, parent=None, modal=True, name="", mode=QFileDialog.ExistingFiles, default_dir="~", no_save_dir=False, ): QObject.__init__(self) ftext = "" if filters: for filter in filters: text, extensions = filter extensions = ["*" + (i if i.startswith(".") else "." + i) for i in extensions] ftext += "%s (%s);;" % (text, " ".join(extensions)) if add_all_files_filter or not ftext: ftext += "All files (*)" if ftext.endswith(";;"): ftext = ftext[:-2] self.dialog_name = name if name else "dialog_" + title self.selected_files = None self.fd = None if no_save_dir: initial_dir = os.path.expanduser(default_dir) else: initial_dir = dynamic.get(self.dialog_name, os.path.expanduser(default_dir)) if not isinstance(initial_dir, basestring): initial_dir = os.path.expanduser(default_dir) self.selected_files = [] use_native_dialog = "CALIBRE_NO_NATIVE_FILEDIALOGS" not in os.environ with SanitizeLibraryPath(): opts = QFileDialog.Option() if not use_native_dialog: opts |= QFileDialog.DontUseNativeDialog if mode == QFileDialog.AnyFile: f = unicode(QFileDialog.getSaveFileName(parent, title, initial_dir, ftext, "", opts)) if f: self.selected_files.append(f) elif mode == QFileDialog.ExistingFile: f = unicode(QFileDialog.getOpenFileName(parent, title, initial_dir, ftext, "", opts)) if f and os.path.exists(f): self.selected_files.append(f) elif mode == QFileDialog.ExistingFiles: fs = QFileDialog.getOpenFileNames(parent, title, initial_dir, ftext, "", opts) for f in fs: f = unicode(f) if not f: continue if not os.path.exists(f): # QFileDialog for some reason quotes spaces # on linux if there is more than one space in a row f = unquote(f) if f and os.path.exists(f): self.selected_files.append(f) else: if mode == QFileDialog.Directory: opts |= QFileDialog.ShowDirsOnly f = unicode(QFileDialog.getExistingDirectory(parent, title, initial_dir, opts)) if os.path.exists(f): self.selected_files.append(f) if self.selected_files: self.selected_files = [unicode(q) for q in self.selected_files] saved_loc = self.selected_files[0] if os.path.isfile(saved_loc): saved_loc = os.path.dirname(saved_loc) if not no_save_dir: dynamic[self.dialog_name] = saved_loc self.accepted = bool(self.selected_files)
def fileSaveMovie(self): """ Save a copy of the current movie file loaded in the Movie Player. """ # Make sure there is a moviefile to save. if not self.w.assy.current_movie or not self.w.assy.current_movie.filename \ or not os.path.exists(self.w.assy.current_movie.filename): msg = redmsg("Save Movie File: No movie file to save.") env.history.message(msg) msg = "To create a movie, click on the <b>Simulator</b> <img source=\"simicon\"> icon." #QMimeSourceFactory.defaultFactory().setPixmap( "simicon", # self.simSetupAction.iconSet().pixmap() ) env.history.message(msg) return env.history.message(greenmsg("Save Movie File:")) if self.w.assy.filename: sdir = self.w.assy.filename else: sdir = env.prefs[workingDirectory_prefs_key] sfilter = QString("Differential Position Bytes Format (*.dpb)") # Removed .xyz as an option in the sfilter since the section of code below # to save XYZ files never worked anyway. This also fixes bug 492. Mark 050816. fn = QFileDialog.getSaveFileName( self, "Save As", sdir, "Differential Position Bytes Format (*.dpb);;POV-Ray Series (*.pov)", sfilter) if not fn: env.history.message("Cancelled.") return else: fn = str(fn) dir, fil, ext2 = filesplit(fn) del ext2 #bruce 050413 ext = str( sfilter[-5:-1] ) # Get "ext" from the sfilter. It *can* be different from "ext2"!!! - Mark #bruce 050413 comment: the above assumes that len(ext) is always 4 (.xxx). # I'm speculating that this is ok for now since it has to be one of the ones # provided to the getSaveFileName method above. # Changed os.path.join > os.path.normpath to partially fix bug #956. Mark 050911. safile = os.path.normpath(dir + "/" + fil + ext) # full path of "Save As" filename if os.path.exists( safile): # ...and if the "Save As" file exists... # ... confirm overwrite of the existing file. ret = QMessageBox.warning( self, "Confirm overwrite", "The file \"" + fil + ext + "\" already exists.\n"\ "Do you want to overwrite the existing file or cancel?", "&Overwrite", "&Cancel", "", 0, # Enter == button 0 1 ) # Escape == button 1 if ret == 1: # The user cancelled env.history.message("Cancelled. File not saved.") return # Cancel clicked or Alt+C pressed or Escape pressed if ext == '.dpb': self.w.assy.current_movie._close() import shutil shutil.copy(self.w.assy.current_movie.filename, safile) # Get the trace file name. tfile1 = self.w.assy.current_movie.get_trace_filename() # Copy the tracefile if os.path.exists(tfile1): fullpath, ext = os.path.splitext(safile) tfile2 = fullpath + "-trace.txt" shutil.copy(tfile1, tfile2) env.history.message("DPB movie file saved: " + safile) # note that we are still playing it from the old file and filename... does it matter? [bruce 050427 question] # Added "hflag=False" to suppress history msg, fixing bug #956. Mark 050911. self.w.assy.current_movie.cueMovie( propMgr=self, hflag=False) # Do not print info to history widget. elif ext == '.pov': self.w.assy.current_movie._write_povray_series( os.path.normpath(dir + "/" + fil)) else: #.xyz (or something unexpected) #bruce 051115 added warning and immediate return, to verify that this code is never called QMessageBox.warning( self, "ERROR", "internal error: unsupported file extension %r" % (ext, )) # args are title, content return # from fileSaveMovie
def __init__(self, title=_('Choose Files'), filters=[], add_all_files_filter=True, parent=None, modal=True, name='', mode=QFileDialog.ExistingFiles, default_dir='~', no_save_dir=False, combine_file_and_saved_dir=False): QObject.__init__(self) ftext = '' if filters: for filter in filters: text, extensions = filter extensions = [ '*' + (i if i.startswith('.') else '.' + i) for i in extensions ] ftext += '%s (%s);;' % (text, ' '.join(extensions)) if add_all_files_filter or not ftext: ftext += 'All files (*)' if ftext.endswith(';;'): ftext = ftext[:-2] self.dialog_name = name if name else 'dialog_' + title self.selected_files = None self.fd = None if combine_file_and_saved_dir: bn = os.path.basename(default_dir) prev = dynamic.get(self.dialog_name, os.path.expanduser('~')) if os.path.exists(prev): if os.path.isfile(prev): prev = os.path.dirname(prev) else: prev = os.path.expanduser('~') initial_dir = os.path.join(prev, bn) elif no_save_dir: initial_dir = os.path.expanduser(default_dir) else: initial_dir = dynamic.get(self.dialog_name, os.path.expanduser(default_dir)) if not isinstance(initial_dir, basestring): initial_dir = os.path.expanduser(default_dir) if not initial_dir or ( not os.path.exists(initial_dir) and not (mode == QFileDialog.AnyFile and (no_save_dir or combine_file_and_saved_dir))): initial_dir = select_initial_dir(initial_dir) self.selected_files = [] use_native_dialog = 'CALIBRE_NO_NATIVE_FILEDIALOGS' not in os.environ with SanitizeLibraryPath(): opts = QFileDialog.Option() if not use_native_dialog: opts |= QFileDialog.DontUseNativeDialog if mode == QFileDialog.AnyFile: f = unicode( QFileDialog.getSaveFileName(parent, title, initial_dir, ftext, "", opts)) if f: self.selected_files.append(f) elif mode == QFileDialog.ExistingFile: f = unicode( QFileDialog.getOpenFileName(parent, title, initial_dir, ftext, "", opts)) if f and os.path.exists(f): self.selected_files.append(f) elif mode == QFileDialog.ExistingFiles: fs = QFileDialog.getOpenFileNames(parent, title, initial_dir, ftext, "", opts) for f in fs: f = unicode(f) if not f: continue if not os.path.exists(f): # QFileDialog for some reason quotes spaces # on linux if there is more than one space in a row f = unquote(f) if f and os.path.exists(f): self.selected_files.append(f) else: if mode == QFileDialog.Directory: opts |= QFileDialog.ShowDirsOnly f = unicode( QFileDialog.getExistingDirectory(parent, title, initial_dir, opts)) if os.path.exists(f): self.selected_files.append(f) if self.selected_files: self.selected_files = [unicode(q) for q in self.selected_files] saved_loc = self.selected_files[0] if os.path.isfile(saved_loc): saved_loc = os.path.dirname(saved_loc) if not no_save_dir: dynamic[self.dialog_name] = saved_loc self.accepted = bool(self.selected_files)
def fileSaveMovie(self): """ Save a copy of the current movie file loaded in the Movie Player. """ # Make sure there is a moviefile to save. if not self.w.assy.current_movie or not self.w.assy.current_movie.filename \ or not os.path.exists(self.w.assy.current_movie.filename): msg = redmsg("Save Movie File: No movie file to save.") env.history.message(msg) msg = "To create a movie, click on the <b>Simulator</b> <img source=\"simicon\"> icon." #QMimeSourceFactory.defaultFactory().setPixmap( "simicon", # self.simSetupAction.iconSet().pixmap() ) env.history.message(msg) return env.history.message(greenmsg("Save Movie File:")) if self.w.assy.filename: sdir = self.w.assy.filename else: sdir = env.prefs[workingDirectory_prefs_key] sfilter = QString("Differential Position Bytes Format (*.dpb)") # Removed .xyz as an option in the sfilter since the section of code below # to save XYZ files never worked anyway. This also fixes bug 492. Mark 050816. fn = QFileDialog.getSaveFileName( self, "Save As", sdir, "Differential Position Bytes Format (*.dpb);;POV-Ray Series (*.pov)", sfilter) if not fn: env.history.message("Cancelled.") return else: fn = str(fn) dir, fil, ext2 = filesplit(fn) del ext2 #bruce 050413 ext = str(sfilter[-5:-1]) # Get "ext" from the sfilter. It *can* be different from "ext2"!!! - Mark #bruce 050413 comment: the above assumes that len(ext) is always 4 (.xxx). # I'm speculating that this is ok for now since it has to be one of the ones # provided to the getSaveFileName method above. # Changed os.path.join > os.path.normpath to partially fix bug #956. Mark 050911. safile = os.path.normpath(dir + "/" + fil + ext) # full path of "Save As" filename if os.path.exists(safile): # ...and if the "Save As" file exists... # ... confirm overwrite of the existing file. ret = QMessageBox.warning( self, "Confirm overwrite", "The file \"" + fil + ext + "\" already exists.\n"\ "Do you want to overwrite the existing file or cancel?", "&Overwrite", "&Cancel", "", 0, # Enter == button 0 1 ) # Escape == button 1 if ret == 1: # The user cancelled env.history.message( "Cancelled. File not saved." ) return # Cancel clicked or Alt+C pressed or Escape pressed if ext == '.dpb': self.w.assy.current_movie._close() import shutil shutil.copy(self.w.assy.current_movie.filename, safile) # Get the trace file name. tfile1 = self.w.assy.current_movie.get_trace_filename() # Copy the tracefile if os.path.exists(tfile1): fullpath, ext = os.path.splitext(safile) tfile2 = fullpath + "-trace.txt" shutil.copy(tfile1, tfile2) env.history.message("DPB movie file saved: " + safile) # note that we are still playing it from the old file and filename... does it matter? [bruce 050427 question] # Added "hflag=False" to suppress history msg, fixing bug #956. Mark 050911. self.w.assy.current_movie.cueMovie(propMgr = self, hflag = False) # Do not print info to history widget. elif ext == '.pov': self.w.assy.current_movie._write_povray_series( os.path.normpath(dir + "/" + fil)) else: #.xyz (or something unexpected) #bruce 051115 added warning and immediate return, to verify that this code is never called QMessageBox.warning(self, "ERROR", "internal error: unsupported file extension %r" % (ext,) ) # args are title, content return # from fileSaveMovie
def writeOut(self): fileName = QFileDialog.getSaveFileName(self, "Open Points File", "", "Text File (*.txt);;", "") file = open(fileName, "w") file.write("________CONTROL POINTS________\n\n") for i,j in self.control.iteritems(): file.write(i +":\n"+ str(j)+"\n") file.write("________UNKNOWNS________\n\n") file.write(str(self.unknowns)+'\n\n') file.write("_______________________________________ CALCULATIONS _______________________________________ \n\n\n\n") k=0 for i in range (self.iterations): k+=1 provis=adjustProvisional(self.Xdict,self.provis, self.obs, self.unknowns) A,Xdict,provis,obs,control,unknowns,L=Iterate(provis, self.obs, self.control, self.unknowns,self.P) X=((A.T*self.P*A)**-1)*A.T*self.P*L Xdict=Points("Solutions Dictionary") j=0 for i in unknowns: Xdict[i]=X[j] j+=1 V,posteriori,covarience_mat,precisi=precisions(A,X,self.P,L,obs,unknowns) file.write("________ITERATION: "+str(k)+" ________\n\n") if float(round(float((A.T*self.P*V).T*(A.T*self.P*V)),6))==0.: file.write("____________________________________________________\n\nCalculation check 'A.tPV' successful\n---------------------------------------------\n") else: file.write("Calculation check 'A.tPV' unsuccessful to 6 dec places\n\n") # V,posteriori,covarience_mat,precisions file.write("________'V.TPV'________\n\n") file.write(str(V.T*self.P*V)+'\n\n') file.write("________Posteriori________\n\n") file.write(str(posteriori)+'\n\n') # file.write("________Covarience Matrix________\n\n") # COVARIENCE MATRIX # file.write(str(covarience_mat)+'\n\n') file.write("________Precisions of Unknowns ________\n\n") for i,j in precisi.iteritems(): file.write(i +":\n"+ str(round(float(j),3))+"\n\n") check=globalCheck(provis,control,V,obs,unknowns,Xdict) file.write("________Global Check________\n\n") for i,j in check.iteritems(): file.write(i +":\n"+ str(j)+"\n") file.write("________________---- END OF ITERATION "+str(k)+" ----____________\n\n") file.write("_______________________________________________________________________\n\n") # showGraph(N,provisionals,control) file.write("________FINAL COORDINATES________\n\n") for i,j in provis.iteritems(): file.write(i +":\n"+ str(j)+"\n\n") file.write("________X Solution Vector, With distances in meters and directions in seconds ________\n\n") for i,j in Xdict.iteritems(): file.write(i +":\n"+ str(round(float(j),3))+"\n\n")
def saveToFileBowditch(self): ''' the bowditch needs to be setup such that the final coordinate is a known point, a single letter, then the reference will be in the next 2 rows, with a dash next to the single letter''' fileName = QFileDialog.getSaveFileName(self, "Open Points File", "", "Excel (*.xlsx)", "") dX,dY=bowditchAdjust(self.provisionals,self.control,self.obsOrder[-1][4:]) self.bowditch.setText("not completed yet.") sumDistance=0 for i,j in self.obs1.iteritems(): for p,t in j.iteritems(): if self.provisionals.has_key(p): sumDistance=sumDistance+t.distance dX=dX/sumDistance dY=dY/sumDistance fileName=str(fileName) workbook = xlsxwriter.Workbook(fileName) worksheet = workbook.add_worksheet() i=0 worksheet.write(0,0, 'Leg') worksheet.write(0,1, 'Dir/OrCorr./Dis') worksheet.write(0,2, 'Name') worksheet.write(0,3, 'Y') worksheet.write(0,4, 'X') worksheet.write(2,2, self.control[self.stationsOrder[0]].name) worksheet.write(2,3, self.control[self.stationsOrder[0]].y) worksheet.write(2,4, self.control[self.stationsOrder[0]].x) i+=4 temp=self.stationsOrder[0] soFar=0 format = workbook.add_format() format.set_underline() for nm3 in self.stationsOrder: for nm,ob in self.obs1[nm3].iteritems(): if self.provisionals.has_key(nm): worksheet.write(i,0, nm3+"-"+nm) worksheet.write(i,1, rad2dms(self.obs1[nm3][nm].direction)) worksheet.write(i,2, nm) worksheet.write(i,3, round(self.provisionals[nm].y,3)) worksheet.write(i,4, round(self.provisionals[nm].x,3)) i+=1 ldist=self.obs1[nm3][nm].distance soFar+=ldist worksheet.write(i,3,soFar*dY) worksheet.write(i,4,soFar*dX) i+=1 worksheet.write(i,1, str(round(self.obs1[nm3][nm].distance,2))+"m") worksheet.write(i,2, nm,format) worksheet.write(i,3, round(self.provisionals[nm].y+soFar*dY,2),format) worksheet.write(i,4, round(self.provisionals[nm].x+soFar*dX,2),format) i+=2 temp=nm workbook.close()