2024-06-24 13:52:37 发布
网友
我在一个布局中有一堆小部件,而布局是QFrame的子级。这允许我在这个布局周围创建一个边框。现在,当任何子对象接收到焦点时,我想更改QFrame的边框颜色,以向用户指示当前焦点所在的位置。如何在不将每个子控件的focuInEvent/focusOutEvent子类化并回调其父小部件(QFrame)的样式表的情况下做到这一点呢?当测试聚焦到QFrame的焦点时,我永远无法触发它。有什么儿童焦点事件吗?在
我想我想出了一个很好的解决方案,在尝试了一些东西,并学习了很多关于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_())
我想我想出了一个很好的解决方案,在尝试了一些东西,并学习了很多关于eventFilter的东西之后。基本上,我发现你需要在父对象中安装一个事件过滤器,并捕捉子对象的所有焦点事件。举个例子比较容易,这比它可能需要的要复杂一些,但它说明了一些重要的点:
相关问题 更多 >
编程相关推荐