Python + Qt: pyqtProperty, stylesheets and event handlers
pyqt, pyqt4, python, qtstylesheets
Solution
There are a couple of issues here.
Firstly, the re-implemented `mousePressEvent` should call the base-class implementation in order to retain the normal behaviour.
Secondly, changes to properties do not automatically trigger style changes, so you need to explicitly do that in your code.
Also, its worth noting that `pyqtProperty` can be used as a decorator, which might improve the readability of the code a little.
So, with these changes, the code might look something like this:
...
@QtCore.pyqtProperty(bool)
def state(self):
return self._state
@state.setter
def state(self, value):
self._state = value
def mousePressEvent(self, event):
print 'clicked'
if self.state:
self.state = False
self.setText('OFF')
else:
self.state = True
self.setText('ON')
self.style().unpolish(self)
self.style().polish(self)
self.update()
super(CustomButton, self).mousePressEvent(event)
Problem
Recently, I have been struggling with understanding of pyqtProperty usage. In following snippet I try to create a custom button which would change it's text and appearance after clicking on it. I wanted to separate logic and appearance, so I've created custom property 'state', which is used in the stylesheet. The result looks kind of strange to me. Program throws `'CustomButton' object has no attribute '_state'` exception, but runs anyway. Button's text is changing after clicking on it, but color stays the same. ``` #!/usr/bin/python # -*- coding: utf-8 -*- import sys from PyQt4 import QtGui, QtCore STYLE = ''' CustomButton { margin: 50px; padding: 10px; } CustomButton[state='true'] { background: yellowgreen; } CustomButton[state='false'] { background: orangered; } ''' class CustomButton(QtGui.QPushButton): def __init__(self): super(CustomButton, self).__init__() self.setText('ON') self.setStyleSheet(STYLE) self._state = True def g_state(self): return self._state def s_state(self, value): self._state = value state = QtCore.pyqtProperty(bool, fget=g_state, fset=s_state) def mousePressEvent(self, event): print 'clicked' if self.state == True: self.state = False self.setText('OFF') else: self.state = True self.setText('ON') if __name__ == '__main__': app = QtGui.QApplication(sys.argv) b = CustomButton() b.show() sys.exit(app.exec_()) ```