Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
169 changes: 169 additions & 0 deletions pyobs_gui/genericwidgets.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
import logging

from PyQt5.QtCore import Qt
from PyQt5 import QtWidgets
from PyQt5.QtCore import pyqtSignal

from pyobs_gui.basewidget import BaseWidget

from pyobs.interfaces import IStoppable, IAltAz, IRaDec, ILatLon

log = logging.getLogger(__name__)


class QtToggleButtons(QtWidgets.QWidget):
toggled = pyqtSignal(bool)

def __init__(self):
super().__init__()

start = QtWidgets.QPushButton("Start")
start.setCheckable(True)
start.setAutoExclusive(True)
start.setChecked(False)
start.toggled.connect(self.toggled)
self.start = start

stop = QtWidgets.QPushButton("Stop")
stop.setCheckable(True)
stop.setAutoExclusive(True)
stop.setChecked(True)

lyt = QtWidgets.QHBoxLayout(self)
lyt.addWidget(start)
lyt.addWidget(stop)

def setChecked(self, ischecked):
self.start.setChecked(ischecked)


class WidgetStoppable(QtWidgets.QWidget):
"""Simple widget for any Module implementing the IStoppable interface."""
def __init__(self, module, comm, parent=None):
super().__init__(parent=parent)
self.module = module

self.running = QtToggleButtons()
self.running.toggled.connect(self.on_toggle)

self.state = QtWidgets.QLabel("State: Unknown")

# layout GUI
layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(self.state)
layout.addWidget(self.running)

def _update(self):
isrunning = self.module.is_running().wait()
self.running.setChecked(isrunning)
if isrunning:
self.state.setText("State: Running")
else:
self.state.setText("State: Stopped")

def on_toggle(self, running):
if running:
self.module.start()
else:
self.module.stop()


class WidgetCoordinates(QtWidgets.QWidget):
"""
Simple widget for any Module implementing any of the coordinate
interfaces like IAltAz.

Support IAltAz, IRaDec and ILatLon
"""
def __init__(self, module, comm, parent=None):
super().__init__(parent=parent)
self.module = module
self.comm = comm

coordtypes = [(IAltAz, "move_altaz", "get_altaz",
"Horizontal (Alt, Az) in deg"),
(IRaDec, "move_radec", "get_readec",
"Equatorial (Ra, Dec) in deg"),
(ILatLon, "move_latlon", "get_latlon",
"Geographic (Lat, Lon) in deg")]

# create widgets
self.edittargetcoord = QtWidgets.QLineEdit("")
self.cmbcoordtype = QtWidgets.QComboBox()
self.cmbcoordtype.setEditable(False)
self.btnmovetotarget = QtWidgets.QPushButton("Move to target")
self.btnmovetotarget.clicked.connect(self.on_move_to_target)

frmcurrentcoord = QtWidgets.QGroupBox("Current position")
lytcurrentcoord = QtWidgets.QFormLayout(frmcurrentcoord)

self.interfaces = {}
for Interface, setter, getter, name in coordtypes:
if isinstance(self.module, Interface):
setterfn = getattr(self.module, setter)
getterfn = getattr(self.module, getter)
lblcurrentcoord = QtWidgets.QLabel("")
lytcurrentcoord.addRow(name, lblcurrentcoord)
self.interfaces[name] = setterfn, getterfn, lblcurrentcoord
self.cmbcoordtype.addItem(name)

# build GUI
layout = QtWidgets.QFormLayout(self)
layout.addRow(frmcurrentcoord)
layout.addRow(self.cmbcoordtype, self.edittargetcoord)
layout.addRow(self.btnmovetotarget)

def _update(self):
for name, (_, getter, lbl) in self.interfaces.items():
lbl.setText("{:.3f}, {:.3f}".format(*getter().wait()))

def on_move_to_target(self):
coordstr = self.edittargetcoord.text()
coords = [float(x) for x in coordstr.split(",")]
coordtype = self.cmbcoordtype.currentText()
setter = self.interfaces[coordtype][0]
setter(coords[0], coords[1]).wait()


class GenericWidget(BaseWidget):
"""
A container widget of all subwidgets for the Interfaces a module
implements.
"""

@staticmethod
def create(module, comm):
"""
Convenience method to build a Generic widget containing all subwidgets
for the Interfaces the module implements.

TODO: why can't this be done in the constructor?
"""
genericwidgets = [(IStoppable, WidgetStoppable),
((IAltAz, IRaDec, ILatLon), WidgetCoordinates)]

widgets = [widget(module, comm)
for Interface, widget in genericwidgets
if isinstance(module, Interface)]
if not widgets:
return None

return GenericWidget(module, comm, widgets)

def __init__(self, module, comm, widgets, parent=None):
BaseWidget.__init__(self, parent=parent, update_func=self._update)
self.module = module
self.comm = comm
self.widgets = widgets

layout = QtWidgets.QVBoxLayout(self)
layout.setAlignment(Qt.AlignTop)

for w in self.widgets:
layout.addWidget(w)

layout.addWidget

def _update(self):
for w in self.widgets:
w._update()
6 changes: 5 additions & 1 deletion pyobs_gui/mainwindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from pyobs_gui.widgetfocus import WidgetFocus
from pyobs_gui.widgetscript import WidgetScript
from pyobs_gui.widgetweather import WidgetWeather
from pyobs_gui.genericwidgets import GenericWidget


class PagesListWidgetItem(QtWidgets.QListWidgetItem):
Expand Down Expand Up @@ -258,7 +259,10 @@ def _client_connected(self, client: str):
widget = WidgetScript(proxy, self.comm)
icon = QtGui.QIcon(":/resources/Crystal_Clear_app_demo.png")
else:
return
widget = GenericWidget.create(proxy, self.comm)
if widget is None:
return
icon = QtGui.QIcon(":/resources/Crystal_Clear_app_demo.png")

# get label
label = proxy.label().wait()
Expand Down