Allow setting bandwidth and LNB LO (for upconverters or downconverters); show info about device in settings

This commit is contained in:
Michal Krenek (Mikos) 2017-03-21 10:36:08 +01:00
parent ea969b89e2
commit c574761a8c
13 changed files with 512 additions and 228 deletions

View File

@ -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):

View File

@ -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

View File

@ -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='<f4')
step = (high_edge - low_edge) / len(data)
if (low_edge // 1000000) <= (self.params["start_freq"]):
if (low_edge // 1000000) <= (self.params["start_freq"] - self.lnb_lo / 1e6):
# Reset databuffer at the start of each sweep even if we somehow
# did not complete the previous sweep.
self.databuffer = {"timestamp": [], "x": [], "y": []}
x_axis = list(np.arange(low_edge + step / 2, high_edge, step))
x_axis = list(np.arange(low_edge + self.lnb_lo + step / 2, high_edge + self.lnb_lo, step))
self.databuffer["x"].extend(x_axis)
for i in range(len(data)):
self.databuffer["y"].append(data[i])
if (high_edge / 1e6) >= (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)]

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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:

View File

@ -41,185 +41,185 @@
<context>
<name>QSpectrumAnalyzerMainWindow</name>
<message>
<location filename="../ui_qspectrumanalyzer.py" line="298"/>
<location filename="../ui_qspectrumanalyzer.py" line="301"/>
<source>QSpectrumAnalyzer</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer.py" line="312"/>
<source>Settings</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer.py" line="309"/>
<source> MHz</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer.py" line="311"/>
<location filename="../ui_qspectrumanalyzer.py" line="314"/>
<source> kHz</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer.py" line="315"/>
<location filename="../ui_qspectrumanalyzer.py" line="318"/>
<source>auto</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer.py" line="305"/>
<source>Frequency</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer.py" line="301"/>
<source>Controls</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer.py" line="327"/>
<source>Levels</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../__main__.py" line="383"/>
<location filename="../__main__.py" line="435"/>
<source>Frequency hops: {} | Sweep time: {:.2f} s | FPS: {:.2f}</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../__main__.py" line="383"/>
<location filename="../__main__.py" line="435"/>
<source>N/A</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../__main__.py" line="550"/>
<location filename="../__main__.py" line="604"/>
<source>About - QSpectrumAnalyzer</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../__main__.py" line="550"/>
<location filename="../__main__.py" line="604"/>
<source>QSpectrumAnalyzer {}</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer.py" line="299"/>
<location filename="../ui_qspectrumanalyzer.py" line="302"/>
<source>&amp;File</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer.py" line="300"/>
<location filename="../ui_qspectrumanalyzer.py" line="303"/>
<source>&amp;Help</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer.py" line="302"/>
<location filename="../ui_qspectrumanalyzer.py" line="305"/>
<source>&amp;Start</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer.py" line="303"/>
<location filename="../ui_qspectrumanalyzer.py" line="306"/>
<source>S&amp;top</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer.py" line="304"/>
<location filename="../ui_qspectrumanalyzer.py" line="307"/>
<source>Si&amp;ngle shot</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer.py" line="306"/>
<location filename="../ui_qspectrumanalyzer.py" line="309"/>
<source>Start:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer.py" line="308"/>
<location filename="../ui_qspectrumanalyzer.py" line="311"/>
<source>Stop:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer.py" line="310"/>
<source>Bin size:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer.py" line="313"/>
<source>Interval [s]:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer.py" line="314"/>
<source>Gain [dB]:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer.py" line="316"/>
<location filename="../ui_qspectrumanalyzer.py" line="319"/>
<source>Corr. [ppm]:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer.py" line="317"/>
<location filename="../ui_qspectrumanalyzer.py" line="320"/>
<source>Crop [%]:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer.py" line="318"/>
<location filename="../ui_qspectrumanalyzer.py" line="321"/>
<source>Main curve</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer.py" line="319"/>
<location filename="../ui_qspectrumanalyzer.py" line="322"/>
<source>Colors...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer.py" line="320"/>
<location filename="../ui_qspectrumanalyzer.py" line="323"/>
<source>Max. hold</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer.py" line="321"/>
<location filename="../ui_qspectrumanalyzer.py" line="324"/>
<source>Min. hold</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer.py" line="322"/>
<location filename="../ui_qspectrumanalyzer.py" line="325"/>
<source>Average</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer.py" line="323"/>
<location filename="../ui_qspectrumanalyzer.py" line="326"/>
<source>Smoothing</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer.py" line="326"/>
<location filename="../ui_qspectrumanalyzer.py" line="329"/>
<source>...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer.py" line="325"/>
<location filename="../ui_qspectrumanalyzer.py" line="328"/>
<source>Persistence</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer.py" line="328"/>
<location filename="../ui_qspectrumanalyzer.py" line="331"/>
<source>&amp;Settings...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer.py" line="329"/>
<location filename="../ui_qspectrumanalyzer.py" line="332"/>
<source>&amp;Quit</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer.py" line="330"/>
<location filename="../ui_qspectrumanalyzer.py" line="333"/>
<source>Ctrl+Q</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer.py" line="331"/>
<location filename="../ui_qspectrumanalyzer.py" line="334"/>
<source>&amp;About</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer.py" line="304"/>
<source>&amp;Controls</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer.py" line="308"/>
<source>Fre&amp;quency</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer.py" line="313"/>
<source>&amp;Bin size:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer.py" line="315"/>
<source>Se&amp;ttings</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer.py" line="316"/>
<source>&amp;Interval [s]:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer.py" line="317"/>
<source>&amp;Gain [dB]:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer.py" line="330"/>
<source>&amp;Levels</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>QSpectrumAnalyzerPersistence</name>
@ -252,78 +252,98 @@
<context>
<name>QSpectrumAnalyzerSettings</name>
<message>
<location filename="../__main__.py" line="65"/>
<location filename="../__main__.py" line="73"/>
<source>Select executable - QSpectrumAnalyzer</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer_settings.py" line="109"/>
<location filename="../ui_qspectrumanalyzer_settings.py" line="148"/>
<source>Settings - QSpectrumAnalyzer</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer_settings.py" line="110"/>
<location filename="../ui_qspectrumanalyzer_settings.py" line="149"/>
<source>&amp;Backend:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer_settings.py" line="117"/>
<location filename="../ui_qspectrumanalyzer_settings.py" line="156"/>
<source>soapy_power</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer_settings.py" line="112"/>
<location filename="../ui_qspectrumanalyzer_settings.py" line="151"/>
<source>rx_power</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer_settings.py" line="113"/>
<location filename="../ui_qspectrumanalyzer_settings.py" line="152"/>
<source>rtl_power_fftw</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer_settings.py" line="114"/>
<location filename="../ui_qspectrumanalyzer_settings.py" line="153"/>
<source>rtl_power</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer_settings.py" line="115"/>
<location filename="../ui_qspectrumanalyzer_settings.py" line="154"/>
<source>hackrf_sweep</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer_settings.py" line="116"/>
<location filename="../ui_qspectrumanalyzer_settings.py" line="155"/>
<source>E&amp;xecutable:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer_settings.py" line="118"/>
<location filename="../ui_qspectrumanalyzer_settings.py" line="157"/>
<source>...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer_settings.py" line="120"/>
<location filename="../ui_qspectrumanalyzer_settings.py" line="159"/>
<source>Sa&amp;mple rate:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer_settings.py" line="121"/>
<location filename="../ui_qspectrumanalyzer_settings.py" line="160"/>
<source>&amp;Waterfall history size:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer_settings.py" line="119"/>
<location filename="../ui_qspectrumanalyzer_settings.py" line="158"/>
<source>&amp;Device:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer_settings.py" line="122"/>
<source>Additional &amp;parameters:</source>
<location filename="../ui_qspectrumanalyzer_settings.py" line="161"/>
<source>Bandwidt&amp;h:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer_settings.py" line="123"/>
<source>?</source>
<location filename="../ui_qspectrumanalyzer_settings.py" line="163"/>
<source>&amp;LNB LO:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer_settings.py" line="166"/>
<source> ? </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer_settings.py" line="169"/>
<source>Negative frequency for upconverters, positive frequency for downconverters.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer_settings.py" line="164"/>
<source>Add&amp;itional parameters:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer_settings.py" line="170"/>
<source> MHz</source>
<translation type="unfinished"></translation>
</message>
</context>

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>1200</width>
<height>810</height>
<height>840</height>
</rect>
</property>
<property name="windowTitle">
@ -52,7 +52,7 @@
<x>0</x>
<y>0</y>
<width>1200</width>
<height>30</height>
<height>32</height>
</rect>
</property>
<widget class="QMenu" name="menu_File">
@ -82,15 +82,15 @@
</property>
<property name="minimumSize">
<size>
<width>10</width>
<height>10</height>
<width>190</width>
<height>130</height>
</size>
</property>
<property name="features">
<set>QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable</set>
</property>
<property name="windowTitle">
<string>Controls</string>
<string>&amp;Controls</string>
</property>
<attribute name="dockWidgetArea">
<number>2</number>
@ -143,15 +143,15 @@
</property>
<property name="minimumSize">
<size>
<width>10</width>
<height>10</height>
<width>182</width>
<height>166</height>
</size>
</property>
<property name="features">
<set>QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable</set>
</property>
<property name="windowTitle">
<string>Frequency</string>
<string>Fre&amp;quency</string>
</property>
<attribute name="dockWidgetArea">
<number>2</number>
@ -182,6 +182,9 @@
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="showGroupSeparator" stdset="0">
<bool>true</bool>
</property>
<property name="suffix">
<string> MHz</string>
</property>
@ -220,6 +223,9 @@
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="showGroupSeparator" stdset="0">
<bool>true</bool>
</property>
<property name="suffix">
<string> MHz</string>
</property>
@ -240,7 +246,7 @@
<item row="2" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Bin size:</string>
<string>&amp;Bin size:</string>
</property>
<property name="buddy">
<cstring>binSizeSpinBox</cstring>
@ -258,6 +264,9 @@
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="showGroupSeparator" stdset="0">
<bool>true</bool>
</property>
<property name="suffix">
<string> kHz</string>
</property>
@ -299,7 +308,7 @@
<set>QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable</set>
</property>
<property name="windowTitle">
<string>Settings</string>
<string>Se&amp;ttings</string>
</property>
<attribute name="dockWidgetArea">
<number>2</number>
@ -309,7 +318,7 @@
<item row="0" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Interval [s]:</string>
<string>&amp;Interval [s]:</string>
</property>
<property name="buddy">
<cstring>intervalSpinBox</cstring>
@ -319,7 +328,7 @@
<item row="0" column="1">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Gain [dB]:</string>
<string>&amp;Gain [dB]:</string>
</property>
<property name="buddy">
<cstring>gainSpinBox</cstring>
@ -497,7 +506,7 @@
<set>QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable</set>
</property>
<property name="windowTitle">
<string>Levels</string>
<string>&amp;Levels</string>
</property>
<attribute name="dockWidgetArea">
<number>2</number>

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>600</width>
<height>310</height>
<height>388</height>
</rect>
</property>
<property name="windowTitle">
@ -76,6 +76,12 @@
</item>
<item>
<widget class="QToolButton" name="executableButton">
<property name="minimumSize">
<size>
<width>50</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>...</string>
</property>
@ -83,7 +89,7 @@
</item>
</layout>
</item>
<item row="2" column="0">
<item row="3" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>&amp;Device:</string>
@ -93,9 +99,6 @@
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="deviceEdit"/>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
@ -106,23 +109,7 @@
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QSpinBox" name="sampleRateSpinBox">
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>25000000</number>
</property>
<property name="singleStep">
<number>10000</number>
</property>
<property name="value">
<number>2560000</number>
</property>
</widget>
</item>
<item row="5" column="0">
<item row="7" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>&amp;Waterfall history size:</string>
@ -132,7 +119,7 @@
</property>
</widget>
</item>
<item row="5" column="1">
<item row="7" column="1">
<widget class="QSpinBox" name="waterfallHistorySizeSpinBox">
<property name="minimum">
<number>1</number>
@ -145,30 +132,157 @@
</property>
</widget>
</item>
<item row="3" column="0">
<item row="5" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Bandwidt&amp;h:</string>
</property>
<property name="buddy">
<cstring>bandwidthSpinBox</cstring>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_8">
<property name="toolTip">
<string>Negative frequency for upconverters, positive frequency for downconverters.</string>
</property>
<property name="text">
<string>&amp;LNB LO:</string>
</property>
<property name="buddy">
<cstring>lnbSpinBox</cstring>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Additional &amp;parameters:</string>
<string>Add&amp;itional parameters:</string>
</property>
<property name="buddy">
<cstring>paramsEdit</cstring>
</property>
</widget>
</item>
<item row="3" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item row="2" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLineEdit" name="paramsEdit"/>
</item>
<item>
<widget class="QToolButton" name="helpButton">
<widget class="QToolButton" name="paramsHelpButton">
<property name="minimumSize">
<size>
<width>50</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>?</string>
<string> ? </string>
</property>
</widget>
</item>
</layout>
</item>
<item row="3" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLineEdit" name="deviceEdit"/>
</item>
<item>
<widget class="QToolButton" name="deviceHelpButton">
<property name="minimumSize">
<size>
<width>50</width>
<height>0</height>
</size>
</property>
<property name="text">
<string> ? </string>
</property>
</widget>
</item>
</layout>
</item>
<item row="4" column="1">
<widget class="QDoubleSpinBox" name="sampleRateSpinBox">
<property name="showGroupSeparator" stdset="0">
<bool>true</bool>
</property>
<property name="suffix">
<string> MHz</string>
</property>
<property name="decimals">
<number>3</number>
</property>
<property name="minimum">
<double>0.000000000000000</double>
</property>
<property name="maximum">
<double>61.439999999999998</double>
</property>
<property name="singleStep">
<double>0.010000000000000</double>
</property>
<property name="value">
<double>61.439999999999998</double>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QDoubleSpinBox" name="bandwidthSpinBox">
<property name="showGroupSeparator" stdset="0">
<bool>true</bool>
</property>
<property name="suffix">
<string> MHz</string>
</property>
<property name="decimals">
<number>3</number>
</property>
<property name="minimum">
<double>0.000000000000000</double>
</property>
<property name="maximum">
<double>61.439999999999998</double>
</property>
<property name="singleStep">
<double>0.010000000000000</double>
</property>
<property name="value">
<double>0.000000000000000</double>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QDoubleSpinBox" name="lnbSpinBox">
<property name="toolTip">
<string>Negative frequency for upconverters, positive frequency for downconverters.</string>
</property>
<property name="showGroupSeparator" stdset="0">
<bool>true</bool>
</property>
<property name="suffix">
<string> MHz</string>
</property>
<property name="decimals">
<number>3</number>
</property>
<property name="minimum">
<double>-999999.998999999952503</double>
</property>
<property name="maximum">
<double>999999.998999999952503</double>
</property>
<property name="singleStep">
<double>0.010000000000000</double>
</property>
<property name="value">
<double>0.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item>
@ -200,12 +314,14 @@
<tabstop>backendComboBox</tabstop>
<tabstop>executableEdit</tabstop>
<tabstop>executableButton</tabstop>
<tabstop>deviceEdit</tabstop>
<tabstop>paramsEdit</tabstop>
<tabstop>helpButton</tabstop>
<tabstop>paramsHelpButton</tabstop>
<tabstop>deviceEdit</tabstop>
<tabstop>deviceHelpButton</tabstop>
<tabstop>sampleRateSpinBox</tabstop>
<tabstop>bandwidthSpinBox</tabstop>
<tabstop>lnbSpinBox</tabstop>
<tabstop>waterfallHistorySizeSpinBox</tabstop>
<tabstop>buttonBox</tabstop>
</tabstops>
<resources/>
<connections>
@ -216,8 +332,8 @@
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>303</y>
<x>254</x>
<y>377</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
@ -232,8 +348,8 @@
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>303</y>
<x>322</x>
<y>377</y>
</hint>
<hint type="destinationlabel">
<x>286</x>

View File

@ -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"))

View File

@ -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 &parameters:"))
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"))

View File

@ -30,7 +30,7 @@ setup(
],
},
install_requires=[
"soapy_power>=1.3.0",
"soapy_power>=1.4.0",
"pyqtgraph>=0.10.0",
"Qt.py"
],