2
0
forked from awendt/pyrelacs

11 Commits

Author SHA1 Message Date
wendtalexander
4868b0e196 Merge branch 'jgrewe-icons' 2024-09-30 10:13:04 +02:00
b0897bf52d [icons] revert back to the qt resource system for icons 2024-09-30 10:03:29 +02:00
09dd7f3d51 [resources] add relacstux to resources 2024-09-30 10:03:04 +02:00
wendtalexander
2e264fb582 [project] changing to absolut imports 2024-09-30 09:49:11 +02:00
0a00875d2e [icons] replace with working images 2024-09-30 09:48:57 +02:00
wendtalexander
ab51fa7475 [ui] removing duplicate toolbar, adding textfield 2024-09-30 09:48:47 +02:00
wendtalexander
6a3a610cd3 [project] changing to absolut imports 2024-09-30 09:46:27 +02:00
wendtalexander
8b02b9083f [repos] adding check for spec.loader 2024-09-30 09:45:14 +02:00
wendtalexander
5dadf1bd7c Merge branch 'jgrewe-uistuff' 2024-09-30 07:48:26 +02:00
wendtalexander
9e8dc06c26 plot without decibels and beat without squaring 2024-09-29 18:28:01 +02:00
wendtalexander
bf8f3f5cb7 adding comments 2024-09-29 18:27:27 +02:00
10 changed files with 88 additions and 63 deletions

View File

@@ -3,12 +3,14 @@ import sys
from PyQt6.QtCore import QSettings from PyQt6.QtCore import QSettings
from PyQt6.QtWidgets import QApplication from PyQt6.QtWidgets import QApplication
from . import info from pyrelacs import info
from .ui.mainwindow import PyRelacs from pyrelacs.ui.mainwindow import PyRelacs
from .util.logging import config_logging from pyrelacs.util.logging import config_logging
import resources
log = config_logging() log = config_logging()
from . import resources from . import resources # best created with pyside6-rcc resources.qrc -o resources.py (rcc produces an error...)
def main(): def main():
app = QApplication(sys.argv) app = QApplication(sys.argv)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@@ -1,15 +1,24 @@
import sys import sys
import ast import ast
import pathlib import pathlib
from typing import Tuple
from IPython import embed
import nixio as nix import nixio as nix
import importlib.util import importlib.util
from pyrelacs.util.logging import config_logging from pyrelacs.util.logging import config_logging
log = config_logging() log = config_logging()
from IPython import embed
class Repro: class Repro:
"""
Repro Class that searches in the repro folder for classes instances and executes the
the run function in the searched class
"""
def __init__(self) -> None: def __init__(self) -> None:
pass pass
@@ -25,14 +34,27 @@ class Repro:
log.error("Could not load the module of the repro") log.error("Could not load the module of the repro")
else: else:
sys.modules[name] = module sys.modules[name] = module
spec.loader.exec_module(module) if spec.loader is not None:
spec.loader.exec_module(module)
else:
log.error(f"{spec.loader} is None")
if hasattr(module, name): if hasattr(module, name):
rep_class = getattr(module, name) rep_class = getattr(module, name)
rep_class.run(nix_file) rep_class.run(nix_file)
else: else:
raise AttributeError(f"{file.name} has no {name} class") raise AttributeError(f"{file.name} has no {name} class")
def names_of_repros(self): def names_of_repros(self) -> Tuple[list, list]:
"""
Searches for class names in the repro folder in all python files
Returns
-------
Tuple[list, list]
list of class names
list of file names from the class names
"""
file_path_cur = pathlib.Path(__file__).parent file_path_cur = pathlib.Path(__file__).parent
python_files = list(file_path_cur.glob("**/*.py")) python_files = list(file_path_cur.glob("**/*.py"))
exclude_files = ["repros.py", "__init__.py"] exclude_files = ["repros.py", "__init__.py"]

View File

