123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455 |
- """
- This module defines the Initial view of the gui
- """
- from PyQt4 import QtGui, QtCore
- import logging
- from . import kcgwidget as kcgw
- from .kcgwidget import error
- from .backend import board
- from .backend.board import available_boards
- from .groupedelements import Checkboxes, Buttons, Elements
- from . import backendinterface as bif
- from .loghandler import LogArea
- from . import storage
- from .. import config
- import traceback
- tr = kcgw.tr
- # 888 88888888888888888b.
- # 888 888 888 "Y88b
- # 888 888 888 888
- # 888 8888888 888 888
- # 888 888 888 888
- # 888 888 888 888
- # 888 888 888 .d88P
- # 8888888888888888888888888P"
- class LED(QtGui.QWidget):
- """
- Produces a graphical LED
- """
- def __init__(self, parent=None, status=1, height=10, width=10):
- """
- Initialize a LED
- :param parent: (QWidget) parent of this widget
- :param status: (int) (0=out, 1=off, 2=orange, 3=on) initial status of this LED
- :param height: (int) height of the LED
- :param width: (int) width of the LED
- :return: -
- """
- QtGui.QWidget.__init__(self, parent)
- colorRGB=(255, 0, 0)
- self.width = width
- self.height = height
- self.color = QtGui.QColor(colorRGB[0], colorRGB[1], colorRGB[2])
- self.center = QtCore.QPoint(width, height)
- self.setMinimumSize(2 * width, 2 * height)
- self.setMaximumSize(2 * width, 2 * height)
- if status == 3:
- self.set_on()
- elif status == 1:
- self.set_off()
- elif status == 0:
- self.set_out()
- elif status == 2:
- self.set_tri()
- self.status = status
- def paintEvent(self, event):
- paint = QtGui.QPainter()
- paint.begin(self)
- paint.setRenderHint(QtGui.QPainter.Antialiasing)
- # draw a grey 'socket' for the LED
- paint.setPen(QtGui.QColor(160, 160, 160))
- paint.setBrush(QtGui.QColor(180, 180, 180))
- paint.drawEllipse(self.center, self.width, self.height)
- # draw the body of the LED
- paint.setBrush(self.color)
- paint.drawEllipse(self.center, self.width*0.85, self.height*0.85)
- def set_on(self):
- """
- Set the LED to "on" state
- :return: -
- """
- self.color = QtGui.QColor(0, 255, 0)
- self.update()
- self.status = 3
- def set_off(self):
- """
- Set the LED to "off" state
- :return: -
- """
- self.color = QtGui.QColor(255, 0, 0)
- self.update()
- self.status = 1
- def set_out(self):
- """
- Set the LED to "OUT" state (that is like an LED without power)
- :return: -
- """
- self.color = QtGui.QColor(150, 150, 150)
- self.update()
- self.status = 0
- def set_tri(self):
- """
- Set the LED to "TRI" state (that is led is orange)
- :return: -
- """
- self.color = QtGui.QColor(255, 255, 0)
- self.update()
- self.status = 2
- def set_status(self, status):
- """
- Set the status of the led
- :param status: status (in 0, 1, 2, 3)
- """
- if status == 0:
- self.set_out()
- elif status == 1:
- self.set_off()
- elif status == 2:
- self.set_tri()
- elif status == 3:
- self.set_on()
- # .d8888b. 888 888 888 88888888888888888b.
- # d88P Y88b888 888 888 888 888 "Y88b
- # Y88b. 888 888 888 888 888 888
- # "Y888b. 888888 8888b. 888888888 888.d8888b 888 8888888 888 888
- # "Y88b.888 "88b888 888 88888K 888 888 888 888
- # "888888 .d888888888 888 888"Y8888b.888 888 888 888
- # Y88b d88PY88b. 888 888Y88b. Y88b 888 X88888 888 888 .d88P
- # "Y8888P" "Y888"Y888888 "Y888 "Y88888 88888P'8888888888888888888888888P"
- class StatusLED(QtGui.QWidget):
- """
- Create a Status LED with Label next to it
- """
- def __init__(self, text, status=None):
- """
- Initialise StatusLED
- :param text: label text next to the LED
- :param status: initial status of the LED
- :return: -
- """
- super(StatusLED, self).__init__()
- self.layout = QtGui.QHBoxLayout()
- self.label = QtGui.QLabel(text)
- self.led = LED(status=status, width=9, height=9)
- self.layout.addWidget(self.led)
- self.layout.addWidget(self.label)
- self.setLayout(self.layout)
- def set_on(self):
- """
- See set_on of LED Class
- """
- self.led.set_on()
- def set_off(self):
- """
- See set_off of LED Class
- """
- self.led.set_off()
- def set_out(self):
- """
- See set_out of LED Class
- """
- self.led.set_out()
- def set_tri(self):
- """
- See set_tri of LED Class
- """
- self.led.set_tri()
- def set_status(self, status):
- """
- See set_status of LED Class
- :param status: the status to set the led to
- """
- self.led.set_status(status)
- # 888888b. 888 .d8888b. 888 888
- # 888 "88b 888d88P Y88b 888 888
- # 888 .88P 888888 888 888 888
- # 8888888K. .d88b. 8888b. 888d888 .d88888888 .d88b. 88888b. 888888888d888 .d88b. 888
- # 888 "Y88bd88""88b "88b888P" d88" 888888 d88""88b888 "88b888 888P" d88""88b888
- # 888 888888 888.d888888888 888 888888 888888 888888 888888 888 888 888888
- # 888 d88PY88..88P888 888888 Y88b 888Y88b d88PY88..88P888 888Y88b. 888 Y88..88P888
- # 8888888P" "Y88P" "Y888888888 "Y88888 "Y8888P" "Y88P" 888 888 "Y888888 "Y88P" 888
- class BoardControl(kcgw.KCGWidgets):
- """
- The main view of the gui for each board at startup
- """
- def __init__(self, board_id, single=False):
- super(BoardControl, self).__init__()
- self.board_id = board_id
- self.layout = QtGui.QVBoxLayout()
- self.setLayout(self.layout)
- if not single:
- self.header_layout = QtGui.QHBoxLayout()
- left_line = QtGui.QFrame()
- left_line.setFrameShape(QtGui.QFrame.HLine)
- left_line.setFrameShadow(QtGui.QFrame.Sunken)
- right_line = QtGui.QFrame()
- right_line.setFrameShape(QtGui.QFrame.HLine)
- right_line.setFrameShadow(QtGui.QFrame.Sunken)
- self.header_layout.addWidget(left_line)
- header_label = self.createLabel("Board: {}".format(available_boards.get_board_name_from_id(board_id)))
- header_label.setFixedWidth(header_label.sizeHint().width())
- self.header_layout.addWidget(header_label)
- self.header_layout.addWidget(right_line)
- self.layout.addLayout(self.header_layout)
- self.mainControlLayout = QtGui.QHBoxLayout()
- self.subControlLayout = QtGui.QGridLayout()#QtGui.QHBoxLayout()
- self.subControlWidget = QtGui.QWidget()
- self.subControlWidget.setLayout(self.subControlLayout)
- self.statusLayout = QtGui.QHBoxLayout()
- self.layout.addLayout(self.mainControlLayout)
- self.layout.addWidget(self.subControlWidget)
- self.layout.addLayout(self.statusLayout)
- # ----------[ LED Status ]---------------
- self.pipeline_led = StatusLED(tr("Label", "DataFlow Pipeline"))
- self.master_control_led = StatusLED(tr("Label", "Master Control"))
- #self.data_check_led = StatusLED(tr("Label", "Data Check"))
- self.pll_ld_led = StatusLED(tr("Label", "PLL Lock"))
- self.statusLayout.addWidget(self.pipeline_led)
- self.statusLayout.addWidget(self.master_control_led)
- #self.statusLayout.addWidget(self.data_check_led)
- self.statusLayout.addWidget(self.pll_ld_led)
- # -----------[ Buttons ]--------------
- from functools import partial
- conf = board.get_board_config(board_id)
- if conf.get('board_version') > 10:
- logging.critical('Board Offline - GUI not working! - restart with active board')
- self.mainControlLayout.addWidget(self.createLabel('Board Offline - GUI not working! - restart with active board'))
- else:
- self.all_in_one_button = self.createButton(text=tr("Button", "Prepare Board"), connect=self.all_in_one,
- tooltip=tr("Tooltip", "Start, Calibrate, Synchronize and set Defaults\nCtrl+A"))
- self.toggleButton = self.createButton(text="", connect=self.toggle_sub_control)
- self.toggleButton.setIcon(QtGui.QIcon(config.icon_path("chevron-bottom.svg")))
- self.toggleButton.setFixedWidth(50)
- # self.all_in_one_button.setShortcut("Ctrl+A")
- # self.all_in_one_button.setObjectName("all_in_one")
- self.skip_init_button = self.createButton(text=tr("Button", "Skip Initialisation"), connect=self.skip_init,
- tooltip=tr("Tooltip", "Skip Initialisation and read values from board.\n"
- "NOTE: ONLY DO THIS IF BOARD WAS CALIBRATED AND SYNCHRONIZED BEFORE"))
- self.set_default_button = self.createButton(text=tr("Button", "Set Defaults"), connect=lambda x: bif.bk_write_values(board_id=board_id, defaults=True))
- self.soft_reset_button = self.createButton(text=tr("Button", "Soft Reset"), connect=lambda x: bif.bk_soft_reset(board_id=board_id))
- #self.off_button = self.createButton(text=tr("Button", "Board Off"), connect=lambda x: bif.bk_stop_board(board_id=board_id))
- #self.off_button.setObjectName("off")
- self.check_status_button = self.createButton(text=tr("Button", "Check Status"), connect=lambda x: bif._bif_status_readout(board_id=board_id))
- seqlist = conf.get_sequence_list()
- columnctr=0
- linectr = 0
- seqcolum = -1
- try:
- for item in seqlist:
- buttontemp = self.createButton(text=tr("Button", conf.get_sequence_comment(item)), connect=partial(bif.bk_run_sequence, board_id=board_id, name=item))
- Buttons.addButton(item, buttontemp)
- Elements.addItem('no_board_{}'.format(board_id),[buttontemp])
- #self.subControlLayout.addWidget(buttontemp)
- if 'PLL_sequence' in item:
- if seqcolum == -1:
- seqcolum = columnctr
- columnctr += 1
- self.subControlLayout.addWidget(buttontemp, linectr, seqcolum)
- linectr += 1
- else:
- self.subControlLayout.addWidget(buttontemp, 0,columnctr)
- columnctr += 1
- self.subControlLayout.addWidget(self.set_default_button, 0, columnctr)
- except Exception as e:
- traceback.print_exc()
- Buttons.addButton(['set_defaults_{}'.format(board_id), 'after_start_{}'.format(board_id)], self.set_default_button)
- Elements.addItem('no_board_{}'.format(board_id),
- [
- self.set_default_button,
- self.soft_reset_button,
- #self.off_button,
- self.all_in_one_button
- ])
- self.mainControlLayout.addWidget(self.all_in_one_button)
- self.mainControlLayout.addWidget(self.toggleButton)
- self.mainControlLayout.addWidget(self.skip_init_button)
- self.mainControlLayout.addWidget(self.soft_reset_button)
- #self.mainControlLayout.addWidget(self.off_button)
- self.statusLayout.addWidget(self.check_status_button)
- # register the led updater function (used in backendinterface.bk_status_readout)
- storage.get_board_specific_storage(board_id).update_LED = self.on_check
- self.geo = self.saveGeometry()
- self.subControlWidget.hide()
- def toggle_sub_control(self):
- """
- Show or hide the subcontrol buttons
- """
- self.subControlWidget.setHidden(not self.subControlWidget.isHidden())
- if self.subControlWidget.isHidden():
- self.toggleButton.setIcon(QtGui.QIcon(config.icon_path("chevron-bottom.svg")))
- else:
- self.toggleButton.setIcon(QtGui.QIcon(config.icon_path("chevron-top.svg")))
- self.parent().adjustSize()
- def all_in_one(self):
- """
- Function that gets called when the Prepare Board Button is pressed.
- It Starts the board, syncs it and sets defaults.
- This is accomplished via the Sequences module
- :return: -
- """
- seq = board.get_board_config(self.board_id).get_init_order()
- for item in seq:
- if item == 'startup_sequence':
- if board.is_active(board_id):
- logging.info('Board already powered on - skip startup_sequence')
- continue
- bif.bk_run_sequence(self.board_id, item)
- popup = kcgw.PopupDialog("Do not forget to turn on the T/H switches!",
- title='Reminder', okonly=True)
- popup.exec_()
- popup.deleteLater()
- popup.get_return_value()
- board.get_board_config(self.board_id).set_startup()
- def skip_init(self):
- """
- Skip board initialisation progress and read data from board. This will adjust the values in the gui to those
- on the board (for every value that is stored on the board)
- """
- board.get_board_config(self.board_id).read_from_board()
- board.get_board_status(self.board_id).calibrated = True
- board.get_board_status(self.board_id).synced = True
- board.get_board_status(self.board_id).defaults_set = True
- bif.bk_status_readout()
- logging.info("Initialisation skipped, configuration and status was read from KAPTURE.")
- def on_check(self):
- """
- This function is the handler for the status leds on the ControlWidget View.
- Parses the registers and sets the colors of the leds according.
- :return: -
- """
- try:
- status = bif.bk_get_status(self.board_id)
- except IndexError:
- error(0x002, "Pci returned not enough registers to update LEDs.")
- return
- for led, st in list(status.items()):
- try:
- getattr(self, led.lower()+"_led").set_status(st)
- except:
- pass
- # .d8888b. 888 888888 888d8b 888 888
- # d88P Y88b 888 888888 o 888Y8P 888 888
- # 888 888 888 888888 d8b 888 888 888
- # 888 .d88b. 88888b. 888888888d888 .d88b. 888888 d888b 888888 .d88888 .d88b. .d88b. 888888
- # 888 d88""88b888 "88b888 888P" d88""88b888888d88888b888888d88" 888d88P"88bd8P Y8b888
- # 888 888888 888888 888888 888 888 88888888888P Y88888888888 888888 88888888888888
- # Y88b d88PY88..88P888 888Y88b. 888 Y88..88P8888888P Y8888888Y88b 888Y88b 888Y8b. Y88b.
- # "Y8888P" "Y88P" 888 888 "Y888888 "Y88P" 888888P Y888888 "Y88888 "Y88888 "Y8888 "Y888
- # 888
- # Y8b d88P
- # "Y88P"
- class ControlWidget(kcgw.KCGWidgets):
- """
- Main Widget that is shown at start of gui.
- """
- def __init__(self):
- super(ControlWidget, self).__init__()
- self.overlayout = QtGui.QVBoxLayout()
- self.setLayout(self.overlayout)
- self.splitter = QtGui.QSplitter(QtCore.Qt.Vertical)
- self.overlayout.addWidget(self.splitter)
- self.log_area = LogArea()
- self.log_area.setReadOnly(True)
- self.log_area.init_logging()
- self.log_area.setKeywords([
- "Activating Board",
- "Started Board Calibration",
- "Synchronize PLLs",
- "Setting default Values",
- "Updating Values"
- ])
- self.board_control_list = {i: BoardControl(i, not available_boards.multi_board) for i in available_boards}
- self.board_widget = QtGui.QWidget()
- self.board_widget_layout = QtGui.QVBoxLayout()
- self.board_widget.setLayout(self.board_widget_layout)
- for bc in list(self.board_control_list.values()):
- self.board_widget_layout.addWidget(bc)
- self.board_widget_layout.addStretch(1)
- if available_boards.multi_board:
- self.scroll_widget = QtGui.QScrollArea()
- # self.scroll_widget.setMaximumWidth(1.1 * self.board_control_list.values()[0].minimumSizeHint().width())
- self.scroll_widget.setWidgetResizable(True)
- self.scroll_widget.setWidget(self.board_widget)
- self.scroll_widget_container = QtGui.QWidget()
- self.scroll_widget_layout = QtGui.QHBoxLayout()
- self.scroll_widget_layout.addWidget(self.scroll_widget)
- self.scroll_widget_layout.setAlignment(QtCore.Qt.AlignLeft)
- self.scroll_widget_container.setLayout(self.scroll_widget_layout)
- self.splitter.addWidget(self.scroll_widget_container)
- else:
- self.splitter.addWidget(self.board_widget)
- # self.log_area = QtGui.QTextEdit()
- self.splitter.addWidget(self.log_area)
- # self.setTabOrder(self.soft_reset_button, self.check_status_button)
- # self.setTabOrder(self.check_status_button, self.off_button)
- # ------------------[ Logging ]----------------------
- # log_handler = LogHandler(self.log_area)
- # self.logger = logging.getLogger()
- # self.logger.addHandler(log_handler)
- # self.logger.setLevel(config.log_level)
- # logging.logger = self.logger
- # logging.logger.addHandler(log_handler)
|