我想在尝试了一些事情并学习了很多关于event filter的知识之后,我想出了一个很好的解决方案。基本上,我发现您需要在父级中安装一个事件过滤器并捕获子级的所有焦点事件。举一个例子比较容易,这比它可能需要的复杂一些,但是它说明了一些重要的点:
import os
import sys
from PyQt4 import QtGui, QtCore
class BasePanel(QtGui.QWidget):
"""This is more or less abstract, subclass it for 'panels' in the main UI"""
def __init__(self, parent=None):
super(BasePanel, self).__init__(parent)
self.frame_layout = QtGui.QVBoxLayout()
self.frame_layout.setContentsMargins(0, 0, 0, 0)
self.setLayout(self.frame_layout)
self.frame = QtGui.QFrame()
self.frame.setObjectName("base_frame")
self.frame.setFrameStyle(QtGui.QFrame.Box | QtGui.QFrame.Plain)
self.frame.setLineWidth(1)
self.frame_layout.addWidget(self.frame)
self.base_layout = QtGui.QVBoxLayout()
self.frame.setLayout(self.base_layout)
self.focus_in_color = "rgb(50, 255, 150)"
self.focus_out_color = "rgb(100, 100, 100)"
self.frame.setStyleSheet("#base_frame {border: 1px solid %s}" % self.focus_out_color)
self.installEventFilter(self)
self.install_filters()
def eventFilter(self, object, event):
if event.type() == QtCore.QEvent.FocusIn:
self.frame.setStyleSheet("#base_frame {border: 1px solid %s}" % self.focus_in_color)
elif event.type() == QtCore.QEvent.FocusOut:
self.frame.setStyleSheet("#base_frame {border: 1px solid %s}" % self.focus_out_color)
return False
def install_filters(self):
for widget in self.findChildren(QtGui.QWidget):
widget.installEventFilter(self)
class LeftPanel(BasePanel):
def __init__(self, parent=None):
super(LeftPanel, self).__init__(parent)
title = QtGui.QLabel("Left Panel")
title.setAlignment(QtCore.Qt.AlignCenter)
self.base_layout.addWidget(title)
edit = QtGui.QLineEdit()
self.base_layout.addWidget(edit)
class RightPanel(BasePanel):
def __init__(self, parent=None):
super(RightPanel, self).__init__(parent)
title = QtGui.QLabel("Right Panel")
title.setAlignment(QtCore.Qt.AlignCenter)
self.base_layout.addWidget(title)
edit = QtGui.QLineEdit()
self.base_layout.addWidget(edit)
class MainApp(QtGui.QMainWindow):
def __init__(self):
super(MainApp, self).__init__()
main_layout = QtGui.QHBoxLayout()
central_widget = QtGui.QWidget()
central_widget.setLayout(main_layout)
self.setCentralWidget(central_widget)
left_panel = LeftPanel()
main_layout.addWidget(left_panel)
right_panel = RightPanel()
main_layout.addWidget(right_panel)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
ex = MainApp()
ex.show()
sys.exit(app.exec_())