@@ -5,5 +5,6 @@
<file>icons/disconnect.png</file> <file>icons/disconnect.png</file>
<file>icons/record.png</file> <file>icons/record.png</file>
<file>icons/stop.png</file> <file>icons/stop.png</file>
<file>icons/relacstuxheader.png</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@@ -1,5 +1,3 @@
import pathlib
from PyQt6.QtGui import QPixmap from PyQt6.QtGui import QPixmap
from PyQt6.QtWidgets import QDialog, QDialogButtonBox, QLabel, QVBoxLayout, QWidget from PyQt6.QtWidgets import QDialog, QDialogButtonBox, QLabel, QVBoxLayout, QWidget
from PyQt6.QtCore import Qt from PyQt6.QtCore import Qt
@@ -40,8 +38,7 @@ class About(QWidget):
rtd_link.setAlignment(Qt.AlignmentFlag.AlignCenter) rtd_link.setAlignment(Qt.AlignmentFlag.AlignCenter)
iconlabel = QLabel() iconlabel = QLabel()
_root = pathlib.Path(__file__).parent.parent pixmap = QPixmap(":/icons/relacstuxheader.png")
pixmap = QPixmap(str(pathlib.Path.joinpath(_root, "icons/relacstuxheader.png")))
s = pixmap.size() s = pixmap.size()
new_height = int(s.height() * 300/s.width()) new_height = int(s.height() * 300/s.width())
pixmap = pixmap.scaled(300, new_height, Qt.AspectRatioMode.KeepAspectRatio, Qt.TransformationMode.FastTransformation) pixmap = pixmap.scaled(300, new_height, Qt.AspectRatioMode.KeepAspectRatio, Qt.TransformationMode.FastTransformation)

View File

