动画不更新
Animation doesn't update
我正在尝试重做此 Qt 代码 https://github.com/laserpants/qt-material-widgets,但使用 Python 和 PyQt4,我遇到了动画问题。
我想重新创建示例的复选框,除动画外一切正常;它不会更新。
主要问题是我想保留状态机和按钮的转换,但我找到的解决方案没有使用它们。
我只想让图标在点击时淡入淡出
知道为什么这不起作用吗?
class materialCheckBox(QWidget):
clicked = pyqtSignal()
def __init__(self, parent):
super(materialCheckBox,self).__init__(parent)
self.setProperty("value", bool)
checkedIcon = materialIcon(self, "C:/Users/User/.qgis2/python/plugins/Material/icons/baseline-check_box-24px.svg")
uncheckedIcon = materialIcon(self, "C:/Users/User/.qgis2/python/plugins/Material/icons/baseline-check_box_outline_blank-24px.svg")
self.stateMachine = QStateMachine()
self.checkedState = QState()
self.checkedState.assignProperty(self, "value", True)
self.checkedState.assignProperty(checkedIcon, "opacity", 1.0)
self.checkedState.assignProperty(uncheckedIcon, "opacity", 0.0)
self.uncheckedState = QState()
self.uncheckedState.assignProperty(self, "value", False)
self.uncheckedState.assignProperty(checkedIcon, "opacity", 0.0)
self.uncheckedState.assignProperty(uncheckedIcon, "opacity", 1.0)
self.stateMachine.addState(self.checkedState)
self.stateMachine.addState(self.uncheckedState)
self.stateMachine.setInitialState(self.uncheckedState)
transition1 = self.checkedState.addTransition(self.clicked, self.uncheckedState)
animation1 = QPropertyAnimation(checkedIcon, "opacity", self)
animation1.setDuration(2000)
transition1.addAnimation(animation1)
animation2 = QPropertyAnimation(uncheckedIcon, "opacity", self)
animation2.setDuration(2000)
transition1.addAnimation(animation2)
transition2 = self.uncheckedState.addTransition(self.clicked, self.checkedState)
animation3 = QPropertyAnimation(checkedIcon, "opacity", self)
animation3.setDuration(2000)
transition2.addAnimation(animation3)
animation4 = QPropertyAnimation(uncheckedIcon, "opacity", self)
animation4.setDuration(2000)
transition2.addAnimation(animation4)
self.stateMachine.start()
self.clicked.connect(self.update)
self.setGeometry(0, 0, 24, 24)
def isChecked(self):
return self.property("value")
def mousePressEvent(self, event):
self.clicked.emit()
class materialIcon(QWidget):
def __init__(self, parent, address):
super(materialIcon, self).__init__(parent)
self.icon = QPixmap(address)
self.setProperty("opacity", float)
def paintEvent(self, event):
painter = QPainter(self)
painter.begin(self)
painter.setOpacity(self.property("opacity"))
mask = QPainter(self.icon)
mask.begin(self.icon)
mask.setCompositionMode(QPainter.CompositionMode_SourceIn)
mask.fillRect(self.icon.rect(), QColor(0, 158, 227))
mask.end()
painter.drawPixmap(0, 0, self.icon)
painter.end()
每次不透明度变化时都必须调用 update() 方法,因此创建一个 pyqtProperty 比创建一个动态的更好 属性:
import os
from PyQt4 import QtCore, QtGui
root_path = os.path.dirname(os.path.realpath(__file__))
icons_path = file = os.path.join(root_path, "icons")
class MaterialCheckBox(QtGui.QWidget):
clicked = QtCore.pyqtSignal()
toggled = QtCore.pyqtSignal(bool)
def __init__(self, parent=None):
super(MaterialCheckBox, self).__init__(parent)
self._is_checked = False
checkedIcon = MaterialIcon(
self, os.path.join(icons_path, "baseline-check_box-24px.svg")
)
uncheckedIcon = MaterialIcon(
self,
os.path.join(
icons_path, "baseline-check_box_outline_blank-24px.svg"
),
)
stateMachine = QtCore.QStateMachine(self)
checkedState = QtCore.QState()
checkedState.assignProperty(self, b"checked", True)
checkedState.assignProperty(checkedIcon, b"opacity", 1.0)
checkedState.assignProperty(uncheckedIcon, b"opacity", 0.0)
uncheckedState = QtCore.QState()
uncheckedState.assignProperty(self, b"checked", False)
uncheckedState.assignProperty(checkedIcon, b"opacity", 0.0)
uncheckedState.assignProperty(uncheckedIcon, b"opacity", 1.0)
stateMachine.addState(checkedState)
stateMachine.addState(uncheckedState)
stateMachine.setInitialState(uncheckedState)
duration = 2000
transition1 = checkedState.addTransition(self.clicked, uncheckedState)
animation1 = QtCore.QPropertyAnimation(
checkedIcon, b"opacity", self, duration=duration
)
transition1.addAnimation(animation1)
animation2 = QtCore.QPropertyAnimation(
uncheckedIcon, b"opacity", self, duration=duration
)
transition1.addAnimation(animation2)
transition2 = uncheckedState.addTransition(self.clicked, checkedState)
animation3 = QtCore.QPropertyAnimation(
checkedIcon, b"opacity", self, duration=duration
)
transition2.addAnimation(animation3)
animation4 = QtCore.QPropertyAnimation(
uncheckedIcon, b"opacity", self, duration=duration
)
transition2.addAnimation(animation4)
stateMachine.start()
def sizeHint(self):
return QtCore.QSize(24, 24)
def isChecked(self):
return self._is_checked
def setChecked(self, value):
if self._is_checked != value:
self._is_checked = value
self.toggled.emit(self._is_checked)
checked = QtCore.pyqtProperty(
bool, fget=isChecked, fset=setChecked, notify=toggled
)
def mousePressEvent(self, event):
self.clicked.emit()
self.update()
super(MaterialCheckBox, self).mousePressEvent(event)
class MaterialIcon(QtGui.QWidget):
opacityChanged = QtCore.pyqtSignal()
def __init__(self, parent, address):
super(MaterialIcon, self).__init__(parent)
self.icon = QtGui.QPixmap(address)
self._opacity = 0.0
def opacity(self):
return self._opacity
def setOpacity(self, o):
if o != self._opacity:
self._opacity = o
self.opacityChanged.emit()
self.update()
opacity = QtCore.pyqtProperty(
float, fget=opacity, fset=setOpacity, notify=opacityChanged
)
def paintEvent(self, event):
painter = QtGui.QPainter(self)
painter.setOpacity(self.opacity)
mask = QtGui.QPainter(self.icon)
mask.setCompositionMode(QtGui.QPainter.CompositionMode_SourceIn)
mask.fillRect(self.icon.rect(), QtGui.QColor(0, 158, 227))
mask.end()
painter.drawPixmap(0, 0, self.icon)
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
w = MaterialCheckBox()
w.show()
sys.exit(app.exec_())
完整的例子是here。
我正在尝试重做此 Qt 代码 https://github.com/laserpants/qt-material-widgets,但使用 Python 和 PyQt4,我遇到了动画问题。
我想重新创建示例的复选框,除动画外一切正常;它不会更新。
主要问题是我想保留状态机和按钮的转换,但我找到的解决方案没有使用它们。
我只想让图标在点击时淡入淡出
知道为什么这不起作用吗?
class materialCheckBox(QWidget):
clicked = pyqtSignal()
def __init__(self, parent):
super(materialCheckBox,self).__init__(parent)
self.setProperty("value", bool)
checkedIcon = materialIcon(self, "C:/Users/User/.qgis2/python/plugins/Material/icons/baseline-check_box-24px.svg")
uncheckedIcon = materialIcon(self, "C:/Users/User/.qgis2/python/plugins/Material/icons/baseline-check_box_outline_blank-24px.svg")
self.stateMachine = QStateMachine()
self.checkedState = QState()
self.checkedState.assignProperty(self, "value", True)
self.checkedState.assignProperty(checkedIcon, "opacity", 1.0)
self.checkedState.assignProperty(uncheckedIcon, "opacity", 0.0)
self.uncheckedState = QState()
self.uncheckedState.assignProperty(self, "value", False)
self.uncheckedState.assignProperty(checkedIcon, "opacity", 0.0)
self.uncheckedState.assignProperty(uncheckedIcon, "opacity", 1.0)
self.stateMachine.addState(self.checkedState)
self.stateMachine.addState(self.uncheckedState)
self.stateMachine.setInitialState(self.uncheckedState)
transition1 = self.checkedState.addTransition(self.clicked, self.uncheckedState)
animation1 = QPropertyAnimation(checkedIcon, "opacity", self)
animation1.setDuration(2000)
transition1.addAnimation(animation1)
animation2 = QPropertyAnimation(uncheckedIcon, "opacity", self)
animation2.setDuration(2000)
transition1.addAnimation(animation2)
transition2 = self.uncheckedState.addTransition(self.clicked, self.checkedState)
animation3 = QPropertyAnimation(checkedIcon, "opacity", self)
animation3.setDuration(2000)
transition2.addAnimation(animation3)
animation4 = QPropertyAnimation(uncheckedIcon, "opacity", self)
animation4.setDuration(2000)
transition2.addAnimation(animation4)
self.stateMachine.start()
self.clicked.connect(self.update)
self.setGeometry(0, 0, 24, 24)
def isChecked(self):
return self.property("value")
def mousePressEvent(self, event):
self.clicked.emit()
class materialIcon(QWidget):
def __init__(self, parent, address):
super(materialIcon, self).__init__(parent)
self.icon = QPixmap(address)
self.setProperty("opacity", float)
def paintEvent(self, event):
painter = QPainter(self)
painter.begin(self)
painter.setOpacity(self.property("opacity"))
mask = QPainter(self.icon)
mask.begin(self.icon)
mask.setCompositionMode(QPainter.CompositionMode_SourceIn)
mask.fillRect(self.icon.rect(), QColor(0, 158, 227))
mask.end()
painter.drawPixmap(0, 0, self.icon)
painter.end()
每次不透明度变化时都必须调用 update() 方法,因此创建一个 pyqtProperty 比创建一个动态的更好 属性:
import os
from PyQt4 import QtCore, QtGui
root_path = os.path.dirname(os.path.realpath(__file__))
icons_path = file = os.path.join(root_path, "icons")
class MaterialCheckBox(QtGui.QWidget):
clicked = QtCore.pyqtSignal()
toggled = QtCore.pyqtSignal(bool)
def __init__(self, parent=None):
super(MaterialCheckBox, self).__init__(parent)
self._is_checked = False
checkedIcon = MaterialIcon(
self, os.path.join(icons_path, "baseline-check_box-24px.svg")
)
uncheckedIcon = MaterialIcon(
self,
os.path.join(
icons_path, "baseline-check_box_outline_blank-24px.svg"
),
)
stateMachine = QtCore.QStateMachine(self)
checkedState = QtCore.QState()
checkedState.assignProperty(self, b"checked", True)
checkedState.assignProperty(checkedIcon, b"opacity", 1.0)
checkedState.assignProperty(uncheckedIcon, b"opacity", 0.0)
uncheckedState = QtCore.QState()
uncheckedState.assignProperty(self, b"checked", False)
uncheckedState.assignProperty(checkedIcon, b"opacity", 0.0)
uncheckedState.assignProperty(uncheckedIcon, b"opacity", 1.0)
stateMachine.addState(checkedState)
stateMachine.addState(uncheckedState)
stateMachine.setInitialState(uncheckedState)
duration = 2000
transition1 = checkedState.addTransition(self.clicked, uncheckedState)
animation1 = QtCore.QPropertyAnimation(
checkedIcon, b"opacity", self, duration=duration
)
transition1.addAnimation(animation1)
animation2 = QtCore.QPropertyAnimation(
uncheckedIcon, b"opacity", self, duration=duration
)
transition1.addAnimation(animation2)
transition2 = uncheckedState.addTransition(self.clicked, checkedState)
animation3 = QtCore.QPropertyAnimation(
checkedIcon, b"opacity", self, duration=duration
)
transition2.addAnimation(animation3)
animation4 = QtCore.QPropertyAnimation(
uncheckedIcon, b"opacity", self, duration=duration
)
transition2.addAnimation(animation4)
stateMachine.start()
def sizeHint(self):
return QtCore.QSize(24, 24)
def isChecked(self):
return self._is_checked
def setChecked(self, value):
if self._is_checked != value:
self._is_checked = value
self.toggled.emit(self._is_checked)
checked = QtCore.pyqtProperty(
bool, fget=isChecked, fset=setChecked, notify=toggled
)
def mousePressEvent(self, event):
self.clicked.emit()
self.update()
super(MaterialCheckBox, self).mousePressEvent(event)
class MaterialIcon(QtGui.QWidget):
opacityChanged = QtCore.pyqtSignal()
def __init__(self, parent, address):
super(MaterialIcon, self).__init__(parent)
self.icon = QtGui.QPixmap(address)
self._opacity = 0.0
def opacity(self):
return self._opacity
def setOpacity(self, o):
if o != self._opacity:
self._opacity = o
self.opacityChanged.emit()
self.update()
opacity = QtCore.pyqtProperty(
float, fget=opacity, fset=setOpacity, notify=opacityChanged
)
def paintEvent(self, event):
painter = QtGui.QPainter(self)
painter.setOpacity(self.opacity)
mask = QtGui.QPainter(self.icon)
mask.setCompositionMode(QtGui.QPainter.CompositionMode_SourceIn)
mask.fillRect(self.icon.rect(), QtGui.QColor(0, 158, 227))
mask.end()
painter.drawPixmap(0, 0, self.icon)
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
w = MaterialCheckBox()
w.show()
sys.exit(app.exec_())
完整的例子是here。