Как мне использовать функцию на двух классах?
У меня есть вот такой код
class Radio(QRadioButton):
def __init__(self, icon, size, margin, parent=None):
super(Radio, self).__init__(parent)
change_color(self)
self._animation = QtCore.QVariantAnimation(
startValue=QtGui.QColor("red"),
endValue=QtGui.QColor("white"),
valueChanged=self._on_value_changed,
duration=400,
)
self._update_stylesheet(QtGui.QColor("blue"), QtGui.QColor("black"))
self.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
def _on_value_changed(self, color):
foreground = (
QtGui.QColor("yellow")
if self._animation.direction() == QtCore.QAbstractAnimation.Forward
else QtGui.QColor("green")
)
self._update_stylesheet(color, foreground)
def _update_stylesheet(self, background, foreground):
self.setStyleSheet(
"""
background-color: %s;
color: %s;
"""
% (background.name(), foreground.name())
)
def enterEvent(self, event):
self._animation.setDirection(QtCore.QAbstractAnimation.Backward)
self._animation.start()
super().enterEvent(event)
def leaveEvent(self, event):
self._animation.setDirection(QtCore.QAbstractAnimation.Forward)
self._animation.start()
super().leaveEvent(event)
class Label(QLabel):
def __init__(self, icon, size, margin, parent=None):
super(Label, self).__init__(parent)
change_color(self)
self._animation = QtCore.QVariantAnimation(
startValue=QtGui.QColor("red"),
endValue=QtGui.QColor("white"),
valueChanged=self._on_value_changed,
duration=400,
)
self._update_stylesheet(QtGui.QColor("blue"), QtGui.QColor("black"))
self.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
def _on_value_changed(self, color):
foreground = (
QtGui.QColor("yellow")
if self._animation.direction() == QtCore.QAbstractAnimation.Forward
else QtGui.QColor("green")
)
self._update_stylesheet(color, foreground)
def _update_stylesheet(self, background, foreground):
self.setStyleSheet(
"""
background-color: %s;
color: %s;
"""
% (background.name(), foreground.name())
)
def enterEvent(self, event):
self._animation.setDirection(QtCore.QAbstractAnimation.Backward)
self._animation.start()
super().enterEvent(event)
def leaveEvent(self, event):
self._animation.setDirection(QtCore.QAbstractAnimation.Forward)
self._animation.start()
super().leaveEvent(event)
И я хочу написать функцию чтобы сократить код
def color(self):
def face_init(self):
self._animation = QtCore.QVariantAnimation(
startValue=QtGui.QColor("red"),
endValue=QtGui.QColor("white"),
valueChanged=self._on_value_changed,
duration=400,
)
self._update_stylesheet(QtGui.QColor("blue"), QtGui.QColor("black"))
self.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
def _on_value_changed(self, color):
foreground = (
QtGui.QColor("yellow")
if self._animation.direction() == QtCore.QAbstractAnimation.Forward
else QtGui.QColor("green")
)
self._update_stylesheet(color, foreground)
def _update_stylesheet(self, background, foreground):
self.setStyleSheet(
"""
background-color: %s;
color: %s;
"""
% (background.name(), foreground.name())
)
def enterEvent(self, event):
self._animation.setDirection(QtCore.QAbstractAnimation.Backward)
self._animation.start()
super().enterEvent(event)
def leaveEvent(self, event):
self._animation.setDirection(QtCore.QAbstractAnimation.Forward)
self._animation.start()
super().leaveEvent(event)
class Radio(QRadioButton):
def __init__(self, icon, size, margin, parent=None):
super(Radio, self).__init__(parent)
color(self)
class Label(QLabel):
def __init__(self, icon, size, margin, parent=None):
super(Label, self).__init__(parent)
color(self)
Но проблема в том что я все еще плохо знаю как работать с классами. Я могу обработать только то что находится внутри одного метода
def color(self):
self._animation = QtCore.QVariantAnimation(
startValue=QtGui.QColor("red"),
endValue=QtGui.QColor("white"),
valueChanged=self._on_value_changed,
duration=400,
)
return self
Но как запихнуть в функцию все методы _on_value_changed, _update_stylesheet,enterEvent,leaveEvent. Я не знаю.
Ответы (1 шт):
Автор решения: gil9red
→ Ссылка
Это типичная задача ООП -- наследование.
Оформляйте color как класс от QWidget и указываете его предком для Radio и Label.
Пример:
class MyColor(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.face_init()
def face_init(self):
self._animation = QtCore.QVariantAnimation(
startValue=QtGui.QColor("red"),
endValue=QtGui.QColor("white"),
valueChanged=self._on_value_changed,
duration=400,
)
self._update_stylesheet(QtGui.QColor("blue"), QtGui.QColor("black"))
self.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
def _on_value_changed(self, color):
foreground = (
QtGui.QColor("yellow")
if self._animation.direction() == QtCore.QAbstractAnimation.Forward
else QtGui.QColor("green")
)
self._update_stylesheet(color, foreground)
def _update_stylesheet(self, background, foreground):
self.setStyleSheet(
"""
background-color: %s;
color: %s;
"""
% (background.name(), foreground.name())
)
def enterEvent(self, event):
self._animation.setDirection(QtCore.QAbstractAnimation.Backward)
self._animation.start()
super().enterEvent(event)
def leaveEvent(self, event):
self._animation.setDirection(QtCore.QAbstractAnimation.Forward)
self._animation.start()
super().leaveEvent(event)
class Radio(QRadioButton, MyColor):
def __init__(self, icon, size, margin, parent=None):
super().__init__()
class Label(QLabel, MyColor):
def __init__(self, icon, size, margin, parent=None):
super().__init__()
Пример запуска
from PyQt5.QtWidgets import QWidget, QRadioButton, QLabel, QApplication
from PyQt5 import QtCore
from PyQt5 import QtGui
...
app = QApplication([])
b = Radio(1, 2, 3)
b.setText('[Button] Hello World!')
b.show()
l = Label(1, 2, 3)
l.setText('[Label] Hello World!')
l.show()
app.exec()
PS.
Для отлова ошибок советую использовать sys.excepthook. Пока отлаживал ответ, мне очень пригодилось.
from PyQt5.QtWidgets import QMessageBox
...
def log_uncaught_exceptions(ex_cls, ex, tb):
text = '{}: {}:\n'.format(ex_cls.__name__, ex)
import traceback
text += ''.join(traceback.format_tb(tb))
print(text)
QMessageBox.critical(None, 'Error', text)
quit()
import sys
sys.excepthook = log_uncaught_exceptions
...
app = QApplication([])