@@ -8,7 +8,7 @@ from PyQt6.QtWidgets import (
QMainWindow, QMainWindow,
QPlainTextEdit, QPlainTextEdit,
QMenuBar, QMenuBar,
QStatusBar QStatusBar,
) )
import uldaq import uldaq
import numpy as np import numpy as np
@@ -18,19 +18,23 @@ import pyqtgraph as pg
from pathlib import Path as path from pathlib import Path as path
from scipy.signal import welch, find_peaks from scipy.signal import welch, find_peaks
from ..worker import Worker from pyrelacs.worker import Worker
from ..repros.repros import Repro from pyrelacs.repros.repros import Repro
from ..util.logging import config_logging from pyrelacs.util.logging import config_logging
from .about import AboutDialog from pyrelacs.ui.about import AboutDialog
log = config_logging() log = config_logging()
_root = path(__file__).parent.parent _root = path(__file__).parent.parent
from IPython import embed from IPython import embed
class PyRelacs(QMainWindow): class PyRelacs(QMainWindow):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
# self.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon) # Ensure icons are displayed with text self.setToolButtonStyle(
Qt.ToolButtonStyle.ToolButtonTextBesideIcon
) # Ensure icons are displayed with text
self.setWindowTitle("PyRelacs") self.setWindowTitle("PyRelacs")
self.beat_plot = pg.PlotWidget() self.beat_plot = pg.PlotWidget()
self.power_plot = pg.PlotWidget() self.power_plot = pg.PlotWidget()
@@ -48,47 +52,39 @@ class PyRelacs(QMainWindow):
self.create_toolbars() self.create_toolbars()
layout = QGridLayout() layout = QGridLayout()
layout.addWidget(self.plot_calibration_button, 0, 0) layout.addWidget(self.beat_plot, 0, 0, 1, 2)
layout.addWidget(self.daq_disconnect_button, 0, 1) layout.addWidget(self.power_plot, 1, 0, 1, 2)
layout.addWidget(self.beat_plot, 2, 0, 1, 2) layout.addWidget(self.text, 2, 0, 1, 2)
layout.addWidget(self.power_plot, 3, 0, 1, 2)
self.toolbar = QToolBar("Repros")
self.addToolBar(self.toolbar)
self.repros_to_toolbar()
# self.setFixedSize(QSize(400, 300))
widget = QWidget() widget = QWidget()
widget.setLayout(layout) widget.setLayout(layout)
self.setCentralWidget(widget) self.setCentralWidget(widget)
filename = path.joinpath(path.cwd(), "data.nix") filename = path.joinpath(path.cwd(), "data")
self.nix_file = nix.File.open( self.nix_file = nix.File.open(str(filename), nix.FileMode.Overwrite)
str(filename), nix.FileMode.Overwrite
)
def create_actions(self): def create_actions(self):
self._rlx_exitaction = QAction(QIcon(str(path.joinpath(_root, "icons/exit.png"))), "Exit", self) self._rlx_exitaction = QAction(QIcon(":/icons/exit.png"), "Exit", self)
self._rlx_exitaction.setStatusTip("Close relacs") self._rlx_exitaction.setStatusTip("Close relacs")
self._rlx_exitaction.setShortcut(QKeySequence("Alt+q")) self._rlx_exitaction.setShortcut(QKeySequence("Alt+q"))
self._rlx_exitaction.triggered.connect(self.on_exit) self._rlx_exitaction.triggered.connect(self.on_exit)
self._rlx_aboutaction = QAction("about") self._rlx_aboutaction = QAction("about")
self._rlx_aboutaction.setStatusTip("Show about dialog") self._rlx_aboutaction.setStatusTip("Show about dialog")
self._rlx_aboutaction.setEnabled(True) self._rlx_aboutaction.setEnabled(True)
self._rlx_aboutaction.triggered.connect(self.on_about) self._rlx_aboutaction.triggered.connect(self.on_about)
self._daq_connectaction = QAction(QIcon(str(path.joinpath(_root, "icons/connect.png"))), "Connect DAQ", self) self._daq_connectaction = QAction(QIcon(":icons/connect.png"), "Connect DAQ", self)
self._daq_connectaction.setStatusTip("Connect to daq device") self._daq_connectaction.setStatusTip("Connect to daq device")
# self._daq_connectaction.setShortcut(QKeySequence("Alt+d")) # self._daq_connectaction.setShortcut(QKeySequence("Alt+d"))
self._daq_connectaction.triggered.connect(self.connect_dac) self._daq_connectaction.triggered.connect(self.connect_dac)
self._daq_disconnectaction = QAction(QIcon(str(path.joinpath(_root, "icons/disconnect.png"))), "Disconnect DAQ", self) self._daq_disconnectaction = QAction(QIcon(":/icons/disconnect.png"), "Disconnect DAQ", self)
self._daq_disconnectaction.setStatusTip("Disconnect the DAQ device") self._daq_disconnectaction.setStatusTip("Disconnect the DAQ device")
# self._daq_connectaction.setShortcut(QKeySequence("Alt+d")) # self._daq_connectaction.setShortcut(QKeySequence("Alt+d"))
self._daq_disconnectaction.triggered.connect(self.disconnect_dac) self._daq_disconnectaction.triggered.connect(self.disconnect_dac)
self._daq_calibaction = QAction(QIcon(str(path.joinpath(_root, "icons/calibration.png"))), "Plot calibration", self) self._daq_calibaction = QAction(QIcon(":/icons/calibration.png"), "Plot calibration", self)
self._daq_calibaction.setStatusTip("Calibrate the attenuator device") self._daq_calibaction.setStatusTip("Calibrate the attenuator device")
# self._daq_calibaction.setShortcut(QKeySequence("Alt+d")) # self._daq_calibaction.setShortcut(QKeySequence("Alt+d"))
self._daq_calibaction.triggered.connect(self.plot_calibration) self._daq_calibaction.triggered.connect(self.plot_calibration)
@@ -96,19 +92,28 @@ class PyRelacs(QMainWindow):
def create_menu(self): def create_menu(self):
menu = self.menuBar() menu = self.menuBar()
file_menu = menu.addMenu("&File") if menu is not None:
file_menu.addAction(self._rlx_exitaction) file_menu = menu.addMenu("&File")
file_menu.addAction(self._rlx_aboutaction) device_menu = menu.addMenu("&DAQ")
help_menu = menu.addMenu("&Help")
device_menu = menu.addMenu("&DAQ") if file_menu is not None:
device_menu.addAction(self._daq_connectaction) file_menu.addAction(self._rlx_exitaction)
device_menu.addAction(self._daq_disconnectaction) file_menu.addAction(self._rlx_aboutaction)
device_menu.addSeparator()
device_menu.addAction(self._daq_calibaction) if device_menu is not None:
device_menu.addAction(self._daq_connectaction)
device_menu.addAction(self._daq_disconnectaction)
device_menu.addSeparator()
device_menu.addAction(self._daq_calibaction)
if help_menu is not None:
help_menu.addSeparator()
# help_menu.addAction(self._help_action)
else:
log.error("could not create file menu and device menu")
self.on_exit()
help_menu = menu.addMenu("&Help")
help_menu.addSeparator()
# help_menu.addAction(self._help_action)
self.setMenuBar(menu) self.setMenuBar(menu)
def create_toolbars(self): def create_toolbars(self):
@@ -215,12 +220,20 @@ class PyRelacs(QMainWindow):
try: try:
self.daq_device = uldaq.DaqDevice(devices[0]) self.daq_device = uldaq.DaqDevice(devices[0])
log.debug(f"Found daq devices {len(devices)}, connecting to the first one") log.debug(f"Found daq devices {len(devices)}, connecting to the first one")
self.daq_device.connect()
log.debug("Connected")
except IndexError: except IndexError:
log.debug("DAQ is not connected, closing") log.error("DAQ is not connected")
self.on_exit() log.error("Please connect a DAQ device to the system")
self.daq_connect_button.setDisabled(True)
if hasattr(PyRelacs, "daq_device"):
try:
self.daq_device.connect()
log.debug("Connected")
except uldaq.ul_exception.ULException as e:
log.error(f"Could not Connect to DAQ: {e}")
self.daq_connect_button.setDisabled(True)
else:
log.debug("Already handeld the error")
pass
def disconnect_dac(self): def disconnect_dac(self):
try: try:
@@ -233,16 +246,6 @@ class PyRelacs(QMainWindow):
except AttributeError: except AttributeError:
log.debug("DAQ was not connected") log.debug("DAQ was not connected")
def repros_to_toolbar(self):
repro_names, file_names = self.repros.names_of_repros()
for rep, fn in zip(repro_names, file_names):
individual_repro_button = QAction(rep, self)
individual_repro_button.setStatusTip("Button")
individual_repro_button.triggered.connect(
lambda checked, n=rep, f=fn: self.run_repro(n, f)
)
self.toolbar.addAction(individual_repro_button)
def run_repro(self, n, fn): def run_repro(self, n, fn):
self.text.appendPlainText(f"started Repro {n}, {fn}") self.text.appendPlainText(f"started Repro {n}, {fn}")
worker = Worker(self.repros.run_repro, self.nix_file, n, fn) worker = Worker(self.repros.run_repro, self.nix_file, n, fn)
@@ -255,7 +258,7 @@ class PyRelacs(QMainWindow):
def on_exit(self): def on_exit(self):
print("exit button!") print("exit button!")
self.close() self.close()
def on_about(self, e): def on_about(self, e):
about = AboutDialog(self) about = AboutDialog(self)
about.show() about.show()
@@ -267,4 +270,4 @@ class PyRelacs(QMainWindow):
print("THREAD COMPLETE!") print("THREAD COMPLETE!")
def progress_fn(self, n): def progress_fn(self, n):
print("%d%% done" % n) print("%d%% done" % n)