Qt:在焦点上更改QFrame边框颜色

2024-06-24 13:52:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我在一个布局中有一堆小部件,而布局是QFrame的子级。这允许我在这个布局周围创建一个边框。现在,当任何子对象接收到焦点时,我想更改QFrame的边框颜色,以向用户指示当前焦点所在的位置。如何在不将每个子控件的focuInEvent/focusOutEvent子类化并回调其父小部件(QFrame)的样式表的情况下做到这一点呢?当测试聚焦到QFrame的焦点时,我永远无法触发它。有什么儿童焦点事件吗?在


Tags: 对象用户颜色部件情况布局样式表控件
1条回答
网友
1楼 · 发布于 2024-06-24 13:52:37

我想我想出了一个很好的解决方案,在尝试了一些东西,并学习了很多关于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_())

相关问题 更多 >