我在一个布局中有一堆小部件,这个布局是一个QFrame的子级。这允许我在这个布局周围创建一个边框。现在,当任意子对象接收到焦点时,我想要更改QFrame的边框颜色,以向用户指示当前焦点所在的位置。如何在不通过回调父窗口小部件( QFrame)的样式表的子类化每个子级的focuInEvent/focusOutEvent的情况下做到这一点?当测试QFrame的focusInEvent时,我永远不能让它触发。有没有什么儿童焦点事件之类的?
发布于 2018-06-18 02:46:39
我想我在尝试了一些东西并学习了更多关于eventFilter的知识之后,想出了一个很好的解决方案。基本上,我发现你需要在父元素中安装一个事件过滤器,来捕捉所有子元素的焦点事件。它更容易展示一个例子,这比它可能需要的要复杂一些,但它说明了一些重要的观点:
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) # this will catch focus events
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 # passes this event to the child, i.e. does not block it from the child widgets
def install_filters(self):
# this will install the focus in/out event filter in all children of the panel
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_())https://stackoverflow.com/questions/50893147
复制相似问题