Friday, 10 June 2016

Using PyQT setStyleSheet controlled by State to avoid high CPU consumption

 it is adviced in QT documentation to use only setStyleSheet in the constructor and for dynamic styles use properties. Calling it for each updateStyle is unefficient.

The setStyleSheet can provide different styles depending on widget state (if defined as property):

 Applying this advice one can have something like (taurus recipe by j.kotansky):

 diff --git a/lib/taurus/qt/qtgui/panel/taurusvalue.py b/lib/taurus/qt/qtgui/panel/taurusvalue.py
index dff58d2..a36c30c 100644
--- a/lib/taurus/qt/qtgui/panel/taurusvalue.py
+++ b/lib/taurus/qt/qtgui/panel/taurusvalue.py
@@ -78,7 +78,18 @@ class DefaultLabelWidget(TaurusLabel):
         self.setSizePolicy(Qt.QSizePolicy.Preferred, Qt.QSizePolicy.Maximum)
         self.setBgRole(None)
         self.autoTrim = False
-        self.setStyleSheet('DefaultLabelWidget {border-style: solid; border-width: 1px; border-color: transparent; border-radius: 4px;}')
+        self.setProperty('state', 'init')
+        self.setStyleSheet(
+            'DefaultLabelWidget[state="init"] {border-style: solid; ' \
+            'border-width: 1px; border-color: transparent; ' \
+            'border-radius: 4px;}; ' \
+            'DefaultLabelWidget[state="pending"] {border-style: solid ; ' \
+            'border-width: 1px; border-color: blue; color: blue; ' \
+            'border-radius:4px;}; ' \
+            'DefaultLabelWidget[state="idle"] {border-style: solid; ' \
+            'border-width: 1px; border-color: transparent; color: black; ' \
+            'border-radius:4px;};'
+        )

     def setModel(self, model):
         if model is None or model=='': 
@@ -1067,13 +1078,19 @@ class TaurusValue(Qt.QWidget, TaurusBaseWidget):

     def updatePendingOpsStyle(self):
         if self._labelWidget is None: return
+        state = self._labelWidget.property('state')
         if self.hasPendingOperations():
-            self._labelWidget.setStyleSheet(
-                '%s {border-style: solid ; border-width: 1px; border-color: blue; color: blue; border-radius:4px;}'%self._labelWidget.__class__.__name__)
+            if state == 'pending':
+                return
+            self._labelWidget.setProperty('state', 'pending')
         else:
-            self._labelWidget.setStyleSheet(
-                '%s {border-style: solid; border-width: 1px; border-color: transparent; color: black;  border-radius:4px;}'%self._labelWidget.__class__.__name__)
-            
+            if state == 'idle':
+                return
+            self._labelWidget.setProperty('state', 'idle')
+        self._labelWidget.style().unpolish(self._labelWidget)
+        self._labelWidget.style().polish(self._labelWidget)
+        self._labelWidget.update()
+
     def getLabelConfig(self):
         return self._labelConfig

diff --git a/lib/taurus/qt/qtgui/table/taurusgrid.py b/lib/taurus/qt/qtgui/table/taurusgrid.py
index 5048dfa..98894d2 100644
--- a/lib/taurus/qt/qtgui/table/taurusgrid.py
+++ b/lib/taurus/qt/qtgui/table/taurusgrid.py
@@ -838,13 +838,22 @@ class TaurusGrid(QtGui.QFrame, TaurusBaseWidget):
             if item_name: item = self.getItemByModel(item_name)
             else: item = self._last_selected
         if item:
+            state = item._labelWidget.property('state')
         if selected:
-                item._labelWidget.setStyleSheet('border-style: solid ; border-width: 1px; border-color: blue; color: blue; border-radius:4px;')
+                if state != 'pending':
+                    item._labelWidget.setProperty('state', 'pending')
+                    item._labelWidget.style().unpolish(item._labelWidget)
+                    item._labelWidget.style().polish(item._labelWidget)
+                    item._labelWidget.update()
                 if self._last_selected and self._last_selected!=item:
                     self.setItemSelected(self._last_selected,False)
                 self._last_selected = item
             else:
-                item._labelWidget.setStyleSheet('border-style: solid; border-width: 1px; border-color: transparent; color: black;  border-radius:4px;')        
+                if state != 'idle':
+                    item._labelWidget.setProperty('state', 'idle')
+                    item._labelWidget.style().unpolish(item._labelWidget)
+                    item._labelWidget.style().polish(item._labelWidget)
+                    item._labelWidget.update()
                 self._last_selected = None
         else: return None

No comments:

Post a Comment