From d153f2573e6092804cdf23f6b881bdb0b48e2d51 Mon Sep 17 00:00:00 2001 From: MAKOMO Date: Fri, 24 Sep 2021 08:58:01 +0200 Subject: [PATCH] - removes HUD - improves on Issue #695 --- src/artisanlib/acaia.py | 2 +- src/artisanlib/ble.py | 6 +- src/artisanlib/comparator.py | 6 +- src/artisanlib/curves.py | 215 +++---- src/artisanlib/event_button_style.py | 92 +++ src/artisanlib/main.py | 563 +++--------------- src/artisanlib/roast_properties.py | 13 +- .../{sliderStyle.py => slider_style.py} | 1 - 8 files changed, 262 insertions(+), 636 deletions(-) create mode 100644 src/artisanlib/event_button_style.py rename src/artisanlib/{sliderStyle.py => slider_style.py} (99%) diff --git a/src/artisanlib/acaia.py b/src/artisanlib/acaia.py index 514e0801f..5abe19726 100644 --- a/src/artisanlib/acaia.py +++ b/src/artisanlib/acaia.py @@ -264,7 +264,7 @@ def parseWeightEvent(self,payload): # if value is fresh and reading is stable if value != self.weight: # and stable: self.weight = value - _log.debug("new weight: %s", self.weight) +# _log.debug("new weight: %s", self.weight) return self.EVENT_WEIGHT_LEN diff --git a/src/artisanlib/ble.py b/src/artisanlib/ble.py index 82da402f4..f0a1636fd 100644 --- a/src/artisanlib/ble.py +++ b/src/artisanlib/ble.py @@ -169,7 +169,7 @@ def update_connected(self,connected=bool): def heartbeat(self): if self.m_connected: - _log.debug("send heartbeat") +# _log.debug("send heartbeat") self.sendHeartbeat(self.write) QtCore.QTimer.singleShot(2000,self.heartbeat) @@ -293,9 +293,9 @@ def deviceHasService(device, service_uuid): @QtCore.pyqtSlot("QBluetoothDeviceInfo") def addDevice(self, device): - _log.debug("addDevice()") +# _log.debug("addDevice()") if self.m_device is None and device.coreConfigurations() & QtBluetooth.QBluetoothDeviceInfo.LowEnergyCoreConfiguration: - _log.debug("discovered LE Device name: %s, address: %s", device.name(), device.address().toString()) +# _log.debug("discovered LE Device name: %s, address: %s", device.name(), device.address().toString()) m_device = QtBluetooth.QBluetoothDeviceInfo(device) if self.device_names is None: _log.debug("check device for matching services") diff --git a/src/artisanlib/comparator.py b/src/artisanlib/comparator.py index e2615ff36..d6fff5e88 100644 --- a/src/artisanlib/comparator.py +++ b/src/artisanlib/comparator.py @@ -685,7 +685,7 @@ class roastCompareDlg(ArtisanDialog): __slots__ = [ 'foreground', 'background', 'maxentries', 'basecolors', 'profiles', 'label_number', 'l_align', 'legend', 'legendloc_pos', 'addButton', 'deleteButton', 'alignnames', 'alignComboBox', 'etypes', 'eventsComboBox', 'cb', 'model', 'button_7_org_state_hidden', 'button_1_org_state_hidden', - 'button_2_org_state_hidden', 'button_10_org_state_hidden', 'button_18_org_state_hidden', 'pick_handler_id' ] + 'button_2_org_state_hidden', 'button_10_org_state_hidden', 'pick_handler_id' ] def __init__(self, parent = None, aw = None, foreground = None, background = None): super().__init__(parent, aw) @@ -808,7 +808,6 @@ def __init__(self, parent = None, aw = None, foreground = None, background = Non self.button_1_org_state_hidden = self.aw.button_1.isHidden() # ON/OFF self.button_2_org_state_hidden = self.aw.button_2.isHidden() # START/STOP self.button_10_org_state_hidden = self.aw.button_10.isHidden() # CONTROL - self.button_18_org_state_hidden = self.aw.button_18.isHidden() # HUD self.disableButtons() self.aw.disableEditMenus(compare=True) @@ -849,15 +848,12 @@ def enableButtons(self): self.aw.button_2.show() # START/STOP if not self.button_10_org_state_hidden: self.aw.button_10.show() # CONTROL - if not self.button_18_org_state_hidden: - self.aw.button_18.show() # HUD def disableButtons(self): self.aw.button_7.hide() # RESET self.aw.button_1.hide() # ON/OFF self.aw.button_2.hide() # START/STOP self.aw.button_10.hide() # CONTROL - self.aw.button_18.hide() # HUD ### DRAWING diff --git a/src/artisanlib/curves.py b/src/artisanlib/curves.py index 291517039..c538c9215 100644 --- a/src/artisanlib/curves.py +++ b/src/artisanlib/curves.py @@ -17,7 +17,7 @@ # Marko Luther, 2020 ########################################################################## -##################### EXTRAS/HUD EDIT DLG ####################### +##################### Curves DLG ################################# ########################################################################## import sys @@ -38,7 +38,7 @@ from PyQt6.QtWidgets import (QApplication, QWidget, QCheckBox, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit, # @UnusedImport @Reimport @UnresolvedImport QPushButton, QSpinBox, QTabWidget, QComboBox, QDialogButtonBox, QGridLayout, # @UnusedImport @Reimport @UnresolvedImport QGroupBox, QLayout, QMessageBox, QRadioButton, QStyleFactory, QHeaderView, # @UnusedImport @Reimport @UnresolvedImport - QTableWidget, QTableWidgetItem) # @UnusedImport @Reimport @UnresolvedImport + QTableWidget, QTableWidgetItem, QFrame) # @UnusedImport @Reimport @UnresolvedImport except Exception: #pylint: disable = E, W, R, C from PyQt5.QtCore import (Qt, pyqtSlot, QSettings, QCoreApplication, QRegularExpression) # @UnusedImport @Reimport @UnresolvedImport @@ -46,7 +46,7 @@ from PyQt5.QtWidgets import (QApplication, QWidget, QCheckBox, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit, # @UnusedImport @Reimport @UnresolvedImport QPushButton, QSpinBox, QTabWidget, QComboBox, QDialogButtonBox, QGridLayout, # @UnusedImport @Reimport @UnresolvedImport QGroupBox, QLayout, QMessageBox, QRadioButton, QStyleFactory, QHeaderView, # @UnusedImport @Reimport @UnresolvedImport - QTableWidget, QTableWidgetItem) # @UnusedImport @Reimport @UnresolvedImport + QTableWidget, QTableWidgetItem, QFrame) # @UnusedImport @Reimport @UnresolvedImport ######################################################################################## @@ -272,7 +272,7 @@ def copyDataTabletoClipboard(self,_=False): -class HUDDlg(ArtisanDialog): +class CurvesDlg(ArtisanDialog): def __init__(self, parent = None, aw = None, activeTab = 0): super().__init__(parent, aw) @@ -292,7 +292,6 @@ def __init__(self, parent = None, aw = None, activeTab = 0): self.org_patheffects = self.aw.qmc.patheffects self.org_graphstyle = self.aw.qmc.graphstyle self.org_graphfont = self.aw.qmc.graphfont - self.org_HUDbuttonflag = self.aw.qmc.HUDbuttonflag self.org_filterDropOuts = self.aw.qmc.filterDropOuts self.org_dropSpikes = self.aw.qmc.dropSpikes self.org_dropDuplicates = self.aw.qmc.dropDuplicates @@ -313,21 +312,6 @@ def __init__(self, parent = None, aw = None, activeTab = 0): self.org_BTname = self.aw.BTname self.org_foregroundShowFullflag = self.aw.qmc.foregroundShowFullflag - self.showHUDbutton = QCheckBox(QApplication.translate("Label", "HUD Button", None)) - self.showHUDbutton.setChecked(self.aw.qmc.HUDbuttonflag) - self.showHUDbutton.setFocusPolicy(Qt.FocusPolicy.NoFocus) - self.showHUDbutton.stateChanged.connect(self.showHUDbuttonToggle) - ETLabel = QLabel(QApplication.translate("Label", "ET Target 1",None)) - ETLabel.setAlignment(Qt.AlignmentFlag.AlignRight) - BTLabel = QLabel(QApplication.translate("Label", "BT Target 1",None)) - BTLabel.setAlignment(Qt.AlignmentFlag.AlignRight) - ET2Label = QLabel(QApplication.translate("Label", "ET Target 2",None)) - ET2Label.setAlignment(Qt.AlignmentFlag.AlignRight) - BT2Label = QLabel(QApplication.translate("Label", "BT Target 2",None)) - BT2Label.setAlignment(Qt.AlignmentFlag.AlignRight) - modeLabel = QLabel(QApplication.translate("Label", "Mode",None)) - modeLabel.setAlignment(Qt.AlignmentFlag.AlignRight) - ETPIDLabel = QLabel(QApplication.translate("Label", "ET p-i-d 1",None)) #delta ET self.DeltaET = QCheckBox() self.DeltaET.setFocusPolicy(Qt.FocusPolicy.NoFocus) @@ -457,61 +441,10 @@ def __init__(self, parent = None, aw = None, activeTab = 0): pass self.deltaETspan.currentIndexChanged.connect(self.changeDeltaETspan) #toggle - self.modeComboBox = QComboBox() - self.modeComboBox.setMaximumWidth(100) - self.modeComboBox.setMinimumWidth(55) - self.modeComboBox.addItems([QApplication.translate("ComboBox","metrics",None), - QApplication.translate("ComboBox","thermal",None)]) - self.modeComboBox.setCurrentIndex(self.aw.HUDfunction) - self.ETlineEdit = QLineEdit(str(self.aw.qmc.ETtarget)) - self.ETlineEdit.setAlignment(Qt.AlignmentFlag.AlignRight) - self.BTlineEdit = QLineEdit(str(self.aw.qmc.BTtarget)) - self.BTlineEdit.setAlignment(Qt.AlignmentFlag.AlignRight) - self.ETlineEdit.setValidator(QIntValidator(0, 1000, self.ETlineEdit)) - self.BTlineEdit.setValidator(QIntValidator(0, 1000, self.BTlineEdit)) - self.ETlineEdit.setMaximumWidth(60) - self.BTlineEdit.setMaximumWidth(60) - self.ET2lineEdit = QLineEdit(str(self.aw.qmc.ET2target)) - self.ET2lineEdit.setAlignment(Qt.AlignmentFlag.AlignRight) - self.BT2lineEdit = QLineEdit(str(self.aw.qmc.BT2target)) - self.BT2lineEdit.setAlignment(Qt.AlignmentFlag.AlignRight) - self.ET2lineEdit.setValidator(QIntValidator(0, 1000, self.ET2lineEdit)) - self.BT2lineEdit.setValidator(QIntValidator(0, 1000, self.BT2lineEdit)) - self.ET2lineEdit.setMaximumWidth(60) - self.BT2lineEdit.setMaximumWidth(60) - self.ETpidP = QLineEdit(str(self.aw.qmc.hudETpid[0])) - self.ETpidP.setAlignment(Qt.AlignmentFlag.AlignRight) - self.ETpidI = QLineEdit(str(self.aw.qmc.hudETpid[1])) - self.ETpidI.setAlignment(Qt.AlignmentFlag.AlignRight) - self.ETpidD = QLineEdit(str(self.aw.qmc.hudETpid[2])) - self.ETpidD.setAlignment(Qt.AlignmentFlag.AlignRight) - self.ETpidP.setValidator(QIntValidator(0, 1000, self.ETpidP)) - self.ETpidI.setValidator(QIntValidator(0, 1000, self.ETpidI)) - self.ETpidD.setValidator(QIntValidator(0, 1000, self.ETpidD)) - self.ETpidP.setMaximumWidth(60) - self.ETpidI.setMaximumWidth(60) - self.ETpidD.setMaximumWidth(60) - # connect the ArtisanDialog standard OK/Cancel buttons self.dialogbuttons.accepted.connect(self.updatetargets) self.dialogbuttons.rejected.connect(self.close) - hudLayout = QGridLayout() - hudLayout.addWidget(BTLabel,0,0) - hudLayout.addWidget(self.BTlineEdit,0,1) - hudLayout.addWidget(BT2Label,0,2) - hudLayout.addWidget(self.BT2lineEdit,0,3) - hudLayout.addWidget(ETLabel,1,0) - hudLayout.addWidget(self.ETlineEdit,1,1) - hudLayout.addWidget(ET2Label,1,2) - hudLayout.addWidget(self.ET2lineEdit,1,3) - hudLayout.addWidget(ETPIDLabel,2,0) - hudLayout.addWidget(self.ETpidP,2,1) - hudLayout.addWidget(self.ETpidI,2,2) - hudLayout.addWidget(self.ETpidD,2,3) - hudLayout.addWidget(modeLabel,3,0) - hudLayout.addWidget(self.modeComboBox,3,1) - hudLayout.addWidget(self.showHUDbutton,3,3) rorBoxLayout = QHBoxLayout() rorBoxLayout.addWidget(self.DeltaET) rorBoxLayout.addWidget(DeltaETlabel) @@ -589,20 +522,7 @@ def __init__(self, parent = None, aw = None, activeTab = 0): rorSymbolicFormulaGroupLayout = QGroupBox(QApplication.translate("GroupBox","Rate of Rise Symbolic Assignments",None)) rorSymbolicFormulaGroupLayout.setLayout(rorSymbolicFormulas) - - hudHBox = QHBoxLayout() - hudHBox.addStretch() - hudHBox.addLayout(hudLayout) - hudHBox.addStretch() - hudGroupLayout = QGroupBox(QApplication.translate("GroupBox","Head Up Display",None)) - hudGroupLayout.setLayout(hudHBox) - if self.app.artisanviewerMode: - hudGroupLayout.setEnabled(False) - rorRoRAlgo = QHBoxLayout() - rorRoRAlgo.addWidget(self.PolyFitFlag) - rorRoRAlgo.addSpacing(20) - rorRoRAlgo.addWidget(self.OptimalSmoothingFlag) - rorRoRAlgo.addStretch() + inputFilter0 = QHBoxLayout() inputFilter0.addWidget(self.DropDuplicates) inputFilter0.addWidget(self.DropDuplicatesLimit) @@ -613,30 +533,43 @@ def __init__(self, parent = None, aw = None, activeTab = 0): inputFilter1.addWidget(self.swapETBT) inputFilter2 = QHBoxLayout() inputFilter2.addWidget(self.MinMaxLimits) - inputFilter2.addStretch() + inputFilter2.addSpacing(20) inputFilter2.addWidget(minlabel) inputFilter2.addWidget(self.minLimit) - inputFilter2.addSpacing(20) + inputFilter2.addSpacing(15) inputFilter2.addWidget(maxlabel) inputFilter2.addWidget(self.maxLimit) + inputFilter2.addStretch() inputFilterVBox = QVBoxLayout() inputFilterVBox.addLayout(inputFilter0) inputFilterVBox.addLayout(inputFilter1) - inputFilterVBox.addLayout(inputFilter2) + inputFilterVBox.addLayout(inputFilter2) + inputFilterVBox.addStretch() inputFilterGroupLayout = QGroupBox(QApplication.translate("GroupBox","Input Filter",None)) inputFilterGroupLayout.setLayout(inputFilterVBox) + + inputFilter0.setContentsMargins(0,0,0,0) + inputFilter1.setContentsMargins(0,0,0,0) + inputFilter2.setContentsMargins(0,0,0,0) + + inputFilterVBox.setContentsMargins(7,7,7,7) + # Post Roast Group postRoastVBox = QVBoxLayout() postRoastVBox.addLayout(spikesLayout2) postRoastGroupLayout = QGroupBox(QApplication.translate("GroupBox","Curve Filter",None)) postRoastGroupLayout.setLayout(postRoastVBox) + postRoastVBox.setContentsMargins(7,7,7,7) + # Render xGroup renderVBox = QVBoxLayout() renderVBox.addWidget(self.ShowFull) renderGroupLayout = QGroupBox(QApplication.translate("GroupBox","Display Filter",None)) - renderGroupLayout.setLayout(renderVBox) + renderGroupLayout.setLayout(renderVBox) + + renderVBox.setContentsMargins(7,7,7,7) #swapETBT flag self.rorFilter = QCheckBox(QApplication.translate("CheckBox", "Limits",None)) @@ -662,18 +595,33 @@ def __init__(self, parent = None, aw = None, activeTab = 0): self.rormaxLimit.setSuffix(" C/min") rorFilterHBox = QHBoxLayout() rorFilterHBox.addWidget(self.rorFilter) - rorFilterHBox.addStretch() + rorFilterHBox.addSpacing(20) rorFilterHBox.addWidget(rorminlabel) rorFilterHBox.addWidget(self.rorminLimit) - rorFilterHBox.addSpacing(20) + rorFilterHBox.addSpacing(15) rorFilterHBox.addWidget(rormaxlabel) rorFilterHBox.addWidget(self.rormaxLimit) + rorFilterHBox.addStretch() + rorFilterVBoxHLine = QFrame() + rorFilterVBoxHLine.setFrameStyle(QFrame.Shape.HLine) + rorFilterVBoxHLine.setFrameShadow(QFrame.Shadow.Sunken) rorFilterVBox = QVBoxLayout() - rorFilterVBox.addLayout(sensitivityLayout) - rorFilterVBox.addLayout(rorRoRAlgo) + rorFilterVBox.addStretch() + rorFilterVBox.addWidget(self.PolyFitFlag) + rorFilterVBox.addWidget(self.OptimalSmoothingFlag) + rorFilterVBox.addWidget(rorFilterVBoxHLine) rorFilterVBox.addLayout(rorFilterHBox) + rorHBox = QHBoxLayout() + rorHBox.addLayout(sensitivityLayout) + rorHBox.addSpacing(12) + rorHBox.addLayout(rorFilterVBox) rorFilterGroupLayout = QGroupBox(QApplication.translate("GroupBox","Rate of Rise Filter",None)) - rorFilterGroupLayout.setLayout(rorFilterVBox) + rorFilterGroupLayout.setLayout(rorHBox) + + rorFilterHBox.setContentsMargins(0,0,0,0) + rorFilterHBox.setSpacing(2) + rorFilterVBox.setContentsMargins(0,0,0,0) + # path effects effectslabel = QLabel(QApplication.translate("Label", "Path Effects",None)) self.PathEffects = QSpinBox() @@ -727,14 +675,12 @@ def __init__(self, parent = None, aw = None, activeTab = 0): tab1UpperLayout.addWidget(inputFilterGroupLayout) tab1UpperLayout.addLayout(tab1UpperRightLayout) + tab1UpperRightLayout.setSpacing(5) + tab1Layout = QVBoxLayout() tab1Layout.addLayout(tab1UpperLayout) tab1Layout.addWidget(rorFilterGroupLayout) tab1Layout.addStretch() - #tab11 - tab11Layout = QVBoxLayout() - tab11Layout.addWidget(hudGroupLayout) - tab11Layout.addStretch() #tab2 #Equation plotter # self.equlabel = QLabel(QApplication.translate("Label", "Y(x)",None)) @@ -1348,47 +1294,48 @@ def __init__(self, parent = None, aw = None, activeTab = 0): ############################ TABS LAYOUT self.TabWidget = QTabWidget() + # RoR C0Widget = QWidget() C0Widget.setLayout(tab0Layout) - tab0Layout.setContentsMargins(10,10,10,10) - C0Widget.setContentsMargins(0,10,0,10) + tab0Layout.setContentsMargins(5, 5, 5, 5) # L,T,R,B + C0Widget.setContentsMargins(0, 0, 0, 0) self.TabWidget.addTab(C0Widget,QApplication.translate("Tab","RoR",None)) + # Filters C1Widget = QWidget() C1Widget.setLayout(tab1Layout) - tab1Layout.setContentsMargins(10,10,10,10) - C1Widget.setContentsMargins(0,10,0,10) + tab1Layout.setContentsMargins(5, 5, 5, 0) + C1Widget.setContentsMargins(0, 0, 0, 0) self.TabWidget.addTab(C1Widget,QApplication.translate("Tab","Filters",None)) - C11Widget = QWidget() - C11Widget.setLayout(tab11Layout) - tab11Layout.setContentsMargins(10,10,10,10) - C11Widget.setContentsMargins(0,10,0,10) - self.TabWidget.addTab(C11Widget,QApplication.translate("Tab","HUD",None)) + # Plotter C2Widget = QWidget() C2Widget.setLayout(tab2Layout) - tab2Layout.setContentsMargins(10,10,10,10) - C2Widget.setContentsMargins(0,0,0,0) + tab2Layout.setContentsMargins(5, 5, 5, 0) + C2Widget.setContentsMargins(0, 0, 0, 0) self.TabWidget.addTab(C2Widget,QApplication.translate("Tab","Plotter",None)) + # Math C3Widget = QWidget() C3Widget.setLayout(tab3Layout) - tab3Layout.setContentsMargins(10,10,10,10) - C3Widget.setContentsMargins(0,0,0,0) + tab3Layout.setContentsMargins(5, 5, 0, 5) + C3Widget.setContentsMargins(0, 0, 0, 0) self.TabWidget.addTab(C3Widget,QApplication.translate("Tab","Math",None)) + # Analyzer C4Widget = QWidget() C4Widget.setLayout(tab4Layout) - tab4Layout.setContentsMargins(10,10,10,10) - C3Widget.setContentsMargins(0,0,0,0) + tab4Layout.setContentsMargins(5, 5, 5, 0) + C3Widget.setContentsMargins(0, 0, 0, 0) self.TabWidget.addTab(C4Widget,QApplication.translate("Tab","Analyze",None)) + # UI C5Widget = QWidget() C5Widget.setLayout(tab5Layout) - tab5Layout.setContentsMargins(10,10,10,10) - C5Widget.setContentsMargins(0,10,0,0) + tab5Layout.setContentsMargins(5,5,5,0) + C5Widget.setContentsMargins(0,0,0,0) self.TabWidget.addTab(C5Widget,QApplication.translate("Tab","UI",None)) buttonsLayout = QHBoxLayout() buttonsLayout.addStretch() buttonsLayout.addWidget(self.dialogbuttons) #incorporate layouts Slayout = QVBoxLayout() - Slayout.addWidget(self.TabWidget,1) + Slayout.addWidget(self.TabWidget) Slayout.addStretch() Slayout.addLayout(buttonsLayout) self.TabWidget.currentChanged.connect(self.tabSwitched) @@ -1577,15 +1524,6 @@ def toggleWebLCDs(self,b): self.QRpic.setPixmap(QPixmap()) self.aw.stopWebLCDs() - @pyqtSlot(int) - def showHUDbuttonToggle(self,i): - if i: - self.aw.qmc.HUDbuttonflag = True - if not self.app.artisanviewerMode: - self.aw.button_18.setVisible(True) - else: - self.aw.qmc.HUDbuttonflag = False - self.aw.button_18.setVisible(False) def changedpi(self): try: @@ -2143,7 +2081,7 @@ def polyfitcurveschanged(self,_=0): @pyqtSlot(int) def tabSwitched(self,i): self.closeHelp() - if i != 4: + if i != 3: # not Math tab if self.polyfitCheck.isChecked(): self.polyfitCheck.setChecked(False) if self.expvarCheck.isChecked(): @@ -2154,7 +2092,7 @@ def tabSwitched(self,i): self.interpCheck.setChecked(False) if self.univarCheck.isChecked(): self.univarCheck.setChecked(False) - else: + else: # Math tab self.collectCurves() # TODO: add background curves temp1B, temp2B, timeB, delta1B, delta2B (could be of different size!) # pylint: disable=fixme @@ -2445,7 +2383,7 @@ def close(self): settings = QSettings() settings.setValue("CurvesPosition",self.frameGeometry().topLeft()) - self.aw.HUDDlg_activeTab = self.TabWidget.currentIndex() + self.aw.CurveDlg_activeTab = self.TabWidget.currentIndex() #restore settings self.aw.qmc.DeltaETflag = self.org_DeltaET @@ -2456,7 +2394,6 @@ def close(self): self.aw.qmc.patheffects = self.org_patheffects self.aw.qmc.graphstyle = self.org_graphstyle self.aw.qmc.graphfont = self.org_graphfont - self.aw.qmc.HUDbuttonflag = self.org_HUDbuttonflag self.aw.qmc.filterDropOuts = self.org_filterDropOuts self.aw.qmc.dropSpikes = self.org_dropSpikes self.aw.qmc.dropDuplicates = self.org_dropDuplicates @@ -2493,7 +2430,7 @@ def updatetargets(self): #save window position (only; not size!) settings = QSettings() settings.setValue("CurvesPosition",self.frameGeometry().topLeft()) - self.aw.HUDDlg_activeTab = self.TabWidget.currentIndex() + self.aw.CurveDlg_activeTab = self.TabWidget.currentIndex() self.aw.qmc.DeltaETfunction = str(self.DeltaETfunctionedit.text()) self.aw.qmc.DeltaBTfunction = str(self.DeltaBTfunctionedit.text()) @@ -2527,24 +2464,6 @@ def updatetargets(self): self.aw.qmc.filterDropOut_tmin = int(self.minLimit.value()) self.aw.qmc.filterDropOut_tmax = int(self.maxLimit.value()) self.aw.qmc.foregroundShowFullflag = self.ShowFull.isChecked() - mode = self.modeComboBox.currentText() - if mode == QApplication.translate("ComboBox","metrics", None): - self.aw.HUDfunction = 0 - elif mode == QApplication.translate("ComboBox","thermal", None): - self.aw.HUDfunction = 1 - self.aw.qmc.ETtarget = int(str(self.ETlineEdit.text())) - self.aw.qmc.BTtarget = int(str(self.BTlineEdit.text())) - self.aw.qmc.ET2target = int(str(self.ET2lineEdit.text())) - self.aw.qmc.BT2target = int(str(self.BT2lineEdit.text())) - if self.aw.qmc.ETtarget > self.aw.qmc.ET2target: # swap such that ETtarget < ET2target - self.aw.qmc.ETtarget = int(str(self.ET2lineEdit.text())) - self.aw.qmc.ET2target = int(str(self.ETlineEdit.text())) - if self.aw.qmc.BTtarget > self.aw.qmc.BT2target: # swap such that BTtarget < BT2target - self.aw.qmc.BTtarget = int(str(self.BT2lineEdit.text())) - self.aw.qmc.BT2target = int(str(self.BTlineEdit.text())) - self.aw.qmc.hudETpid[0] = int(str(self.ETpidP.text())) - self.aw.qmc.hudETpid[1] = int(str(self.ETpidI.text())) - self.aw.qmc.hudETpid[2] = int(str(self.ETpidD.text())) self.aw.qmc.plotcurves[0] = str(self.equedit1.text()) self.aw.qmc.plotcurves[1] = str(self.equedit2.text()) self.aw.qmc.plotcurves[2] = str(self.equedit3.text()) diff --git a/src/artisanlib/event_button_style.py b/src/artisanlib/event_button_style.py new file mode 100644 index 000000000..cd40d5075 --- /dev/null +++ b/src/artisanlib/event_button_style.py @@ -0,0 +1,92 @@ +# -*- coding: utf-8 -*- + +from artisanlib.util import createGradient + +artisan_event_button_style = """ + QPushButton {{ + min-width: {min_width}; + font-size: {default_font_size}; + font-weight: bold; + padding: 3px; + border-style:solid; + border-radius:4; + border-color:grey; + border-width:0; + color: white; + }} + + MajorEventPushButton[Selected=false]:flat {{ + color: darkgrey; + background-color: #E0E0E0; + }} + MajorEventPushButton[Selected=false]:flat:!pressed:hover {{ + color: #F5F5F5; + background-color: #CDCDCD; + }} + MajorEventPushButton[Selected=false]:flat:pressed {{ + color: #EEEEEE; + background-color: #9E9E9E; + }} + MajorEventPushButton[Selected=false]:!flat:pressed {{ + color: #EEEEEE; + background-color:""" + createGradient('#116999') + """ ; + }} + MajorEventPushButton[Selected=false]:!pressed:hover {{ + background-color:""" + createGradient('#1985ba') + """ ; + }} + + + MinorEventPushButton[Selected=false]:flat {{ + color: #BDBDBD; + background-color: #EEEEEE; + }} + MinorEventPushButton[Selected=false]:flat:!pressed:hover {{ + color: #F5F5F5; + background-color: #DDDDDD; + }} + MinorEventPushButton[Selected=false]:flat:pressed {{ + color: #EEEEEE; + background-color: #BEBEBE; + }} + MinorEventPushButton[Selected=false]:!flat:pressed {{ + color: #EEEEEE; + background-color:""" + createGradient('#147bb3') + """ ; + }} + MinorEventPushButton[Selected=false]:!pressed:hover {{ + background-color:""" + createGradient('#43a7cf') + """ ; + }} + + + QPushButton[Selected=true] {{ + font-size: {selected_font_size}; + background-color:""" + createGradient('#d4336a') + """ ; + }} + QPushButton[Selected=true]:flat {{ + color: darkgrey; + background-color: #f9e2ea; + }} + QPushButton[Selected=true]:flat:!pressed:hover {{ + color: #F5F5F5; + background-color: #e687a8; + }} + QPushButton[Selected=true]:flat:pressed {{ + color: #EEEEEE; + background-color: #d4336a; + }} + QPushButton[Selected=true]:!flat:pressed {{ + color: white; + background-color:""" + createGradient('#A61145') + """ ; + }} + QPushButton[Selected=true]:!pressed:hover {{ + color: white; + background-color:""" + createGradient('#cc0f50') + """ ; + }} + + + AuxEventPushButton[Selected=false]:pressed {{ + background-color:""" + createGradient('#757575') + """ ; + }} + AuxEventPushButton[Selected=false]:!pressed:hover {{ + background-color:""" + createGradient('#9e9e9e') + """ ; + }} +""" \ No newline at end of file diff --git a/src/artisanlib/main.py b/src/artisanlib/main.py index 75bfe7cde..01a3c762f 100644 --- a/src/artisanlib/main.py +++ b/src/artisanlib/main.py @@ -139,17 +139,17 @@ def md_version(pkg_name): QInputDialog, QGroupBox, QLineEdit, # @Reimport @UnresolvedImport QSizePolicy, QVBoxLayout, QHBoxLayout, QPushButton, # @Reimport @UnresolvedImport QLCDNumber, QSpinBox, QComboBox, # @Reimport @UnresolvedImport - QSlider, QStackedWidget, # @Reimport @UnresolvedImport + QSlider, # @Reimport @UnresolvedImport QColorDialog, QFrame, QProgressDialog, # @Reimport @UnresolvedImport QStyleFactory, QMenu, QLayout) # @Reimport @UnresolvedImport from PyQt6.QtGui import (QAction, QImageReader, QWindow, # @Reimport @UnresolvedImport # pylint: disable=import-error QKeySequence, # @Reimport s@UnresolvedImport QPixmap,QColor,QDesktopServices,QIcon, # @Reimport @UnresolvedImport - QRegularExpressionValidator,QDoubleValidator, QPainter, QFont,QBrush, QRadialGradient,QCursor) # @Reimport @UnresolvedImport + QRegularExpressionValidator,QDoubleValidator, QPainter ,QCursor) # @Reimport @UnresolvedImport from PyQt6.QtPrintSupport import (QPrinter,QPrintDialog) # @Reimport @UnresolvedImport # pylint: disable=import-error from PyQt6.QtCore import (QLibraryInfo, QTranslator, QLocale, QFileInfo, PYQT_VERSION_STR, pyqtSignal, pyqtSlot, # @Reimport @UnresolvedImport # pylint: disable=import-error qVersion, QTime, QTimer, QFile, QIODevice, QTextStream, QSettings, # @Reimport @UnresolvedImport - QRegularExpression, QDate, QUrl, QDir, Qt, QPoint, QEvent, QDateTime, QObject, QThread, QSemaphore, qInstallMessageHandler) # @Reimport @UnresolvedImport + QRegularExpression, QDate, QUrl, QDir, Qt, QEvent, QDateTime, QObject, QThread, QSemaphore, qInstallMessageHandler) # @Reimport @UnresolvedImport from PyQt6.QtNetwork import QLocalSocket, QLocalServer # @Reimport @UnusedImport @UnresolvedImport # pylint: disable=import-error from PyQt6 import sip # @Reimport @UnusedImport @UnresolvedImport # pylint: disable=import-error @@ -578,7 +578,8 @@ def event(self, event): from artisanlib.wsport import wsport from artisanlib.modbusport import modbusport from artisanlib.phidgets import PhidgetManager -from artisanlib.sliderStyle import artisan_slider_style +from artisanlib.slider_style import artisan_slider_style +from artisanlib.event_button_style import artisan_event_button_style from artisanlib.cropster import extractProfileCropsterXLS from artisanlib.giesen import extractProfileGiesenCSV from artisanlib.petroncini import extractProfilePetronciniCSV @@ -594,7 +595,7 @@ def event(self, event): from artisanlib.large_lcds import (LargeMainLCDs, LargeDeltaLCDs, LargePIDLCDs, LargeExtraLCDs, LargePhasesLCDs) from artisanlib.logs import (serialLogDlg, errorDlg, messageDlg) from artisanlib.events import EventsDlg, customEventDlg -from artisanlib.curves import HUDDlg +from artisanlib.curves import CurvesDlg from artisanlib.devices import DeviceAssignmentDlg from artisanlib.ports import comportDlg from artisanlib.comm import serialport, colorport, scaleport @@ -728,14 +729,13 @@ class tgraphcanvas(FigureCanvas): 'backgroundReproduce', 'backgroundReproduceBeep', 'backgroundPlaybackEvents', 'backgroundPlaybackDROP', 'Betypes', 'backgroundFlavors', 'flavorbackgroundflag', 'E1backgroundtimex', 'E2backgroundtimex', 'E3backgroundtimex', 'E4backgroundtimex', 'E1backgroundvalues', 'E2backgroundvalues', 'E3backgroundvalues', 'E4backgroundvalues', 'l_backgroundeventtype1dots', 'l_backgroundeventtype2dots', 'l_backgroundeventtype3dots', 'l_backgroundeventtype4dots', - 'DeltaETBflag', 'DeltaBTBflag', 'clearBgbeforeprofileload', 'hideBgafterprofileload', 'HUDflag', 'hudresizeflag', 'ETtarget', 'ET2target', 'BTtarget', - 'BT2target', 'hudETpid', 'pidpreviouserror', 'heating_types', 'operator', 'organization', 'roastertype', 'roastersize', 'roasterheating', 'drumspeed', + 'DeltaETBflag', 'DeltaBTBflag', 'clearBgbeforeprofileload', 'hideBgafterprofileload', 'heating_types', 'operator', 'organization', 'roastertype', 'roastersize', 'roasterheating', 'drumspeed', 'organization_setup', 'operator_setup', 'roastertype_setup', 'roastersize_setup', 'roasterheating_setup', 'drumspeed_setup', 'machinesetup_energy_ratings', 'machinesetup', 'roastingnotes', 'cuppingnotes', 'roastdate', 'roastepoch', 'lastroastepoch', 'batchcounter', 'batchsequence', 'batchprefix', 'neverUpdateBatchCounter', 'roastbatchnr', 'roastbatchprefix', 'roastbatchpos', 'roasttzoffset', 'roastUUID', 'plus_default_store', 'plus_store', 'plus_store_label', 'plus_coffee', 'plus_coffee_label', 'plus_blend_spec', 'plus_blend_spec_labels', 'plus_blend_label', 'plus_sync_record_hash', 'beans', 'projectFlag', 'ETcurve', 'BTcurve', 'ETlcd', 'BTlcd', 'swaplcds', 'LCDdecimalplaces', 'foregroundShowFullflag', 'DeltaETflag', 'DeltaBTflag', 'DeltaETlcdflag', 'DeltaBTlcdflag', - 'swapdeltalcds', 'HUDbuttonflag', 'PIDbuttonflag', 'Controlbuttonflag', 'deltaETfilter', 'deltaBTfilter', 'curvefilter', 'deltaETspan', 'deltaBTspan', + 'swapdeltalcds', 'PIDbuttonflag', 'Controlbuttonflag', 'deltaETfilter', 'deltaBTfilter', 'curvefilter', 'deltaETspan', 'deltaBTspan', 'deltaETsamples', 'deltaBTsamples', 'profile_sampling_interval', 'background_profile_sampling_interval', 'optimalSmoothing', 'polyfitRoRcalc', 'patheffects', 'graphstyle', 'graphfont', 'buttonvisibility', 'buttonactions', 'buttonactionstrings', 'extrabuttonactions', 'extrabuttonactionstrings', 'xextrabuttonactions', 'xextrabuttonactionstrings', 'autoChargeFlag', 'autoDropFlag', 'autoChargeIdx', 'autoDropIdx', 'markTPflag', 'autoTPIdx', @@ -1638,16 +1638,6 @@ def __init__(self, parent, dpi, *, locale): self.DeltaBTBflag = True self.clearBgbeforeprofileload = False self.hideBgafterprofileload = False - - # projection variables of change of rate - self.HUDflag = False - self.hudresizeflag = False - self.ETtarget = 300 - self.ET2target = 350 - self.BTtarget = 200 - self.BT2target = 250 - self.hudETpid = [5,240,60] # HUD pid: p = 20, i = 60, d = 13 - self.pidpreviouserror = 0 # temporary storage of pid error self.heating_types: Final = [ "", @@ -1722,7 +1712,6 @@ def __init__(self, parent, dpi, *, locale): self.DeltaETlcdflag = False self.DeltaBTlcdflag = True self.swapdeltalcds = False - self.HUDbuttonflag = False self.PIDbuttonflag = True # TC4 PID firmware available? self.Controlbuttonflag = False # PID Control active (either internal/external or Fuji) # user filter values x are translated as follows to internal filter values: y = x*2 + 1 (to go the other direction: x = y/2) @@ -2622,7 +2611,7 @@ def updateBackground(self): def doUpdate(self): if not self.designerflag: self.resetlinecountcaches() # ensure that the line counts are up to date - self.resetlines() # get rid of HUD, projection, cross lines and AUC line + self.resetlines() # get rid of projection, cross lines and AUC line try: with warnings.catch_warnings(): @@ -4591,13 +4580,6 @@ def updategraphics(self): if self.AUClcdFlag: aw.updateAUCLCD() - #check if HUD is ON (done after self.fig.canvas.draw()) - if self.HUDflag: - try: - aw.showHUD[aw.HUDfunction]() - except Exception as e: # pylint: disable=broad-except - _log.exception(e) - #check triggered alarms if self.temporaryalarmflag > -3: i = self.temporaryalarmflag # reset self.temporaryalarmflag before calling alarm @@ -4647,36 +4629,6 @@ def updateLCDtime(self): finally: QTimer.singleShot(int(round(nextreading)),self.updateLCDtime) - @pyqtSlot(bool) - def toggleHUD(self,_=False): - aw.soundpopSignal.emit() - #OFF - if self.HUDflag: - self.HUDflag = False - aw.HUD.clear() - aw.button_18.setStyleSheet(aw.pushbuttonstyles["HUD_OFF"]) - aw.stack.setCurrentIndex(0) - self.resetlines() - aw.sendmessage(QApplication.translate("Message","HUD OFF", None)) - - #ON - else: - self.redraw(False,False) - #load - img = self.grab() - aw.HUD.setPixmap(img) - self.HUDflag = True - aw.button_18.setStyleSheet(aw.pushbuttonstyles["HUD_ON"]) - aw.stack.setCurrentIndex(1) - aw.sendmessage(QApplication.translate("Message","HUD ON", None)) - - def refreshHUD(self): - aw.stack.setCurrentIndex(0) - self.redraw(False,False) - img = self.grab() - aw.HUD.setPixmap(img) - aw.stack.setCurrentIndex(1) - # redraws at least the canvas if redraw=True and force=True def timealign(self,redraw=True,recompute=False,force=False): try: @@ -5287,26 +5239,6 @@ def updateProjection(self): _, _, exc_tb = sys.exc_info() aw.qmc.adderror((QApplication.translate("Error Message","Exception:",None) + " updateProjection() {0}").format(str(ex)),getattr(exc_tb, 'tb_lineno', '?')) - # this function is called from the HUD DLg and reports the linear time (straight line) it would take to reach a temperature target - # acording to the current rate of change - def getTargetTime(self): - - if self.rateofchange1 > 0: - ETreachTime = (self.ETtarget - self.temp1[-1])/(self.rateofchange1/60.) - ET2reachTime = (self.ET2target - self.temp1[-1])/(self.rateofchange1/60.) - else: - ETreachTime = -1 - ET2reachTime = -1 - - if self.rateofchange2 > 0: - BTreachTime = (self.BTtarget - self.temp2[-1])/(self.rateofchange2/60.) - BT2reachTime = (self.BT2target - self.temp2[-1])/(self.rateofchange2/60.) - else: - BTreachTime = -1 - BT2reachTime = -1 - - return ETreachTime, BTreachTime, ET2reachTime, BT2reachTime - # takes array with readings, the current index, the sign of the shift as character and the shift value # returns val, evalsign @staticmethod @@ -6270,10 +6202,6 @@ def reset(self,redraw=True,soundOn=True,sampling=False,keepProperties=False,fire aw.qmc.roastbatchpos = 1 # initialized to 1, set to increased batchsequence on DROP aw.qmc.roastbatchprefix = aw.qmc.batchprefix - if self.HUDflag: - self.toggleHUD() - self.hudresizeflag = False - aw.sendmessage(QApplication.translate("Message","Scope has been reset",None)) aw.button_3.setDisabled(False) aw.button_4.setDisabled(False) @@ -6384,7 +6312,7 @@ def reset(self,redraw=True,soundOn=True,sampling=False,keepProperties=False,fire self.ystep_up = 0 # reset keyboard mode - aw.keyboardmoveindex = 3 + aw.keyboardmoveindex = 0 # points to the last activated button; we start with the CHARGE button (see keyboardButtonList) aw.keyboardmoveflag = 0 aw.resetKeyboardButtonMarks() @@ -9693,10 +9621,6 @@ def fahrenheitMode(self,setdefaultaxes=True): self.phases[i] = int(round(fromCtoF(self.phases[i]))) if self.step100temp is not None: self.step100temp = int(round(fromCtoF(self.step100temp))) - self.ETtarget = int(round(fromCtoF(self.ETtarget))) - self.ET2target = int(round(fromCtoF(self.ET2target))) - self.BTtarget = int(round(fromCtoF(self.BTtarget))) - self.BT2target = int(round(fromCtoF(self.BT2target))) self.AUCbase = int(round(fromCtoF(self.AUCbase))) self.alarmtemperature = [(fromCtoF(t) if t != 500 else t) for t in self.alarmtemperature] # conv Arduino mode @@ -9730,10 +9654,6 @@ def celsiusMode(self,setdefaultaxes=True): self.phases[i] = int(round(fromFtoC(self.phases[i]))) if self.step100temp is not None: self.step100temp = int(round(fromFtoC(self.step100temp))) - self.ETtarget = int(round(fromFtoC(self.ETtarget))) - self.ET2target = int(round(fromFtoC(self.ET2target))) - self.BTtarget = int(round(fromFtoC(self.BTtarget))) - self.BT2target = int(round(fromFtoC(self.BT2target))) self.AUCbase = int(round(fromFtoC(self.AUCbase))) self.alarmtemperature = [(fromFtoC(t) if t != 500 else t) for t in self.alarmtemperature] # conv Arduino mode @@ -10453,8 +10373,7 @@ def OnMonitor(self): def OffMonitor(self): try: # first activate "Stopping Mode" to ensure that sample() is not reseting the timer now (independent of the flagstart state) - if self.HUDflag: - self.toggleHUD() + # stop Recorder if still running recording = self.flagstart if recording: @@ -10870,9 +10789,6 @@ def OnRecorder(self): aw.button_1.setEnabled(True) # ensure that the OFF button is enabled #disable RESET button: aw.button_7.setEnabled(False) - aw.button_18.setEnabled(True) - aw.button_18.setStyleSheet(aw.pushbuttonstyles["HUD_OFF"]) - aw.button_18.setGraphicsEffect(aw.makeShadow()) self.updateLCDtime() aw.lowerbuttondialog.setVisible(True) aw.applyStandardButtonVisibility() @@ -10911,8 +10827,6 @@ def OffRecorder(self, autosave=True): #enable RESET button: aw.button_7.setStyleSheet(aw.pushbuttonstyles["RESET"]) aw.button_7.setEnabled(True) - aw.button_18.setEnabled(False) - aw.button_18.setGraphicsEffect(None) self.updateLCDtime() #prevents accidentally deleting a modified profile: if len(self.timex) > 2: @@ -11061,7 +10975,8 @@ def markCharge(self,_=False): slidervalue = aw.slider3.value() elif slidernr == 3: slidervalue = aw.slider4.value() - if slidervalue != 0: + # only mark events that have not been marked before not to duplicate the event values + if slidervalue != 0 and slidernr not in self.specialeventstype: value = aw.float2float((slidervalue + 10.0) / 10.0) # note that EventRecordAction avoids to generate events were type and value matches to the previously recorded one aw.qmc.EventRecordAction(extraevent = 1,eventtype=slidernr,eventvalue=value,takeLock=False,doupdategraphics=False) @@ -15518,10 +15433,10 @@ class ApplicationWindow(QMainWindow): 'recentThemeActs', 'applicationDirectory', 'helpdialog', 'redrawTimer', 'lastLoadedProfile', 'lastLoadedBackground', 'analysisresultsanno', 'segmentresultsanno', 'largeLCDs_dialog', 'LargeLCDsFlag', 'largeDeltaLCDs_dialog', 'LargeDeltaLCDsFlag', 'largePIDLCDs_dialog', 'LargePIDLCDsFlag', 'largeExtraLCDs_dialog', 'LargeExtraLCDsFlag', 'largePhasesLCDs_dialog', 'LargePhasesLCDsFlag', 'WebLCDs', 'WebLCDsPort', - 'WebLCDsAlerts', 'EventsDlg_activeTab', 'graphColorDlg_activeTab', 'PID_DlgControl_activeTab', 'HUDDlg_activeTab', 'editGraphDlg_activeTab', + 'WebLCDsAlerts', 'EventsDlg_activeTab', 'graphColorDlg_activeTab', 'PID_DlgControl_activeTab', 'CurveDlg_activeTab', 'editGraphDlg_activeTab', 'backgroundDlg_activeTab', 'DeviceAssignmentDlg_activeTab', 'AlarmDlg_activeTab', 'resetqsettings', 'settingspath', 'wheelpath', 'profilepath', 'userprofilepath', 'printer', 'main_widget', 'defaultdpi', 'dpi', 'qmc', 'HottopControlActive', 'AsyncSamplingAction', 'wheeldialog', - 'simulator', 'simulatorpath', 'comparator', 'HUD', 'showHUD', 'HUDfunction', 'stack', 'eventsbuttonflag', 'minieventsflag', 'seriallogflag', + 'simulator', 'simulatorpath', 'comparator', 'stack', 'eventsbuttonflag', 'minieventsflag', 'seriallogflag', 'seriallog', 'ser', 'modbus', 'extraMODBUStemps', 'extraMODBUStx', 's7', 'ws', 'scale', 'color', 'extraser', 'extracomport', 'extrabaudrate', 'extrabytesize', 'extraparity', 'extrastopbits', 'extratimeout', 'fujipid', 'dtapid', 'pidcontrol', 'soundflag', 'recentRoasts', 'maxRecentRoasts', 'lcdpaletteB', 'lcdpaletteF', 'extraeventsbuttonsflags', 'extraeventslabels', 'extraeventbuttoncolor', 'extraeventsactionstrings', @@ -15536,7 +15451,7 @@ class ApplicationWindow(QMainWindow): 'fileSaveAction', 'fileSaveCopyAsAction', 'exportMenu', 'convMenu', 'saveGraphMenu', 'reportMenu', 'htmlAction', 'productionMenu', 'productionWebAction', 'productionCsvAction', 'productionExcelAction', 'rankingMenu', 'rankingWebAction', 'rankingCsvAction', 'rankingExcelAction', 'savestatisticsAction', 'printAction', 'quitAction', 'cutAction', 'copyAction', 'pasteAction', 'editGraphAction', 'backgroundAction', - 'flavorAction', 'switchAction', 'switchETBTAction', 'machineMenu', 'deviceAction', 'commportAction', 'calibrateDelayAction', 'hudAction', + 'flavorAction', 'switchAction', 'switchETBTAction', 'machineMenu', 'deviceAction', 'commportAction', 'calibrateDelayAction', 'curvesAction', 'eventsAction', 'alarmAction', 'phasesGraphAction', 'StatisticsAction', 'WindowconfigAction', 'colorsAction', 'themeMenu', 'autosaveAction', 'batchAction', 'temperatureConfMenu', 'FahrenheitAction', 'CelsiusAction', 'languageMenu', 'analyzeMenu', 'fitIdealautoAction', 'analyzeMenu', 'fitIdealx2Action', 'fitIdealx3Action', 'fitIdealx0Action', 'fitBkgndAction', 'clearresultsAction', 'roastCompareAction', @@ -15547,7 +15462,7 @@ class ApplicationWindow(QMainWindow): 'button_font_size_tiny', 'button_font_size_micro', 'main_button_min_width', 'standard_button_min_width', 'small_button_min_width', 'tiny_button_min_width', 'pushbuttonstyles_simulator', 'pushbuttonstyles', 'standard_button_tiny_height', 'standard_button_small_height', 'standard_button_height', 'button_1', 'button_2', 'button_3', 'button_4', 'button_5', 'button_6', 'button_7', 'button_8', 'button_9', 'button_10', 'button_11', 'button_12', - 'button_13', 'button_14', 'button_15', 'button_16', 'button_17', 'button_18', 'button_19', 'button_20', 'lcd1', 'lcd2', 'lcd3', 'lcd4', 'lcd5', + 'button_13', 'button_14', 'button_15', 'button_16', 'button_17', 'button_19', 'button_20', 'lcd1', 'lcd2', 'lcd3', 'lcd4', 'lcd5', 'lcd6', 'lcd7', 'label2', 'label3', 'label4', 'label5', 'label6', 'label7', 'nLCDs', 'extraLCD1', 'extraLCD2', 'extraLCDlabel1', 'extraLCDlabel2', 'extraLCDframe1', 'extraLCDframe2', 'extraLCDvisibility1', 'extraLCDvisibility2', 'extraCurveVisibility1', 'extraCurveVisibility2', 'extraDelta1', 'extraDelta2', 'extraFill1', 'extraFill2', 'channel_tare_values', 'messagehist', 'eventlabel', 'eNumberSpinBox', @@ -15647,7 +15562,7 @@ def __init__(self, parent = None, *, locale): self.EventsDlg_activeTab = 0 self.graphColorDlg_activeTab = 0 self.PID_DlgControl_activeTab = 0 - self.HUDDlg_activeTab = 0 # curves dialog + self.CurveDlg_activeTab = 0 # curves dialog self.editGraphDlg_activeTab = 0 # roast properties dialog self.backgroundDlg_activeTab = 0 self.DeviceAssignmentDlg_activeTab = 0 @@ -15722,22 +15637,7 @@ def __init__(self, parent = None, *, locale): self.comparator = None # holds the profile comparator dialog - #### HUD - self.HUD = QLabel() #main canvas for hud widget - self.HUD.setSizePolicy(QSizePolicy.Policy.Ignored, QSizePolicy.Policy.Ignored) - - #This is a list of different HUD functions. - self.showHUD = [self.showHUDmetrics, self.showHUDthermal] - #this holds the index of the HUD functions above - self.HUDfunction = 0 - - self.stack = QStackedWidget() - self.stack.addWidget(self.qmc) - self.stack.addWidget(self.HUD) - self.stack.setCurrentIndex(0) - self.stack.setContentsMargins(0,0,0,0) self.qmc.setContentsMargins(0,0,0,0) - self.HUD.setContentsMargins(0,0,0,0) #events config self.eventsbuttonflag = 0 self.minieventsflag = 0 #minieditor flag @@ -16277,9 +16177,9 @@ def __init__(self, parent = None, *, locale): self.ConfMenu.addSeparator() - self.hudAction = QAction(QApplication.translate("Menu", "Curves...", None), self) - self.hudAction.triggered.connect(self.hudset) - self.ConfMenu.addAction(self.hudAction) + self.curvesAction = QAction(QApplication.translate("Menu", "Curves...", None), self) + self.curvesAction.triggered.connect(self.setCurves) + self.ConfMenu.addAction(self.curvesAction) self.ConfMenu.addSeparator() @@ -17166,51 +17066,6 @@ def __init__(self, parent = None, *, locale): background-color:""" + createGradient('#85cae1') + """ ; } """, - - "HUD_OFF": """ - QPushButton { - min-width: """ + self.main_button_min_width + """; - """ + border_modern + """ - font-size: """ + self.button_font_size + """; - font-weight: bold; - color: white; - background-color: #2298c7; - } - QPushButton:!enabled { - color: darkgrey; - background-color: #E0E0E0; - } - QPushButton:pressed { - color: #EEEEEE; - background-color: #1985ba; - } - QPushButton:hover:!pressed { - color: white; - background-color: #43a7cf; - } - """, - "HUD_ON": """ - QPushButton { - min-width: """ + self.main_button_min_width + """; - """ + border_modern + """ - font-size: """ + self.button_font_size + """; - font-weight: bold; - color: white; - background-color: #54b5ff; - } - QPushButton:!enabled { - color: darkgrey; - background-color: #E0E0E0; - } - QPushButton:pressed { - color: #EEEEEE; - background-color: #1985ba; - } - QPushButton:hover:!pressed { - color: white; - background-color: #77cafd; - } - """, "SELECTED": """ QPushButton { min-width: """ + self.standard_button_min_width + """; @@ -17270,36 +17125,6 @@ def __init__(self, parent = None, *, locale): color: white; background-color:""" + createGradient('#c70d49') + """ ; } - """, - "SELECTED_MAIN_LARGE": """ - QPushButton { - min-width: """ + self.main_button_min_width + """; - """ + border_modern + """ - font-size: """ + self.button_font_size + """; - font-weight: bold; - color: white; - background-color:""" + createGradient('#c00b40') + """ ; - } - QPushButton:flat{ - color: darkgrey; - background-color: #f0b7cb; - } - QPushButton:flat:hover:!pressed{ - color: #F5F5F5; - background-color: #db5785; - } - QPushButton:flat:hover:pressed{ - color: #EEEEEE; - background-color: #cc0f50; - } - QPushButton:pressed { - color: white; - background-color:""" + createGradient('#147bb3') + """ ; - } - QPushButton:hover:!pressed { - color: white; - background-color:""" + createGradient('#c70d49') + """ ; - } """ } # we use this high to dynamically adjust the button size to different font sizes (important for high-dpi displays on Windows) @@ -17482,21 +17307,7 @@ def __init__(self, parent = None, *, locale): self.button_17.setToolTip(QApplication.translate("Tooltip", "Decreases the current SV value by 5", None)) self.button_17.setCursor(QCursor(Qt.CursorShape.PointingHandCursor)) - #create HUD button - self.button_18 = QPushButton(QApplication.translate("Button", "HUD", None)) - self.button_18.setFocusPolicy(Qt.FocusPolicy.NoFocus) - self.button_18.setStyleSheet(self.pushbuttonstyles["HUD_OFF"]) - self.button_18.setGraphicsEffect(self.makeShadow()) - self.button_18.setMinimumHeight(self.standard_button_height) - self.button_18.setContentsMargins(0,0,0,0) - self.button_18.clicked.connect(self.qmc.toggleHUD) - self.button_18.setToolTip(QApplication.translate("Tooltip", "Turns ON/OFF the HUD", None)) - self.button_18.setEnabled(False) - self.button_18.setCursor(QCursor(Qt.CursorShape.PointingHandCursor)) - if not self.qmc.HUDbuttonflag: - self.button_18.setVisible(False) - if app.artisanviewerMode: - self.button_18.setVisible(False) + #HUD button (button_18 was removed) #create DRY button self.button_19 = QPushButton(QApplication.translate("Button", "DRY\nEND", None)) @@ -17813,29 +17624,24 @@ def __init__(self, parent = None, *, locale): self.setCentralWidget(self.main_widget) #list of functions to choose from (using left-right keyboard arrow) - self.keyboardmove = [self.qmc.reset,self.qmc.toggleHUD,self.qmc.ToggleMonitor,self.qmc.markCharge,self.qmc.markDryEnd,self.qmc.mark1Cstart,self.qmc.mark1Cend, + # sidecond: len(self.keyboardmove) = len(self.keyboardButtonList) # for each self.keyboardmoveindex we have a keyboardmove function + self.keyboardmove = [self.qmc.markCharge,self.qmc.markDryEnd,self.qmc.mark1Cstart,self.qmc.mark1Cend, self.qmc.mark2Cstart,self.qmc.mark2Cend,self.qmc.markDrop,self.qmc.markCoolEnd,self.qmc.EventRecord] # list of buttons that can be controlled via the keyboard - # RESET -> HUD -> ON/OFF -> .. -> EVENT (RESET at index 0 is never used) + # RESET -> ON/OFF -> .. -> EVENT (RESET at index 0 is never used) self.keyboardButtonList = [ - self.button_7, # RESET - self.button_18, # HUD_ON - self.button_1, # ON - self.button_8, # CHARGE - self.button_19, # DRY END - self.button_3, # FC START - self.button_4, # FC END - self.button_5, # SC START - self.button_6, # SC END - self.button_9, # DROP - self.button_20, # COOL END - self.button_11 # EVENT + self.button_8, # 0 CHARGE + self.button_19, # 1 DRY END + self.button_3, # 2 FC START + self.button_4, # 3 FC END + self.button_5, # 4 SC START + self.button_6, # 5 SC END + self.button_9, # 6 DROP + self.button_20, # 7 COOL END + self.button_11 # 8 EVENT ] - # 0:RESET,1:HUD,2:ON/OFF,3:CHARGE,4:DRY,5:FCs,6:FCe,7:SCs,8:SCe,9:DROP,10:COOL,11:EVENT + # 0:CHARGE,1:DRY,2:FCs,3:FCe,4:SCs,5:SCe,6:DROP,7:COOL,8:EVENT self.keyboardButtonStyles = [ - "RESET", - "HUD_ON", - "ON", "CHARGE", "DRY END", "FC START", @@ -17847,7 +17653,7 @@ def __init__(self, parent = None, *, locale): "EVENT"] #current function above - self.keyboardmoveindex = 3 + self.keyboardmoveindex = 0 # points to the last activated button; we start with the CHARGE button (see keyboardButtonList) #state flag for above. It is initialized by pressing SPACE or left-right arrows self.keyboardmoveflag = 0 #time stamp of last keyboard event SPACE to prevent multiple recognitions @@ -17863,7 +17669,7 @@ def __init__(self, parent = None, *, locale): #################### APPLICATION WINDOW (AW) LAYOUT ############################################## self.level1frame = QFrame() - self.level1layout = QHBoxLayout() # matplotlib toolbox + HUD button + reset button + LCD Timer + self.level1layout = QHBoxLayout() # matplotlib toolbox + RESET button + LCD Timer self.level1frame.setLayout(self.level1layout) level3layout = QHBoxLayout() # PID buttons, graph, temperature LCDs @@ -18050,15 +17856,13 @@ def __init__(self, parent = None, *, locale): self.level1layout.addSpacing(15) self.level1layout.addWidget(self.button_10) self.level1layout.addSpacing(10) - self.level1layout.addWidget(self.button_18) - self.level1layout.addSpacing(10) self.level1layout.addWidget(self.lcd1) self.level1layout.setSpacing(0) self.level1layout.setContentsMargins(0,7,7,12) # left, top, right, bottom #level 3 level3layout.addLayout(pidbuttonLayout,0) - level3layout.addWidget(self.stack,1) + level3layout.addWidget(self.qmc) level3layout.setSpacing(0) level3layout.setContentsMargins(0,0,0,0) @@ -21583,9 +21387,6 @@ def addserial(self,serialstring): def resizeEvent(self, event): if not aw.qmc.flagon and aw.qmc.statssummary and len(aw.qmc.timex) > 3: self.redrawTimer.start(500) # (re-) start the redraw time to be fired in half a second - #if HUD is ON when resizing application. No drawing should be done inside this handler - if self.qmc.HUDflag: - self.qmc.hudresizeflag = True super().resizeEvent(event) def setdpi(self,dpi,moveWindow=True): @@ -21599,8 +21400,8 @@ def setdpi(self,dpi,moveWindow=True): warnings.simplefilter("ignore") aw.qmc.fig.canvas.draw() aw.qmc.fig.canvas.update() - aw.stack.adjustSize() - FigureCanvas.updateGeometry(aw.stack) #@UndefinedVariable + aw.qmc.adjustSize() + FigureCanvas.updateGeometry(aw.qmc) #@UndefinedVariable QApplication.processEvents() def enableSaveActions(self): @@ -21678,7 +21479,7 @@ def eventaction_internal(self,action,cmd): BTB_subst = 0 ETB_subst = 0 try: - if self.qmc.flagstart: + if self.qmc.flagstart and len(self.qmc.timex)>0: timex = self.qmc.timex[-1] if self.qmc.timeindex[0] != -1: timex -= self.qmc.timex[self.qmc.timeindex[0]] @@ -23119,7 +22920,10 @@ def calc_env(): try: with subprocess.Popen(command, stdout = subprocess.PIPE) as proc: for line in proc.stdout: - (k, _, value) = line.partition("=") + if isinstance(line, bytes): + (k, _, value) = line.partition(b"=") + else: + (k, _, value) = line.partition("=") # don't copy PYTHONHOME nor PYTHONPATH if it points to the Artisan.app if not ((k in ['PYTHONHOME','PYTHONPATH']) and (("Artisan.app" in value) or "artisan" in value)): my_env[k] = value @@ -23165,16 +22969,23 @@ def call_prog_with_args(self,cmd_str): #subprocess.Popen([prg_file] + [x.strip() for x in cmd_str_parts[1:]], shell=False,env=my_env) subprocess.Popen([prg_file] + [x.strip() for x in cmd_str_parts[1:]], # pylint: disable=consider-using-with startupinfo=startupinfo, - stdin=None, stdout=None, stderr=None, # creationflags=DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP, # with this the process ends before sleep # close_fds=True, # this seems not to change a thing - env=my_env) #.wait() # with this wait(), the script blocks the Artisan event loop + env=my_env, + stdin=None, + # supress output: + stdout=subprocess.DEVNULL, + stderr=subprocess.STDOUT + ) #.wait() # with this wait(), the script blocks the Artisan event loop else: subprocess.Popen(os.path.expanduser(cmd_str), # pylint: disable=consider-using-with shell=True, - stdin=None, stdout=None, stderr=None, close_fds=True, - env=my_env) + env=my_env, + stdin=None, + # supress output: + stdout=subprocess.DEVNULL, + stderr=subprocess.STDOUT) QDir.setCurrent(current.absolutePath()) # alternative approach, that seems to fail on some Mac OS X versions: #QProcess.startDetached(prg_file) @@ -23743,7 +23554,7 @@ def enableEditMenus(self): self.languageMenu.setEnabled(True) self.deviceAction.setEnabled(True) self.commportAction.setEnabled(True) - self.hudAction.setEnabled(True) + self.curvesAction.setEnabled(True) self.analyzeMenu.setEnabled(True) self.roastCompareAction.setEnabled(True) self.designerAction.setEnabled(True) @@ -23811,9 +23622,9 @@ def disableEditMenus(self,designer=False,wheel=False,compare=False,sampling=Fals self.deviceAction.setEnabled(False) self.commportAction.setEnabled(False) if designer or wheel: - self.hudAction.setEnabled(False) # Curves menu + self.curvesAction.setEnabled(False) # Curves menu else: - self.hudAction.setEnabled(True) + self.curvesAction.setEnabled(True) if wheel or designer: self.eventsAction.setEnabled(False) self.phasesGraphAction.setEnabled(False) @@ -24167,46 +23978,32 @@ def releaseminieditor(self): self.eNumberSpinBox.clearFocus() # this function respects the button visibility via aw.qmc.buttonvisibility and if button.isDisabled() - # ON/OFF (2,self.button_1) -> CHARGE (3,self.button_8) -> DRYEND (4,self.button_19) -> FCs (5,self.button_3) - # -> FCe (6,self.button_4) -> SCs (7,self.button_5) -> SCe (8,self.button_6) -> DROP (9,self.button_9) - # -> COOLend (10,self.button_20) -> EVENT (11,self.button_11) -> HUD (1,self.button_18) -> ON/OFF - # currentButtonIndex is from [1-11] + # ON/OFF (1,self.button_1) -> CHARGE (2,self.button_8) -> DRYEND (3,self.button_19) -> FCs (4,self.button_3) + # -> FCe (5,self.button_4) -> SCs (6,self.button_5) -> SCe (7,self.button_6) -> DROP (8,self.button_9) + # -> COOLend (9,self.button_20) -> EVENT (10,self.button_11)-> ON/OFF + # currentButtonIndex is from [1-10] # buttons that trigger events and can be triggered only once def nextActiveButton(self,currentButtonIndex): - if currentButtonIndex == 11 and aw.qmc.HUDbuttonflag: # current: EVENT - # the current button index is the event button, we move to the HUD button - return 1 # next: HUD - if currentButtonIndex == 1 or (currentButtonIndex == 11 and not aw.qmc.HUDbuttonflag): # current: HUD - return 2 # next: ON/OFF - if currentButtonIndex == 10: # current: COOL - # check if the EVENT button is active, else move to the HUD + if currentButtonIndex == 8: # current: EVENT + return 0 # next: CHARGE + if currentButtonIndex == 7: # current: COOL (last before EVENT) + # check if the EVENT button is active, else move to the ON/OFF if aw.eventsbuttonflag: - return 11 # next: EVENT - if aw.qmc.HUDbuttonflag: - return 1 # next: HUD - return 2 # next: ON/OFF + return 8 # next: EVENT + return 0 # next: CHARGE # we check if the next button is visible, else we recurse (the index of buttonvisibility starts from 0:CHARGE and leads to 7:COOL) - # there is an offset of 3 - if aw.qmc.buttonvisibility[currentButtonIndex - 2] and self.keyboardButtonList[currentButtonIndex + 1].isEnabled(): + if aw.qmc.buttonvisibility[currentButtonIndex + 1] and self.keyboardButtonList[currentButtonIndex + 1].isEnabled(): return currentButtonIndex + 1 return self.nextActiveButton(currentButtonIndex + 1) def previousActiveButton(self,currentButtonIndex): - if currentButtonIndex == 2 and aw.qmc.HUDbuttonflag: # current: ON/OFF - # the current button index is the ON/OFF button, we move to the HUD button (if visible) - return 1 - if currentButtonIndex == 2 and not aw.qmc.HUDbuttonflag: - return self.previousActiveButton(1) - if currentButtonIndex == 1 or (currentButtonIndex == 2 and not aw.qmc.HUDbuttonflag): # current: HUD - # check if the EVENT button is active, else move to the HUD + if currentButtonIndex == 0: # current: CHARGE + # check if the EVENT button is active, else move beyond if aw.eventsbuttonflag: - return 11 # move to EVENT - return self.previousActiveButton(11) # move to prev(EVENT) - if currentButtonIndex == 3: # current: CHARGE - return 2 # next: ON/OFF + return 8 # next: EVENT + currentButtonIndex = 8 # set to EVENT and move to previous non-flat button # we check if the previous button is visible, else we recurse (the index of buttonvisibility starts from 0:CHARGE and leads to 7:COOL) - # there is an offset of 3 - if aw.qmc.buttonvisibility[currentButtonIndex - 4] and self.keyboardButtonList[currentButtonIndex - 1].isEnabled(): + if aw.qmc.buttonvisibility[currentButtonIndex - 1] and self.keyboardButtonList[currentButtonIndex - 1].isEnabled(): return currentButtonIndex - 1 return self.previousActiveButton(currentButtonIndex - 1) @@ -24230,21 +24027,15 @@ def resetKeyboardButtonMarks(self): self.button_6.setStyleSheet(self.pushbuttonstyles["SC END"]) self.button_9.setStyleSheet(self.pushbuttonstyles["DROP"]) self.button_11.setStyleSheet(self.pushbuttonstyles["EVENT"]) - if self.qmc.flagstart: - if self.qmc.HUDflag: - self.button_18.setStyleSheet(self.pushbuttonstyles["HUD_ON"]) - else: - self.button_18.setStyleSheet(self.pushbuttonstyles["HUD_OFF"]) - else: - pass def ignoreFlatButtons(self,moveindex): - if self.keyboardButtonList[moveindex].isFlat() or not aw.qmc.buttonvisibility[moveindex - 3]: + # there is an offset between keyboardButtonList and self.buttonvisibilty of 1 + if self.keyboardButtonList[moveindex].isFlat() or (moveindex < 7 and not aw.qmc.buttonvisibility[moveindex]): # we search forward for the next non-flat button - if moveindex < 10: + if moveindex < 7: # exclude the EVENT button that is not covered by aw.qmc.buttonvisibility m = moveindex + 1 # we jump over invisible buttons - while m < 10 and (not aw.qmc.buttonvisibility[m - 3] or self.keyboardButtonList[m].isFlat()): + while m < 8 and (not aw.qmc.buttonvisibility[m] or self.keyboardButtonList[m].isFlat()): m = m + 1 return m return moveindex @@ -24287,11 +24078,12 @@ def moveKbutton(self, kcommand): if self.keyboardmoveflag: if kcommand == "space": now = libtime.perf_counter() - if self.lastkeyboardcmd == 0 or (now > self.lastkeyboardcmd + 2): # accept SPACE keyboard cmds only every 2sec. + if self.lastkeyboardcmd == 0 or (now > self.lastkeyboardcmd + 1): # accept SPACE keyboard cmds only every 1sec. + button_is_flat = self.keyboardButtonList[self.keyboardmoveindex].isFlat() self.keyboardmove[self.keyboardmoveindex]() #apply button command #behaviour rules after pressing a button - #if less than EVENT jump forward to the right once automatically - if self.keyboardmoveindex > 1 and self.keyboardmoveindex < 11: + #if less than EVENT jump forward to the right one automatically + if not button_is_flat and self.keyboardmoveindex < 8: self.moveKbutton("right") self.lastkeyboardcmd = now self.releaseminieditor() @@ -24305,18 +24097,10 @@ def moveKbutton(self, kcommand): # activate the button at index nextcmd if self.keyboardButtonStyles[nextcmd] in ["CHARGE", "DROP"]: self.keyboardButtonList[nextcmd].setStyleSheet(self.pushbuttonstyles["SELECTED_MAIN"]) - if self.keyboardButtonStyles[nextcmd] in ["ON", "HUD_ON"]: - self.keyboardButtonList[nextcmd].setStyleSheet(self.pushbuttonstyles["SELECTED_MAIN_LARGE"]) else: self.keyboardButtonList[nextcmd].setStyleSheet(self.pushbuttonstyles["SELECTED"]) - # deactivate the button at index self.keyboardmoveindex - if self.keyboardmoveindex == 1: # we make an exception to respect the state of the HUD button - if self.qmc.HUDflag: - self.button_18.setStyleSheet(self.pushbuttonstyles["HUD_ON"]) - else: - self.button_18.setStyleSheet(self.pushbuttonstyles["HUD_OFF"]) - else: - self.keyboardButtonList[self.keyboardmoveindex].setStyleSheet(self.pushbuttonstyles[self.keyboardButtonStyles[self.keyboardmoveindex]]) + # turn the style of the button at index self.keyboardmoveindex to standard + self.keyboardButtonList[self.keyboardmoveindex].setStyleSheet(self.pushbuttonstyles[self.keyboardButtonStyles[self.keyboardmoveindex]]) # update self.keyboardmoveindex self.keyboardmoveindex = nextcmd # we enable keyboard event processing again @@ -29201,27 +28985,6 @@ def settingsLoad(self, filename=None, theme=False, machine=False): self.qmc.xextrabuttonactionstrings = list(map(str,list(toStringList(settings.value("xextrabuttonactionstrings",self.qmc.xextrabuttonactionstrings))))) settings.endGroup() self.qmc.transMappingMode = toInt(settings.value("transMappingMode",self.qmc.transMappingMode)) - settings.beginGroup("HUD") - self.qmc.projectFlag = bool(toBool(settings.value("Projection",self.qmc.projectFlag))) - self.qmc.projectionmode = toInt(settings.value("ProjectionMode",self.qmc.projectionmode)) - self.qmc.ETtarget = toInt(settings.value("ETtarget",self.qmc.ETtarget)) - self.qmc.BTtarget = toInt(settings.value("BTtarget",self.qmc.BTtarget)) - if settings.contains("ET2target"): - self.qmc.ET2target = toInt(settings.value("ET2target",self.qmc.ET2target)) - if settings.contains("BT2target"): - self.qmc.BT2target = toInt(settings.value("BT2target",self.qmc.BT2target)) - self.HUDfunction = toInt(settings.value("Mode",self.HUDfunction)) - if settings.contains("hudETpid"): - self.qmc.hudETpid = [toInt(x) for x in toList(settings.value("hudETpid"))] - if settings.contains("buttonFlag"): - self.qmc.HUDbuttonflag = bool(toBool(settings.value("buttonFlag",self.qmc.HUDbuttonflag))) - if self.qmc.HUDbuttonflag: - aw.button_18.setVisible(True) - else: - aw.button_18.setVisible(False) - if app.artisanviewerMode: - aw.button_18.setVisible(False) - settings.endGroup() settings.beginGroup("Style") if settings.contains("patheffects"): self.qmc.patheffects = toInt(settings.value("patheffects",self.qmc.patheffects)) @@ -29865,7 +29628,7 @@ def settingsLoad(self, filename=None, theme=False, machine=False): if settings.contains("Geometry"): self.restoreGeometry(settings.value("Geometry")) if not filename: # only if an external settings file is loaded - FigureCanvas.updateGeometry(aw.stack) #@UndefinedVariable + FigureCanvas.updateGeometry(aw.qmc) #@UndefinedVariable #update visibility of main event button, extra event buttons and self.applyStandardButtonVisibility() @@ -30684,17 +30447,6 @@ def closeEventSettings(self, filename=None): settings.setValue("xextrabuttonactionstrings",self.qmc.xextrabuttonactionstrings) settings.endGroup() settings.setValue("transMappingMode",self.qmc.transMappingMode) - settings.beginGroup("HUD") - settings.setValue("Projection",self.qmc.projectFlag) - settings.setValue("ProjectionMode",self.qmc.projectionmode) - settings.setValue("ETtarget",self.qmc.ETtarget) - settings.setValue("BTtarget",self.qmc.BTtarget) - settings.setValue("ET2target",self.qmc.ET2target) - settings.setValue("BT2target",self.qmc.BT2target) - settings.setValue("Mode",self.HUDfunction) - settings.setValue("hudETpid",self.qmc.hudETpid) - settings.setValue("buttonFlag",self.qmc.HUDbuttonflag) - settings.endGroup() settings.beginGroup("Style") settings.setValue("patheffects",self.qmc.patheffects) settings.setValue("graphstyle",self.qmc.graphstyle) @@ -35663,146 +35415,13 @@ def saveVectorGraph(self,extension="*.pdf",fname=""): except IOError as ex: aw.qmc.adderror((QApplication.translate("Error Message","IO Error:", None) + " saveVectorGraph() {0}").format(str(ex))) - #displays Dialog for the setting of the HUD + #displays Dialog for the setting of the curves parameters (like RoR, Filters,..) @pyqtSlot() @pyqtSlot(bool) - def hudset(self,_=False): - hudDl = HUDDlg(self,self,self.HUDDlg_activeTab) - hudDl.show() - - def showHUDmetrics(self): - if self.qmc.hudresizeflag: - self.qmc.refreshHUD() - self.qmc.hudresizeflag = False - if len(self.qmc.temp2) > 1: #Need this because viewProjections use rate of change (two values needed) - ETreachTime,BTreachTime,ET2reachTime,BT2reachTime = self.qmc.getTargetTime() - if 0 < ETreachTime < 2000: - text1 = QApplication.translate("Label","{0} to reach ET {1}{2}", None).format(stringfromseconds(ETreachTime),str(self.qmc.ETtarget),self.qmc.mode) - if self.qmc.timeindex[0] > -1: - text1 = text1 + QApplication.translate("Label"," at {0}", None).format(stringfromseconds(self.qmc.timex[-1] - self.qmc.timex[self.qmc.timeindex[0]]+ETreachTime)) - else: - text1 = QApplication.translate("Label","{0} to reach ET {1}{2}", None).format("xx:xx",str(self.qmc.ETtarget),self.qmc.mode) - if 0 < ET2reachTime < 2000: - text2 = QApplication.translate("Label","{0} to reach ET {1}{2}", None).format(stringfromseconds(ET2reachTime),str(self.qmc.ET2target),self.qmc.mode) - if self.qmc.timeindex[0] > -1: - text2 = text2 + QApplication.translate("Label"," at {0}", None).format(stringfromseconds(self.qmc.timex[-1] - self.qmc.timex[self.qmc.timeindex[0]]+ET2reachTime)) - else: - text2 = QApplication.translate("Label","{0} to reach ET {1}{2}", None).format("xx:xx",str(self.qmc.ET2target),self.qmc.mode) - - if 0 < BTreachTime < 2000: - text3 = QApplication.translate("Label","{0} to reach BT {1}{2}", None).format(stringfromseconds(BTreachTime),str(self.qmc.BTtarget),self.qmc.mode) - if self.qmc.timeindex[0] > -1: - text3 = text3 + QApplication.translate("Label"," at {0}", None).format(stringfromseconds(self.qmc.timex[-1] - self.qmc.timex[self.qmc.timeindex[0]]+BTreachTime)) - else: - text3 = QApplication.translate("Label","{0} to reach BT {1}{2}", None).format("xx:xx",str(self.qmc.BTtarget),self.qmc.mode) - if 0 < BT2reachTime < 2000: - text4 = QApplication.translate("Label","{0} to reach BT {1}{2}", None).format(stringfromseconds(BT2reachTime),str(self.qmc.BT2target),self.qmc.mode) - if self.qmc.timeindex[0] > -1: - text4 = text4 + QApplication.translate("Label"," at {0}", None).format(stringfromseconds(self.qmc.timex[-1] - self.qmc.timex[self.qmc.timeindex[0]]+BT2reachTime)) - else: - text4 = QApplication.translate("Label","{0} to reach BT {1}{2}", None).format("xx:xx",str(self.qmc.BT2target),self.qmc.mode) - #### Phase Texts ##### - phasetext1 = "" # lower textline - phasetext2 = "" # higher textline - if self.qmc.timeindex[2]: # after FCs - FCs_time = self.qmc.timex[self.qmc.timeindex[2]] - if self.qmc.timeindex[6]: # after DROP - afterFCs = self.qmc.timex[self.qmc.timeindex[6]] - FCs_time - else: - afterFCs = self.qmc.timex[-1] - FCs_time - phasetext1 = QApplication.translate("Label","{0} after FCs", None).format(stringfromseconds(afterFCs)) - if self.qmc.timeindex[3]: # after FCe - FCe_time = self.qmc.timex[self.qmc.timeindex[3]] - if self.qmc.timeindex[6]: # after DROP - afterFCe = self.qmc.timex[self.qmc.timeindex[6]] - FCe_time - else: - afterFCe = self.qmc.timex[-1] - FCe_time - phasetext2 = QApplication.translate("Label","{0} after FCe", None).format(stringfromseconds(afterFCe)) - if self.qmc.timeindex[2]: - phasetext2 = phasetext2 + " (" + stringfromseconds(FCe_time - self.qmc.timex[self.qmc.timeindex[2]]) + " FC)" - #### ET pid ###### - error = self.qmc.ETtarget - self.qmc.temp1[-1] - differror = error - self.qmc.pidpreviouserror - difftime = self.qmc.timex[-1] - self.qmc.timex[-2] - if not difftime: difftime = 0.01 - proportionalterm = self.qmc.hudETpid[0]*error - integralterm = self.qmc.hudETpid[1]*differror*difftime - derivativeterm = self.qmc.hudETpid[2]*differror/difftime - self.qmc.pidpreviouserror = error - MV = proportionalterm + integralterm + derivativeterm # Manipulated Variable - if MV > 100.:MV = 100. - elif MV < 0.:MV = 0. - MVV = int(round(MV)) - pidstring = "ET pid = %i "%MVV - ##### end of ET pid - img = self.qmc.grab() - Wwidth = self.qmc.size().width() - Wheight = self.qmc.size().height() - #Draw begins - p = QPainter(img) - p.setOpacity(0.8) - p.setPen(QColor("slategrey")) - p.drawText(QPoint(Wwidth/7,Wheight - Wheight/4.5),text1) - p.drawText(QPoint(Wwidth/7,Wheight - Wheight/5.3),text2) - p.drawText(QPoint(Wwidth/7,Wheight - Wheight/6.6),text3) - p.drawText(QPoint(Wwidth/7,Wheight - Wheight/8.5),text4) - #draw pid - p.drawText(QPoint(Wwidth/7,Wheight - Wheight/3),pidstring) - p.drawRect(Wwidth/7+140, Wheight - Wheight/3-12, 100, 12) - p.fillRect(Wwidth/7+140, Wheight - Wheight/3-12, MVV, 12, QColor("pink")) - delta = QApplication.translate("Label","ET - BT = {0}", None).format("%.1f"%(self.qmc.temp1[-1] - self.qmc.temp2[-1])) - p.drawText(QPoint(Wwidth/7,Wheight - Wheight/3.5),delta) - #draw phase texts - p.drawText(QPoint(Wwidth/2 + 100,Wheight - Wheight/6),phasetext1) - p.drawText(QPoint(Wwidth/2 + 100,Wheight - Wheight/8),phasetext2) - p.end() - self.HUD.setPixmap(img) - - def showHUDthermal(self): - if self.qmc.hudresizeflag: - self.qmc.refreshHUD() - self.qmc.hudresizeflag = False - if len(self.qmc.temp2) > 0: - img = self.qmc.grab() - p = QPainter(img) - Wwidth= self.qmc.size().width() - Wheight = self.qmc.size().height() - p.setOpacity(1) - p.setPen(QColor(96,255,237)) #color the rectangle the same as HUD button - p.drawRect(10,10, Wwidth - 20, Wheight - 20) - if self.qmc.mode == "F" and self.qmc.temp1: - ETradius = int(self.qmc.temp1[-1]/3) - BTradius = int(self.qmc.temp2[-1]/3) - elif self.qmc.mode == "C" and self.qmc.temp1: - ETradius = int(fromCtoF(self.qmc.temp1[-1]/3)) - BTradius = int(fromCtoF(self.qmc.temp2[-1]/3)) - else: - ETradius = 50 - BTradius = 50 - Tradius = 300 - p.setOpacity(0.5) - g = QRadialGradient(Wwidth/2, Wheight/2, ETradius) - beanbright = max(100 - ETradius,0) - g.setColorAt(0.0, QColor(240,255,beanbright)) #bean center - g.setColorAt(.5, Qt.GlobalColor.yellow) - g.setColorAt(.8, Qt.GlobalColor.red) - g.setColorAt(1.,QColor("lightgrey")) - p.setBrush(QBrush(g)) - #draw thermal circle - p.setPen(0) - p.drawEllipse(Wwidth/2 -Tradius/2 , Wheight/2 - Tradius/2 , Tradius,Tradius) - #draw ET circle - p.setBrush(0) - p.setPen(QColor("black")) - p.drawEllipse(Wwidth/2 -ETradius/2 , Wheight/2 - ETradius/2 , ETradius,ETradius) - #draw BT circle - p.drawEllipse(Wwidth/2 -BTradius/2 , Wheight/2 - BTradius/2 , BTradius,BTradius) - delta = QApplication.translate("Label","ET - BT = {0}{1}", None).format("%.1f"%(self.qmc.temp1[-1] - self.qmc.temp2[-1]),self.qmc.mode) - p.setFont(QFont('Utopia', 14, -1)) - p.drawText(QPoint(Wwidth/2,Wheight/2),delta) - p.end() - self.HUD.setPixmap(img) - + def setCurves(self,_=False): + curvesDlg = CurvesDlg(self,self,self.CurveDlg_activeTab) + curvesDlg.show() + #used by WheelGraphDlg() #wrap values in unicode(.) if and only if those are of type string def getWheelGraph(self): diff --git a/src/artisanlib/roast_properties.py b/src/artisanlib/roast_properties.py index 3d2d07437..8e181024a 100644 --- a/src/artisanlib/roast_properties.py +++ b/src/artisanlib/roast_properties.py @@ -313,7 +313,7 @@ def __init__(self, parent = None, aw = None, weightIn=None, weightOut=None, def ble_scan_failed(self): self.scale_weight = None self.scale_battery = None - self.scaleWeight.setText("") + self.scaleWeight.setText("----") pyqtSlot(float) def ble_weight_changed(self,w): @@ -329,7 +329,7 @@ def update_scale_weight(self,weight=None): if self.scale_weight is not None and self.tare is not None: self.scaleWeight.setText("{0:.1f}g".format(self.scale_weight - self.tare)) else: - self.scaleWeight.setText("") + self.scaleWeight.setText("----") except Exception as e: # pylint: disable=broad-except # the dialog might have been closed already and thus the qlabel might not exist anymore _log.exception(e) @@ -1479,6 +1479,7 @@ def __init__(self, parent = None, aw = None, activeTab = 0): self.ble.deviceDisconnected.connect(self.ble_scan_failed) self.ble.weightChanged.connect(self.ble_weight_changed) self.ble.batteryChanged.connect(self.ble_battery_changed) + self.scaleWeight.setText("----") self.ble.scanDevices() except Exception as e: # pylint: disable=broad-except _log.exception(e) @@ -1801,7 +1802,7 @@ def ble_scan_failed(self): # _log.debug("ble_scan_failed: %s", st) self.scale_weight = None self.scale_battery = None - self.scaleWeight.setText("") + self.scaleWeight.setText("----") if self.ble is not None: QTimer.singleShot(200, self.ble.scanDevices) @@ -1842,7 +1843,7 @@ def update_scale_weight(self): self.scaleWeight.setText(v_formatted) self.updateScaleWeightAccumulated(self.scale_weight - tare) else: - self.scaleWeight.setText("") + self.scaleWeight.setText("----") self.updateScaleWeightAccumulated() def updateTemplateLine(self): @@ -2655,8 +2656,8 @@ def changeWeightUnit(self,i): # weight unit changed, we update the selected blend in plus mode if self.plus_blends_combo.currentIndex() > 0: self.blendSelectionChanged(self.plus_blends_combo.currentIndex()) - except Exception as e: # pylint: disable=broad-except - _log.exception(e) + except Exception: # pylint: disable=broad-except + pass # self.plus_blends_combo might not be allocated @pyqtSlot(int) def changeVolumeUnit(self,i): diff --git a/src/artisanlib/sliderStyle.py b/src/artisanlib/slider_style.py similarity index 99% rename from src/artisanlib/sliderStyle.py rename to src/artisanlib/slider_style.py index 17ad781b4..fbab3025d 100644 --- a/src/artisanlib/sliderStyle.py +++ b/src/artisanlib/slider_style.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- -# artisan_slider_style = """ QSlider::groove:vertical:focus {{