diff --git a/audio_player.py b/audio_player.py index 927fef3..af7a27a 100644 --- a/audio_player.py +++ b/audio_player.py @@ -14,7 +14,6 @@ class AudioPlayer(object): """ __time_step = 500 # Milliseconds. - __delay_load_audio = 250 # Milliseconds def __init__(self, play, pause, stop, volume, audio_progress): self.__paused = False diff --git a/double_text_button.py b/double_text_button.py new file mode 100644 index 0000000..51af643 --- /dev/null +++ b/double_text_button.py @@ -0,0 +1,16 @@ +from PyQt5.QtWidgets import QPushButton + +class DoubleTextButton(QPushButton): + def __init__(self, parent = None): + super().__init__(parent) + self.clicked.connect(self.change_text) + + def set_texts(self, text_a, text_b): + self.text_a = text_a + self.text_b = text_b + + def change_text(self): + if self.isChecked(): + self.setText(self.text_b) + else: + self.setText(self.text_a) \ No newline at end of file diff --git a/filters.py b/filters.py index e69de29..6e3f994 100644 --- a/filters.py +++ b/filters.py @@ -0,0 +1,13 @@ +from collections import namedtuple + +class Filters(object): + def __init__(self, *all_filters): + self.filter_widgets = all_filters + + def activate(self): + for f in self.filter_widgets: + f.setEnabled(True) + + def deactivate(self): + for f in self.filter_widgets: + f.setEnabled(False) diff --git a/main.py b/main.py index ab0733c..b367334 100644 --- a/main.py +++ b/main.py @@ -15,6 +15,8 @@ from PyQt5.QtCore import QFileInfo, QSize, Qt from audio_player import AudioPlayer +from double_text_button import DoubleTextButton + qt_creator_file = "main_window.ui" Ui_MainWindow, _ = uic.loadUiType(qt_creator_file) @@ -38,10 +40,6 @@ class MyApp(QMainWindow, Ui_MainWindow): def __init__(self): super().__init__() self.setupUi(self) - - - - self.set_initial_size() self.show() self.actionExit.triggered.connect(qApp.quit) @@ -51,6 +49,8 @@ class MyApp(QMainWindow, Ui_MainWindow): self.undefined_freq = False self.undefined_band = False self.signal_names = [] + self.apply_reset_freq_filter_btn.set_texts("Apply frequency filters", + "Remove frequency filters") UrlColors = namedtuple("UrlColors", ["inactive", "active", "clicked"]) self.url_button.colors = UrlColors("#9f9f9f", "#4c75ff", "#942ccc") self.category_labels = [self.cat_mil, @@ -83,6 +83,7 @@ class MyApp(QMainWindow, Ui_MainWindow): self.load_db() self.display_signals() self.search_bar.textChanged.connect(self.display_signals) + self.apply_reset_freq_filter_btn.clicked.connect(self.display_signals) self.result_list.currentItemChanged.connect(self.display_specs) self.audio_widget = AudioPlayer(self.play, self.pause, @@ -105,11 +106,56 @@ class MyApp(QMainWindow, Ui_MainWindow): BandLabel(self.ehf_left, self.ehf, self.ehf_right), ] + self.frequency_filters = ( + self.elf_filter_btn, + self.slf_filter_btn, + self.ulf_filter_btn, + self.vlf_filter_btn, + self.lf_filter_btn, + self.mf_filter_btn, + self.hf_filter_btn, + self.vhf_filter_btn, + self.uhf_filter_btn, + self.shf_filter_btn, + self.ehf_filter_btn, + ) + def set_initial_size(self): + """ + Function to handle high resolution screens. The function sets bigger sizes + for all the relevant fixed-size widgets. + """ d = QDesktopWidget().availableGeometry() w = d.width() h = d.height() self.setGeometry(50, 50, (3 * w) // 4, (3 * h) // 4) + if w > 3000 or h > 2000: + self.fixed_audio_and_image.setFixedSize(540, 1150) + self.play.setFixedSize(140, 140) + self.pause.setFixedSize(140, 140) + self.stop.setFixedSize(140, 140) + self.lower_freq_spinbox.setFixedWidth(200) + self.upper_freq_spinbox.setFixedWidth(200) + self.lower_freq_filter_unit.setFixedWidth(120) + self.upper_freq_filter_unit.setFixedWidth(120) + self.lower_freq_confidence.setFixedWidth(120) + self.upper_freq_confidence.setFixedWidth(120) + self.audio_progress.setFixedHeight(20) + self.volume.setStyleSheet(""" + QSlider::groove:horizontal { + height: 12px; + background: #7a7a7a; + margin: 0 10px; + border-radius: 6px + } + QSlider::handle:horizontal { + background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 gray, stop:0.5 white, stop:1.0 gray); + border: 1px solid #5c5c5c; + width: 25px; + margin: -10px -10px; + border-radius: 12px; + } + """) def load_db(self): names = ["name", @@ -165,9 +211,54 @@ class MyApp(QMainWindow, Ui_MainWindow): def display_signals(self): self.result_list.clear() for signal in self.signal_names: - if self.search_bar.text().lower() in signal.lower(): + if self.search_bar.text().lower() in signal.lower() and \ + self.frequency_filters_ok(signal): self.result_list.addItem(signal) + def frequency_filters_ok(self, signal_name): + if self.apply_reset_freq_filter_btn.isChecked(): + undef_freq, _ = self.find_if_undefined(self.db.loc[signal_name]) + if not undef_freq: + conversion_factors = {"Hz":1, "kHz":1000, "MHz":1000000, + "GHz":1000000000} + + signal_freqs = (int(self.db.at[signal_name, "inf_freq"]), + int(self.db.at[signal_name, "sup_freq"])) + + band_filter_ok = False + any_checked = False + for btn, band_limits in zip(self.frequency_filters, self.bands): + if btn.isChecked(): + any_checked = True + if signal_freqs[0] >= band_limits.lower and signal_freqs[1] < band_limits.upper: + band_filter_ok = True + lower_freq_filter = self.lower_freq_spinbox.value() + upper_freq_filter = self.upper_freq_spinbox.value() + if lower_freq_filter > 0 and upper_freq_filter > 0: + lower_tol = self.lower_freq_confidence.value() + upper_tol = self.upper_freq_confidence.value() + lower_limit = lower_freq_filter - lower_tol / 100 * lower_freq_filter + upper_limit = upper_freq_filter + lower_tol / 100 * lower_freq_filter + lower_units = self.lower_freq_filter_unit.currentText() + upper_units = self.upper_freq_filter_unit.currentText() + lower_limit *= conversion_factors[lower_units] + upper_limit *= conversion_factors[upper_units] + if signal_freqs[0] >= lower_limit and signal_freqs[1] <= upper_limit: + if any_checked: + return band_filter_ok + else: + return True + else: + return False + else: + if any_checked: + return band_filter_ok + else: + return False + else: + return False + return True + def display_specs(self): self.display_spectrogram() item = self.result_list.currentItem() @@ -189,15 +280,15 @@ class MyApp(QMainWindow, Ui_MainWindow): else: self.url_button.setStyleSheet(f"color: {self.url_button.colors.clicked};") category_code = current_signal.at["category_code"] - self.find_if_undefined(current_signal) - if not self.undefined_freq: + undef_freq, undef_band = self.find_if_undefined(current_signal) + if not undef_freq: self.freq_lab.setText(self.format_numbers( current_signal.at["inf_freq"], current_signal.at["sup_freq"]) ) else: self.freq_lab.setText("Undefined") - if not self.undefined_band: + if not undef_band: self.band_lab.setText(self.format_numbers( current_signal.at["inf_band"], current_signal.at["sup_band"]) @@ -236,13 +327,14 @@ class MyApp(QMainWindow, Ui_MainWindow): upper_freq = current_signal.at["sup_freq"] upper_band = current_signal.at["sup_band"] if lower_freq == '0' and upper_freq == "100000000000": - self.undefined_freq = True + undefined_freq = True else: - self.undefined_freq = False + undefined_freq = False if lower_band == '0' and upper_band == '100000000': - self.undefined_band = True + undefined_band = True else: - self.undefined_band = False + undefined_band = False + return undefined_freq, undefined_band @classmethod def format_numbers(cls, lower, upper): diff --git a/main_window.ui b/main_window.ui index eb9561d..83e0bc1 100644 --- a/main_window.ui +++ b/main_window.ui @@ -6,7 +6,7 @@ 0 0 - 1211 + 1206 638 @@ -306,6 +306,10 @@ QTabBar::tab:selected { QTabBar::tab:!selected { margin-top: 3px; /* make non-selected tabs look smaller */ +} + +QPushButton:!enabled { + color:#9f9f9f; } @@ -1909,30 +1913,22 @@ p, li { white-space: pre-wrap; } - QLineEdit { - background-color: rgb(52,52,52); - color: #ffffff; - border: 1px solid gray; - border-radius: 5px; -} -/* -QComboBox { - background-color: rgb(52,52,52); - color: #ffffff; - border: 1px solid gray; - border-radius: 5px; -} -*/ -QComboBox { + QComboBox { background-color: rgb(52,52,52); color: #ffffff; border: 1px solid gray; border-radius: 5px; } +QComboBox:!enabled { + color: #9f9f9f; +} + QComboBox QAbstractItemView { border: 1px solid gray; selection-background-color: #999999; + selection-color: #1d5eff; + color: #ffffff; } QSpinBox { @@ -1942,10 +1938,22 @@ QSpinBox { border-radius: 5px; } +QSpinBox:!enabled { + color:#9f9f9f; +} + QPushButton { background-color: rgb(52,52,52); border: 1px solid gray; border-radius: 5px; +} + +QPushButton:!enabled { + color:#9f9f9f; +} + +QPushButton:checked { + color: #39eaff; } @@ -1971,147 +1979,11 @@ QPushButton { - - - - - 12 - 75 - true - - - - LF - - - true - - - - - - - - 12 - 75 - true - - - - VLF - - - true - - - - - - - - 12 - 75 - true - - - - EHF - - - true - - - false - - - - - - - - 12 - 75 - true - - - - SHF - - - true - - - - - - - - 12 - 75 - true - - - - VHF - - - true - - - - - - - - 12 - 75 - true - - - - SLF - - - true - - - - - - - - 12 - 75 - true - - - - UHF - - - true - - - - - - - - 12 - 75 - true - - - - ULF - - - true - - - - + + + true + 0 @@ -2133,13 +2005,50 @@ QPushButton { + + + + true + + + + 12 + 75 + true + + + + SLF + + + true + + + + + + + true + + + + 12 + 75 + true + + + + ULF + + + true + + + - - - - 0 - 0 - + + + true @@ -2149,20 +2058,17 @@ QPushButton { - HF + VLF true - - - - - 0 - 0 - + + + + true @@ -2172,15 +2078,18 @@ QPushButton { - EHF + LF true - - + + + + true + 0 @@ -2202,6 +2111,115 @@ QPushButton { + + + + true + + + + 0 + 0 + + + + + 12 + 75 + true + + + + HF + + + true + + + + + + + true + + + + 12 + 75 + true + + + + VHF + + + true + + + + + + + true + + + + 12 + 75 + true + + + + UHF + + + true + + + + + + + true + + + + 12 + 75 + true + + + + SHF + + + true + + + + + + + true + + + + 12 + 75 + true + + + + EHF + + + true + + + false + + + @@ -2213,7 +2231,7 @@ QPushButton { 0 - + @@ -2222,326 +2240,382 @@ QPushButton { 0 - - - - - 6 + + + + + true - + + + 0 + 0 + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + + 12 + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 1000000000 + + + + + + + + 0 + 0 + + + + + 12 + 75 + true + + + + Upper frequency + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + true + + + + 0 + 0 + + + + + 60 + 0 + + + + + 16777215 + 16777215 + + + + + 12 + 75 + true + + + + + Hz + + + + + kHz + + + + + MHz + + + + + GHz + + + + + + + + true + + + + 0 + 0 + + + + + 60 + 0 + + + + + 50 + 16777215 + + + + + 12 + + + + false + + + Qt::AlignCenter + + + QAbstractSpinBox::UpDownArrows + + + + + + 100 + + + 5 + + + + + + + true + + + + 0 + 0 + + + + + 60 + 0 + + + + + 50 + 16777215 + + + + + 12 + + + + false + + + Qt::AlignCenter + + + QAbstractSpinBox::UpDownArrows + + + + + + 100 + + + 5 + + + + + + + + 0 + 0 + + + + + 12 + 75 + true + + + + Lower frequency + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + 12 + 75 + true + + + + Confidence % + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + 12 + 75 + true + + + + Confidence % + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + true + + + + 0 + 0 + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + + 12 + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 1000000000 + + + 0 + + + + + + + true + + + + 0 + 0 + + + + + 60 + 0 + + + + + 16777215 + 16777215 + + + + + 12 + 75 + true + + + + 4 + + + false + + 0 - - - - 0 - 0 - - - - - 12 - 75 - true - - - - Lower frequency - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - + + Hz + - - - - 0 - 0 - - - - - 100 - 0 - - - - - 100 - 16777215 - - - - - 12 - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - 1000000000 - - + + kHz + - - - - 0 - 0 - - - - - 50 - 16777215 - - - - - 12 - 75 - true - - - - 4 - - - false - - - 0 - - + + MHz + - - - - 0 - 0 - - - - - 12 - 75 - true - - - - Confidence % - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - + + GHz + - - - - - 0 - 0 - - - - - 60 - 0 - - - - - 50 - 16777215 - - - - - 12 - - - - false - - - Qt::AlignCenter - - - QAbstractSpinBox::UpDownArrows - - - - - - 100 - - - 5 - - - - - - - - - - - - 0 - 0 - - - - - 12 - 75 - true - - - - Upper frequency - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - - 100 - 0 - - - - - 100 - 16777215 - - - - - 12 - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - 1000000000 - - - 100 - - - - - - - - 0 - 0 - - - - - 50 - 16777215 - - - - - 12 - 75 - true - - - - - - - - - 0 - 0 - - - - - 12 - 75 - true - - - - Confidence % - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - - 60 - 0 - - - - - 50 - 16777215 - - - - - 12 - - - - false - - - Qt::AlignCenter - - - QAbstractSpinBox::UpDownArrows - - - - - - 100 - - - 5 - - - - + @@ -2550,7 +2624,10 @@ QPushButton { - + + + true + 12 @@ -2559,21 +2636,10 @@ QPushButton { - Applay + Applay frequency filters - - - - - - - 12 - 75 - true - - - - Reset + + true @@ -2613,6 +2679,9 @@ QPushButton { + + true + 15 @@ -2626,7 +2695,7 @@ border: 1px solid gray; border-radius: 5px; - Reset all filters + Remove all filters @@ -2636,7 +2705,7 @@ border-radius: 5px; - + 0 @@ -2876,7 +2945,7 @@ QSlider::handle:horizontal { - + 0 0 @@ -2914,7 +2983,7 @@ QSlider::handle:horizontal { 0 0 - 1211 + 1206 21 @@ -2961,6 +3030,13 @@ QMenu::item:selected { + + + DoubleTextButton + QPushButton +
double_text_button.h
+
+