Implement themes
1
.gitignore
vendored
@@ -6,3 +6,4 @@ wav_converter.py
|
|||||||
*.txt
|
*.txt
|
||||||
icons_imgs
|
icons_imgs
|
||||||
TestData
|
TestData
|
||||||
|
themes/.current_theme
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ import sys
|
|||||||
from pydub import AudioSegment
|
from pydub import AudioSegment
|
||||||
from pygame import mixer
|
from pygame import mixer
|
||||||
from PyQt5.QtCore import QTimer, QTimer, pyqtSlot, QObject
|
from PyQt5.QtCore import QTimer, QTimer, pyqtSlot, QObject
|
||||||
import qtawesome as qta
|
|
||||||
|
|
||||||
from utilities import Constants
|
from utilities import Constants
|
||||||
|
import qtawesome as qta
|
||||||
|
|
||||||
|
|
||||||
class AudioPlayer(QObject): # Maybe useless inheriting from QObject
|
class AudioPlayer(QObject): # Maybe useless inheriting from QObject
|
||||||
@@ -17,7 +17,7 @@ class AudioPlayer(QObject): # Maybe useless inheriting from QObject
|
|||||||
|
|
||||||
__time_step = 500 # Milliseconds.
|
__time_step = 500 # Milliseconds.
|
||||||
|
|
||||||
def __init__(self, play, pause, stop, volume, audio_progress):
|
def __init__(self, play, pause, stop, volume, audio_progress, active_color, inactive_color):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.__paused = False
|
self.__paused = False
|
||||||
self.__first_call = True
|
self.__first_call = True
|
||||||
@@ -33,18 +33,21 @@ class AudioPlayer(QObject): # Maybe useless inheriting from QObject
|
|||||||
self.__pause.clicked.connect(self.__pause_audio)
|
self.__pause.clicked.connect(self.__pause_audio)
|
||||||
self.__stop.clicked.connect(self.__stop_audio)
|
self.__stop.clicked.connect(self.__stop_audio)
|
||||||
self.__volume.valueChanged.connect(self.__set_volume)
|
self.__volume.valueChanged.connect(self.__set_volume)
|
||||||
self.__play.setIcon(qta.icon('fa5.play-circle',
|
|
||||||
color = "#4facf1",
|
|
||||||
color_disabled = '#7a7a7a'))
|
|
||||||
self.__play.setIconSize(self.__play.size())
|
self.__play.setIconSize(self.__play.size())
|
||||||
self.__pause.setIcon(qta.icon('fa5.pause-circle',
|
|
||||||
color = "#4facf1",
|
|
||||||
color_disabled = '#7a7a7a'))
|
|
||||||
self.__pause.setIconSize(self.__pause.size())
|
self.__pause.setIconSize(self.__pause.size())
|
||||||
self.__stop.setIcon(qta.icon('fa5.stop-circle',
|
|
||||||
color = "#4facf1",
|
|
||||||
color_disabled = '#7a7a7a'))
|
|
||||||
self.__stop.setIconSize(self.__stop.size())
|
self.__stop.setIconSize(self.__stop.size())
|
||||||
|
self.refresh_btns_colors(active_color, inactive_color)
|
||||||
|
|
||||||
|
def refresh_btns_colors(self, active_color, inactive_color):
|
||||||
|
self.__play.setIcon(qta.icon('fa5.play-circle',
|
||||||
|
color = active_color,
|
||||||
|
color_disabled = inactive_color))
|
||||||
|
self.__pause.setIcon(qta.icon('fa5.pause-circle',
|
||||||
|
color = active_color,
|
||||||
|
color_disabled = inactive_color))
|
||||||
|
self.__stop.setIcon(qta.icon('fa5.stop-circle',
|
||||||
|
color = active_color,
|
||||||
|
color_disabled = inactive_color))
|
||||||
|
|
||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
def __set_volume(self):
|
def __set_volume(self):
|
||||||
|
|||||||
@@ -14,33 +14,7 @@
|
|||||||
<string>Download database</string>
|
<string>Download database</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="styleSheet">
|
<property name="styleSheet">
|
||||||
<string notr="true">QWidget {
|
<string notr="true"/>
|
||||||
background-color: #464646
|
|
||||||
}
|
|
||||||
|
|
||||||
QLabel {
|
|
||||||
color: #ffffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
QProgressBar {
|
|
||||||
border: 2px #7a7a7a;
|
|
||||||
border-radius: 5px;
|
|
||||||
background-color: #7a7a7a;
|
|
||||||
}
|
|
||||||
|
|
||||||
QProgressBar::chunk {
|
|
||||||
background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #1d5eff, stop:0.5 #4177ff, stop:1 #1d5eff);
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QMessageBox {
|
|
||||||
color: #ffffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
QPushButton {
|
|
||||||
color: #ffffff;
|
|
||||||
}</string>
|
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<property name="sizeConstraint">
|
<property name="sizeConstraint">
|
||||||
@@ -73,6 +47,9 @@ Please wait</string>
|
|||||||
<property name="value">
|
<property name="value">
|
||||||
<number>-1</number>
|
<number>-1</number>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="textVisible">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
@@ -83,13 +60,7 @@ Please wait</string>
|
|||||||
</font>
|
</font>
|
||||||
</property>
|
</property>
|
||||||
<property name="styleSheet">
|
<property name="styleSheet">
|
||||||
<string notr="true">QPushButton {
|
<string notr="true"/>
|
||||||
background-color: rgb(52,52,52);
|
|
||||||
color: #FFFFFF;
|
|
||||||
border: 1px solid gray;
|
|
||||||
border-radius: 8px;
|
|
||||||
}
|
|
||||||
</string>
|
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Cancel</string>
|
<string>Cancel</string>
|
||||||
|
|||||||
202
main.py
@@ -1,5 +1,6 @@
|
|||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
from glob import glob
|
||||||
import webbrowser
|
import webbrowser
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
@@ -7,12 +8,13 @@ import sys
|
|||||||
from pandas import read_csv
|
from pandas import read_csv
|
||||||
from PyQt5.QtWidgets import (QMainWindow,
|
from PyQt5.QtWidgets import (QMainWindow,
|
||||||
QApplication,
|
QApplication,
|
||||||
|
QAction,
|
||||||
QMessageBox,
|
QMessageBox,
|
||||||
qApp,
|
qApp,
|
||||||
QDesktopWidget,
|
QDesktopWidget,
|
||||||
QListWidgetItem,
|
QListWidgetItem,
|
||||||
QTreeView,
|
QTreeView,
|
||||||
QTreeWidgetItem)
|
QTreeWidgetItem,)
|
||||||
from PyQt5.QtGui import QPixmap
|
from PyQt5.QtGui import QPixmap
|
||||||
from PyQt5 import uic
|
from PyQt5 import uic
|
||||||
from PyQt5.QtCore import (QFileInfo,
|
from PyQt5.QtCore import (QFileInfo,
|
||||||
@@ -24,7 +26,12 @@ from audio_player import AudioPlayer
|
|||||||
|
|
||||||
from double_text_button import DoubleTextButton
|
from double_text_button import DoubleTextButton
|
||||||
from download_window import DownloadWindow
|
from download_window import DownloadWindow
|
||||||
from utilities import Constants, reset_apply_remove_btn
|
|
||||||
|
|
||||||
|
from utilities import (Constants,
|
||||||
|
reset_apply_remove_btn,
|
||||||
|
throwable_message,
|
||||||
|
is_valid_html_color,)
|
||||||
|
|
||||||
qt_creator_file = "main_window.ui"
|
qt_creator_file = "main_window.ui"
|
||||||
Ui_MainWindow, _ = uic.loadUiType(qt_creator_file)
|
Ui_MainWindow, _ = uic.loadUiType(qt_creator_file)
|
||||||
@@ -42,6 +49,8 @@ class MyApp(QMainWindow, Ui_MainWindow):
|
|||||||
self.current_signal_name = ''
|
self.current_signal_name = ''
|
||||||
self.signal_names = []
|
self.signal_names = []
|
||||||
self.total_signals = 0
|
self.total_signals = 0
|
||||||
|
self.active_color = Constants.ACTIVE_COLOR
|
||||||
|
self.inactive_color = Constants.INACTIVE_COLOR
|
||||||
|
|
||||||
# Manage frequency filters.
|
# Manage frequency filters.
|
||||||
self.frequency_filters_btns = (
|
self.frequency_filters_btns = (
|
||||||
@@ -301,6 +310,13 @@ class MyApp(QMainWindow, Ui_MainWindow):
|
|||||||
self.reset_location_filters_btn.clicked.connect(self.reset_location_filters)
|
self.reset_location_filters_btn.clicked.connect(self.reset_location_filters)
|
||||||
self.locations_list.itemClicked.connect(self.remove_if_unselected_location)
|
self.locations_list.itemClicked.connect(self.remove_if_unselected_location)
|
||||||
|
|
||||||
|
# Find available themes.
|
||||||
|
self.default_images_folder = os.path.join(Constants.THEMES_FOLDER,
|
||||||
|
Constants.DEFAULT_THEME,
|
||||||
|
Constants.ICONS_FOLDER)
|
||||||
|
# self.find_themes()
|
||||||
|
# self.set_theme()
|
||||||
|
|
||||||
# ##########################################################################################
|
# ##########################################################################################
|
||||||
|
|
||||||
self.load_db()
|
self.load_db()
|
||||||
@@ -309,16 +325,15 @@ class MyApp(QMainWindow, Ui_MainWindow):
|
|||||||
self.search_bar.textChanged.connect(self.display_signals)
|
self.search_bar.textChanged.connect(self.display_signals)
|
||||||
self.result_list.addItems(self.signal_names)
|
self.result_list.addItems(self.signal_names)
|
||||||
self.result_list.currentItemChanged.connect(self.display_specs)
|
self.result_list.currentItemChanged.connect(self.display_specs)
|
||||||
self.result_list.itemDoubleClicked.connect(lambda: self.main_tab.setCurrentWidget(
|
self.result_list.itemDoubleClicked.connect(lambda: self.main_tab.setCurrentWidget(self.signal_properties_tab))
|
||||||
self.signal_properties_tab
|
|
||||||
)
|
|
||||||
)
|
|
||||||
self.display_signals()
|
self.display_signals()
|
||||||
self.audio_widget = AudioPlayer(self.play,
|
self.audio_widget = AudioPlayer(self.play,
|
||||||
self.pause,
|
self.pause,
|
||||||
self.stop,
|
self.stop,
|
||||||
self.volume,
|
self.volume,
|
||||||
self.audio_progress)
|
self.audio_progress,
|
||||||
|
self.active_color,
|
||||||
|
self.inactive_color)
|
||||||
|
|
||||||
BandLabel = namedtuple("BandLabel", ["left", "center", "right"])
|
BandLabel = namedtuple("BandLabel", ["left", "center", "right"])
|
||||||
self.band_labels = [
|
self.band_labels = [
|
||||||
@@ -334,8 +349,124 @@ class MyApp(QMainWindow, Ui_MainWindow):
|
|||||||
BandLabel(self.shf_left, self.shf, self.shf_right),
|
BandLabel(self.shf_left, self.shf, self.shf_right),
|
||||||
BandLabel(self.ehf_left, self.ehf, self.ehf_right),
|
BandLabel(self.ehf_left, self.ehf, self.ehf_right),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
self.find_themes()
|
||||||
|
self.set_theme()
|
||||||
|
|
||||||
self.show()
|
self.show()
|
||||||
|
|
||||||
|
def find_themes(self):
|
||||||
|
themes = []
|
||||||
|
for theme_folder in os.listdir(Constants.THEMES_FOLDER):
|
||||||
|
relative_folder = os.path.join(Constants.THEMES_FOLDER, theme_folder)
|
||||||
|
if os.path.isdir(os.path.abspath(relative_folder)):
|
||||||
|
relative_folder = os.path.join(Constants.THEMES_FOLDER, theme_folder)
|
||||||
|
themes.append(relative_folder)
|
||||||
|
for theme in themes:
|
||||||
|
theme_name = '&' + ' '.join(
|
||||||
|
map(lambda s: s.capitalize(),
|
||||||
|
os.path.basename(theme).split('-')[1].split('_')
|
||||||
|
)
|
||||||
|
)
|
||||||
|
new_theme = QAction(theme_name, self)
|
||||||
|
self.menu_themes.addAction(new_theme)
|
||||||
|
|
||||||
|
@pyqtSlot()
|
||||||
|
def show_new_theme(theme):
|
||||||
|
self.change_theme(theme)
|
||||||
|
self.display_specs(self.result_list.currentItem(), None)
|
||||||
|
new_theme.triggered.connect(partial(show_new_theme, theme))
|
||||||
|
|
||||||
|
@pyqtSlot()
|
||||||
|
def change_theme(self, theme_path):
|
||||||
|
try:
|
||||||
|
with open(os.path.join(
|
||||||
|
theme_path,
|
||||||
|
os.path.basename(theme_path).split('-')[1] + Constants.THEME_EXTENSION)
|
||||||
|
) as stylesheet:
|
||||||
|
style = stylesheet.read()
|
||||||
|
self.setStyleSheet(style)
|
||||||
|
self.download_window.setStyleSheet(style)
|
||||||
|
except FileNotFoundError:
|
||||||
|
throwable_message(self, title = "Theme not found",
|
||||||
|
text = f"Missing theme in {Constants.THEMES_FOLDER} folder.").show()
|
||||||
|
else:
|
||||||
|
icons_path = os.path.join(theme_path, Constants.ICONS_FOLDER)
|
||||||
|
default_icons_path = os.path.join(Constants.THEMES_FOLDER, Constants.DEFAULT_THEME, Constants.ICONS_FOLDER)
|
||||||
|
|
||||||
|
if os.path.exists(os.path.join(icons_path, Constants.NOT_SELECTED)) and \
|
||||||
|
os.path.exists(os.path.join(icons_path, Constants.NOT_AVAILABLE)):
|
||||||
|
self.default_images_folder = icons_path
|
||||||
|
else:
|
||||||
|
self.default_images_folder = default_icons_path
|
||||||
|
|
||||||
|
path_to_search_label = os.path.join(icons_path, Constants.SEARCH_LABEL_IMG)
|
||||||
|
default_search_label = os.path.join(default_icons_path, Constants.SEARCH_LABEL_IMG)
|
||||||
|
|
||||||
|
if os.path.exists(path_to_search_label):
|
||||||
|
self.search_label.setPixmap(QPixmap(path_to_search_label))
|
||||||
|
self.modulation_search_label.setPixmap(QPixmap(path_to_search_label))
|
||||||
|
self.location_search_label.setPixmap(QPixmap(path_to_search_label))
|
||||||
|
else:
|
||||||
|
self.search_label.setPixmap(QPixmap(default_search_label))
|
||||||
|
self.modulation_search_label.setPixmap(QPixmap(default_search_label))
|
||||||
|
self.location_search_label.setPixmap(QPixmap(default_search_label))
|
||||||
|
|
||||||
|
self.search_label.setScaledContents(True)
|
||||||
|
self.modulation_search_label.setScaledContents(True)
|
||||||
|
self.location_search_label.setScaledContents(True)
|
||||||
|
|
||||||
|
path_to_volume_label = os.path.join(icons_path, Constants.VOLUME_LABEL_IMG)
|
||||||
|
default_volume_label = os.path.join(default_icons_path, Constants.VOLUME_LABEL_IMG)
|
||||||
|
|
||||||
|
if os.path.exists(path_to_volume_label):
|
||||||
|
self.volume_label.setPixmap(QPixmap(path_to_volume_label))
|
||||||
|
else:
|
||||||
|
self.volume_label.setPixmap(QPixmap(default_volume_label))
|
||||||
|
|
||||||
|
self.volume_label.setScaledContents(True)
|
||||||
|
|
||||||
|
path_to_colors = os.path.join(theme_path, Constants.THEME_COLORS)
|
||||||
|
active_color_ok = False
|
||||||
|
inactive_color_ok = False
|
||||||
|
valid_format = False
|
||||||
|
valid_file = False
|
||||||
|
if os.path.exists(path_to_colors):
|
||||||
|
valid_file = True
|
||||||
|
with open(path_to_colors, "r") as colors_file:
|
||||||
|
for line in colors_file:
|
||||||
|
if '=' in line:
|
||||||
|
valid_format = True
|
||||||
|
quality, color = line.split("=")
|
||||||
|
color = color.rstrip()
|
||||||
|
if quality == "active" and is_valid_html_color(color):
|
||||||
|
self.active_color = color
|
||||||
|
active_color_ok = True
|
||||||
|
if quality == "inactive" and is_valid_html_color(color):
|
||||||
|
self.inactive_color = color
|
||||||
|
inactive_color_ok = True
|
||||||
|
|
||||||
|
if not all([valid_file, valid_format, active_color_ok, inactive_color_ok]):
|
||||||
|
self.active_color = Constants.ACTIVE_COLOR
|
||||||
|
self.inactive_color = Constants.INACTIVE_COLOR
|
||||||
|
|
||||||
|
self.audio_widget.refresh_btns_colors(self.active_color, self.inactive_color)
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(os.path.join(Constants.THEMES_FOLDER,
|
||||||
|
Constants.CURRENT_THEME), "w") as current_theme:
|
||||||
|
current_theme.write(theme_path)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def set_theme(self):
|
||||||
|
current_theme_file = os.path.join(Constants.THEMES_FOLDER, Constants.CURRENT_THEME)
|
||||||
|
if os.path.exists(current_theme_file):
|
||||||
|
with open(current_theme_file) as current_theme:
|
||||||
|
theme = current_theme.read()
|
||||||
|
if theme != Constants.DEFAULT_THEME:
|
||||||
|
self.change_theme(theme)
|
||||||
|
|
||||||
@pyqtSlot(QListWidgetItem)
|
@pyqtSlot(QListWidgetItem)
|
||||||
def remove_if_unselected_modulation(self, item):
|
def remove_if_unselected_modulation(self, item):
|
||||||
if not item.isSelected():
|
if not item.isSelected():
|
||||||
@@ -440,42 +571,25 @@ class MyApp(QMainWindow, Ui_MainWindow):
|
|||||||
self.display_signals()
|
self.display_signals()
|
||||||
|
|
||||||
def load_db(self):
|
def load_db(self):
|
||||||
names = ["name",
|
names = Constants.DB_NAMES
|
||||||
"inf_freq",
|
|
||||||
"sup_freq",
|
|
||||||
"mode",
|
|
||||||
"inf_band",
|
|
||||||
"sup_band",
|
|
||||||
"location",
|
|
||||||
"url",
|
|
||||||
"description",
|
|
||||||
"modulation",
|
|
||||||
"category_code",
|
|
||||||
"acf",]
|
|
||||||
try:
|
try:
|
||||||
self.db = read_csv(os.path.join(Constants.DATA_FOLDER, 'db.csv'),
|
self.db = read_csv(os.path.join(Constants.DATA_FOLDER, Constants.DB_NAME),
|
||||||
sep = '*',
|
sep = '*',
|
||||||
header = None,
|
header = None,
|
||||||
index_col = 0,
|
index_col = 0,
|
||||||
dtype = {'inf_freq': str,
|
dtype = {name : str for name in Constants.DB_STRINGS},
|
||||||
'sup_freq': str,
|
|
||||||
'mode': str,
|
|
||||||
'inf_band': str,
|
|
||||||
'sup_band': str,
|
|
||||||
'category_code': str,},
|
|
||||||
names = names,)
|
names = names,)
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
self.search_bar.setDisabled(True)
|
self.search_bar.setDisabled(True)
|
||||||
box = QMessageBox(self)
|
box = QMessageBox(self)
|
||||||
box.setWindowTitle("No database")
|
box.setWindowTitle(Constants.Messages.NO_DB)
|
||||||
box.setText("No database available.\n"
|
box.setText(Constants.Messages.NO_DB_AVAIL)
|
||||||
"Go to Updates->Update database.")
|
|
||||||
box.show()
|
box.show()
|
||||||
else:
|
else:
|
||||||
self.signal_names = self.db.index
|
self.signal_names = self.db.index
|
||||||
self.total_signals = len(self.signal_names)
|
self.total_signals = len(self.signal_names)
|
||||||
self.db.fillna(Constants.UNKNOWN, inplace = True)
|
self.db.fillna(Constants.UNKNOWN, inplace = True)
|
||||||
self.db["url_clicked"] = False
|
self.db[Constants.DB_WIKI_CLICKED] = False
|
||||||
self.update_status_tip(self.total_signals)
|
self.update_status_tip(self.total_signals)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@@ -530,13 +644,13 @@ class MyApp(QMainWindow, Ui_MainWindow):
|
|||||||
range_lbl):
|
range_lbl):
|
||||||
activate_low = False
|
activate_low = False
|
||||||
activate_high = False
|
activate_high = False
|
||||||
color = Constants.INACTIVE_COLOR
|
color = self.inactive_color
|
||||||
title = ''
|
title = ''
|
||||||
to_display = ''
|
to_display = ''
|
||||||
if activate_low_btn.isChecked():
|
if activate_low_btn.isChecked():
|
||||||
to_display += str(lower_spinbox.value()) + ' ' + lower_unit.currentText()
|
to_display += str(lower_spinbox.value()) + ' ' + lower_unit.currentText()
|
||||||
activate_low = True
|
activate_low = True
|
||||||
color = Constants.ACTIVE_COLOR
|
color = self.active_color
|
||||||
if lower_confidence.value() != 0:
|
if lower_confidence.value() != 0:
|
||||||
to_display += ' - ' + str(lower_confidence.value()) + ' %'
|
to_display += ' - ' + str(lower_confidence.value()) + ' %'
|
||||||
else:
|
else:
|
||||||
@@ -545,7 +659,7 @@ class MyApp(QMainWindow, Ui_MainWindow):
|
|||||||
if activate_up_btn.isChecked():
|
if activate_up_btn.isChecked():
|
||||||
to_display += str(upper_spinbox.value()) + ' ' + upper_unit.currentText()
|
to_display += str(upper_spinbox.value()) + ' ' + upper_unit.currentText()
|
||||||
activate_high = True
|
activate_high = True
|
||||||
color = Constants.ACTIVE_COLOR
|
color = self.active_color
|
||||||
if upper_confidence.value() != 0:
|
if upper_confidence.value() != 0:
|
||||||
to_display += ' + ' + str(upper_confidence.value()) + ' %'
|
to_display += ' + ' + str(upper_confidence.value()) + ' %'
|
||||||
else:
|
else:
|
||||||
@@ -591,7 +705,7 @@ class MyApp(QMainWindow, Ui_MainWindow):
|
|||||||
|
|
||||||
def update_status_tip(self, available_signals):
|
def update_status_tip(self, available_signals):
|
||||||
if available_signals < self.total_signals:
|
if available_signals < self.total_signals:
|
||||||
self.statusbar.setStyleSheet(f'color: {Constants.ACTIVE_COLOR}')
|
self.statusbar.setStyleSheet(f'color: {self.active_color}')
|
||||||
else:
|
else:
|
||||||
self.statusbar.setStyleSheet('color: #ffffff')
|
self.statusbar.setStyleSheet('color: #ffffff')
|
||||||
self.statusbar.showMessage(f"{available_signals} out of {self.total_signals} signals displayed.")
|
self.statusbar.showMessage(f"{available_signals} out of {self.total_signals} signals displayed.")
|
||||||
@@ -821,21 +935,21 @@ class MyApp(QMainWindow, Ui_MainWindow):
|
|||||||
self.description_text.setText(current_signal.at["description"])
|
self.description_text.setText(current_signal.at["description"])
|
||||||
for cat, cat_lab in zip(category_code, self.category_labels):
|
for cat, cat_lab in zip(category_code, self.category_labels):
|
||||||
if cat == '0':
|
if cat == '0':
|
||||||
cat_lab.setStyleSheet(f"color: {Constants.INACTIVE_COLOR};")
|
cat_lab.setStyleSheet(f"color: {self.inactive_color};")
|
||||||
elif cat == '1':
|
elif cat == '1':
|
||||||
cat_lab.setStyleSheet(f"color: {Constants.ACTIVE_COLOR};")
|
cat_lab.setStyleSheet(f"color: {self.active_color};")
|
||||||
self.set_band_range(current_signal)
|
self.set_band_range(current_signal)
|
||||||
self.audio_widget.set_audio_player(self.current_signal_name)
|
self.audio_widget.set_audio_player(self.current_signal_name)
|
||||||
else:
|
else:
|
||||||
self.url_button.setEnabled(False)
|
self.url_button.setEnabled(False)
|
||||||
self.url_button.setStyleSheet(f"color: {self.url_button.colors.inactive};")
|
self.url_button.setStyleSheet(f"color: {self.url_button.colors.inactive};")
|
||||||
self.current_signal_name = ''
|
self.current_signal_name = ''
|
||||||
self.name_lab.setText("No signal")
|
self.name_lab.setText("No Signal")
|
||||||
self.name_lab.setAlignment(Qt.AlignHCenter)
|
self.name_lab.setAlignment(Qt.AlignHCenter)
|
||||||
for lab in self.property_labels:
|
for lab in self.property_labels:
|
||||||
lab.setText(Constants.UNKNOWN)
|
lab.setText(Constants.UNKNOWN)
|
||||||
for lab in self.category_labels:
|
for lab in self.category_labels:
|
||||||
lab.setStyleSheet(f"color: {Constants.INACTIVE_COLOR};")
|
lab.setStyleSheet(f"color: {self.inactive_color};")
|
||||||
self.set_band_range()
|
self.set_band_range()
|
||||||
self.audio_widget.set_audio_player()
|
self.audio_widget.set_audio_player()
|
||||||
|
|
||||||
@@ -882,23 +996,21 @@ class MyApp(QMainWindow, Ui_MainWindow):
|
|||||||
return 10**9
|
return 10**9
|
||||||
|
|
||||||
def display_spectrogram(self):
|
def display_spectrogram(self):
|
||||||
default_pic = os.path.join(Constants.ICONS_FOLDER, "nosignalselected.png")
|
default_pic = os.path.join(self.default_images_folder, Constants.NOT_SELECTED)
|
||||||
item = self.result_list.currentItem()
|
item = self.result_list.currentItem()
|
||||||
if item:
|
if item:
|
||||||
spectrogram_name = item.text()
|
spectrogram_name = item.text()
|
||||||
path_spectr = os.path.join(Constants.DATA_FOLDER,
|
path_spectr = os.path.join(Constants.DATA_FOLDER,
|
||||||
Constants.SPECTRA_FOLDER,
|
Constants.SPECTRA_FOLDER,
|
||||||
spectrogram_name + ".png")
|
spectrogram_name + Constants.SPECTRA_EXT)
|
||||||
if not QFileInfo(path_spectr).exists():
|
if not QFileInfo(path_spectr).exists():
|
||||||
path_spectr = os.path.join(Constants.ICONS_FOLDER,
|
path_spectr = os.path.join(self.default_images_folder, Constants.NOT_AVAILABLE)
|
||||||
"spectrumnotavailable.png")
|
|
||||||
else:
|
else:
|
||||||
path_spectr = default_pic
|
path_spectr = default_pic
|
||||||
self.spectrogram.setPixmap(QPixmap(path_spectr))
|
self.spectrogram.setPixmap(QPixmap(path_spectr))
|
||||||
|
|
||||||
@staticmethod
|
def activate_band_category(self, band_label, activate = True):
|
||||||
def activate_band_category(band_label, activate = True):
|
color = self.active_color if activate else self.inactive_color
|
||||||
color = Constants.ACTIVE_COLOR if activate else Constants.INACTIVE_COLOR
|
|
||||||
for label in band_label:
|
for label in band_label:
|
||||||
label.setStyleSheet(f"color: {color};")
|
label.setStyleSheet(f"color: {color};")
|
||||||
|
|
||||||
|
|||||||
1031
main_window.ui
BIN
themes/1-system/icons/nosignalselected.png
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
themes/1-system/icons/search_icon.png
Normal file
|
After Width: | Height: | Size: 5.4 KiB |
BIN
themes/1-system/icons/spectrumnotavailable.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
themes/1-system/icons/volume.png
Normal file
|
After Width: | Height: | Size: 34 KiB |
0
themes/1-system/system.th
Normal file
239
themes/2-dark/dark.th
Normal file
@@ -0,0 +1,239 @@
|
|||||||
|
QMenuBar {
|
||||||
|
color: rgb(255, 255, 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
QMenuBar::item:selected {
|
||||||
|
background:#999999;
|
||||||
|
color: #1d5eff
|
||||||
|
}
|
||||||
|
|
||||||
|
QMenu::item:selected {
|
||||||
|
background-color: #999999;
|
||||||
|
color: #1d5eff
|
||||||
|
}
|
||||||
|
|
||||||
|
QMenu {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget {
|
||||||
|
background-color: #464646
|
||||||
|
}
|
||||||
|
|
||||||
|
QLabel {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton {
|
||||||
|
color: #FFFFFF;
|
||||||
|
background-color: rgb(52,52,52);
|
||||||
|
border: 1px solid gray;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton:!enabled {
|
||||||
|
color:#9f9f9f;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton:checked {
|
||||||
|
color: #39eaff;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTabWidget::pane { /* The tab widget frame */
|
||||||
|
/* border-left: 1px solid gray;*/
|
||||||
|
border: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QTabWidget::tab-bar {
|
||||||
|
left: 30px; /* move to the right by 5px */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Style the tab using the tab sub-control. Note that
|
||||||
|
it reads QTabBar _not_ QTabWidget */
|
||||||
|
QTabBar::tab {
|
||||||
|
background: #7a7a7a;
|
||||||
|
border-top-left-radius: 8px;
|
||||||
|
border-top-right-radius: 8px;
|
||||||
|
min-width: 16ex;
|
||||||
|
padding: 2px;
|
||||||
|
color: #FFFFFF
|
||||||
|
}
|
||||||
|
|
||||||
|
QTabBar::tab:selected {
|
||||||
|
background: #999999;
|
||||||
|
color: #1d5eff
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QTabBar::tab:!selected {
|
||||||
|
margin-top: 3px; /* make non-selected tabs look smaller */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
QProgressBar {
|
||||||
|
border: 2px #7a7a7a;
|
||||||
|
border-radius: 3px;
|
||||||
|
background-color: #7a7a7a;
|
||||||
|
}
|
||||||
|
|
||||||
|
QProgressBar::chunk {
|
||||||
|
/*background-color: #1d5eff;*/
|
||||||
|
background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #1d5eff, stop:0.5 #4177ff, stop:1 #1d5eff);
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QAbstractScrollArea::corner {
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar:vertical, QScrollBar:horizontal{
|
||||||
|
background-color:#343434;
|
||||||
|
border-radius: 5px;
|
||||||
|
/*background: none;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar:vertical {
|
||||||
|
margin-top: 0px;
|
||||||
|
margin-bottom: 0px;
|
||||||
|
/*width: 10px;*/
|
||||||
|
}
|
||||||
|
QScrollBar:horizontal{
|
||||||
|
margin-left: 0px;
|
||||||
|
margin-right: 0px;
|
||||||
|
/*height: 10px;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::handle:vertical, QScrollBar::handle:horizontal{
|
||||||
|
border-radius: 5px;
|
||||||
|
border-color: none;
|
||||||
|
border-width: 1px;
|
||||||
|
background-color: #999999;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::add-line:vertical, QScrollBar::add-line:horizontal{
|
||||||
|
width: 0px;
|
||||||
|
height: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::sub-line:vertical, QScrollBar::sub-line:horizontal{
|
||||||
|
width: 0px;
|
||||||
|
height: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::add-page:vertical{
|
||||||
|
border-left: 1px solid gray;
|
||||||
|
background: transparent;
|
||||||
|
border-radius: 5px;
|
||||||
|
/*
|
||||||
|
border: 1px#343434;
|
||||||
|
background-color: #343434;*/
|
||||||
|
}
|
||||||
|
QScrollBar::add-page:horizontal{
|
||||||
|
border-top: 1px solid gray;
|
||||||
|
background: transparent;
|
||||||
|
border-radius: 5px;
|
||||||
|
/*
|
||||||
|
border: 1px#343434;
|
||||||
|
background-color: #343434;*/
|
||||||
|
}
|
||||||
|
QScrollBar::sub-page:vertical{
|
||||||
|
border-left: 1px solid gray;
|
||||||
|
background: transparent;
|
||||||
|
border-radius: 5px;
|
||||||
|
/* border: 1px #343434;
|
||||||
|
background-color: #343434;*/
|
||||||
|
}
|
||||||
|
QScrollBar::sub-page:horizontal{
|
||||||
|
border-top: 1px solid gray;
|
||||||
|
background: transparent;
|
||||||
|
border-radius: 5px;
|
||||||
|
/* border: 1px #343434;
|
||||||
|
background-color: #343434;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
QTextEdit{
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMessageBox {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolTip {
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTextBrowser {
|
||||||
|
background-color: #464646;
|
||||||
|
color: #ffffff;
|
||||||
|
border: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QRadioButton {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
QListWidget {
|
||||||
|
background-color:rgb(52,52,52);
|
||||||
|
color: rgb(255, 255, 255);
|
||||||
|
border: 1px solid gray;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QLineEdit {
|
||||||
|
background-color: #343434;
|
||||||
|
color: rgb(255, 255, 255);
|
||||||
|
border: 1px solid gray;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {
|
||||||
|
background-color: rgb(52,52,52);
|
||||||
|
color: #ffffff;
|
||||||
|
border: 1px solid gray;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSpinBox:!enabled {
|
||||||
|
color:#9f9f9f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* SPECIAL WIDGETS */
|
||||||
|
QPushButton#url_button {
|
||||||
|
color: #9f9f9f;
|
||||||
|
border: 0px;
|
||||||
|
background-color: #464646;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton#play, QPushButton#pause, QPushButton#stop {
|
||||||
|
color: #464646;
|
||||||
|
border: 0px;
|
||||||
|
background-color: #464646;
|
||||||
|
}
|
||||||
|
|
||||||
|
QLabel#band_range_lbl {
|
||||||
|
color: #9f9f9f;
|
||||||
|
}
|
||||||
BIN
themes/3-material_design/icons/down-arrow.png
Normal file
|
After Width: | Height: | Size: 270 B |
BIN
themes/3-material_design/icons/down-arrow_hover.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
themes/3-material_design/icons/down-arrow_off.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
themes/3-material_design/icons/off.png
Normal file
|
After Width: | Height: | Size: 820 B |
BIN
themes/3-material_design/icons/off_press.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
themes/3-material_design/icons/on.png
Normal file
|
After Width: | Height: | Size: 916 B |
BIN
themes/3-material_design/icons/on_press.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
themes/3-material_design/icons/search_icon.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
themes/3-material_design/icons/up-arrow.png
Normal file
|
After Width: | Height: | Size: 827 B |
BIN
themes/3-material_design/icons/up-arrow_hover.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
themes/3-material_design/icons/up-arrow_off.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
themes/3-material_design/icons/volume.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
410
themes/3-material_design/material_design.th
Normal file
@@ -0,0 +1,410 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
MainWindow
|
||||||
|
*****************************************************************************/
|
||||||
|
QWidget:window {
|
||||||
|
border: 0px solid #2e2f34;
|
||||||
|
background-color: #2e2f34;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
Search bar
|
||||||
|
*****************************************************************************/
|
||||||
|
QLineEdit {
|
||||||
|
background-color: transparent;
|
||||||
|
border: 0px solid transparent;
|
||||||
|
border-bottom: 2px solid #669900;
|
||||||
|
color: #669900;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
Scroll Bars
|
||||||
|
*****************************************************************************/
|
||||||
|
QScrollBar:horizontal {
|
||||||
|
background: transparent; /* Background where slider is not */
|
||||||
|
height: 10px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar:vertical {
|
||||||
|
background: transparent; /* Background where slider is not */
|
||||||
|
width: 10px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::handle:horizontal {
|
||||||
|
background: #37474F; /* Slider color */
|
||||||
|
min-width: 16px;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::handle:vertical {
|
||||||
|
background: #37474F; /* Slider color */
|
||||||
|
min-height: 16px;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal,
|
||||||
|
QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {
|
||||||
|
background: none; /* Removes the dotted background */
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::add-line:horizontal, QScrollBar::sub-line:horizontal,
|
||||||
|
QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical { /* Hides the slider arrows */
|
||||||
|
border: none;
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
List
|
||||||
|
*****************************************************************************/
|
||||||
|
QListWidget {
|
||||||
|
background-color: transparent;
|
||||||
|
border: 0px solid transparent;
|
||||||
|
border-bottom: 2px solid #80CBC4;
|
||||||
|
color: #c2cfd6;
|
||||||
|
}
|
||||||
|
|
||||||
|
QListView::item:hover {
|
||||||
|
color: #669900;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
QListView::item:selected {
|
||||||
|
color: #88cc00;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
QListView {
|
||||||
|
background-color: transparent;
|
||||||
|
color: #c2cfd6;
|
||||||
|
outline: 0;
|
||||||
|
border: 0px solid transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* === QTabBar === */
|
||||||
|
QTabBar {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTabWidget::pane {
|
||||||
|
background: transparent; /* Only at the very bottom of the tabs */
|
||||||
|
}
|
||||||
|
|
||||||
|
QTabBar::tab {
|
||||||
|
background: transparent;
|
||||||
|
border: 0px solid transparent;
|
||||||
|
border-bottom: 2px solid transparent;
|
||||||
|
color: #546E7A;
|
||||||
|
padding-left: 10px;
|
||||||
|
padding-right: 10px;
|
||||||
|
padding-top: 3px;
|
||||||
|
padding-bottom: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTabBar::tab:hover {
|
||||||
|
background-color: transparent;
|
||||||
|
border: 0px solid transparent;
|
||||||
|
border-bottom: 2px solid #88cc00;
|
||||||
|
color: #AFBDC4;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTabBar::tab:selected {
|
||||||
|
background-color: transparent;
|
||||||
|
border: 0px solid transparent;
|
||||||
|
border-top: none;
|
||||||
|
border-bottom: 2px solid #88cc00;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStackedWidget {
|
||||||
|
background: #2e2f34;/* This covers a bunch of things, I was thinking about making it transparent, */
|
||||||
|
/* but I would have to find all the other elements... but QTabWidget::pane may be it */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ==================== Dialog ==================== */
|
||||||
|
QLabel {
|
||||||
|
background: transparent;
|
||||||
|
color: #CFD8DC; /* Not sure about this one */
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog {
|
||||||
|
background-color: #263238;
|
||||||
|
color: #546E7A;
|
||||||
|
outline: 0;
|
||||||
|
border: 2px solid transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
Buttons
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
QToolTip {
|
||||||
|
background-color: #80CBC4;
|
||||||
|
color: black;
|
||||||
|
padding: 5px;
|
||||||
|
border-radius: 0;
|
||||||
|
opacity: 200;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton {
|
||||||
|
background-color: transparent;
|
||||||
|
color: #c2cfd6;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
padding: 4px 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton:hover {
|
||||||
|
border-left: 2px solid #88cc00;
|
||||||
|
border-right: 2px solid #88cc00;
|
||||||
|
color: #f0f3f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton:pressed {
|
||||||
|
color: #efffcc;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton:disabled {
|
||||||
|
color:#546E7A;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton:checked {
|
||||||
|
color: #88cc00;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
Rich Text Box
|
||||||
|
*****************************************************************************/
|
||||||
|
QTextBrowser {
|
||||||
|
background: transparent;
|
||||||
|
border: 0px solid transparent;
|
||||||
|
color: #546E7A;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
Main Menu (Upper part)
|
||||||
|
*****************************************************************************/
|
||||||
|
QTreeView {
|
||||||
|
background-color: #263238;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMenu {
|
||||||
|
background-color: #263238; /* File Menu Background color */
|
||||||
|
color: #546E7A;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMenu::item:selected {
|
||||||
|
color: #AFBDC4;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMenu::item:pressed {
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMenu::separator {
|
||||||
|
height: 1px;
|
||||||
|
background: transparent; /* Could change this to #546E7A and reduce the margin top and bottom to 1px */
|
||||||
|
margin-left: 10px;
|
||||||
|
margin-right: 10px;
|
||||||
|
margin-top: 5px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
Main Menu (Bar)
|
||||||
|
*****************************************************************************/
|
||||||
|
QMenuBar {
|
||||||
|
background-color: transparent;
|
||||||
|
color: #546E7A;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMenuBar::item {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMenuBar::item:disabled {
|
||||||
|
color: gray;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMenuBar::item:selected {
|
||||||
|
color: #AFBDC4;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMenuBar::item:pressed {
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolBar {
|
||||||
|
background: transparent;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolBar:handle {
|
||||||
|
background: transparent;
|
||||||
|
border-left: 2px dotted #80CBC4; /* Fix the 4 handle dots so it doesn't look crappy */
|
||||||
|
color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolBar::separator {
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
ComboBox
|
||||||
|
*****************************************************************************/
|
||||||
|
QComboBox {
|
||||||
|
border: 0px solid gray;
|
||||||
|
border-radius: 2px;
|
||||||
|
padding: 1px 6px 1px 6px;
|
||||||
|
min-width: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
QComboBox:!editable, QComboBox::drop-down:editable {
|
||||||
|
color: #c2cfd6;
|
||||||
|
selection-color: #80CBC4;
|
||||||
|
background-color: transparent;
|
||||||
|
selection-background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
QComboBox:disabled {
|
||||||
|
color: #546E7A;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* QComboBox gets the "on" state when the popup is open */
|
||||||
|
QComboBox:!editable:on,
|
||||||
|
QComboBox::drop-down:editable:on {
|
||||||
|
color: #c2cfd6;
|
||||||
|
background-color: transparent;
|
||||||
|
selection-background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
QComboBox:on { /* shift the text when the popup opens */
|
||||||
|
padding-top: 3px;
|
||||||
|
padding-left: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QComboBox::drop-down {
|
||||||
|
background-color: transparent;
|
||||||
|
subcontrol-origin: padding;
|
||||||
|
subcontrol-position: top right;
|
||||||
|
width: 20px;
|
||||||
|
border-top-right-radius: 2px;
|
||||||
|
border-bottom-right-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QComboBox::down-arrow:enabled {
|
||||||
|
image: url("./themes/3-material_design/icons/down-arrow.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
QComboBox::down-arrow:disabled {
|
||||||
|
image: url("./themes/3-material_design/icons/down-arrow_off.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
QComboBox::down-arrow:hover {
|
||||||
|
image: url("./themes/3-material_design/icons/down-arrow_hover.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
QComboBox::down-arrow:on { /* shift the arrow when popup is open */
|
||||||
|
top: 1px;
|
||||||
|
left: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QComboBox QAbstractItemView {
|
||||||
|
background-color: #2e2f34;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
RadioButton
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
QRadioButton{
|
||||||
|
color: #c2cfd6;
|
||||||
|
}
|
||||||
|
|
||||||
|
QRadioButton:disabled{
|
||||||
|
color: #546E7A;
|
||||||
|
}
|
||||||
|
|
||||||
|
QRadioButton::indicator{
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QRadioButton::indicator::unchecked {
|
||||||
|
image: url("./themes/3-material_design/icons/off.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
QRadioButton::indicator:unchecked:hover {
|
||||||
|
image: url("./themes/3-material_design/icons/off_press.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
QRadioButton::indicator:unchecked:pressed {
|
||||||
|
image: url("./themes/3-material_design/icons/off_press.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
QRadioButton::indicator::checked {
|
||||||
|
image: url("./themes/3-material_design/icons/on.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
QRadioButton::indicator:checked:hover {
|
||||||
|
image: url("./themes/3-material_design/icons/on_press.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
QRadioButton::indicator:checked:pressed {
|
||||||
|
image: url("./themes/3-material_design/icons/on_press.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
SpinBox
|
||||||
|
*****************************************************************************/
|
||||||
|
QSpinBox {
|
||||||
|
color: #c2cfd6;
|
||||||
|
border-width: 0px;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSpinBox:disabled {
|
||||||
|
color: #546E7A;
|
||||||
|
border-width: 0px;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSpinBox::up-button {
|
||||||
|
subcontrol-origin: border;
|
||||||
|
subcontrol-position: top right;
|
||||||
|
width: 16px;
|
||||||
|
image: url("./themes/3-material_design/icons/up-arrow.png");
|
||||||
|
border-width: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSpinBox::up-button:hover {
|
||||||
|
image: url("./themes/3-material_design/icons/up-arrow_hover.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
QSpinBox::up-button:pressed {
|
||||||
|
image: url("./themes/3-material_design/icons/up-arrow.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
QSpinBox::up-button:disabled {
|
||||||
|
image: url("./themes/3-material_design/icons/up-arrow_off.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
QSpinBox::down-button {
|
||||||
|
subcontrol-origin: border;
|
||||||
|
subcontrol-position: bottom right; /* position at bottom right corner */
|
||||||
|
width: 16px;
|
||||||
|
image: url("./themes/3-material_design/icons/down-arrow.png");
|
||||||
|
border-width: 0px;
|
||||||
|
border-top-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSpinBox::down-button:hover {
|
||||||
|
image: url("./themes/3-material_design/icons/down-arrow_hover.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
QSpinBox::down-button:pressed {
|
||||||
|
image: url("./themes/3-material_design/icons/down-arrow.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
QSpinBox::down-button:disabled {
|
||||||
|
image: url("./themes/3-material_design/icons/down-arrow_off.png");
|
||||||
|
}
|
||||||
87
utilities.py
@@ -1,37 +1,70 @@
|
|||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
import hashlib
|
import hashlib
|
||||||
|
import re
|
||||||
from pandas import read_csv
|
from pandas import read_csv
|
||||||
|
|
||||||
class _ReadOnlyProperty(object):
|
from PyQt5.QtWidgets import QMessageBox
|
||||||
def __init__(self, value):
|
|
||||||
self.__value = value
|
|
||||||
|
|
||||||
def __get__(self, obj, objtype):
|
# class _ReadOnlyProperty(object):
|
||||||
return self.__value
|
# def __init__(self, value):
|
||||||
|
# self.__value = value
|
||||||
|
|
||||||
def __set__(self, obj, value):
|
# def __get__(self, obj, objtype):
|
||||||
return NotImplementedError("Cannot change a constant.")
|
# return self.__value
|
||||||
|
|
||||||
# def change_hardcoded_value(self, value):
|
# def __set__(self, obj, value):
|
||||||
# self.__value = value
|
# return NotImplementedError("Cannot change a constant.")
|
||||||
|
|
||||||
def __make_read_only(cls):
|
# def __make_read_only(cls):
|
||||||
for k, v in cls.__dict__.items():
|
# for k, v in cls.__dict__.items():
|
||||||
if not callable(getattr(cls, k)) and '__' not in k:
|
# if not callable(getattr(cls, k)) and '__' not in k:
|
||||||
setattr(cls, k, _ReadOnlyProperty(v))
|
# setattr(cls, k, _ReadOnlyProperty(v))
|
||||||
# def raise_err(self, attr, value):
|
# # def raise_err(self, attr, value):
|
||||||
# raise NotImplementedError("Cannot add an attribute.")
|
# # raise NotImplementedError("Cannot add an attribute.")
|
||||||
# setattr(cls, '__setattr__', raise_err)
|
# # setattr(cls, '__setattr__', raise_err)
|
||||||
return cls
|
# return cls
|
||||||
|
|
||||||
@__make_read_only
|
# @__make_read_only
|
||||||
class __Constants(object):
|
class Constants(object):
|
||||||
|
class Messages(object):
|
||||||
|
NO_DB_AVAIL = "No database available.\nGo to Updates->Update database."
|
||||||
|
NO_DB = "No database"
|
||||||
DB_LOCATION = "https://aresvalley.com/Storage/Artemis/Database/data.zip"
|
DB_LOCATION = "https://aresvalley.com/Storage/Artemis/Database/data.zip"
|
||||||
REF_LOC = "https://aresvalley.com/Storage/Artemis/Database/data.zip.log"
|
REF_LOC = "https://aresvalley.com/Storage/Artemis/Database/data.zip.log"
|
||||||
|
DB_NAME = "db.csv"
|
||||||
|
DB_NAMES = ("name",
|
||||||
|
"inf_freq",
|
||||||
|
"sup_freq",
|
||||||
|
"mode",
|
||||||
|
"inf_band",
|
||||||
|
"sup_band",
|
||||||
|
"location",
|
||||||
|
"url",
|
||||||
|
"description",
|
||||||
|
"modulation",
|
||||||
|
"category_code",
|
||||||
|
"acf",)
|
||||||
|
DB_WIKI_CLICKED = "url_clicked"
|
||||||
|
DB_STRINGS = ('inf_freq',
|
||||||
|
'sup_freq',
|
||||||
|
'mode',
|
||||||
|
'inf_band',
|
||||||
|
'sup_band',
|
||||||
|
'category_code',)
|
||||||
DATA_FOLDER = "Data"
|
DATA_FOLDER = "Data"
|
||||||
SPECTRA_FOLDER = "Spectra"
|
SPECTRA_FOLDER = "Spectra"
|
||||||
|
SPECTRA_EXT = ".png"
|
||||||
AUDIO_FOLDER = "Audio"
|
AUDIO_FOLDER = "Audio"
|
||||||
ICONS_FOLDER = "icons_imgs"
|
THEMES_FOLDER = "themes"
|
||||||
|
THEME_EXTENSION = ".th"
|
||||||
|
ICONS_FOLDER = "icons"
|
||||||
|
DEFAULT_THEME = "1-system"
|
||||||
|
CURRENT_THEME = ".current_theme"
|
||||||
|
THEME_COLORS = "colors.txt"
|
||||||
|
NOT_AVAILABLE = "spectrumnotavailable.png"
|
||||||
|
NOT_SELECTED = "nosignalselected.png"
|
||||||
|
SEARCH_LABEL_IMG = "search_icon.png"
|
||||||
|
VOLUME_LABEL_IMG = "volume.png"
|
||||||
__Band = namedtuple("Band", ["lower", "upper"])
|
__Band = namedtuple("Band", ["lower", "upper"])
|
||||||
__ELF = __Band(0, 30) # Formally it is (3, 30) Hz.
|
__ELF = __Band(0, 30) # Formally it is (3, 30) Hz.
|
||||||
__SLF = __Band(30, 300)
|
__SLF = __Band(30, 300)
|
||||||
@@ -88,7 +121,6 @@ class __Constants(object):
|
|||||||
"PSK",
|
"PSK",
|
||||||
"QAM",
|
"QAM",
|
||||||
"TDMA",)
|
"TDMA",)
|
||||||
|
|
||||||
LOCATIONS = (UNKNOWN,
|
LOCATIONS = (UNKNOWN,
|
||||||
"Australia",
|
"Australia",
|
||||||
"Canada",
|
"Canada",
|
||||||
@@ -121,13 +153,21 @@ class __Constants(object):
|
|||||||
"World Wide",
|
"World Wide",
|
||||||
"Worldwide",)
|
"Worldwide",)
|
||||||
|
|
||||||
Constants = __Constants()
|
# Constants = __Constants()
|
||||||
|
|
||||||
def reset_apply_remove_btn(button):
|
def reset_apply_remove_btn(button):
|
||||||
if button.isChecked():
|
if button.isChecked():
|
||||||
button.setChecked(False)
|
button.setChecked(False)
|
||||||
button.clicked.emit()
|
button.clicked.emit()
|
||||||
|
|
||||||
|
def throwable_message(cls, title, text, connection = None):
|
||||||
|
msg = QMessageBox(cls)
|
||||||
|
msg.setWindowTitle(title)
|
||||||
|
msg.setText(text)
|
||||||
|
if connection:
|
||||||
|
msg.setText(text).finished.connect(connection)
|
||||||
|
return msg
|
||||||
|
|
||||||
def checksum_ok(data, what):
|
def checksum_ok(data, what):
|
||||||
code = hashlib.sha256()
|
code = hashlib.sha256()
|
||||||
code.update(data)
|
code.update(data)
|
||||||
@@ -142,3 +182,6 @@ def checksum_ok(data, what):
|
|||||||
except HTTPError:
|
except HTTPError:
|
||||||
return False
|
return False
|
||||||
return code.hexdigest() == reference
|
return code.hexdigest() == reference
|
||||||
|
|
||||||
|
def is_valid_html_color(color):
|
||||||
|
return bool(re.match("#([a-zA-Z0-9]){6}", color))
|
||||||
|
|||||||