diff --git a/qspectrumanalyzer/__main__.py b/qspectrumanalyzer/__main__.py index 9165ba1..693d0e7 100755 --- a/qspectrumanalyzer/__main__.py +++ b/qspectrumanalyzer/__main__.py @@ -28,13 +28,15 @@ class QSpectrumAnalyzerSettings(QtWidgets.QDialog, Ui_QSpectrumAnalyzerSettings) # Initialize UI super().__init__(parent) self.setupUi(self) - self.help_dialog = None + self.params_help_dialog = None + self.device_help_dialog = None # Load settings settings = QtCore.QSettings() self.executableEdit.setText(settings.value("executable", "soapy_power")) - self.waterfallHistorySizeSpinBox.setValue(settings.value("waterfall_history_size", 100, int)) self.deviceEdit.setText(settings.value("device", "")) + self.lnbSpinBox.setValue(settings.value("lnb_lo", 0, float) / 1e6) + self.waterfallHistorySizeSpinBox.setValue(settings.value("waterfall_history_size", 100, int)) backend = settings.value("backend", "soapy_power") try: @@ -43,9 +45,15 @@ class QSpectrumAnalyzerSettings(QtWidgets.QDialog, Ui_QSpectrumAnalyzerSettings) backend_module = backends.soapy_power self.paramsEdit.setText(settings.value("params", backend_module.Info.additional_params)) - self.sampleRateSpinBox.setMinimum(backend_module.Info.sample_rate_min) - self.sampleRateSpinBox.setMaximum(backend_module.Info.sample_rate_max) - self.sampleRateSpinBox.setValue(settings.value("sample_rate", backend_module.Info.sample_rate, int)) + self.deviceHelpButton.setEnabled(bool(backend_module.Info.help_device)) + + self.sampleRateSpinBox.setMinimum(backend_module.Info.sample_rate_min / 1e6) + self.sampleRateSpinBox.setMaximum(backend_module.Info.sample_rate_max / 1e6) + self.sampleRateSpinBox.setValue(settings.value("sample_rate", backend_module.Info.sample_rate, float) / 1e6) + + self.bandwidthSpinBox.setMinimum(backend_module.Info.bandwidth_min / 1e6) + self.bandwidthSpinBox.setMaximum(backend_module.Info.bandwidth_max / 1e6) + self.bandwidthSpinBox.setValue(settings.value("bandwidth", backend_module.Info.bandwidth, float) / 1e6) self.backendComboBox.blockSignals(True) self.backendComboBox.clear() @@ -67,21 +75,38 @@ class QSpectrumAnalyzerSettings(QtWidgets.QDialog, Ui_QSpectrumAnalyzerSettings) self.executableEdit.setText(filename) @QtCore.Slot() - def on_helpButton_clicked(self): - """Open help dialog when button is clicked""" + def on_paramsHelpButton_clicked(self): + """Open additional parameters help dialog when button is clicked""" try: backend_module = getattr(backends, self.backendComboBox.currentText()) except AttributeError: backend_module = backends.soapy_power - self.help_dialog = QSpectrumAnalyzerSettingsHelp( - backend_module.Info.help(self.executableEdit.text()), + self.params_help_dialog = QSpectrumAnalyzerSettingsHelp( + backend_module.Info.help_params(self.executableEdit.text()), parent=self ) - self.help_dialog.show() - self.help_dialog.raise_() - self.help_dialog.activateWindow() + self.params_help_dialog.show() + self.params_help_dialog.raise_() + self.params_help_dialog.activateWindow() + + @QtCore.Slot() + def on_deviceHelpButton_clicked(self): + """Open device help dialog when button is clicked""" + try: + backend_module = getattr(backends, self.backendComboBox.currentText()) + except AttributeError: + backend_module = backends.soapy_power + + self.device_help_dialog = QSpectrumAnalyzerSettingsHelp( + backend_module.Info.help_device(self.executableEdit.text(), self.deviceEdit.text()), + parent=self + ) + + self.device_help_dialog.show() + self.device_help_dialog.raise_() + self.device_help_dialog.activateWindow() @QtCore.Slot(str) def on_backendComboBox_currentIndexChanged(self, text): @@ -95,19 +120,25 @@ class QSpectrumAnalyzerSettings(QtWidgets.QDialog, Ui_QSpectrumAnalyzerSettings) backend_module = backends.soapy_power self.paramsEdit.setText(backend_module.Info.additional_params) - self.sampleRateSpinBox.setMinimum(backend_module.Info.sample_rate_min) - self.sampleRateSpinBox.setMaximum(backend_module.Info.sample_rate_max) - self.sampleRateSpinBox.setValue(backend_module.Info.sample_rate) + self.deviceHelpButton.setEnabled(bool(backend_module.Info.help_device)) + self.sampleRateSpinBox.setMinimum(backend_module.Info.sample_rate_min / 1e6) + self.sampleRateSpinBox.setMaximum(backend_module.Info.sample_rate_max / 1e6) + self.sampleRateSpinBox.setValue(backend_module.Info.sample_rate / 1e6) + self.bandwidthSpinBox.setMinimum(backend_module.Info.bandwidth_min / 1e6) + self.bandwidthSpinBox.setMaximum(backend_module.Info.bandwidth_max / 1e6) + self.bandwidthSpinBox.setValue(backend_module.Info.bandwidth / 1e6) def accept(self): """Save settings when dialog is accepted""" settings = QtCore.QSettings() - settings.setValue("executable", self.executableEdit.text()) - settings.setValue("waterfall_history_size", self.waterfallHistorySizeSpinBox.value()) - settings.setValue("device", self.deviceEdit.text()) - settings.setValue("params", self.paramsEdit.text()) - settings.setValue("sample_rate", self.sampleRateSpinBox.value()) settings.setValue("backend", self.backendComboBox.currentText()) + settings.setValue("executable", self.executableEdit.text()) + settings.setValue("params", self.paramsEdit.text()) + settings.setValue("device", self.deviceEdit.text()) + settings.setValue("sample_rate", self.sampleRateSpinBox.value() * 1e6) + settings.setValue("bandwidth", self.bandwidthSpinBox.value() * 1e6) + settings.setValue("lnb_lo", self.lnbSpinBox.value() * 1e6) + settings.setValue("waterfall_history_size", self.waterfallHistorySizeSpinBox.value()) QtWidgets.QDialog.accept(self) @@ -243,13 +274,14 @@ class QSpectrumAnalyzerMainWindow(QtWidgets.QMainWindow, Ui_QSpectrumAnalyzerMai 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) + # Setup default values and limits in case that backend is changed backend = settings.value("backend", "soapy_power") try: backend_module = getattr(backends, backend) except AttributeError: backend_module = backends.soapy_power - if not self.backend or backend != self.backend: + if self.backend is None or backend != self.backend: self.backend = backend self.gainSpinBox.setMinimum(backend_module.Info.gain_min) self.gainSpinBox.setMaximum(backend_module.Info.gain_max) @@ -273,6 +305,26 @@ class QSpectrumAnalyzerMainWindow(QtWidgets.QMainWindow, Ui_QSpectrumAnalyzerMai self.cropSpinBox.setMaximum(backend_module.Info.crop_max) self.cropSpinBox.setValue(backend_module.Info.crop) + # Setup default values and limits in case that LNB LO is changed + lnb_lo = settings.value("lnb_lo", 0, float) / 1e6 + + start_freq_min = backend_module.Info.start_freq_min + lnb_lo + start_freq_max = backend_module.Info.start_freq_max + lnb_lo + start_freq = self.startFreqSpinBox.value() + stop_freq_min = backend_module.Info.stop_freq_min + lnb_lo + stop_freq_max = backend_module.Info.stop_freq_max + lnb_lo + stop_freq = self.stopFreqSpinBox.value() + + self.startFreqSpinBox.setMinimum(start_freq_min if start_freq_min > 0 else 0) + self.startFreqSpinBox.setMaximum(start_freq_max) + if start_freq < start_freq_min or start_freq > start_freq_max: + self.startFreqSpinBox.setValue(start_freq_min) + + self.stopFreqSpinBox.setMinimum(stop_freq_min if stop_freq_min > 0 else 0) + self.stopFreqSpinBox.setMaximum(stop_freq_max) + if stop_freq < stop_freq_min or stop_freq > stop_freq_max: + self.stopFreqSpinBox.setValue(stop_freq_max) + self.power_thread = backend_module.PowerThread(self.data_storage) self.power_thread.powerThreadStarted.connect(self.update_buttons) self.power_thread.powerThreadStopped.connect(self.update_buttons) @@ -433,7 +485,9 @@ class QSpectrumAnalyzerMainWindow(QtWidgets.QMainWindow, Ui_QSpectrumAnalyzerMai crop=int(self.cropSpinBox.value()) / 100.0, single_shot=single_shot, device=settings.value("device", ""), - sample_rate=settings.value("sample_rate", 2560000, int)) + sample_rate=settings.value("sample_rate", 2560000, float), + bandwidth=settings.value("bandwidth", 0, float), + lnb_lo=settings.value("lnb_lo", 0, float)) self.power_thread.start() def stop(self): diff --git a/qspectrumanalyzer/backends/__init__.py b/qspectrumanalyzer/backends/__init__.py index c1e8755..d6eebbd 100644 --- a/qspectrumanalyzer/backends/__init__.py +++ b/qspectrumanalyzer/backends/__init__.py @@ -8,6 +8,9 @@ class BaseInfo: sample_rate_min = 0 sample_rate_max = 3200000 sample_rate = 2560000 + bandwidth_min = 0 + bandwidth_max = 0 + bandwidth = 0 gain_min = -1 gain_max = 49 gain = 37 @@ -30,9 +33,10 @@ class BaseInfo: crop_max = 99 crop = 0 additional_params = '' + help_device = None @classmethod - def help(cls, executable): + def help_params(cls, executable): try: p = subprocess.run([executable, '-h'], universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, @@ -61,8 +65,8 @@ class BasePowerThread(QtCore.QThread): 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=0, sample_rate=2560000): + 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, bandwidth=0, lnb_lo=0): """Setup power process params""" raise NotImplementedError diff --git a/qspectrumanalyzer/backends/hackrf_sweep.py b/qspectrumanalyzer/backends/hackrf_sweep.py index 9225aee..85cf19b 100644 --- a/qspectrumanalyzer/backends/hackrf_sweep.py +++ b/qspectrumanalyzer/backends/hackrf_sweep.py @@ -38,7 +38,7 @@ class PowerThread(BasePowerThread): """Thread which runs hackrf_sweep process""" def setup(self, start_freq=0, stop_freq=6000, bin_size=1000, interval=0.0, gain=40, ppm=0, crop=0, single_shot=False, - device=0, sample_rate=20000000): + device=0, sample_rate=20000000, bandwidth=0, lnb_lo=0): """Setup hackrf_sweep params""" # theoretically we can support bins smaller than 40 kHz, but it is # unlikely to result in acceptable performance @@ -78,6 +78,7 @@ class PowerThread(BasePowerThread): "crop": 0, "single_shot": single_shot } + self.lnb_lo = lnb_lo self.databuffer = {"timestamp": [], "x": [], "y": []} print("hackrf_sweep params:") @@ -90,8 +91,8 @@ class PowerThread(BasePowerThread): settings = QtCore.QSettings() cmdline = shlex.split(settings.value("executable", "hackrf_sweep")) cmdline.extend([ - "-f", "{}:{}".format(int(self.params["start_freq"]), - int(self.params["stop_freq"])), + "-f", "{}:{}".format(int(self.params["start_freq"] - self.lnb_lo / 1e6), + int(self.params["stop_freq"] - self.lnb_lo / 1e6)), "-B", "-w", "{}".format(int(self.params["bin_size"] * 1000)), "-l", "{}".format(int(self.params["lna_gain"])), @@ -114,15 +115,15 @@ class PowerThread(BasePowerThread): data = np.fromstring(buf[16:], dtype='= (self.params["stop_freq"]): + if (high_edge / 1e6) >= (self.params["stop_freq"] - self.lnb_lo / 1e6): # We've reached the end of a pass, so sort and display it. sorted_data = sorted(zip(self.databuffer["x"], self.databuffer["y"])) self.databuffer["x"], self.databuffer["y"] = [list(x) for x in zip(*sorted_data)] diff --git a/qspectrumanalyzer/backends/rtl_power.py b/qspectrumanalyzer/backends/rtl_power.py index 8e27313..d65c697 100644 --- a/qspectrumanalyzer/backends/rtl_power.py +++ b/qspectrumanalyzer/backends/rtl_power.py @@ -13,8 +13,8 @@ class Info(BaseInfo): class PowerThread(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=0, sample_rate=2560000): + 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, bandwidth=0, lnb_lo=0): """Setup rtl_power params""" if bin_size > 2800: bin_size = 2800 @@ -30,6 +30,7 @@ class PowerThread(BasePowerThread): "crop": crop, "single_shot": single_shot } + self.lnb_lo = lnb_lo self.databuffer = {} self.last_timestamp = "" @@ -43,8 +44,8 @@ class PowerThread(BasePowerThread): settings = QtCore.QSettings() cmdline = shlex.split(settings.value("executable", "rtl_power")) cmdline.extend([ - "-f", "{}M:{}M:{}k".format(self.params["start_freq"], - self.params["stop_freq"], + "-f", "{}M:{}M:{}k".format(self.params["start_freq"] - self.lnb_lo / 1e6, + self.params["stop_freq"] - self.lnb_lo / 1e6, self.params["bin_size"]), "-i", "{}".format(self.params["interval"]), "-d", "{}".format(self.params["device"]), @@ -73,7 +74,7 @@ class PowerThread(BasePowerThread): step = float(line[4]) samples = float(line[5]) - x_axis = list(np.arange(start_freq, stop_freq, step)) + x_axis = list(np.arange(start_freq + self.lnb_lo, stop_freq + self.lnb_lo, 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 rtl_power!") @@ -94,6 +95,6 @@ class PowerThread(BasePowerThread): self.databuffer["y"].extend(y_axis) # This have to be stupid like this to be compatible with old broken version of rtl_power. Right way is: - # if stop_freq == self.params["stop_freq"] * 1e6: - if stop_freq > (self.params["stop_freq"] * 1e6) - step: + # if stop_freq == (self.params["stop_freq"] - self.lnb_lo / 1e6) * 1e6: + if stop_freq > ((self.params["stop_freq"] - self.lnb_lo / 1e6) * 1e6) - step: self.data_storage.update(self.databuffer) diff --git a/qspectrumanalyzer/backends/rtl_power_fftw.py b/qspectrumanalyzer/backends/rtl_power_fftw.py index 3294fcc..00eecf0 100644 --- a/qspectrumanalyzer/backends/rtl_power_fftw.py +++ b/qspectrumanalyzer/backends/rtl_power_fftw.py @@ -12,8 +12,8 @@ class Info(BaseInfo): class PowerThread(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=0, sample_rate=2560000): + 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, bandwidth=0, lnb_lo=0): """Setup rtl_power_fftw params""" crop = crop * 100 overlap = crop * 2 @@ -31,7 +31,7 @@ class PowerThread(BasePowerThread): "stop_freq": stop_freq, "freq_range": freq_range, "device": device, - "sample_rate": sample_rate, + "sample_rate": int(sample_rate), "bin_size": bin_size, "bins": bins, "interval": interval, @@ -45,6 +45,7 @@ class PowerThread(BasePowerThread): "overhang": overhang, "single_shot": single_shot } + self.lnb_lo = lnb_lo self.freqs = [self.get_hop_freq(hop) for hop in range(hops)] self.freqs_crop = [(f[0] + crop_freq, f[1] - crop_freq) for f in self.freqs] self.databuffer = {"timestamp": [], "x": [], "y": []} @@ -68,13 +69,14 @@ class PowerThread(BasePowerThread): settings = QtCore.QSettings() cmdline = shlex.split(settings.value("executable", "rtl_power_fftw")) cmdline.extend([ - "-f", "{}M:{}M".format(self.params["start_freq"], - self.params["stop_freq"]), + "-f", "{}M:{}M".format(self.params["start_freq"] - self.lnb_lo / 1e6, + self.params["stop_freq"] - self.lnb_lo / 1e6), "-b", "{}".format(self.params["bins"]), "-t", "{}".format(self.params["time"]), "-d", "{}".format(self.params["device"]), "-r", "{}".format(self.params["sample_rate"]), "-p", "{}".format(self.params["ppm"]), + "-q", ]) if self.params["gain"] >= 0: @@ -88,7 +90,7 @@ class PowerThread(BasePowerThread): if additional_params: cmdline.extend(shlex.split(additional_params)) - self.process = subprocess.Popen(cmdline, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, + self.process = subprocess.Popen(cmdline, stdout=subprocess.PIPE, universal_newlines=True) def parse_output(self, line): @@ -123,7 +125,7 @@ class PowerThread(BasePowerThread): # Parse frequency and power elif line[0].isdigit(): freq, power = line.split() - freq, power = float(freq), float(power) + freq, power = float(freq) + self.lnb_lo, float(power) start_freq, stop_freq = self.freqs_crop[self.hop] # Apply cropping diff --git a/qspectrumanalyzer/backends/rx_power.py b/qspectrumanalyzer/backends/rx_power.py index 95f6e09..1c1ca21 100644 --- a/qspectrumanalyzer/backends/rx_power.py +++ b/qspectrumanalyzer/backends/rx_power.py @@ -18,8 +18,8 @@ class Info(BaseInfo): class PowerThread(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): + 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, bandwidth=0, lnb_lo=0): """Setup rx_power params""" self.params = { "start_freq": start_freq, @@ -33,6 +33,7 @@ class PowerThread(BasePowerThread): "crop": crop, "single_shot": single_shot } + self.lnb_lo = lnb_lo self.databuffer = {} self.last_timestamp = "" @@ -46,8 +47,8 @@ class PowerThread(BasePowerThread): settings = QtCore.QSettings() cmdline = shlex.split(settings.value("executable", "rx_power")) cmdline.extend([ - "-f", "{}M:{}M:{}k".format(self.params["start_freq"], - self.params["stop_freq"], + "-f", "{}M:{}M:{}k".format(self.params["start_freq"] - self.lnb_lo / 1e6, + self.params["stop_freq"] - self.lnb_lo / 1e6, self.params["bin_size"]), "-i", "{}".format(self.params["interval"]), "-d", "{}".format(self.params["device"]), @@ -76,10 +77,10 @@ class PowerThread(BasePowerThread): step = float(line[4]) samples = float(line[5]) - x_axis = list(np.arange(start_freq, stop_freq, step)) + x_axis = list(np.arange(start_freq + self.lnb_lo, stop_freq + self.lnb_lo, 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!") + print("ERROR: len(x_axis) != len(y_axis)!") if len(x_axis) > len(y_axis): print("Trimming x_axis...") x_axis = x_axis[:len(y_axis)] @@ -96,7 +97,7 @@ class PowerThread(BasePowerThread): 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: + # This have to be stupid like this to be compatible with old broken version of rtl_power. Right way is: + # if stop_freq == (self.params["stop_freq"] - self.lnb_lo / 1e6) * 1e6: + if stop_freq > ((self.params["stop_freq"] - self.lnb_lo / 1e6) * 1e6) - step: self.data_storage.update(self.databuffer) diff --git a/qspectrumanalyzer/backends/soapy_power.py b/qspectrumanalyzer/backends/soapy_power.py index 402e322..25483c4 100644 --- a/qspectrumanalyzer/backends/soapy_power.py +++ b/qspectrumanalyzer/backends/soapy_power.py @@ -27,23 +27,44 @@ class Info(BaseInfo): """soapy_power device metadata""" sample_rate_min = 0 sample_rate_max = 61440000 + bandwidth_min = 0 + bandwidth_max = 61440000 start_freq_min = 0 start_freq_max = 6000 stop_freq_min = 0 stop_freq_max = 6000 additional_params = '--even --fft-window boxcar --remove-dc' + @classmethod + def help_device(cls, executable, device): + try: + text = '' + p = subprocess.run([executable, '--detect'], universal_newlines=True, + stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, + env=dict(os.environ, COLUMNS='125')) + text += p.stdout + '\n' + + if p.returncode == 0: + p = subprocess.run([executable, '--device', device, '--info'], universal_newlines=True, + stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, + env=dict(os.environ, COLUMNS='125')) + text += p.stdout + except OSError: + text = '{} executable not found!'.format(executable) + return text + class PowerThread(BasePowerThread): """Thread which runs soapy_power process""" - 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): + 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, bandwidth=0, lnb_lo=0): """Setup soapy_power params""" self.params = { "start_freq": start_freq, "stop_freq": stop_freq, "device": device, "sample_rate": sample_rate, + "bandwidth": bandwidth, "bin_size": bin_size, "interval": interval, "hops": 0, @@ -52,8 +73,9 @@ class PowerThread(BasePowerThread): "crop": crop * 100, "single_shot": single_shot } + self.lnb_lo = lnb_lo self.databuffer = {"timestamp": [], "x": [], "y": []} - self.min_freq = 0 + self.min_freq = None self.pipe_read = None self.pipe_read_fd = None @@ -92,6 +114,10 @@ class PowerThread(BasePowerThread): ), ]) + if self.lnb_lo != 0: + cmdline.extend(["--lnb-lo", "{}".format(self.lnb_lo)]) + if self.params["bandwidth"] > 0: + cmdline.extend(["-w", "{}".format(self.params["bandwidth"])]) if self.params["gain"] >= 0: cmdline.extend(["-g", "{}".format(self.params["gain"])]) if self.params["crop"] > 0: @@ -143,7 +169,7 @@ class PowerThread(BasePowerThread): if len(x_axis) != len(y_axis): print("ERROR: len(x_axis) != len(y_axis)") - if not self.min_freq: + if self.min_freq is None: self.min_freq = start_freq if start_freq == self.min_freq: diff --git a/qspectrumanalyzer/languages/qspectrumanalyzer_cs.ts b/qspectrumanalyzer/languages/qspectrumanalyzer_cs.ts index 6584d54..b8db029 100644 --- a/qspectrumanalyzer/languages/qspectrumanalyzer_cs.ts +++ b/qspectrumanalyzer/languages/qspectrumanalyzer_cs.ts @@ -41,185 +41,185 @@ QSpectrumAnalyzerMainWindow - + QSpectrumAnalyzer - Settings - - - - MHz - + kHz - + auto - - Frequency - - - - - Controls - - - - - Levels - - - - + Frequency hops: {} | Sweep time: {:.2f} s | FPS: {:.2f} - + N/A - + About - QSpectrumAnalyzer - + QSpectrumAnalyzer {} - + &File - + &Help - + &Start - + S&top - + Si&ngle shot - + Start: - + Stop: - - Bin size: - - - - - Interval [s]: - - - - - Gain [dB]: - - - - + Corr. [ppm]: - + Crop [%]: - + Main curve - + Colors... - + Max. hold - + Min. hold - + Average - + Smoothing - + ... - + Persistence - + &Settings... - + &Quit - + Ctrl+Q - + &About + + + &Controls + + + + + Fre&quency + + + + + &Bin size: + + + + + Se&ttings + + + + + &Interval [s]: + + + + + &Gain [dB]: + + + + + &Levels + + QSpectrumAnalyzerPersistence @@ -252,78 +252,98 @@ QSpectrumAnalyzerSettings - + Select executable - QSpectrumAnalyzer - + Settings - QSpectrumAnalyzer - + &Backend: - + soapy_power - + rx_power - + rtl_power_fftw - + rtl_power - + hackrf_sweep - + E&xecutable: - + ... - + Sa&mple rate: - + &Waterfall history size: - + &Device: - - Additional &parameters: + + Bandwidt&h: - - ? + + &LNB LO: + + + + + ? + + + + + Negative frequency for upconverters, positive frequency for downconverters. + + + + + Add&itional parameters: + + + + + MHz diff --git a/qspectrumanalyzer/qspectrumanalyzer.ui b/qspectrumanalyzer/qspectrumanalyzer.ui index 63467ba..65c9640 100644 --- a/qspectrumanalyzer/qspectrumanalyzer.ui +++ b/qspectrumanalyzer/qspectrumanalyzer.ui @@ -7,7 +7,7 @@ 0 0 1200 - 810 + 840 @@ -52,7 +52,7 @@ 0 0 1200 - 30 + 32 @@ -82,15 +82,15 @@ - 10 - 10 + 190 + 130 QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable - Controls + &Controls 2 @@ -143,15 +143,15 @@ - 10 - 10 + 182 + 166 QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable - Frequency + Fre&quency 2 @@ -182,6 +182,9 @@ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + true + MHz @@ -220,6 +223,9 @@ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + true + MHz @@ -240,7 +246,7 @@ - Bin size: + &Bin size: binSizeSpinBox @@ -258,6 +264,9 @@ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + true + kHz @@ -299,7 +308,7 @@ QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable - Settings + Se&ttings 2 @@ -309,7 +318,7 @@ - Interval [s]: + &Interval [s]: intervalSpinBox @@ -319,7 +328,7 @@ - Gain [dB]: + &Gain [dB]: gainSpinBox @@ -497,7 +506,7 @@ QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable - Levels + &Levels 2 diff --git a/qspectrumanalyzer/qspectrumanalyzer_settings.ui b/qspectrumanalyzer/qspectrumanalyzer_settings.ui index 7ed6c90..0a7de0c 100644 --- a/qspectrumanalyzer/qspectrumanalyzer_settings.ui +++ b/qspectrumanalyzer/qspectrumanalyzer_settings.ui @@ -7,7 +7,7 @@ 0 0 600 - 310 + 388 @@ -76,6 +76,12 @@ + + + 50 + 0 + + ... @@ -83,7 +89,7 @@ - + &Device: @@ -93,9 +99,6 @@ - - - @@ -106,23 +109,7 @@ - - - - 0 - - - 25000000 - - - 10000 - - - 2560000 - - - - + &Waterfall history size: @@ -132,7 +119,7 @@ - + 1 @@ -145,30 +132,157 @@ - + + + + Bandwidt&h: + + + bandwidthSpinBox + + + + + + + Negative frequency for upconverters, positive frequency for downconverters. + + + &LNB LO: + + + lnbSpinBox + + + + - Additional &parameters: + Add&itional parameters: paramsEdit - - + + - + + + + 50 + 0 + + - ? + ? + + + + + + + + + + 50 + 0 + + + + ? + + + + + + + + + true + + + MHz + + + 3 + + + 0.000000000000000 + + + 61.439999999999998 + + + 0.010000000000000 + + + 61.439999999999998 + + + + + + + true + + + MHz + + + 3 + + + 0.000000000000000 + + + 61.439999999999998 + + + 0.010000000000000 + + + 0.000000000000000 + + + + + + + Negative frequency for upconverters, positive frequency for downconverters. + + + true + + + MHz + + + 3 + + + -999999.998999999952503 + + + 999999.998999999952503 + + + 0.010000000000000 + + + 0.000000000000000 + + + @@ -200,12 +314,14 @@ backendComboBox executableEdit executableButton - deviceEdit paramsEdit - helpButton + paramsHelpButton + deviceEdit + deviceHelpButton sampleRateSpinBox + bandwidthSpinBox + lnbSpinBox waterfallHistorySizeSpinBox - buttonBox @@ -216,8 +332,8 @@ accept() - 248 - 303 + 254 + 377 157 @@ -232,8 +348,8 @@ reject() - 316 - 303 + 322 + 377 286 diff --git a/qspectrumanalyzer/ui_qspectrumanalyzer.py b/qspectrumanalyzer/ui_qspectrumanalyzer.py index f38d80f..75c0792 100644 --- a/qspectrumanalyzer/ui_qspectrumanalyzer.py +++ b/qspectrumanalyzer/ui_qspectrumanalyzer.py @@ -11,7 +11,7 @@ from Qt import QtCore, QtGui, QtWidgets class Ui_QSpectrumAnalyzerMainWindow(object): def setupUi(self, QSpectrumAnalyzerMainWindow): QSpectrumAnalyzerMainWindow.setObjectName("QSpectrumAnalyzerMainWindow") - QSpectrumAnalyzerMainWindow.resize(1200, 810) + QSpectrumAnalyzerMainWindow.resize(1200, 840) self.centralwidget = QtWidgets.QWidget(QSpectrumAnalyzerMainWindow) self.centralwidget.setObjectName("centralwidget") self.horizontalLayout = QtWidgets.QHBoxLayout(self.centralwidget) @@ -41,7 +41,7 @@ class Ui_QSpectrumAnalyzerMainWindow(object): self.horizontalLayout.addWidget(self.plotSplitter) QSpectrumAnalyzerMainWindow.setCentralWidget(self.centralwidget) self.menubar = QtWidgets.QMenuBar(QSpectrumAnalyzerMainWindow) - self.menubar.setGeometry(QtCore.QRect(0, 0, 1200, 30)) + self.menubar.setGeometry(QtCore.QRect(0, 0, 1200, 32)) self.menubar.setObjectName("menubar") self.menu_File = QtWidgets.QMenu(self.menubar) self.menu_File.setObjectName("menu_File") @@ -57,7 +57,7 @@ class Ui_QSpectrumAnalyzerMainWindow(object): sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.controlsDockWidget.sizePolicy().hasHeightForWidth()) self.controlsDockWidget.setSizePolicy(sizePolicy) - self.controlsDockWidget.setMinimumSize(QtCore.QSize(10, 10)) + self.controlsDockWidget.setMinimumSize(QtCore.QSize(190, 130)) self.controlsDockWidget.setFeatures(QtWidgets.QDockWidget.DockWidgetFloatable|QtWidgets.QDockWidget.DockWidgetMovable) self.controlsDockWidget.setObjectName("controlsDockWidget") self.controlsDockWidgetContents = QtWidgets.QWidget() @@ -84,7 +84,7 @@ class Ui_QSpectrumAnalyzerMainWindow(object): sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.frequencyDockWidget.sizePolicy().hasHeightForWidth()) self.frequencyDockWidget.setSizePolicy(sizePolicy) - self.frequencyDockWidget.setMinimumSize(QtCore.QSize(10, 10)) + self.frequencyDockWidget.setMinimumSize(QtCore.QSize(182, 166)) self.frequencyDockWidget.setFeatures(QtWidgets.QDockWidget.DockWidgetFloatable|QtWidgets.QDockWidget.DockWidgetMovable) self.frequencyDockWidget.setObjectName("frequencyDockWidget") self.frequencyDockWidgetContents = QtWidgets.QWidget() @@ -103,6 +103,7 @@ class Ui_QSpectrumAnalyzerMainWindow(object): sizePolicy.setHeightForWidth(self.startFreqSpinBox.sizePolicy().hasHeightForWidth()) self.startFreqSpinBox.setSizePolicy(sizePolicy) self.startFreqSpinBox.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) + self.startFreqSpinBox.setProperty("showGroupSeparator", True) self.startFreqSpinBox.setDecimals(3) self.startFreqSpinBox.setMinimum(24.0) self.startFreqSpinBox.setMaximum(1766.0) @@ -119,6 +120,7 @@ class Ui_QSpectrumAnalyzerMainWindow(object): sizePolicy.setHeightForWidth(self.stopFreqSpinBox.sizePolicy().hasHeightForWidth()) self.stopFreqSpinBox.setSizePolicy(sizePolicy) self.stopFreqSpinBox.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) + self.stopFreqSpinBox.setProperty("showGroupSeparator", True) self.stopFreqSpinBox.setDecimals(3) self.stopFreqSpinBox.setMinimum(24.0) self.stopFreqSpinBox.setMaximum(1766.0) @@ -135,6 +137,7 @@ class Ui_QSpectrumAnalyzerMainWindow(object): sizePolicy.setHeightForWidth(self.binSizeSpinBox.sizePolicy().hasHeightForWidth()) self.binSizeSpinBox.setSizePolicy(sizePolicy) self.binSizeSpinBox.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) + self.binSizeSpinBox.setProperty("showGroupSeparator", True) self.binSizeSpinBox.setDecimals(3) self.binSizeSpinBox.setMaximum(2800.0) self.binSizeSpinBox.setProperty("value", 10.0) @@ -298,20 +301,20 @@ class Ui_QSpectrumAnalyzerMainWindow(object): QSpectrumAnalyzerMainWindow.setWindowTitle(_translate("QSpectrumAnalyzerMainWindow", "QSpectrumAnalyzer")) self.menu_File.setTitle(_translate("QSpectrumAnalyzerMainWindow", "&File")) self.menu_Help.setTitle(_translate("QSpectrumAnalyzerMainWindow", "&Help")) - self.controlsDockWidget.setWindowTitle(_translate("QSpectrumAnalyzerMainWindow", "Controls")) + self.controlsDockWidget.setWindowTitle(_translate("QSpectrumAnalyzerMainWindow", "&Controls")) self.startButton.setText(_translate("QSpectrumAnalyzerMainWindow", "&Start")) self.stopButton.setText(_translate("QSpectrumAnalyzerMainWindow", "S&top")) self.singleShotButton.setText(_translate("QSpectrumAnalyzerMainWindow", "Si&ngle shot")) - self.frequencyDockWidget.setWindowTitle(_translate("QSpectrumAnalyzerMainWindow", "Frequency")) + self.frequencyDockWidget.setWindowTitle(_translate("QSpectrumAnalyzerMainWindow", "Fre&quency")) self.label_2.setText(_translate("QSpectrumAnalyzerMainWindow", "Start:")) self.startFreqSpinBox.setSuffix(_translate("QSpectrumAnalyzerMainWindow", " MHz")) self.label_3.setText(_translate("QSpectrumAnalyzerMainWindow", "Stop:")) self.stopFreqSpinBox.setSuffix(_translate("QSpectrumAnalyzerMainWindow", " MHz")) - self.label.setText(_translate("QSpectrumAnalyzerMainWindow", "Bin size:")) + self.label.setText(_translate("QSpectrumAnalyzerMainWindow", "&Bin size:")) self.binSizeSpinBox.setSuffix(_translate("QSpectrumAnalyzerMainWindow", " kHz")) - self.settingsDockWidget.setWindowTitle(_translate("QSpectrumAnalyzerMainWindow", "Settings")) - self.label_4.setText(_translate("QSpectrumAnalyzerMainWindow", "Interval [s]:")) - self.label_6.setText(_translate("QSpectrumAnalyzerMainWindow", "Gain [dB]:")) + self.settingsDockWidget.setWindowTitle(_translate("QSpectrumAnalyzerMainWindow", "Se&ttings")) + self.label_4.setText(_translate("QSpectrumAnalyzerMainWindow", "&Interval [s]:")) + self.label_6.setText(_translate("QSpectrumAnalyzerMainWindow", "&Gain [dB]:")) self.gainSpinBox.setSpecialValueText(_translate("QSpectrumAnalyzerMainWindow", "auto")) self.label_5.setText(_translate("QSpectrumAnalyzerMainWindow", "Corr. [ppm]:")) self.label_7.setText(_translate("QSpectrumAnalyzerMainWindow", "Crop [%]:")) @@ -324,7 +327,7 @@ class Ui_QSpectrumAnalyzerMainWindow(object): self.smoothButton.setText(_translate("QSpectrumAnalyzerMainWindow", "...")) self.persistenceCheckBox.setText(_translate("QSpectrumAnalyzerMainWindow", "Persistence")) self.persistenceButton.setText(_translate("QSpectrumAnalyzerMainWindow", "...")) - self.levelsDockWidget.setWindowTitle(_translate("QSpectrumAnalyzerMainWindow", "Levels")) + self.levelsDockWidget.setWindowTitle(_translate("QSpectrumAnalyzerMainWindow", "&Levels")) self.action_Settings.setText(_translate("QSpectrumAnalyzerMainWindow", "&Settings...")) self.action_Quit.setText(_translate("QSpectrumAnalyzerMainWindow", "&Quit")) self.action_Quit.setShortcut(_translate("QSpectrumAnalyzerMainWindow", "Ctrl+Q")) diff --git a/qspectrumanalyzer/ui_qspectrumanalyzer_settings.py b/qspectrumanalyzer/ui_qspectrumanalyzer_settings.py index dd3e4ed..4f46752 100644 --- a/qspectrumanalyzer/ui_qspectrumanalyzer_settings.py +++ b/qspectrumanalyzer/ui_qspectrumanalyzer_settings.py @@ -11,7 +11,7 @@ from Qt import QtCore, QtGui, QtWidgets class Ui_QSpectrumAnalyzerSettings(object): def setupUi(self, QSpectrumAnalyzerSettings): QSpectrumAnalyzerSettings.setObjectName("QSpectrumAnalyzerSettings") - QSpectrumAnalyzerSettings.resize(600, 310) + QSpectrumAnalyzerSettings.resize(600, 388) self.verticalLayout = QtWidgets.QVBoxLayout(QSpectrumAnalyzerSettings) self.verticalLayout.setObjectName("verticalLayout") self.formLayout = QtWidgets.QFormLayout() @@ -36,46 +36,81 @@ class Ui_QSpectrumAnalyzerSettings(object): self.executableEdit.setObjectName("executableEdit") self.horizontalLayout.addWidget(self.executableEdit) self.executableButton = QtWidgets.QToolButton(QSpectrumAnalyzerSettings) + self.executableButton.setMinimumSize(QtCore.QSize(50, 0)) self.executableButton.setObjectName("executableButton") self.horizontalLayout.addWidget(self.executableButton) self.formLayout.setLayout(1, QtWidgets.QFormLayout.FieldRole, self.horizontalLayout) self.label_5 = QtWidgets.QLabel(QSpectrumAnalyzerSettings) self.label_5.setObjectName("label_5") - self.formLayout.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.label_5) - self.deviceEdit = QtWidgets.QLineEdit(QSpectrumAnalyzerSettings) - self.deviceEdit.setObjectName("deviceEdit") - self.formLayout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.deviceEdit) + self.formLayout.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.label_5) self.label_4 = QtWidgets.QLabel(QSpectrumAnalyzerSettings) self.label_4.setObjectName("label_4") self.formLayout.setWidget(4, QtWidgets.QFormLayout.LabelRole, self.label_4) - self.sampleRateSpinBox = QtWidgets.QSpinBox(QSpectrumAnalyzerSettings) - self.sampleRateSpinBox.setMinimum(0) - self.sampleRateSpinBox.setMaximum(25000000) - self.sampleRateSpinBox.setSingleStep(10000) - self.sampleRateSpinBox.setProperty("value", 2560000) - self.sampleRateSpinBox.setObjectName("sampleRateSpinBox") - self.formLayout.setWidget(4, QtWidgets.QFormLayout.FieldRole, self.sampleRateSpinBox) self.label_2 = QtWidgets.QLabel(QSpectrumAnalyzerSettings) self.label_2.setObjectName("label_2") - self.formLayout.setWidget(5, QtWidgets.QFormLayout.LabelRole, self.label_2) + self.formLayout.setWidget(7, QtWidgets.QFormLayout.LabelRole, self.label_2) self.waterfallHistorySizeSpinBox = QtWidgets.QSpinBox(QSpectrumAnalyzerSettings) self.waterfallHistorySizeSpinBox.setMinimum(1) self.waterfallHistorySizeSpinBox.setMaximum(10000000) self.waterfallHistorySizeSpinBox.setProperty("value", 100) self.waterfallHistorySizeSpinBox.setObjectName("waterfallHistorySizeSpinBox") - self.formLayout.setWidget(5, QtWidgets.QFormLayout.FieldRole, self.waterfallHistorySizeSpinBox) + self.formLayout.setWidget(7, QtWidgets.QFormLayout.FieldRole, self.waterfallHistorySizeSpinBox) + self.label_7 = QtWidgets.QLabel(QSpectrumAnalyzerSettings) + self.label_7.setObjectName("label_7") + self.formLayout.setWidget(5, QtWidgets.QFormLayout.LabelRole, self.label_7) + self.label_8 = QtWidgets.QLabel(QSpectrumAnalyzerSettings) + self.label_8.setObjectName("label_8") + self.formLayout.setWidget(6, QtWidgets.QFormLayout.LabelRole, self.label_8) self.label_6 = QtWidgets.QLabel(QSpectrumAnalyzerSettings) self.label_6.setObjectName("label_6") - self.formLayout.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.label_6) - self.horizontalLayout_3 = QtWidgets.QHBoxLayout() - self.horizontalLayout_3.setObjectName("horizontalLayout_3") + self.formLayout.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.label_6) + self.horizontalLayout_2 = QtWidgets.QHBoxLayout() + self.horizontalLayout_2.setObjectName("horizontalLayout_2") self.paramsEdit = QtWidgets.QLineEdit(QSpectrumAnalyzerSettings) self.paramsEdit.setObjectName("paramsEdit") - self.horizontalLayout_3.addWidget(self.paramsEdit) - self.helpButton = QtWidgets.QToolButton(QSpectrumAnalyzerSettings) - self.helpButton.setObjectName("helpButton") - self.horizontalLayout_3.addWidget(self.helpButton) + self.horizontalLayout_2.addWidget(self.paramsEdit) + self.paramsHelpButton = QtWidgets.QToolButton(QSpectrumAnalyzerSettings) + self.paramsHelpButton.setMinimumSize(QtCore.QSize(50, 0)) + self.paramsHelpButton.setObjectName("paramsHelpButton") + self.horizontalLayout_2.addWidget(self.paramsHelpButton) + self.formLayout.setLayout(2, QtWidgets.QFormLayout.FieldRole, self.horizontalLayout_2) + self.horizontalLayout_3 = QtWidgets.QHBoxLayout() + self.horizontalLayout_3.setObjectName("horizontalLayout_3") + self.deviceEdit = QtWidgets.QLineEdit(QSpectrumAnalyzerSettings) + self.deviceEdit.setObjectName("deviceEdit") + self.horizontalLayout_3.addWidget(self.deviceEdit) + self.deviceHelpButton = QtWidgets.QToolButton(QSpectrumAnalyzerSettings) + self.deviceHelpButton.setMinimumSize(QtCore.QSize(50, 0)) + self.deviceHelpButton.setObjectName("deviceHelpButton") + self.horizontalLayout_3.addWidget(self.deviceHelpButton) self.formLayout.setLayout(3, QtWidgets.QFormLayout.FieldRole, self.horizontalLayout_3) + self.sampleRateSpinBox = QtWidgets.QDoubleSpinBox(QSpectrumAnalyzerSettings) + self.sampleRateSpinBox.setProperty("showGroupSeparator", True) + self.sampleRateSpinBox.setDecimals(3) + self.sampleRateSpinBox.setMinimum(0.0) + self.sampleRateSpinBox.setMaximum(61.44) + self.sampleRateSpinBox.setSingleStep(0.01) + self.sampleRateSpinBox.setProperty("value", 61.44) + self.sampleRateSpinBox.setObjectName("sampleRateSpinBox") + self.formLayout.setWidget(4, QtWidgets.QFormLayout.FieldRole, self.sampleRateSpinBox) + self.bandwidthSpinBox = QtWidgets.QDoubleSpinBox(QSpectrumAnalyzerSettings) + self.bandwidthSpinBox.setProperty("showGroupSeparator", True) + self.bandwidthSpinBox.setDecimals(3) + self.bandwidthSpinBox.setMinimum(0.0) + self.bandwidthSpinBox.setMaximum(61.44) + self.bandwidthSpinBox.setSingleStep(0.01) + self.bandwidthSpinBox.setProperty("value", 0.0) + self.bandwidthSpinBox.setObjectName("bandwidthSpinBox") + self.formLayout.setWidget(5, QtWidgets.QFormLayout.FieldRole, self.bandwidthSpinBox) + self.lnbSpinBox = QtWidgets.QDoubleSpinBox(QSpectrumAnalyzerSettings) + self.lnbSpinBox.setProperty("showGroupSeparator", True) + self.lnbSpinBox.setDecimals(3) + self.lnbSpinBox.setMinimum(-999999.999) + self.lnbSpinBox.setMaximum(999999.999) + self.lnbSpinBox.setSingleStep(0.01) + self.lnbSpinBox.setProperty("value", 0.0) + self.lnbSpinBox.setObjectName("lnbSpinBox") + self.formLayout.setWidget(6, QtWidgets.QFormLayout.FieldRole, self.lnbSpinBox) self.verticalLayout.addLayout(self.formLayout) spacerItem = QtWidgets.QSpacerItem(20, 21, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) self.verticalLayout.addItem(spacerItem) @@ -89,6 +124,8 @@ class Ui_QSpectrumAnalyzerSettings(object): self.label_5.setBuddy(self.deviceEdit) self.label_4.setBuddy(self.sampleRateSpinBox) self.label_2.setBuddy(self.waterfallHistorySizeSpinBox) + self.label_7.setBuddy(self.bandwidthSpinBox) + self.label_8.setBuddy(self.lnbSpinBox) self.label_6.setBuddy(self.paramsEdit) self.retranslateUi(QSpectrumAnalyzerSettings) @@ -97,12 +134,14 @@ 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.deviceEdit) - QSpectrumAnalyzerSettings.setTabOrder(self.deviceEdit, self.paramsEdit) - QSpectrumAnalyzerSettings.setTabOrder(self.paramsEdit, self.helpButton) - QSpectrumAnalyzerSettings.setTabOrder(self.helpButton, self.sampleRateSpinBox) - QSpectrumAnalyzerSettings.setTabOrder(self.sampleRateSpinBox, self.waterfallHistorySizeSpinBox) - QSpectrumAnalyzerSettings.setTabOrder(self.waterfallHistorySizeSpinBox, self.buttonBox) + QSpectrumAnalyzerSettings.setTabOrder(self.executableButton, self.paramsEdit) + QSpectrumAnalyzerSettings.setTabOrder(self.paramsEdit, self.paramsHelpButton) + QSpectrumAnalyzerSettings.setTabOrder(self.paramsHelpButton, self.deviceEdit) + QSpectrumAnalyzerSettings.setTabOrder(self.deviceEdit, self.deviceHelpButton) + QSpectrumAnalyzerSettings.setTabOrder(self.deviceHelpButton, self.sampleRateSpinBox) + QSpectrumAnalyzerSettings.setTabOrder(self.sampleRateSpinBox, self.bandwidthSpinBox) + QSpectrumAnalyzerSettings.setTabOrder(self.bandwidthSpinBox, self.lnbSpinBox) + QSpectrumAnalyzerSettings.setTabOrder(self.lnbSpinBox, self.waterfallHistorySizeSpinBox) def retranslateUi(self, QSpectrumAnalyzerSettings): _translate = QtCore.QCoreApplication.translate @@ -119,6 +158,14 @@ class Ui_QSpectrumAnalyzerSettings(object): self.label_5.setText(_translate("QSpectrumAnalyzerSettings", "&Device:")) self.label_4.setText(_translate("QSpectrumAnalyzerSettings", "Sa&mple rate:")) self.label_2.setText(_translate("QSpectrumAnalyzerSettings", "&Waterfall history size:")) - self.label_6.setText(_translate("QSpectrumAnalyzerSettings", "Additional ¶meters:")) - self.helpButton.setText(_translate("QSpectrumAnalyzerSettings", "?")) + self.label_7.setText(_translate("QSpectrumAnalyzerSettings", "Bandwidt&h:")) + self.label_8.setToolTip(_translate("QSpectrumAnalyzerSettings", "Negative frequency for upconverters, positive frequency for downconverters.")) + self.label_8.setText(_translate("QSpectrumAnalyzerSettings", "&LNB LO:")) + self.label_6.setText(_translate("QSpectrumAnalyzerSettings", "Add&itional parameters:")) + self.paramsHelpButton.setText(_translate("QSpectrumAnalyzerSettings", " ? ")) + self.deviceHelpButton.setText(_translate("QSpectrumAnalyzerSettings", " ? ")) + self.sampleRateSpinBox.setSuffix(_translate("QSpectrumAnalyzerSettings", " MHz")) + self.bandwidthSpinBox.setSuffix(_translate("QSpectrumAnalyzerSettings", " MHz")) + self.lnbSpinBox.setToolTip(_translate("QSpectrumAnalyzerSettings", "Negative frequency for upconverters, positive frequency for downconverters.")) + self.lnbSpinBox.setSuffix(_translate("QSpectrumAnalyzerSettings", " MHz")) diff --git a/setup.py b/setup.py index b817769..ea25e6a 100755 --- a/setup.py +++ b/setup.py @@ -30,7 +30,7 @@ setup( ], }, install_requires=[ - "soapy_power>=1.3.0", + "soapy_power>=1.4.0", "pyqtgraph>=0.10.0", "Qt.py" ],