diff --git a/qspectrumanalyzer/__main__.py b/qspectrumanalyzer/__main__.py index a160e99..780746d 100755 --- a/qspectrumanalyzer/__main__.py +++ b/qspectrumanalyzer/__main__.py @@ -5,7 +5,7 @@ import sys, signal, time from PyQt4 import QtCore, QtGui from qspectrumanalyzer.version import __version__ -from qspectrumanalyzer.backend import RtlPowerThread, RtlPowerFftwThread +from qspectrumanalyzer.backend import RtlPowerThread, RtlPowerFftwThread, SoapyPowerThread, RxPowerThread from qspectrumanalyzer.data import DataStorage from qspectrumanalyzer.plot import SpectrumPlotWidget, WaterfallPlotWidget from qspectrumanalyzer.utils import color_to_str, str_to_color @@ -30,17 +30,19 @@ class QSpectrumAnalyzerSettings(QtGui.QDialog, Ui_QSpectrumAnalyzerSettings): # Load settings settings = QtCore.QSettings() - self.executableEdit.setText(settings.value("rtl_power_executable", "rtl_power")) + self.executableEdit.setText(settings.value("executable", "soapy_power")) self.waterfallHistorySizeSpinBox.setValue(settings.value("waterfall_history_size", 100, int)) - self.deviceIndexSpinBox.setValue(settings.value("device_index", 0, int)) + self.deviceEdit.setText(settings.value("device", "")) self.sampleRateSpinBox.setValue(settings.value("sample_rate", 2560000, int)) - backend = settings.value("backend", "rtl_power") + backend = settings.value("backend", "soapy_power") + self.backendComboBox.blockSignals(True) i = self.backendComboBox.findText(backend) if i == -1: self.backendComboBox.setCurrentIndex(0) else: self.backendComboBox.setCurrentIndex(i) + self.backendComboBox.blockSignals(False) @QtCore.pyqtSlot() def on_executableButton_clicked(self): @@ -53,13 +55,14 @@ class QSpectrumAnalyzerSettings(QtGui.QDialog, Ui_QSpectrumAnalyzerSettings): def on_backendComboBox_currentIndexChanged(self, text): """Change executable when backend is changed""" self.executableEdit.setText(text) + self.deviceEdit.setText("") def accept(self): """Save settings when dialog is accepted""" settings = QtCore.QSettings() - settings.setValue("rtl_power_executable", self.executableEdit.text()) + settings.setValue("executable", self.executableEdit.text()) settings.setValue("waterfall_history_size", self.waterfallHistorySizeSpinBox.value()) - settings.setValue("device_index", self.deviceIndexSpinBox.value()) + settings.setValue("device", self.deviceEdit.text()) settings.setValue("sample_rate", self.sampleRateSpinBox.value()) settings.setValue("backend", self.backendComboBox.currentText()) QtGui.QDialog.accept(self) @@ -157,18 +160,18 @@ class QSpectrumAnalyzerMainWindow(QtGui.QMainWindow, Ui_QSpectrumAnalyzerMainWin # Link main spectrum plot to waterfall plot self.spectrumPlotWidget.plot.setXLink(self.waterfallPlotWidget.plot) - # Setup rtl_power thread and connect signals + # Setup power thread and connect signals self.prev_data_timestamp = None self.data_storage = None - self.rtl_power_thread = None - self.setup_rtl_power_thread() + self.power_thread = None + self.setup_power_thread() self.update_buttons() self.load_settings() - def setup_rtl_power_thread(self): - """Create rtl_power_thread and connect signals to slots""" - if self.rtl_power_thread: + def setup_power_thread(self): + """Create power_thread and connect signals to slots""" + if self.power_thread: self.stop() settings = QtCore.QSettings() @@ -183,14 +186,18 @@ class QSpectrumAnalyzerMainWindow(QtGui.QMainWindow, Ui_QSpectrumAnalyzerMainWin self.data_storage.peak_hold_max_updated.connect(self.spectrumPlotWidget.update_peak_hold_max) self.data_storage.peak_hold_min_updated.connect(self.spectrumPlotWidget.update_peak_hold_min) - backend = settings.value("backend", "rtl_power") - if backend == "rtl_power_fftw": - self.rtl_power_thread = RtlPowerFftwThread(self.data_storage) + backend = settings.value("backend", "soapy_power") + if backend == "soapy_power": + self.power_thread = SoapyPowerThread(self.data_storage) + elif backend == "rx_power": + self.power_thread = RxPowerThread(self.data_storage) + elif backend == "rtl_power_fftw": + self.power_thread = RtlPowerFftwThread(self.data_storage) else: - self.rtl_power_thread = RtlPowerThread(self.data_storage) + self.power_thread = RtlPowerThread(self.data_storage) - self.rtl_power_thread.rtlPowerStarted.connect(self.update_buttons) - self.rtl_power_thread.rtlPowerStopped.connect(self.update_buttons) + self.power_thread.powerThreadStarted.connect(self.update_buttons) + self.power_thread.powerThreadStopped.connect(self.update_buttons) def set_dock_size(self, dock, width, height): """Ugly hack for resizing QDockWidget (because it doesn't respect minimumSize / sizePolicy set in Designer) @@ -284,9 +291,9 @@ class QSpectrumAnalyzerMainWindow(QtGui.QMainWindow, Ui_QSpectrumAnalyzerMainWin def update_buttons(self): """Update state of control buttons""" - self.startButton.setEnabled(not self.rtl_power_thread.alive) - self.singleShotButton.setEnabled(not self.rtl_power_thread.alive) - self.stopButton.setEnabled(self.rtl_power_thread.alive) + self.startButton.setEnabled(not self.power_thread.alive) + self.singleShotButton.setEnabled(not self.power_thread.alive) + self.stopButton.setEnabled(self.power_thread.alive) def update_data(self, data_storage): """Update GUI when new data is received""" @@ -297,7 +304,7 @@ class QSpectrumAnalyzerMainWindow(QtGui.QMainWindow, Ui_QSpectrumAnalyzerMainWin self.show_status( self.tr("Frequency hops: {} | Sweep time: {:.2f} s | FPS: {:.2f}").format( - self.rtl_power_thread.params["hops"] or self.tr("N/A"), + self.power_thread.params["hops"] or self.tr("N/A"), sweep_time, 1 / sweep_time ), @@ -305,7 +312,7 @@ class QSpectrumAnalyzerMainWindow(QtGui.QMainWindow, Ui_QSpectrumAnalyzerMainWin ) def start(self, single_shot=False): - """Start rtl_power thread""" + """Start power thread""" settings = QtCore.QSettings() self.prev_data_timestamp = time.time() @@ -338,23 +345,23 @@ class QSpectrumAnalyzerMainWindow(QtGui.QMainWindow, Ui_QSpectrumAnalyzerMainWin self.spectrumPlotWidget.clear_average() self.spectrumPlotWidget.clear_persistence() - if not self.rtl_power_thread.alive: - self.rtl_power_thread.setup(float(self.startFreqSpinBox.value()), - float(self.stopFreqSpinBox.value()), - float(self.binSizeSpinBox.value()), - interval=float(self.intervalSpinBox.value()), - gain=int(self.gainSpinBox.value()), - ppm=int(self.ppmSpinBox.value()), - crop=int(self.cropSpinBox.value()) / 100.0, - single_shot=single_shot, - device_index=settings.value("device_index", 0, int), - sample_rate=settings.value("sample_rate", 2560000, int)) - self.rtl_power_thread.start() + if not self.power_thread.alive: + self.power_thread.setup(float(self.startFreqSpinBox.value()), + float(self.stopFreqSpinBox.value()), + float(self.binSizeSpinBox.value()), + interval=float(self.intervalSpinBox.value()), + gain=int(self.gainSpinBox.value()), + ppm=int(self.ppmSpinBox.value()), + crop=int(self.cropSpinBox.value()) / 100.0, + single_shot=single_shot, + device=settings.value("device", ""), + sample_rate=settings.value("sample_rate", 2560000, int)) + self.power_thread.start() def stop(self): - """Stop rtl_power thread""" - if self.rtl_power_thread.alive: - self.rtl_power_thread.stop() + """Stop power thread""" + if self.power_thread.alive: + self.power_thread.stop() @QtCore.pyqtSlot() def on_startButton_clicked(self): @@ -458,7 +465,7 @@ class QSpectrumAnalyzerMainWindow(QtGui.QMainWindow, Ui_QSpectrumAnalyzerMainWin def on_action_Settings_triggered(self): dialog = QSpectrumAnalyzerSettings(self) if dialog.exec_(): - self.setup_rtl_power_thread() + self.setup_power_thread() @QtCore.pyqtSlot() def on_action_About_triggered(self): diff --git a/qspectrumanalyzer/backend.py b/qspectrumanalyzer/backend.py index 206c910..9c7d1be 100644 --- a/qspectrumanalyzer/backend.py +++ b/qspectrumanalyzer/backend.py @@ -1,13 +1,13 @@ -import subprocess, math, pprint +import subprocess, math, pprint, re import numpy as np from PyQt4 import QtCore -class RtlPowerBaseThread(QtCore.QThread): - """Thread which runs rtl_power process""" - rtlPowerStarted = QtCore.pyqtSignal() - rtlPowerStopped = QtCore.pyqtSignal() +class BasePowerThread(QtCore.QThread): + """Thread which runs Power Spectral Density acquisition and calculation process""" + powerThreadStarted = QtCore.pyqtSignal() + powerThreadStopped = QtCore.pyqtSignal() def __init__(self, data_storage, parent=None): super().__init__(parent) @@ -16,22 +16,22 @@ class RtlPowerBaseThread(QtCore.QThread): self.process = None def stop(self): - """Stop rtl_power thread""" + """Stop power process thread""" self.process_stop() self.alive = False self.wait() def setup(self, start_freq, stop_freq, bin_size, interval=10.0, gain=-1, - ppm=0, crop=0, single_shot=False, device_index=0, sample_rate=2560000): - """Setup rtl_power params""" + ppm=0, crop=0, single_shot=False, device=0, sample_rate=2560000): + """Setup power process params""" raise NotImplementedError def process_start(self): - """Start rtl_power process""" + """Start power process""" raise NotImplementedError def process_stop(self): - """Terminate rtl_power process""" + """Terminate power process""" if self.process: try: self.process.terminate() @@ -41,14 +41,14 @@ class RtlPowerBaseThread(QtCore.QThread): self.process = None def parse_output(self, line): - """Parse one line of output from rtl_power""" + """Parse one line of output from power process""" raise NotImplementedError def run(self): - """Rtl_power thread main loop""" + """Power process thread main loop""" self.process_start() self.alive = True - self.rtlPowerStarted.emit() + self.powerThreadStarted.emit() for line in self.process.stdout: if not self.alive: @@ -57,20 +57,102 @@ class RtlPowerBaseThread(QtCore.QThread): self.process_stop() self.alive = False - self.rtlPowerStopped.emit() + self.powerThreadStopped.emit() -class RtlPowerThread(RtlPowerBaseThread): +class RxPowerThread(BasePowerThread): + """Thread which runs rx_power process""" + def setup(self, start_freq, stop_freq, bin_size, interval=10.0, gain=-1, + ppm=0, crop=0, single_shot=False, device=0, sample_rate=2560000): + """Setup rx_power params""" + self.params = { + "start_freq": start_freq, + "stop_freq": stop_freq, + "bin_size": bin_size, + "interval": interval, + "device": device, + "hops": 0, + "gain": gain, + "ppm": ppm, + "crop": crop, + "single_shot": single_shot + } + self.databuffer = {} + self.last_timestamp = "" + + print("rx_power params:") + pprint.pprint(self.params) + print() + + def process_start(self): + """Start rx_power process""" + if not self.process and self.params: + settings = QtCore.QSettings() + cmdline = [ + settings.value("executable", "rx_power"), + "-f", "{}M:{}M:{}k".format(self.params["start_freq"], + self.params["stop_freq"], + self.params["bin_size"]), + "-i", "{}".format(self.params["interval"]), + "-d", "{}".format(self.params["device"]), + "-p", "{}".format(self.params["ppm"]), + "-c", "{}".format(self.params["crop"]) + ] + + if self.params["gain"] >= 0: + cmdline.extend(["-g", "{}".format(self.params["gain"])]) + if self.params["single_shot"]: + cmdline.append("-1") + + self.process = subprocess.Popen(cmdline, stdout=subprocess.PIPE, + universal_newlines=True) + + def parse_output(self, line): + """Parse one line of output from rx_power""" + line = [col.strip() for col in line.split(",")] + timestamp = " ".join(line[:2]) + start_freq = int(line[2]) + stop_freq = int(line[3]) + step = float(line[4]) + samples = float(line[5]) + + x_axis = list(np.arange(start_freq, stop_freq, step)) + y_axis = [float(y) for y in line[6:]] + if len(x_axis) != len(y_axis): + print("ERROR: len(x_axis) != len(y_axis), use newer version of rx_power!") + if len(x_axis) > len(y_axis): + print("Trimming x_axis...") + x_axis = x_axis[:len(y_axis)] + else: + print("Trimming y_axis...") + y_axis = y_axis[:len(x_axis)] + + if timestamp != self.last_timestamp: + self.last_timestamp = timestamp + self.databuffer = {"timestamp": timestamp, + "x": x_axis, + "y": y_axis} + else: + self.databuffer["x"].extend(x_axis) + self.databuffer["y"].extend(y_axis) + + # This have to be stupid like this to be compatible with old broken version of rx_power. Right way is: + # if stop_freq == self.params["stop_freq"] * 1e6: + if stop_freq > (self.params["stop_freq"] * 1e6) - step: + self.data_storage.update(self.databuffer) + + +class RtlPowerThread(BasePowerThread): """Thread which runs rtl_power process""" def setup(self, start_freq, stop_freq, bin_size, interval=10.0, gain=-1, - ppm=0, crop=0, single_shot=False, device_index=0, sample_rate=2560000): + ppm=0, crop=0, single_shot=False, device=0, sample_rate=2560000): """Setup rtl_power params""" self.params = { "start_freq": start_freq, "stop_freq": stop_freq, "bin_size": bin_size, "interval": interval, - "device_index": device_index, + "device": device, "hops": 0, "gain": gain, "ppm": ppm, @@ -89,12 +171,12 @@ class RtlPowerThread(RtlPowerBaseThread): if not self.process and self.params: settings = QtCore.QSettings() cmdline = [ - settings.value("rtl_power_executable", "rtl_power"), + settings.value("executable", "rtl_power"), "-f", "{}M:{}M:{}k".format(self.params["start_freq"], self.params["stop_freq"], self.params["bin_size"]), "-i", "{}".format(self.params["interval"]), - "-d", "{}".format(self.params["device_index"]), + "-d", "{}".format(self.params["device"]), "-p", "{}".format(self.params["ppm"]), "-c", "{}".format(self.params["crop"]) ] @@ -142,10 +224,10 @@ class RtlPowerThread(RtlPowerBaseThread): self.data_storage.update(self.databuffer) -class RtlPowerFftwThread(RtlPowerBaseThread): +class RtlPowerFftwThread(BasePowerThread): """Thread which runs rtl_power_fftw process""" def setup(self, start_freq, stop_freq, bin_size, interval=10.0, gain=-1, - ppm=0, crop=0, single_shot=False, device_index=0, sample_rate=2560000): + ppm=0, crop=0, single_shot=False, device=0, sample_rate=2560000): """Setup rtl_power_fftw params""" crop = crop * 100 overlap = crop * 2 @@ -160,7 +242,7 @@ class RtlPowerFftwThread(RtlPowerBaseThread): "start_freq": start_freq, "stop_freq": stop_freq, "freq_range": freq_range, - "device_index": device_index, + "device": device, "sample_rate": sample_rate, "bin_size": bin_size, "bins": bins, @@ -197,12 +279,12 @@ class RtlPowerFftwThread(RtlPowerBaseThread): if not self.process and self.params: settings = QtCore.QSettings() cmdline = [ - settings.value("rtl_power_executable", "rtl_power_fftw"), + settings.value("executable", "rtl_power_fftw"), "-f", "{}M:{}M".format(self.params["start_freq"], self.params["stop_freq"]), "-b", "{}".format(self.params["bins"]), "-t", "{}".format(self.params["time"]), - "-d", "{}".format(self.params["device_index"]), + "-d", "{}".format(self.params["device"]), "-r", "{}".format(self.params["sample_rate"]), "-p", "{}".format(self.params["ppm"]), ] @@ -267,3 +349,104 @@ class RtlPowerFftwThread(RtlPowerBaseThread): pass self.prev_line = line + + +class SoapyPowerThread(BasePowerThread): + """Thread which runs soapy_power process""" + re_two_floats = re.compile(r'^[-+\d.eE]+\s+[-+\d.eE]+$') + + def setup(self, start_freq, stop_freq, bin_size, interval=10.0, gain=-1, + ppm=0, crop=0, single_shot=False, device="", sample_rate=2560000): + """Setup soapy_power params""" + self.params = { + "start_freq": start_freq, + "stop_freq": stop_freq, + "device": device, + "sample_rate": sample_rate, + "bin_size": bin_size, + "interval": interval, + "hops": 0, + "gain": gain * 10, + "ppm": ppm, + "crop": crop * 100, + "single_shot": single_shot + } + self.databuffer = {"timestamp": [], "x": [], "y": []} + self.databuffer_hop = {"timestamp": [], "x": [], "y": []} + self.hop = 0 + self.run = 0 + self.prev_line = "" + + print("soapy_power params:") + pprint.pprint(self.params) + print() + + def process_start(self): + """Start soapy_power process""" + if not self.process and self.params: + settings = QtCore.QSettings() + cmdline = [ + settings.value("executable", "soapy_power"), + "-f", "{}M:{}M".format(self.params["start_freq"], + self.params["stop_freq"]), + "-B", "{}k".format(self.params["bin_size"]), + "-T", "{}".format(self.params["interval"]), + "-d", "{}".format(self.params["device"]), + "-r", "{}".format(self.params["sample_rate"]), + "-p", "{}".format(self.params["ppm"]), + ] + + if self.params["gain"] >= 0: + cmdline.extend(["-g", "{}".format(self.params["gain"])]) + if self.params["crop"] > 0: + cmdline.extend(["-k", "{}".format(self.params["crop"])]) + if not self.params["single_shot"]: + cmdline.append("-c") + + self.process = subprocess.Popen(cmdline, stdout=subprocess.PIPE, + universal_newlines=True) + + def parse_output(self, line): + """Parse one line of output from soapy_power""" + line = line.strip() + + # One empty line => new hop + if not line and self.prev_line: + self.hop += 1 + print(' => HOP:', self.hop) + self.databuffer["x"].extend(self.databuffer_hop["x"]) + self.databuffer["y"].extend(self.databuffer_hop["y"]) + self.databuffer_hop = {"timestamp": [], "x": [], "y": []} + + # Two empty lines => new set + elif not line and not self.prev_line: + self.hop = 0 + self.run += 1 + print(' * RUN:', self.run) + self.data_storage.update(self.databuffer) + self.databuffer = {"timestamp": [], "x": [], "y": []} + + # Get timestamp for new hop and set + elif line.startswith("# Acquisition start:"): + timestamp = line.split(":", 1)[1].strip() + if not self.databuffer_hop["timestamp"]: + self.databuffer_hop["timestamp"] = timestamp + if not self.databuffer["timestamp"]: + self.databuffer["timestamp"] = timestamp + + # Skip other comments + elif line.startswith("#"): + pass + + # Parse frequency and power + elif self.re_two_floats.match(line): + try: + freq, power = line.split() + except ValueError: + return + + freq, power = float(freq), float(power) + self.databuffer_hop["x"].append(freq) + self.databuffer_hop["y"].append(power) + + self.prev_line = line diff --git a/qspectrumanalyzer/languages/qspectrumanalyzer_cs.ts b/qspectrumanalyzer/languages/qspectrumanalyzer_cs.ts index a647333..90c721e 100644 --- a/qspectrumanalyzer/languages/qspectrumanalyzer_cs.ts +++ b/qspectrumanalyzer/languages/qspectrumanalyzer_cs.ts @@ -3,37 +3,37 @@ QSpectrumAnalyzerColors - + Colors - QSpectrumAnalyzer - + Main curve color: - + ... - + Average color: - + Persistence color: - + Max. peak hold color: - + Min. peak hold color: @@ -41,182 +41,182 @@ QSpectrumAnalyzerMainWindow - + QSpectrumAnalyzer - + Settings - + MHz - + kHz - + auto - + Frequency - + Controls - + Levels - + QSpectrumAnalyzer {} - + &File - + &Help - + &Start - + S&top - + Si&ngle shot - + &Settings... - + &Quit - + Ctrl+Q - + &About - + Interval [s]: - + Gain [dB]: - + Corr. [ppm]: - + Crop [%]: - + Start: - + Stop: - + Bin size: - + Smoothing - + ... - + N/A - + About - QSpectrumAnalyzer - + Persistence - + Average - + Colors... - + Main curve - + Frequency hops: {} | Sweep time: {:.2f} s | FPS: {:.2f} - + Max. hold - + Min. hold @@ -224,27 +224,27 @@ QSpectrumAnalyzerPersistence - + Persistence - QSpectrumAnalyzer - + Persistence length: - + Decay function: - + linear - + exponential @@ -252,95 +252,105 @@ QSpectrumAnalyzerSettings - + rtl_power - + ... - + rtl_power_fftw - + &Backend: - + E&xecutable: - + &Waterfall history size: - + Sa&mple rate: - + Select executable - QSpectrumAnalyzer - + Settings - QSpectrumAnalyzer - - &Device index: + + soapy_power + + + + + Device: + + + + + rx_power QSpectrumAnalyzerSmooth - + &Window function: - + rectangular - + hanning - + hamming - + bartlett - + blackman - + Window len&gth: - + Smoothing - QSpectrumAnalyzer diff --git a/qspectrumanalyzer/plot.py b/qspectrumanalyzer/plot.py index e9fbd55..4fb284a 100644 --- a/qspectrumanalyzer/plot.py +++ b/qspectrumanalyzer/plot.py @@ -107,7 +107,7 @@ class SpectrumPlotWidget: """Get alpha value for persistence curve (linear decay)""" return (-x / length) + 1 - def decay_exponential(self, x, length, const=1/3): + def decay_exponential(self, x, length, const=1 / 3): """Get alpha value for persistence curve (exponential decay)""" return math.e**(-x / (length * const)) @@ -236,6 +236,7 @@ class SpectrumPlotWidget: self.plot.removeItem(curve) self.create_persistence_curves() + class WaterfallPlotWidget: """Waterfall plot""" def __init__(self, layout, histogram_layout=None): diff --git a/qspectrumanalyzer/qspectrumanalyzer_settings.ui b/qspectrumanalyzer/qspectrumanalyzer_settings.ui index 2f00976..1ae149c 100644 --- a/qspectrumanalyzer/qspectrumanalyzer_settings.ui +++ b/qspectrumanalyzer/qspectrumanalyzer_settings.ui @@ -6,8 +6,8 @@ 0 0 - 325 - 259 + 420 + 255 @@ -30,7 +30,12 @@ - rtl_power + soapy_power + + + + + rx_power @@ -38,6 +43,11 @@ rtl_power_fftw + + + rtl_power + + @@ -55,7 +65,7 @@ - rtl_power + soapy_power @@ -69,52 +79,19 @@ - + - &Waterfall history size: + Device: - waterfallHistorySizeSpinBox + deviceEdit - - - 1 - - - 10000000 - - - 100 - - + - - - &Device index: - - - deviceIndexSpinBox - - - - - - - 0 - - - 99 - - - 0 - - - - Sa&mple rate: @@ -124,7 +101,7 @@ - + 0 @@ -140,6 +117,29 @@ + + + + &Waterfall history size: + + + waterfallHistorySizeSpinBox + + + + + + + 1 + + + 10000000 + + + 100 + + + @@ -171,9 +171,9 @@ backendComboBox executableEdit executableButton - waterfallHistorySizeSpinBox - deviceIndexSpinBox + deviceEdit sampleRateSpinBox + waterfallHistorySizeSpinBox buttonBox @@ -185,8 +185,8 @@ accept() - 236 - 252 + 242 + 248 157 @@ -201,8 +201,8 @@ reject() - 304 - 252 + 310 + 248 286 diff --git a/qspectrumanalyzer/ui_qspectrumanalyzer.py b/qspectrumanalyzer/ui_qspectrumanalyzer.py index db0ed27..1a76881 100644 --- a/qspectrumanalyzer/ui_qspectrumanalyzer.py +++ b/qspectrumanalyzer/ui_qspectrumanalyzer.py @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 'qspectrumanalyzer/qspectrumanalyzer.ui' # -# Created by: PyQt4 UI code generator 4.11.4 +# Created by: PyQt4 UI code generator 4.12 # # WARNING! All changes made in this file will be lost! @@ -77,6 +77,7 @@ class Ui_QSpectrumAnalyzerMainWindow(object): self.controlsDockWidgetContents = QtGui.QWidget() self.controlsDockWidgetContents.setObjectName(_fromUtf8("controlsDockWidgetContents")) self.gridLayout_2 = QtGui.QGridLayout(self.controlsDockWidgetContents) + self.gridLayout_2.setMargin(0) self.gridLayout_2.setObjectName(_fromUtf8("gridLayout_2")) self.startButton = QtGui.QPushButton(self.controlsDockWidgetContents) self.startButton.setObjectName(_fromUtf8("startButton")) @@ -104,6 +105,7 @@ class Ui_QSpectrumAnalyzerMainWindow(object): self.frequencyDockWidgetContents.setObjectName(_fromUtf8("frequencyDockWidgetContents")) self.formLayout = QtGui.QFormLayout(self.frequencyDockWidgetContents) self.formLayout.setFieldGrowthPolicy(QtGui.QFormLayout.ExpandingFieldsGrow) + self.formLayout.setMargin(0) self.formLayout.setObjectName(_fromUtf8("formLayout")) self.label_2 = QtGui.QLabel(self.frequencyDockWidgetContents) self.label_2.setObjectName(_fromUtf8("label_2")) @@ -167,6 +169,7 @@ class Ui_QSpectrumAnalyzerMainWindow(object): self.settingsDockWidgetContents = QtGui.QWidget() self.settingsDockWidgetContents.setObjectName(_fromUtf8("settingsDockWidgetContents")) self.gridLayout = QtGui.QGridLayout(self.settingsDockWidgetContents) + self.gridLayout.setMargin(0) self.gridLayout.setObjectName(_fromUtf8("gridLayout")) self.label_4 = QtGui.QLabel(self.settingsDockWidgetContents) self.label_4.setObjectName(_fromUtf8("label_4")) @@ -248,6 +251,7 @@ class Ui_QSpectrumAnalyzerMainWindow(object): self.levelsDockWidgetContents = QtGui.QWidget() self.levelsDockWidgetContents.setObjectName(_fromUtf8("levelsDockWidgetContents")) self.verticalLayout_6 = QtGui.QVBoxLayout(self.levelsDockWidgetContents) + self.verticalLayout_6.setMargin(0) self.verticalLayout_6.setObjectName(_fromUtf8("verticalLayout_6")) self.histogramPlotLayout = GraphicsLayoutWidget(self.levelsDockWidgetContents) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Ignored, QtGui.QSizePolicy.Expanding) diff --git a/qspectrumanalyzer/ui_qspectrumanalyzer_colors.py b/qspectrumanalyzer/ui_qspectrumanalyzer_colors.py index 4c691e1..de7e249 100644 --- a/qspectrumanalyzer/ui_qspectrumanalyzer_colors.py +++ b/qspectrumanalyzer/ui_qspectrumanalyzer_colors.py @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 'qspectrumanalyzer/qspectrumanalyzer_colors.ui' # -# Created by: PyQt4 UI code generator 4.11.4 +# Created by: PyQt4 UI code generator 4.12 # # WARNING! All changes made in this file will be lost! diff --git a/qspectrumanalyzer/ui_qspectrumanalyzer_persistence.py b/qspectrumanalyzer/ui_qspectrumanalyzer_persistence.py index 38fb932..9d5a46d 100644 --- a/qspectrumanalyzer/ui_qspectrumanalyzer_persistence.py +++ b/qspectrumanalyzer/ui_qspectrumanalyzer_persistence.py @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 'qspectrumanalyzer/qspectrumanalyzer_persistence.ui' # -# Created by: PyQt4 UI code generator 4.11.4 +# Created by: PyQt4 UI code generator 4.12 # # WARNING! All changes made in this file will be lost! diff --git a/qspectrumanalyzer/ui_qspectrumanalyzer_settings.py b/qspectrumanalyzer/ui_qspectrumanalyzer_settings.py index 2c34180..b14979e 100644 --- a/qspectrumanalyzer/ui_qspectrumanalyzer_settings.py +++ b/qspectrumanalyzer/ui_qspectrumanalyzer_settings.py @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 'qspectrumanalyzer/qspectrumanalyzer_settings.ui' # -# Created by: PyQt4 UI code generator 4.11.4 +# Created by: PyQt4 UI code generator 4.12 # # WARNING! All changes made in this file will be lost! @@ -25,7 +25,7 @@ except AttributeError: class Ui_QSpectrumAnalyzerSettings(object): def setupUi(self, QSpectrumAnalyzerSettings): QSpectrumAnalyzerSettings.setObjectName(_fromUtf8("QSpectrumAnalyzerSettings")) - QSpectrumAnalyzerSettings.resize(325, 259) + QSpectrumAnalyzerSettings.resize(420, 255) self.verticalLayout = QtGui.QVBoxLayout(QSpectrumAnalyzerSettings) self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) self.formLayout = QtGui.QFormLayout() @@ -37,6 +37,8 @@ class Ui_QSpectrumAnalyzerSettings(object): self.backendComboBox.setObjectName(_fromUtf8("backendComboBox")) self.backendComboBox.addItem(_fromUtf8("")) self.backendComboBox.addItem(_fromUtf8("")) + self.backendComboBox.addItem(_fromUtf8("")) + self.backendComboBox.addItem(_fromUtf8("")) self.formLayout.setWidget(0, QtGui.QFormLayout.FieldRole, self.backendComboBox) self.label = QtGui.QLabel(QSpectrumAnalyzerSettings) self.label.setObjectName(_fromUtf8("label")) @@ -50,34 +52,31 @@ class Ui_QSpectrumAnalyzerSettings(object): self.executableButton.setObjectName(_fromUtf8("executableButton")) self.horizontalLayout.addWidget(self.executableButton) self.formLayout.setLayout(1, QtGui.QFormLayout.FieldRole, self.horizontalLayout) - self.label_2 = QtGui.QLabel(QSpectrumAnalyzerSettings) - self.label_2.setObjectName(_fromUtf8("label_2")) - self.formLayout.setWidget(2, QtGui.QFormLayout.LabelRole, self.label_2) - self.waterfallHistorySizeSpinBox = QtGui.QSpinBox(QSpectrumAnalyzerSettings) - self.waterfallHistorySizeSpinBox.setMinimum(1) - self.waterfallHistorySizeSpinBox.setMaximum(10000000) - self.waterfallHistorySizeSpinBox.setProperty("value", 100) - self.waterfallHistorySizeSpinBox.setObjectName(_fromUtf8("waterfallHistorySizeSpinBox")) - self.formLayout.setWidget(2, QtGui.QFormLayout.FieldRole, self.waterfallHistorySizeSpinBox) self.label_5 = QtGui.QLabel(QSpectrumAnalyzerSettings) self.label_5.setObjectName(_fromUtf8("label_5")) - self.formLayout.setWidget(3, QtGui.QFormLayout.LabelRole, self.label_5) - self.deviceIndexSpinBox = QtGui.QSpinBox(QSpectrumAnalyzerSettings) - self.deviceIndexSpinBox.setMinimum(0) - self.deviceIndexSpinBox.setMaximum(99) - self.deviceIndexSpinBox.setProperty("value", 0) - self.deviceIndexSpinBox.setObjectName(_fromUtf8("deviceIndexSpinBox")) - self.formLayout.setWidget(3, QtGui.QFormLayout.FieldRole, self.deviceIndexSpinBox) + self.formLayout.setWidget(2, QtGui.QFormLayout.LabelRole, self.label_5) + self.deviceEdit = QtGui.QLineEdit(QSpectrumAnalyzerSettings) + self.deviceEdit.setObjectName(_fromUtf8("deviceEdit")) + self.formLayout.setWidget(2, QtGui.QFormLayout.FieldRole, self.deviceEdit) self.label_4 = QtGui.QLabel(QSpectrumAnalyzerSettings) self.label_4.setObjectName(_fromUtf8("label_4")) - self.formLayout.setWidget(4, QtGui.QFormLayout.LabelRole, self.label_4) + self.formLayout.setWidget(3, QtGui.QFormLayout.LabelRole, self.label_4) self.sampleRateSpinBox = QtGui.QSpinBox(QSpectrumAnalyzerSettings) self.sampleRateSpinBox.setMinimum(0) self.sampleRateSpinBox.setMaximum(25000000) self.sampleRateSpinBox.setSingleStep(10000) self.sampleRateSpinBox.setProperty("value", 2560000) self.sampleRateSpinBox.setObjectName(_fromUtf8("sampleRateSpinBox")) - self.formLayout.setWidget(4, QtGui.QFormLayout.FieldRole, self.sampleRateSpinBox) + self.formLayout.setWidget(3, QtGui.QFormLayout.FieldRole, self.sampleRateSpinBox) + self.label_2 = QtGui.QLabel(QSpectrumAnalyzerSettings) + self.label_2.setObjectName(_fromUtf8("label_2")) + self.formLayout.setWidget(4, QtGui.QFormLayout.LabelRole, self.label_2) + self.waterfallHistorySizeSpinBox = QtGui.QSpinBox(QSpectrumAnalyzerSettings) + self.waterfallHistorySizeSpinBox.setMinimum(1) + self.waterfallHistorySizeSpinBox.setMaximum(10000000) + self.waterfallHistorySizeSpinBox.setProperty("value", 100) + self.waterfallHistorySizeSpinBox.setObjectName(_fromUtf8("waterfallHistorySizeSpinBox")) + self.formLayout.setWidget(4, QtGui.QFormLayout.FieldRole, self.waterfallHistorySizeSpinBox) self.verticalLayout.addLayout(self.formLayout) spacerItem = QtGui.QSpacerItem(20, 21, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) self.verticalLayout.addItem(spacerItem) @@ -88,9 +87,9 @@ class Ui_QSpectrumAnalyzerSettings(object): self.verticalLayout.addWidget(self.buttonBox) self.label_3.setBuddy(self.backendComboBox) self.label.setBuddy(self.executableEdit) - self.label_2.setBuddy(self.waterfallHistorySizeSpinBox) - self.label_5.setBuddy(self.deviceIndexSpinBox) + self.label_5.setBuddy(self.deviceEdit) self.label_4.setBuddy(self.sampleRateSpinBox) + self.label_2.setBuddy(self.waterfallHistorySizeSpinBox) self.retranslateUi(QSpectrumAnalyzerSettings) QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), QSpectrumAnalyzerSettings.accept) @@ -98,20 +97,22 @@ class Ui_QSpectrumAnalyzerSettings(object): QtCore.QMetaObject.connectSlotsByName(QSpectrumAnalyzerSettings) QSpectrumAnalyzerSettings.setTabOrder(self.backendComboBox, self.executableEdit) QSpectrumAnalyzerSettings.setTabOrder(self.executableEdit, self.executableButton) - QSpectrumAnalyzerSettings.setTabOrder(self.executableButton, self.waterfallHistorySizeSpinBox) - QSpectrumAnalyzerSettings.setTabOrder(self.waterfallHistorySizeSpinBox, self.deviceIndexSpinBox) - QSpectrumAnalyzerSettings.setTabOrder(self.deviceIndexSpinBox, self.sampleRateSpinBox) - QSpectrumAnalyzerSettings.setTabOrder(self.sampleRateSpinBox, self.buttonBox) + QSpectrumAnalyzerSettings.setTabOrder(self.executableButton, self.deviceEdit) + QSpectrumAnalyzerSettings.setTabOrder(self.deviceEdit, self.sampleRateSpinBox) + QSpectrumAnalyzerSettings.setTabOrder(self.sampleRateSpinBox, self.waterfallHistorySizeSpinBox) + QSpectrumAnalyzerSettings.setTabOrder(self.waterfallHistorySizeSpinBox, self.buttonBox) def retranslateUi(self, QSpectrumAnalyzerSettings): QSpectrumAnalyzerSettings.setWindowTitle(_translate("QSpectrumAnalyzerSettings", "Settings - QSpectrumAnalyzer", None)) self.label_3.setText(_translate("QSpectrumAnalyzerSettings", "&Backend:", None)) - self.backendComboBox.setItemText(0, _translate("QSpectrumAnalyzerSettings", "rtl_power", None)) - self.backendComboBox.setItemText(1, _translate("QSpectrumAnalyzerSettings", "rtl_power_fftw", None)) + self.backendComboBox.setItemText(0, _translate("QSpectrumAnalyzerSettings", "soapy_power", None)) + self.backendComboBox.setItemText(1, _translate("QSpectrumAnalyzerSettings", "rx_power", None)) + self.backendComboBox.setItemText(2, _translate("QSpectrumAnalyzerSettings", "rtl_power_fftw", None)) + self.backendComboBox.setItemText(3, _translate("QSpectrumAnalyzerSettings", "rtl_power", None)) self.label.setText(_translate("QSpectrumAnalyzerSettings", "E&xecutable:", None)) - self.executableEdit.setText(_translate("QSpectrumAnalyzerSettings", "rtl_power", None)) + self.executableEdit.setText(_translate("QSpectrumAnalyzerSettings", "soapy_power", None)) self.executableButton.setText(_translate("QSpectrumAnalyzerSettings", "...", None)) - self.label_2.setText(_translate("QSpectrumAnalyzerSettings", "&Waterfall history size:", None)) - self.label_5.setText(_translate("QSpectrumAnalyzerSettings", "&Device index:", None)) + self.label_5.setText(_translate("QSpectrumAnalyzerSettings", "Device:", None)) self.label_4.setText(_translate("QSpectrumAnalyzerSettings", "Sa&mple rate:", None)) + self.label_2.setText(_translate("QSpectrumAnalyzerSettings", "&Waterfall history size:", None)) diff --git a/qspectrumanalyzer/ui_qspectrumanalyzer_smooth.py b/qspectrumanalyzer/ui_qspectrumanalyzer_smooth.py index dceb797..ae70575 100644 --- a/qspectrumanalyzer/ui_qspectrumanalyzer_smooth.py +++ b/qspectrumanalyzer/ui_qspectrumanalyzer_smooth.py @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 'qspectrumanalyzer/qspectrumanalyzer_smooth.ui' # -# Created by: PyQt4 UI code generator 4.11.4 +# Created by: PyQt4 UI code generator 4.12 # # WARNING! All changes made in this file will be lost!