def createWave(self): """ Create the wave, using whatever starting point (basic, copy, function, etc) is necessary. """ # Check if the wave is unique in the application if not self._app.waves().goodWaveName(Util.getWidgetValue(self._ui.createWave_waveName)): warningMessage = QMessageBox() warningMessage.setWindowTitle("Error!") warningMessage.setText("The name you chose has already been used. Please enter a new name.") warningMessage.setIcon(QMessageBox.Critical) warningMessage.setStandardButtons(QMessageBox.Ok) warningMessage.setDefaultButton(QMessageBox.Ok) result = warningMessage.exec_() return False wave = Wave( Util.getWidgetValue(self._ui.createWave_waveName), Util.getWidgetValue(self._ui.createWave_dataType) ) # Check how the wave should be initially populated initialWaveDataTab = self._ui.waveDataStack.currentWidget().objectName() if initialWaveDataTab == "basicTab": # Basic wave. Need to determine the type basicWaveType = Util.getWidgetValue(self._ui.basicWaveType) if basicWaveType == "Blank": pass elif basicWaveType == "Index (starting at 0)": basicWaveLength = Util.getWidgetValue(self._ui.basicWaveLength) wave.extend(range(0, basicWaveLength)) elif basicWaveType == "Index (starting at 1)": basicWaveLength = Util.getWidgetValue(self._ui.basicWaveLength) wave.extend(range(1, basicWaveLength + 1)) elif initialWaveDataTab == "copyTab": # Copy the data from another wave originalWave = ( self._ui.copyWaveOriginalWave.model() .index(self._ui.copyWaveOriginalWave.currentIndex(), 0) .internalPointer() ) startingIndex = Util.getWidgetValue(self._ui.copyWaveStartingIndex) endingIndex = Util.getWidgetValue(self._ui.copyWaveEndingIndex) wave.extend(originalWave.data(startingIndex, endingIndex)) elif initialWaveDataTab == "functionTab": waveLength = Util.getWidgetValue(self._ui.functionWaveLength) functionString = Util.getWidgetValue(self._ui.functionEquation) data = self.parseFunction(waveLength, functionString) wave.extend(data) # Add wave to application self._app.waves().addWave(wave) # Reset certain ui fields self._ui.copyWaveOriginalWave.setCurrentIndex(0) self._ui.functionInsertWave.setCurrentIndex(0)
def importData(self): """Import data into the application as waves.""" # Check if the proposed wave name is acceptable validatedWaveName = Wave.validateWaveName(Util.getWidgetValue(self._ui.waveName)) if not self._app.waves().goodWaveName(validatedWaveName): badWaveNameMessage = QMessageBox() badWaveNameMessage.setText("Wave name is not allowed or already in use. Please change the wave name.") badWaveNameMessage.exec_() return False # Get data type and size uiDataType = Util.getWidgetValue(self._ui.dataType) uiByteOrder = Util.getWidgetValue(self._ui.byteOrder) dataType = self.dataTypes[uiDataType]['dtype'] dataTypeChar = self.dataTypes[uiDataType]['char'] numBytes = self.dataTypes[uiDataType]['numbytes'] byteOrder = self.byteOrders[uiByteOrder] # Load data fileName = Util.getWidgetValue(self._ui.fileName) if os.path.isfile(fileName): data = [] wave = Wave(str(validatedWaveName), dataType) self._app.waves().addWave(wave) fh = open(fileName, 'rb') binDatum = fh.read(numBytes) while binDatum != "": try: datum = struct.unpack(byteOrder + dataTypeChar, binDatum) wave.push(datum[0]) except: pass binDatum = fh.read(numBytes) # data = array.array(dataTypeChar) # numDataPoints = os.path.getsize(fileName) / data.itemsize # fh = open(fileName, 'rb') # data.fromfile(fh, numDataPoints) # # wave = Wave(str(validatedWaveName), dataType) # wave.replaceData(data) # self._app.waves().addWave(wave) # Close window self.window.hide()
def saveUi(self): newOptions = {} for option in self.textOptionsButton().getTextOptions().get().keys(): newOptions[option] = Util.getWidgetValue(self.getChild(option)) # If rotation is custom (i.e. an angle has been specified) then we need to # overwrite what was just added if Util.getWidgetValue(self.getChild('rotation')) == 'custom': newOptions['rotation'] = Util.getWidgetValue(self.getChild('rotationCustom')) self.textOptionsButton().setTextOptions(newOptions)
def exportData(self): fileName = Util.getWidgetValue(self._ui.fileName) if os.path.exists(fileName): if os.path.isfile(fileName): # Ask about overwriting warningMessage = QMessageBox() warningMessage.setWindowTitle("Warning!") warningMessage.setText("The filename you have chosen - " + str(fileName) + " - already exists.") warningMessage.setInformativeText("Do you want to overwrite the file?") warningMessage.setIcon(QMessageBox.Warning) warningMessage.setStandardButtons(QMessageBox.Yes | QMessageBox.No) warningMessage.setDefaultButton(QMessageBox.No) result = warningMessage.exec_() if result != QMessageBox.Yes: return False else: # Do not try to overwrite a directory or link return False # Get waves waveNames = self._ui.fileWavesListView.model().orderedWaveNames() with open(fileName, 'w') as fileHandle: if Util.getWidgetValue(self._ui.outputType) == 'Delimited': delimiterText = Util.getWidgetValue(self._ui.delimiterButtonGroup) if delimiterText == 'Comma': fileWriter = csv.writer(fileHandle, dialect="excel", delimiter=",") elif delimiterText == 'Tab': fileWriter = csv.writer(fileHandle, dialect="excel-tab") elif delimiterText == 'Other': fileWriter = csv.writer(fileHandle, dialect="excel", delimiter=Util.getWidgetValue(self._ui.delimitedOtherDelimiter)) else: fileWriter = csv.writer(fileHandle, dialect="excel", delimiter=",") dataDirection = Util.getWidgetValue(self._ui.dataDirectionButtonGroup) rows = [] for waveName in waveNames: wave = self._app.waves().wave(waveName) row = wave.data() row.insert(0, wave.name()) rows.append(row) if dataDirection == "Rows": fileWriter.writerows(rows) elif dataDirection == "Columns": # Transpose the rows into columns columns = map(lambda *row: ['' if elem is None else elem for elem in row], *rows) fileWriter.writerows(columns)
def modifyWave(self): """ Set the selected wave to have the currently-selected options. """ currentIndex = self._ui.modifyWave_selectWave.currentIndex() if currentIndex: wave = self._wavesListModel.waveByRow(self._ui.modifyWave_selectWave.currentIndex().row()) # Make sure the user wants to change the wave's name if wave.name() != Util.getWidgetValue(self._ui.modifyWave_waveName) and not self._app.waves().goodWaveName( Util.getWidgetValue(self._ui.modifyWave_waveName) ): warningMessage = QMessageBox() warningMessage.setWindowTitle("Error!") warningMessage.setText( "You are trying to change the wave name, but the one you have chosen has already been used. Please enter a new name." ) warningMessage.setIcon(QMessageBox.Critical) warningMessage.setStandardButtons(QMessageBox.Ok) warningMessage.setDefaultButton(QMessageBox.Ok) result = warningMessage.exec_() return False # Make sure the user wants to actually change the data type if wave.dataType() != Util.getWidgetValue(self._ui.modifyWave_dataType): warningMessage = QMessageBox() warningMessage.setWindowTitle("Warning!") warningMessage.setText( "If you change the data type, then you may lose data if it cannot be properly converted." ) warningMessage.setInformativeText("Are you sure you want to continue?") warningMessage.setIcon(QMessageBox.Warning) warningMessage.setStandardButtons(QMessageBox.Yes | QMessageBox.No) warningMessage.setDefaultButton(QMessageBox.No) result = warningMessage.exec_() if result != QMessageBox.Yes: return False # All warnings have been accepted, so we can continue with actually modifying the wave wave.setName(Util.getWidgetValue(self._ui.modifyWave_waveName)) wave.setDataType(Util.getWidgetValue(self._ui.modifyWave_dataType)) self._ui.modifyWave_selectWave.setCurrentIndex(currentIndex) return True
def changeFunction(self, newFunctionName): # Save parameters for old function self.saveParameterTable() #if self._currentFunction: # self._parameterTableData[self._currentFunction] = self.getCurrentParameterTable() # Now update _currentFunction to the function that is currently selected. # If this method was called because the user selected a different function, # then this will be modified. If it was called because the fit curve button # was pressed, then its value will not be changed. self._currentFunction = Util.getWidgetValue(self._ui.function) # Enter in parameters for new function # If there are previously user-entered values, then use them # else, if a wave is selected, then use that # else, use the initial values # Either way, if there are blank entries, then use initial values for them # Clear the table, but leave all the column headers for rowIndex in range(self._ui.parameterTable.rowCount()): self._ui.parameterTable.removeRow(0) parameters = [] # If there is saved data, use it if self._currentFunction in self._parameterTableData: parameters = self._parameterTableData[self._currentFunction] # If there aren't enough rows for all the parameters, extend with # initial values. This will also occur if no parameters had been saved. savedParametersLength = len(parameters) defaultParameters = self._parameterTableDefaults[self._currentFunction] if savedParametersLength < len(defaultParameters): parameters.extend(defaultParameters[len(parameters):]) # Use wave if requested by the user if Util.getWidgetValue(self._ui.useInitialValuesWave): # Convert from QString to str waveName = str(Util.getWidgetValue(self._ui.initialValuesWave)) if self._app.waves().wave(waveName) is None: # waveName is not a name of a wave pass else: waveData = self._app.waves().wave(waveName).data() for i in range(savedParametersLength, len(defaultParameters)): parameters[i][1] = waveData[i] self.writeParametersToTable(parameters)
def changeInitialValuesWaveFromCheckbox(self, checked): """ If the useInitialValuesWave checkbox is checked, then call changeInitialValuesWave. """ if checked: self.changeInitialValuesWave(str(Util.getWidgetValue(self._ui.initialValuesWave)))
def saveSettings(): name = Util.getWidgetValue(nameUi.name) name = name.strip() if name == "": failedMessage = QMessageBox(nameDialog) failedMessage.setText("Cannot use a blank name.") failedMessage.exec_() else: self._app.storedSettings()[self._widgetName].append([name, properties]) nameDialog.close()
def getCurrentUi(self): """ Take the current UI values and return them. """ currentProperties = {} for property in self.properties: currentProperties[property] = Util.getWidgetValue(self.getChild(property)) return currentProperties
def saveCurrentFigure(self): """ Save the current figure to a file. First we make sure that the active window has a figure in it. Then we ask the user for certain options to be set. Then we ask for the file to save the figure to. Then we save the file. """ Util.debug(2, "App.saveCurrentFigure", "Saving current Figure") currentWindow = self.ui.workspace.activeSubWindow() # Check if the active window has a figure in it if type(currentWindow).__name__ != "FigureSubWindow": notFigureMessage = QMessageBox() notFigureMessage.setText("The active window is not a figure, so you cannot save it as a figure.") notFigureMessage.exec_() return False # Ask user for user-configurable options figureOptionsDialog = QDialog() figureOptionsUi = Ui_SaveFigureOptionsDialog() figureOptionsUi.setupUi(figureOptionsDialog) figureOptionsSubWindow = self.ui.workspace.addSubWindow(figureOptionsDialog) figureOptionsResult = figureOptionsDialog.exec_() figureOptionsSubWindow.close() dpi = 100 orientation = "Landscape" if figureOptionsResult == QDialog.Accepted: dpi = Util.getWidgetValue(figureOptionsUi.dpi) orientation = Util.getWidgetValue(figureOptionsUi.orientation) else: return False # As user for the filename to save to fileName = QFileDialog.getSaveFileName(self.ui.workspace, "Save Figure", self.projectDirectory()) # Save the figure to the file currentWindow.widget().figure.savefig(str(fileName), dpi=dpi, orientation=orientation)
def csvFileSelector(self): """Button-lineedit link""" directory = os.path.dirname(Util.getWidgetValue(self._ui.csvFileName)) if not os.path.isdir(directory): directory = self._app.preferences.getInternal('projectDirectory') csvFile = str(QFileDialog.getOpenFileName(self._app.ui.workspace, "Select Data File", directory, "Comma Separated Values (*.csv);;All Files(*)")) if csvFile != "": return Util.setWidgetValue(self._ui.csvFileName, csvFile) return False
def fileSelector(self): """Button-lineedit link""" directory = os.path.dirname(Util.getWidgetValue(self._ui.fileName)) if not os.path.isdir(directory): directory = self._app.preferences.getInternal('projectDirectory') fileName = str(QFileDialog.getOpenFileName(self._app.ui.workspace, "Select Data File", directory, "Binary (*.bin *.dat);;All Files(*)")) if fileName != "": return Util.setWidgetValue(self._ui.fileName, fileName) return False
def changePolynomialDegree(self, newDegree): # If decreasing the degree, just remove the last entries # If increasing the degree, # If a wave is selected, then use that for the new values # else, use the initial values desiredNumRows = newDegree + 1 currentNumRows = self._ui.parameterTable.rowCount() if desiredNumRows == currentNumRows: # Nothing to do return # Set defaults rows = [] for d in range(desiredNumRows): rows.append(['p' + str(d), 1]) self._parameterTableDefaults['Polynomial'] = rows # Update table self._ui.parameterTable.setRowCount(desiredNumRows) if desiredNumRows < currentNumRows: # We are done, because no rows need to be edited return # Degree is being increased parameters = self._parameterTableDefaults['Polynomial'][currentNumRows:desiredNumRows] if Util.getWidgetValue(self._ui.useInitialValuesWave): # Convert from QString to str waveName = str(Util.getWidgetValue(self._ui.initialValuesWave)) if self._app.waves().wave(waveName) is None: # waveName is not a name of a wave pass else: waveData = self._app.waves().wave(waveName).data(currentNumRows, desiredNumRows) for index, value in enumerate(waveData): parameters[index][1] = value self.writeParametersToTable(parameters, currentNumRows)
def changeInitialValuesWave(self, waveName): # Use the wave for as many parameters as possible # if the wave is too long, then just use the first n values # if the wave is too short, then leave the current value in place # if there is no current value, then use the initial values if Util.getWidgetValue(self._ui.useInitialValuesWave): # Get the current values, with any undefined values using the initial values parameters = self.currentParametersBackedByDefaults() # Now get the wave values parameters = self.updateParametersListWithWave(parameters, waveName) # Set the table to the parameters self.writeParametersToTable(parameters)
def connectSlotsOnFunctionChange(self, newFunctionName): """ Disconnect slots dependent on which function is chosen. If polynomial function is chosen, connect slot to update parameter table on degree change. """ # Disconnect slots try: self._ui.polynomialDegree.valueChanged[int].disconnect(self.changePolynomialDegree) except: pass # Connect polynomial degree change if Util.getWidgetValue(self._ui.function) == 'Polynomial': self._ui.polynomialDegree.valueChanged[int].connect(self.changePolynomialDegree)
def importData(self): """Import data into the application as waves.""" dataTable = self._ui.data # Loop through all waves for col in range(dataTable.columnCount()): dataType = Util.getWidgetValue(dataTable.cellWidget(0, col)) wave = Wave(str(dataTable.item(1, col).text()), dataType) for row in range(2, dataTable.rowCount()): if dataTable.item(row, col): wave.push(str(dataTable.item(row, col).text())) else: wave.push('') self._app.waves().addWave(wave) # Close window self.clearTable() self.window.hide()
def createTable(self): """ Create the table. """ tableName = Util.getWidgetValue(self._ui.tableName) waves = self._tableWavesListModel.waves() if len(waves) == 0: warningMessage = QMessageBox() warningMessage.setWindowTitle("Problem!") warningMessage.setText("You must select at least one wave in order to create a table.") warningMessage.setIcon(QMessageBox.Critical) warningMessage.setStandardButtons(QMessageBox.Ok) warningMessage.setDefaultButton(QMessageBox.Ok) result = warningMessage.exec_() return False names = map(Wave.getName, waves) self._app.createTable(waves, tableName) self.closeWindow() return True
def fitPolynomial(self, xData, yData, weightData=None, outputWaves={}, outputOptions={}): # Get the degree of the polynomial the user wants to use degree = Util.getWidgetValue(self._ui.polynomialDegree) def polynomialFunction(p, x): # If x is a list, then val needs to be a list # If x is a number, then val needs to be a number if isinstance(x, list): val = numpy.array([p[0]] * len(x)) else: val = p[0] # Add x, x^2, x^3, etc entries for d in range(1, degree + 1): val += numpy.multiply(p[d], numpy.power(x, d)) return val parameterNames = self.parameterNames('Polynomial') initialValues = self.parameterInitialValues('Polynomial') if initialValues is None: initialValues = [1] * degree self.fitFunction(polynomialFunction, parameterNames, initialValues, xData, yData, weightData, outputWaves, outputOptions, 'Polynomial Fit')
def projectDirectorySelector(self): directory = QFileDialog.getExistingDirectory(self._app.ui.workspace, "Select Project Directory", Util.getWidgetValue(self._ui.projectDirectory)) if os.path.isdir(directory): return self.setUi('projectDirectory', directory) return False
def doFit(self): # save user-defined parameters self.saveParameterTable() # Get all waves that are selected before doing anything else # If any waves are created, as they are in the output tab section, # then the wave combo boxes are refreshed, and the previous selection # is lost xWaveName = Util.getWidgetValue(self._ui.xWave) yWaveName = Util.getWidgetValue(self._ui.yWave) weightWaveName = Util.getWidgetValue(self._ui.weightWave) interpolationDomainWaveName = Util.getWidgetValue(self._ui.interpolationWave) # Get data tab dataRangeStart = Util.getWidgetValue(self._ui.dataRangeStart) dataRangeEnd = Util.getWidgetValue(self._ui.dataRangeEnd) xWave = self._app.waves().wave(xWaveName) yWave = self._app.waves().wave(yWaveName) xLength = xWave.length() yLength = yWave.length() # Verify data range limits are valid if dataRangeStart > xLength or dataRangeStart > yLength: dataRangeStart = 0 if dataRangeEnd > xLength or dataRangeEnd > yLength: dataRangeEnd = min(xLength, yLength) - 1 xData = xWave.data(dataRangeStart, dataRangeEnd + 1) yData = yWave.data(dataRangeStart, dataRangeEnd + 1) # Get weights, if required by user if Util.getWidgetValue(self._ui.useWeights): weightWave = self._app.waves().wave(weightWaveName) weightLength = weightWave.length() weightData = weightWave.data(dataRangeStart, dataRangeEnd + 1) # If weighting inversely, invert the weights if Util.getWidgetValue(self._ui.weightIndirectly): weightData = [1./w if w != 0 else 0 for w in weightData] if len(weightData) != len(yData): print "The number of weight points is not the same as the number of y points." return 1 else: weightData = None # Get output tab outputOptions = {} outputWaves = {} outputOptions['createTable'] = Util.getWidgetValue(self._ui.createTable) outputOptions['outputParameters'] = Util.getWidgetValue(self._ui.outputParameters) if outputOptions['outputParameters']: outputOptions['saveLabels'] = Util.getWidgetValue(self._ui.saveLabels) # Create saveLabels wave if outputOptions['saveLabels']: saveLabelsDestination = self._app.waves().findGoodWaveName(Util.getWidgetValue(self._ui.saveLabelsDestination)) outputWaves['saveLabelsWave'] = Wave(saveLabelsDestination, 'String') self._app.waves().addWave(outputWaves['saveLabelsWave']) # Create parameter wave parameterDestination = self._app.waves().findGoodWaveName(Util.getWidgetValue(self._ui.parameterDestination)) outputWaves['parameterWave'] = Wave(parameterDestination, 'Decimal') self._app.waves().addWave(outputWaves['parameterWave']) outputOptions['outputInterpolation'] = Util.getWidgetValue(self._ui.outputInterpolation) if outputOptions['outputInterpolation']: # Create interpolation wave interpolationDestination = self._app.waves().findGoodWaveName(Util.getWidgetValue(self._ui.interpolationDestination)) outputWaves['interpolationDestinationWave'] = Wave(interpolationDestination, 'Decimal') self._app.waves().addWave(outputWaves['interpolationDestinationWave']) if Util.getWidgetValue(self._ui.useWaveForInterpolation): # Using an already-existing wave for the interpolation points. interpolationDomainWave = self._app.waves().wave(interpolationDomainWaveName) interpolationWaveRangeStart = Util.getWidgetValue(self._ui.interpolationWaveRangeStart) interpolationWaveRangeEnd = Util.getWidgetValue(self._ui.interpolationWaveRangeEnd) outputWaves['interpolationDomainWave'] = interpolationDomainWave # Start the wave with as many blanks as necessary in order to get the destination wave # to line up correctly with the domain wave, for easy plotting. outputWaves['interpolationDestinationWave'].extend([''] * interpolationWaveRangeStart) # Verify data range limits are valid interpolationDomainLength = interpolationDomainWave.length() if interpolationWaveRangeStart > interpolationDomainLength: interpolationWaveRangeStart = 0 if interpolationWaveRangeEnd > interpolationDomainLength: interpolationWaveRangeEnd = interpolationDomainLength - 1 outputOptions['interpolationDomainWaveData'] = interpolationDomainWave.data(interpolationWaveRangeStart, interpolationWaveRangeEnd + 1) else: # Creating a new wave based on a domain and number of points. customWaveName = Util.getWidgetValue(self._ui.interpolationCustomWaveName) customLowerLimit = float(Util.getWidgetValue(self._ui.interpolationCustomLowerLimit)) customUpperLimit = float(Util.getWidgetValue(self._ui.interpolationCustomUpperLimit)) customNumPoints = Util.getWidgetValue(self._ui.interpolationCustomNumPoints) outputOptions['interpolationDomainWaveData'] = numpy.linspace(customLowerLimit, customUpperLimit, customNumPoints, endpoint=True) interpolationDomainWaveName = self._app.waves().findGoodWaveName(customWaveName) outputWaves['interpolationDomainWave'] = Wave(interpolationDomainWaveName, 'Decimal', outputOptions['interpolationDomainWaveData']) self._app.waves().addWave(outputWaves['interpolationDomainWave']) outputOptions['saveResiduals'] = Util.getWidgetValue(self._ui.saveResiduals) if outputOptions['saveResiduals']: residualsDestination = self._app.waves().findGoodWaveName(Util.getWidgetValue(self._ui.residualsDestination)) outputWaves['residualsWave'] = Wave(residualsDestination, 'Decimal') self._app.waves().addWave(outputWaves['residualsWave']) # If the fit is not done to all the data in the wave, then we need to add blanks to the beginning # of the residual wave because the residuals will only be calculated for the part of the data that # was actually fit. outputWaves['residualsWave'].extend([''] * dataRangeStart) # Save the x wave, in case it is different from the interpolationDomainWave outputWaves['xWave'] = xWave # Determine the function and call the appropriate method functionName = Util.getWidgetValue(self._ui.function) if functionName == 'Polynomial': self.fitPolynomial(xData, yData, weightData, outputWaves, outputOptions) elif functionName == 'Sinusoid': self.fitSinusoid(xData, yData, weightData, outputWaves, outputOptions) elif functionName == 'Power Law': self.fitPowerLaw(xData, yData, weightData, outputWaves, outputOptions) elif functionName == 'Exponential': self.fitExponential(xData, yData, weightData, outputWaves, outputOptions) elif functionName == 'Logarithm': self.fitLogarithm(xData, yData, weightData, outputWaves, outputOptions) elif functionName == 'Gaussian': self.fitGaussian(xData, yData, weightData, outputWaves, outputOptions) elif functionName == 'Lorentzian': self.fitLorentzian(xData, yData, weightData, outputWaves, outputOptions)
def loadData(self): """Load data into the widget for viewing before importing into the application.""" # Block the cellChanged signal, because all the cells are going to be changed and we # are dealing with that in this method. self._ui.data.blockSignals(True) dataTable = self._ui.data self.clearTable() # Get data from file csvFile = Util.getWidgetValue(self._ui.csvFileName) if os.path.isfile(csvFile): rows = [] delimiterText = Util.getWidgetValue(self._ui.delimiterButtonGroup) if delimiterText == "Comma": rows = csv.reader(open(csvFile), dialect="excel", delimiter=",") elif delimiterText == "Tab": rows = csv.reader(open(csvFile), dialect="excel-tab") elif delimiterText == "Other": rows = csv.reader(open(csvFile), dialect="excel", delimiter=Util.getWidgetValue(self._ui.otherDelimiter)) else: rows = csv.reader(open(csvFile), dialect="excel", delimiter=",") for rownum, row in enumerate(rows): # Make sure the cells exist to enter the data into dataTable.insertRow(rownum) if len(row) > dataTable.columnCount(): for i in range(dataTable.columnCount(), len(row)): dataTable.insertColumn(dataTable.columnCount()) # Add this row to the table for colnum, item in enumerate(row): dataTable.setItem(rownum, colnum, QTableWidgetItem(item)) # Hide the QT default column header, since we cannot edit it easily dataTable.horizontalHeader().hide() # Add a row for setting the data type of each wave dataTable.insertRow(0) defaultType = Util.getWidgetValue(self._ui.defaultDataType) for col in range(dataTable.columnCount()): typeBox = QComboBox() typeBox.addItem("Integer") typeBox.addItem("Decimal") typeBox.addItem("String") Util.setWidgetValue(typeBox, defaultType) dataTable.setCellWidget(0, col, typeBox) # Potential wave names waveNamePrefix = Util.getWidgetValue(self._ui.waveNamePrefix) tempWaveNames = [] if Util.getWidgetValue(self._ui.useWaveNamePrefix): tempWaveNames = self._app.waves().findGoodWaveNames(dataTable.columnCount(), waveNamePrefix) else: tempWaveNames = self._app.waves().findGoodWaveNames(dataTable.columnCount()) # Wave names can either be generated or taken from the first row in the file if not Util.getWidgetValue(self._ui.firstRowWaveNames): # Generate headers dataTable.insertRow(1) # PyQt does not have QList support yet, so this is a hack to get around that for col,name in enumerate(tempWaveNames): dataTable.setItem(1, col, QTableWidgetItem(name)) else: # Use the first row of data, but check to see if there is text for each column # and if there is no text for a column, add in a tempWaveName entry for col in range(dataTable.columnCount()): if not dataTable.item(1, col) or str(dataTable.item(1, col).text()).strip() == "": dataTable.setItem(1, col, QTableWidgetItem(tempWaveNames.pop(0))) else: # For the names that came from the file, add the prefix specified by the user if Util.getWidgetValue(self._ui.useWaveNamePrefix): dataTable.item(1, col).setText(str(waveNamePrefix) + dataTable.item(1, col).text()) # Edit the name so that it could be valid (no spaces, etc). But it might # still be a duplicate. self.validateWaveNames() # Adjust the row headers so that they number correctly with the wave names in the first row rowLabels = QStringList("Type") rowLabels.append("Name") for row in range(1, dataTable.rowCount()): rowLabels.append(str(row)) dataTable.setVerticalHeaderLabels(rowLabels) # Verify that all wave names are acceptable for the app's waves object self.verifyGoodWaveNames() self._ui.data.blockSignals(False) # Resize rows and columns dataTable.resizeRowsToContents() dataTable.resizeColumnsToContents()
def getUi(self, variable): return Util.getWidgetValue(vars(self._ui)[variable])