Files
HUSH/src/gui.py
2024-01-31 11:20:47 +01:00

696 lines
26 KiB
Python

import inspect
import os
import platform
import random
import sys
import time
from datetime import timedelta
from qtpy import QtCore, QtGui
from qtpy.QtGui import QColor, QFont, QIcon
from qtpy.QtCore import __version__ as QT_VERSION_STR
from qtpy.QtCore import (
PYQT_VERSION_STR, QDate, QDateTime, QEventLoop, Qt, Signal, Slot)
from qtpy.QtWidgets import (
QApplication, QDockWidget, QFrame, QGridLayout, QGroupBox, QHBoxLayout,
QLabel, QMainWindow, QMessageBox, QProgressBar, QPushButton, QSizePolicy,
QSpacerItem, QStackedWidget, QTabBar, QTabWidget, QTableWidget,
QTableWidgetItem, QVBoxLayout, QWidget)
from apps4ops.bdbase.base import BaseWindow
from apps4ops.bdbase.enumkind import MsgSeverity, UserMode, Facility
from caqtwidgets.pvwidgets import CAQLabel, CAQLineEdit, CAQTableWidget, QHLine
_pymodule = os.path.basename(__file__)
def _line():
"""Macro to return the current line number.688
The current line number within the file is used when
reporting messages to the message logging window.
Returns:
int: Current line number.
"""
return inspect.currentframe().f_back.f_lineno
class AppGui(QWidget):
def __init__(self, parent):
super(AppGui, self).__init__()
self.parent = parent
self.cafe = self.parent.cafe
self.cyca = self.parent.cyca
self.send_to_log_window = self.parent.send_to_log_window
self.gui_frame = self.parent.gui_frame
self.gui_header = self.parent.gui_header
self.font_gui = self.parent.gui_frame.font_gui
self.input_parameters = self.parent.input_parameters
self.input_labels = self.parent.input_labels
self.expert_parameters = self.parent.expert_parameters
self.gui_frame.expert_parameters_group.setFixedWidth(260)
self.gui_frame.operator_parameters_group.setFixedWidth(260)
#self.gui_frame.operator_parameters_group.setFixedHeight(260)
self.gui_frame.measurement_tab_wgt.setMinimumWidth(440)
self.gui_frame.measurement_tab_wgt.setFixedHeight(280)
#self.gui_frame.operator_wgt.setFixedHeight(240)
#self.gui_frame.expert_wgt.setFixedHeight(240)
self.gui_frame.central_tab_widget.tabBar().setTabText(0, "Control")
self.gui_frame.central_tab_widget.tabBar().setTabText(1, "IOC")
self.expert_labels = self.parent.expert_labels
self.settings = self.parent.settings
self.obj_to_upper = True if random.randint(1, 10) > 3 else False
self.table_sol_dict = {}
self.table_pwr_dict = {}
self.offtime_dict = {}
self.I_min = 1.0
sec_state_list = ['PG1-HUSH:STATE', 'PSH-HUSH:STATE',
'PG2-HUSH:STATE', 'PO2-HUSH:STATE',
'PPIF-HUSH:STATE', 'PG3-HUSH:STATE']
self.cafe.openPrepare()
self.cafe.open(['PRO-HUSH:LASTPWR','PRO-HUSH:TOTPWR',
'PRO:LASTSAVE', 'PPO-HUSH:TOTSAVE'])
self.cafe.open(sec_state_list)
self.cafe.openNowAndWait(0.1)
wgt = self.group_sector_qtabwidget()
self.gui_frame.measurement_layout.addWidget(
wgt, 0, 1, 6, 3, alignment=Qt.AlignTop)
status_wgt = self.group_sector_status()
self.gui_frame.measurement_layout.addWidget(
status_wgt, 2, 0, 2, 1, alignment=Qt.AlignTop) # | Qt.AlignHCenter)
qf = QFrame()
qf.setFixedHeight(6)
self.gui_frame.measurement_layout.addWidget(
qf, 4, 0, 1, 1, alignment=Qt.AlignTop)
self.sectorI_dict = {}
self.sectorI_dict['G1'] = "Geschlossen"
self.sectorI_dict['SH'] = "Geschlossen"
self.sectorI_dict['G2'] = "Geschlossen"
self.sectorI_dict['O2'] = "Geschlossen"
self.sectorI_dict['PIF'] = "Geschlossen"
self.sectorI_dict['G3'] = "Geschlossen"
g3_line = ["SH", "PIF", "G3"]
pif_line = ["SH", "PIF"]
o2_line = ["SH", "O2"]
g2_line = ["SH", "G2"]
def enable_disable_beamline(sect, sector_line, value):
self.sectorI_dict[sect] = value
#print("sect/value", sect, value)
for sector in sector_line:
if "Geschlossen" not in self.sectorI_dict[sector]:
#print("sector/value", sector, value)
if self.table_sol_dict[
sector].standby_value_button.isEnabled():
self.table_sol_dict[
sector].standby_value_button.setEnabled(False)
print("DISABLE", sector)
else:
#print("Geschlossen? sector/value", sector, value)
if not self.table_sol_dict[
sector].standby_value_button.isEnabled():
self.table_sol_dict[
sector].standby_value_button.setEnabled(True)
def receive_g3_update(value, status, alarm_severity):
print("receive_g3_update", flush=True)
enable_disable_beamline('G3', g3_line, value)
def receive_o2_update(value, status, alarm_severity):
enable_disable_beamline('O2', o2_line, value)
def receive_g2_update(value, status, alarm_severity):
enable_disable_beamline('G2', g2_line, value)
def receive_pif_update(value, status, alarm_severity):
enable_disable_beamline('PIF', pif_line, value)
self.gui_header.beam_current_wgt_dict[
"G3"].trigger_monitor_str.connect(receive_g3_update)
self.gui_header.beam_current_wgt_dict[
"O2"].trigger_monitor_str.connect(receive_o2_update)
self.gui_header.beam_current_wgt_dict[
"G2"].trigger_monitor_str.connect(receive_g2_update)
self.gui_header.beam_current_wgt_dict[
"PIF"].trigger_monitor_str.connect(receive_pif_update)
pvd=self.cafe.getPVCache(self.settings.data["G3"]["status"], dt='str')
receive_g3_update(pvd.value[0], pvd.alarmStatus, pvd.alarmSeverity)
pvd=self.cafe.getPVCache(self.settings.data["PIF"]["status"], dt='str')
receive_pif_update(pvd.value[0], pvd.alarmStatus, pvd.alarmSeverity)
pvd=self.cafe.getPVCache(self.settings.data["G2"]["status"], dt='str')
receive_g2_update(pvd.value[0], pvd.alarmStatus, pvd.alarmSeverity)
pvd=self.cafe.getPVCache(self.settings.data["O2"]["status"], dt='str')
receive_o2_update(pvd.value[0], pvd.alarmStatus, pvd.alarmSeverity)
def receive_sec_state(handle, pv, pvdata):
pvsplit = pv.split("-")
secsplit = pvsplit[0].split("P")
sec = secsplit[1]
if pvdata.value[0] == 'ON':
#print("sec-ON", secsplit[1], flush=True)
self.table_sol_dict[sec].init_value_button.setEnabled(True)
self.table_pwr_dict[sec].init_value_button.setEnabled(True)
else:
#print("sec-OFF", secsplit[1], flush=True)
self.table_sol_dict[sec].init_value_button.setEnabled(False)
self.table_pwr_dict[sec].init_value_button.setEnabled(False)
#print("sec", secsplit[1], flush=True)
for state in sec_state_list:
self.cafe.monitor(state, receive_sec_state)
def group_sector_status(self):
qgrid = QGridLayout()
#Connect all channels
#Heading
idx = self.settings.data["header"].index("G1")
idx_last = self.settings.data["header"].index("MASTER")
#Sector
qlp = QLabel("Power \n(kW)")
f = qlp.font()
f.setPixelSize(13)
qlp.setFont(f)
qlp.setAlignment(Qt.AlignCenter)
qli = QLabel("Initial \n(kW)")
f = qli.font()
f.setPixelSize(13)
qli.setFont(f)
qli.setAlignment(Qt.AlignCenter)
qgrid.addWidget(qli, 0, 1, 1, 1)
qsa = QLabel("Saving \n(MWh)")
f = qsa.font()
f.setPixelSize(13)
qsa.setFont(f)
qsa.setAlignment(Qt.AlignCenter)
qti = QLabel("Time in \nSaving Mode")
f = qti.font()
f.setPixelSize(13)
qti.setFont(f)
qti.setAlignment(Qt.AlignCenter)
qtotsav = QLabel("Tot Saved \n(MWh)")
f = qtotsav.font()
f.setPixelSize(13)
qtotsav.setFont(f)
qtotsav.setAlignment(Qt.AlignCenter)
qgrid.addWidget(qlp, 0, 2, 1, 1)
qgrid.addWidget(qsa, 0, 3, 1, 1)
qgrid.addWidget(qti, 0, 5, 1, 1)
qgrid.addWidget(qtotsav, 0, 6, 1, 1)
for i, sector in enumerate(self.settings.data["header"][idx:idx_last]):
a, b, c, d, e, f = self.sector_status(sector)
a.setContentsMargins(2, 0, 0, 0)
qgrid.addWidget(a, i+1, 0, 1, 1)
qgrid.addWidget(b, i+1, 1, 1, 1)
qgrid.addWidget(c, i+1, 2, 1, 1)
qgrid.addWidget(d, i+1, 3, 1, 1)
qgrid.addWidget(e, i+1, 5, 1, 1)
qgrid.addWidget(f, i+1, 6, 1, 1)
_line = QHLine()
_line.setFixedHeight(10)
_row = qgrid.rowCount()
qgrid.addWidget(_line, _row, 1, 1, 6)
#qgrid.setRowMinimumHeight(_row, 60)
qtot = QLabel("Total:")
fnt = qtot.font()
fnt.setPixelSize(13)
qtot.setFont(fnt)
qgrid.addWidget(qtot, _row+1, 0, 1, 1)
qgrid.addWidget(
CAQLineEdit(self, pv_name="PRO-HUSH:LASTPWR", show_units=True),
_row+1, 1, 1, 1)
qgrid.addWidget(
CAQLineEdit(self, pv_name="PRO-HUSH:TOTPWR", show_units=True),
_row+1, 2, 1, 1)
qgrid.addWidget(
CAQLineEdit(self, pv_name="PRO-HUSH:LASTSAVE", show_units=True),
_row+1, 3, 1, 2)
qgrid.addWidget(
CAQLineEdit(self, pv_name="PRO-HUSH:TOTSAVE", show_units=True),
_row+1, 6, 1, 2)
qgrid.setContentsMargins(9, 20, 9, 9)
qw = QGroupBox("Savings Overview")
qw.setContentsMargins(9, 9, 9, 9)
qw.setObjectName("OUTER")
qw.setLayout(qgrid)
qw.setFixedWidth(596) #480
#for column_no in range(0, 5):
# qgrid.itemAtPosition(1, column_no).widget().setStyleSheet("QWidget { background: lightblue; }") #addStyleName(
#item = qgrid.itemAt(2) #.widget().setStyleSheet("QLabel { background-color: green }")
#item.widget().setStyleSheet("background-color: green") #widgets on grid from left to right starting at top rtow
return qw
def sector_status(self, sector):
'''Create each sector line for inclusion into group
'''
#device = "SEC-" + sector
device = "P" + sector + "-HUSH"
#Qlabel
qsector = QLabel(sector+":")
f = qsector.font()
f.setPixelSize(13)
qsector.setFont(f)
_color = "black"
try:
_color = self.settings.data[sector]["color"]
except KeyError as ex:
print(ex, self.settings.data[sector])
_color_str = "color : {0};".format(_color)
_incolor = "QLabel {" + _color_str + "}"
qsector.setStyleSheet(_incolor)
#Savings
pv_pwr_tot = device + ":TOTPWR"
pv_pwr_last = device + ":LASTPWR"
pv_pwr_saved = device + ":LASTSAVE"
pv_pwr_timeout = device + ":OFFTIME"
pv_pwr_totsave = device + ":TOTSAVE"
self.cafe.openPrepare()
self.cafe.open([pv_pwr_tot, pv_pwr_last, pv_pwr_saved, pv_pwr_timeout])
self.cafe.openNowAndWait(2.0)
time.sleep(0.1)
#print("device", device, flush=True)
def cb_outtime(handle, pv, pvdata):
try:
_delta = "{}".format(str(timedelta(seconds=(pvdata.value[0]))))
if ", " in _delta:
_split = _delta.split(", ")
if len(_split[1]) == len("0:00:00"):
_delta = _split[0] + ", " + _split[1]
if 'days,' in _delta:
_delta = _delta.replace("days,", "d")
elif 'day,' in _delta:
_delta = _delta.replace("day,", "d")
self.offtime_dict[pv].setText(_delta)
except KeyError:
pass
now = QDateTime.currentDateTime()
xdate = QDate(now.date().year(), 1, 15)
xstart = QDateTime(xdate)
qpinit = CAQLineEdit(self, pv_name=pv_pwr_last, show_units=False)
qpnow = CAQLineEdit(self, pv_name=pv_pwr_tot, show_units=False)
qpsave = CAQLineEdit(self, pv_name=pv_pwr_saved, show_units=False)
qptotsave = CAQLineEdit(self, pv_name=pv_pwr_totsave, show_units=False)
qptime = CAQLineEdit(self, pv_name=pv_pwr_timeout,
monitor_callback=cb_outtime, show_units=True)
self.offtime_dict[pv_pwr_timeout] = qptime
#Time to allow cb_outtime to fire
time.sleep(0.5)
qptime.setFixedWidth(104)
#qtdis = QBasicTimer()
#qpnow.setAlignment(Qt.AlignRight)
#qpnow.style().polish(qpnow)
return qsector, qpinit, qpnow, qpsave, qptime, qptotsave
def group_sector_qtabwidget(self):
idx_last = self.settings.data["header"].index("MASTER")
idx = self.settings.data["header"].index("G1")
#open all PVS
pv = []
for sector in self.settings.data["header"][idx:idx_last]:
device_list = self.settings.data[sector]["device"]
attribute_list = self.settings.data[sector]["attribute"]
for att in attribute_list:
for dev in device_list:
pv.append(dev + ":" + att)
self.cafe.openPrepare()
self.cafe.open(pv)
self.cafe.openNowAndWait(1.0)
#self.cafe.supplementHandles()
sector_wgt_dict = {}
for sector in self.settings.data["header"][idx:idx_last]:
sector_wgt_dict[sector] = self.ca_table_sector_widget(sector=sector)
sector_tab_widget = QTabWidget()
sector_tab_widget.setFont(self.font_gui)
sector_tab_widget.setStyleSheet("QTabBar {font-size: 12pt;}")
sector_tab_widget.tabBar().setShape(QTabBar.TriangularNorth)
for i, sector in enumerate(self.settings.data["header"][idx:idx_last]):
sector_tab_widget.addTab(sector_wgt_dict[sector], sector)
color = self.settings.data[sector]["color"]
sector_tab_widget.tabBar().setTabTextColor(i, QColor(color))
#sector_tab_widget.addTab(sector_wgt_dict["INJ2"], "RF")
#color = self.settings.data["INJ2"]["color"]
#sector_tab_widget.tabBar().setTabTextColor(
# len(self.settings.data["header"][idx:]), QColor(color))
return sector_tab_widget
def check_status_list(self, pv_list, status_list, line):
_brk = ("------------------------------------------------------" +
"------------------------------------------------------")
self.parent.trigger_log_message.emit(
MsgSeverity.INFO.name, _pymodule, line, _brk, {})
_options = {}
for pv, stat in zip(pv_list, status_list):
if stat != self.cyca.ICAFE_NORMAL:
_mess = ("Error in 'set' for " + pv + " ")
_options['statusCode'] = (
str(stat) + " " +
self.cafe.getStatusCodeAsString(stat))
_options['statusInfo'] = self.cafe.getStatusInfo(stat)
self.parent.trigger_log_message.emit(
MsgSeverity.WARN.name, _pymodule, line, _mess, _options)
self.parent.trigger_log_message.emit(
MsgSeverity.INFO.name, _pymodule, line, _brk, {})
_mess = ("The following devices reported an error " +
"in 'set' operation:")
self.parent.trigger_log_message.emit(
MsgSeverity.INFO.name, _pymodule, line, _mess, {})
def check_status(self, pv, stat, line):
if stat != self.cyca.ICAFE_NORMAL:
_mess = ("Error in 'set' for " + pv + ".")
_options = {}
_options['statusCode'] = (
str(stat) + " " +
self.cafe.getStatusCodeAsString(stat))
_options['statusInfo'] = self.cafe.getStatusInfo(
stat)
self.parent.trigger_log_message.emit(
MsgSeverity.WARN.name, _pymodule, line,
_mess, _options)
def on_sector_standby(self):
target = self.sender()
sector = target.sector
_table = self.table_sol_dict[sector]
def is_update_enabled():
'''Check if update buttons are enabled
if NOT, then do not allow inital values values to be updated"
'''
if self.table_pwr_dict[sector].init_value_button.isEnabled() \
and _table.init_value_button.isEnabled():
return True
else:
return False
QApplication.processEvents(QEventLoop.AllEvents, 1.0)
#Do NOT do updates if in standby mode!
#Update button is disabled when in standby
#disenable widgets to avoid circular behaviour since
#updates of SOL also update PWR, and vice-versa
#Do not click if already on standby!!
if is_update_enabled():
self.table_pwr_dict[sector].init_value_button.setEnabled(False)
_table.init_value_button.click()
time.sleep(0.05)
self.table_pwr_dict[sector].init_value_button.setEnabled(True)
_table.init_value_button.setEnabled(False)
self.table_pwr_dict[sector].init_value_button.click()
time.sleep(0.05)
self.table_sol_dict[sector].init_value_button.setEnabled(True)
QApplication.processEvents(QEventLoop.AllEvents, 1.0)
if not self.input_parameters['simulation']:
status, status_list, pv_list = _table.set_standby_values()
if status != self.cyca.ICAFE_NORMAL:
self.check_status_list(pv_list, status_list, _line())
pv = 'P' + target.sector + "-HUSH:STATE"
stat = self.cafe.set(pv, 0)
self.check_status(pv, stat, _line())
def on_sector_restore(self):
target = self.sender()
sector = target.sector
_table = self.table_sol_dict[sector]
if not self.input_parameters['simulation']:
status, status_list, pv_list = _table.restore_init_values()
if status != self.cyca.ICAFE_NORMAL:
self.check_status_list(pv_list, status_list, _line())
pv = 'P' + target.sector + "-HUSH:STATE"
stat = self.cafe.set(pv, 1)
self.check_status(pv, stat, _line())
_table_pwr = self.table_pwr_dict[sector]
row_pwr_dict = _table_pwr.get_init_values()
sum_pwr = sum(list(row_pwr_dict.values()))
pv_last_pwr = 'P' + target.sector + "-HUSH:LASTPWR"
stat = self.cafe.set(pv_last_pwr, sum_pwr)
self.check_status(pv_last_pwr, stat, _line())
def ca_table_sector_widget(self, sector: str="", color: str="MACHINE"):
device_list = self.settings.data[sector]["device"]
attribute_list = self.settings.data[sector]["attribute"]
try:
_standby_values = self.settings.data[sector]["standby"]
print("Standby Values", sector, _standby_values, flush=True)
except KeyError as ex:
print("On Standby values not given for sector {0}".format(sector))
pv_dict = {}
for att in attribute_list:
pv_dict[att] = [] #[None] * len(device_list)
for dev in device_list:
pv_dict[att].append(dev + ":" + att)
_table_height = 700
try:
_delay = self.input_parameters["delayRamp"]
except KeyError:
_delay = 0.09
pass
print(pv_dict['SOL:2'], flush=True)
print(_standby_values, flush=True)
table_sol = CAQTableWidget(
self, pv_list=pv_dict['SOL:2'], show_units=True, notify_freq_hz=0,
notify_unison=False, scale_factor=1, show_timestamp=False,
init_column=True, pv_list_show=device_list, standby_column=True,
standby_values=_standby_values, set_delay = _delay)
table_sol.restore_value_button.setToolTip(
("Restore devices to their pre-standby values"))
table_sol.init_value_button.setToolTip(
("Shows initial, pre-standby values. Update is also " +
"executed automatically before the standby procedure."))
table_sol.standby_value_button.sector = sector
table_sol.standby_value_button.clicked.disconnect()
table_sol.standby_value_button.clicked.connect(self.on_sector_standby)
table_sol.restore_value_button.sector = sector
table_sol.restore_value_button.clicked.disconnect()
table_sol.restore_value_button.clicked.connect(self.on_sector_restore)
self.table_sol_dict[sector] = table_sol
table_ist = CAQTableWidget(
self, pv_list=pv_dict['IST:2'], show_units=True, notify_freq_hz=2,
notify_unison=True, scale_factor=1, show_timestamp=False,
init_column=False, pv_list_show=[False])
table_pwr = CAQTableWidget(
self, pv_list=pv_dict['PWR'], show_units=False, notify_freq_hz=0,
suffix = "kW",
notify_unison=False, scale_factor=0.001, show_timestamp=False,
init_column=True, init_list=pv_dict['PWR'], pv_list_show=[False])
table_pwr.init_value_button.setToolTip(
("Shows initial, pre-standby values. Update is also " +
"executed automatically before the standby procedure."))
self.table_pwr_dict[sector] = table_pwr
header_item = QTableWidgetItem()
header_init = QTableWidgetItem()
header_standby = QTableWidgetItem()
header_value = QTableWidgetItem()
f = header_value.font()
f.setPixelSize(13)
header_item.setFont(f)
header_item.setText('Device')
header_init.setFont(f)
header_init.setText('Init. Value')
header_standby.setFont(f)
header_standby.setText('Standby')
header_value.setFont(f)
header_value.setText('SOL:2')
table_sol.setContentsMargins(15, 0, 15, 10)
table_sol.setHorizontalHeaderItem(0, header_item)
table_sol.setHorizontalHeaderItem(1, header_init)
table_sol.setHorizontalHeaderItem(2, header_standby)
table_sol.setHorizontalHeaderItem(3, header_value)
table_sol.setColumnWidth(0, 80)
table_sol.setColumnWidth(1, 88)
table_sol.setColumnWidth(2, 80)
table_sol.setColumnWidth(3, 88)
table_sol.setFixedWidth(386)
ioc_magnets = []
for i, device in enumerate(device_list):
if device in self.settings.data[sector]["iocDevice"]:
ioc_magnets.append(i)
header_value = QTableWidgetItem()
f = header_value.font()
f.setPixelSize(13)
header_value.setFont(f)
header_value.setText('IST:2')
table_ist.setContentsMargins(15, 0, 15, 10)
table_ist.setHorizontalHeaderItem(0, header_value)
table_ist.setColumnWidth(0, 90)
table_ist.setFixedWidth(140)
header_init = QTableWidgetItem()
f = header_init.font()
header_init.setFont(f)
header_init.setText('Init. Value')
header_value = QTableWidgetItem()
f = header_value.font()
f.setPixelSize(13)
header_value.setFont(f)
header_value.setText('PWR')
table_pwr.setContentsMargins(15, 0, 15, 10)
table_pwr.setHorizontalHeaderItem(0, header_init)
table_pwr.setHorizontalHeaderItem(1, header_value)
table_pwr.setColumnWidth(0, 88)
table_pwr.setColumnWidth(1, 88)
table_pwr.setFixedWidth(226)
for i in ioc_magnets:
table_sol.paint_rows(row_range=[i, i+1], reset=False,
columns=[0, 1])
table_ist.paint_rows(row_range=[i, i+1], reset=False)
table_pwr.paint_rows(row_range=[i, i+1], reset=False)
pvStatus = self.settings.data[sector]['status']
beamline_status = self.cafe.getCache(pvStatus)
if beamline_status is not None:
#if I < self.I_min:
if "Geschlossen" in beamline_status:
try:
values = self.settings.data[sector]['ref']
table_sol.set_init_values(values)
except KeyError:
pass
try:
pwr_values = self.settings.data[sector]['pwrref']
table_pwr.set_init_values(pwr_values)
except KeyError:
pass
def on_sol_update():
table_sol.init_value_button.setEnabled(False)
table_pwr.init_value_button.click()
time.sleep(0.1)
table_sol.init_value_button.setEnabled(True)
pv = "P" + table_pwr.init_value_button.sector + "-HUSH:LASTPWR"
_sum = sum(table_pwr.get_init_values().values())
print("SUM up all the values", pv, _sum, flush=True)
stat = self.cafe.set(pv, _sum)
self.check_status(pv, stat, _line())
def on_init_update():
table_pwr.init_value_button.setEnabled(False)
table_sol.init_value_button.click()
time.sleep(0.1)
table_pwr.init_value_button.setEnabled(True)
table_sol.init_value_button.sector = sector
table_sol.init_value_button.clicked.connect(on_sol_update)
table_pwr.init_value_button.sector = sector
table_pwr.init_value_button.clicked.connect(on_init_update)
hbox = QHBoxLayout()
hbox.addWidget(table_sol)
hbox.addWidget(table_ist)
hbox.addWidget(table_pwr)
hbox.setSpacing(10)
hbox.setAlignment(Qt.AlignTop)
qw = QWidget()
qw.setLayout(hbox)
obj_name = self.settings.data[sector]["colorObj"]
if self.obj_to_upper:
obj_name = obj_name.upper()
qw.setObjectName(obj_name)
return qw