Снятие фокуса с lineedit в PyQt5
Я решил создать анимированное поле для ввода на PyQt5 для своего проекта и столкнулся со следующей проблемой:
при нажатии на другое поле фокус с других не убирается.
Код:
import sys
import re
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
class animatedLineEdit(QLineEdit):
def __init__(self, *args, **kwargs):
QLineEdit.__init__(self, *args, **kwargs)
self.installEventFilter(self)
self.co_set = 0
byar = QByteArray()
byar.append('texcolor')
self.click_anim = QPropertyAnimation(self, byar)
self.click_anim.setEndValue('#2979ff')
self.click_anim.setDuration(170)
self.click_anim.setLoopCount(1)
self.off_anim = QPropertyAnimation(self, byar)
self.off_anim.setEndValue('#f5f5f5')
self.off_anim.setDuration(150)
self.off_anim.setLoopCount(1)
self.off_anim.start()
self.on_anim = QPropertyAnimation(self, byar)
self.on_anim.setEndValue('#e6e6e6')
self.on_anim.setDuration(50)
self.on_anim.setLoopCount(1)
self.focusOutEvent = self.offClicked
self.mousePressEvent = self.onClicked
def parseStyleSheet(self):
ss = self.styleSheet()
sts = [s.strip() for s in ss.split(';') if len(s.strip())]
return sts
def offClicked(self, *args, **kwargs):
if self.isEnabled():
self.off_anim.start()
def onClicked(self, *args, **kwargs):
if self.isEnabled():
self.click_anim.start()
def getBackColor(self):
return self.palette().color(self.pal_ele)
def setBackColor(self, color):
self.co_set += 1
sss = self.parseStyleSheet()
bg_new = 'border: 2px solid rgba(%d,%d,%d,%d); border-width: 0 0 2px 0;' % (color.red(), color.green(), color.blue(), color.alpha())
for k, sty in enumerate(sss):
if re.search('\Aborder:', sty):
sss[k] = bg_new
break
else:
sss.append(bg_new)
self.setStyleSheet('; '.join(sss))
pal_ele = QPalette.Window
texcolor = pyqtProperty(QColor, getBackColor, setBackColor)
if __name__ == "__main__":
class Test(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self, parent)
self.setWindowTitle('Animation test')
self.main = QVBoxLayout()
for q in range(5):
layout = QHBoxLayout()
for i in range(5):
linedit = animatedLineEdit(f'Line{str(q)}{str(i)}')
linedit.setFixedSize(100, 30)
layout.addWidget(linedit)
self.main.addLayout(layout)
self.setLayout(self.main)
app = QApplication(sys.argv)
main = Test()
main.show()
app.exec_()
Ответы (1 шт):
Автор решения: S. Nick
→ Ссылка
Попробуйте так:
import sys
import re
from PyQt5.Qt import *
class AnimatedLineEdit(QLineEdit):
clicked = pyqtSignal(object) # +++
def __init__(self, *args, **kwargs):
QLineEdit.__init__(self, *args, **kwargs)
self.installEventFilter(self)
self.co_set = 0
byar = QByteArray()
byar.append('texcolor')
self.click_anim = QPropertyAnimation(self, byar)
self.click_anim.setEndValue('#2979ff')
self.click_anim.setDuration(170)
self.click_anim.setLoopCount(1)
self.off_anim = QPropertyAnimation(self, byar)
self.off_anim.setEndValue('#f5f5f5')
self.off_anim.setDuration(150)
self.off_anim.setLoopCount(1)
self.off_anim.start()
self.on_anim = QPropertyAnimation(self, byar)
self.on_anim.setEndValue('#e6e6e6')
self.on_anim.setDuration(50)
self.on_anim.setLoopCount(1)
# - self.focusOutEvent = self.offClicked # ---
self.mousePressEvent = self.onClicked
def parseStyleSheet(self):
ss = self.styleSheet()
sts = [s.strip() for s in ss.split(';') if len(s.strip())]
return sts
def offClicked(self, *args, **kwargs):
if self.isEnabled():
self.off_anim.start()
def onClicked(self, *args, **kwargs):
self.clicked.emit(self) # +++
if self.isEnabled():
self.click_anim.start()
def getBackColor(self):
return self.palette().color(self.pal_ele)
def setBackColor(self, color):
self.co_set += 1
sss = self.parseStyleSheet()
bg_new = 'border: 2px solid rgba(%d,%d,%d,%d); border-width: 0 0 2px 0;' % (color.red(), color.green(), color.blue(), color.alpha())
for k, sty in enumerate(sss):
if re.search('\Aborder:', sty):
sss[k] = bg_new
break
else:
sss.append(bg_new)
self.setStyleSheet('; '.join(sss))
pal_ele = QPalette.Window
texcolor = pyqtProperty(QColor, getBackColor, setBackColor)
class Test(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('Animation test')
self.main = QVBoxLayout(self)
self.linedits = {} # +++
for r in range(5):
layout = QHBoxLayout()
for c in range(5):
linedit = AnimatedLineEdit(f'Line{str(r)}{str(c)}')
linedit.setFixedSize(100, 30)
linedit.setFocusPolicy(Qt.ClickFocus) # +++
self.linedits[f'{r}{c}'] = linedit # +++
linedit.clicked.connect(self.on_clicked) # +++
layout.addWidget(self.linedits[f'{r}{c}'])
self.main.addLayout(layout)
# +++ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
def on_clicked(self, lineEdit):
for le in self.linedits.values():
if le != lineEdit:
le.offClicked()
else:
lineEdit.setFocus()
if __name__ == "__main__":
app = QApplication(sys.argv)
main = Test()
main.show()
sys.exit(app.exec_())

