Python 如何在单击子窗口小部件时选择父QListWidgetItem?

Python 如何在单击子窗口小部件时选择父QListWidgetItem?,python,pyqt,Python,Pyqt,我有一个GUI,其中QListWidget是中心部件。QListWidgetItems由一个自定义小部件组成,其中包括一个图形区域和一个QTable 单击图形区域或表格时,未选择父QListWidgetItem 查看我正在处理的GUI的图片 顶部QListWidgetItem周围的红色边框表示当前选中的项目 从第二个QListWidgetItem中的表输入中,您可以看到我正在将文本输入到表小部件中 如何使其在QListWidgetItem上的任何位置(包括其子窗口小部件)都被选中 以下是一些相

我有一个GUI,其中QListWidget是中心部件。QListWidgetItems由一个自定义小部件组成,其中包括一个图形区域和一个QTable

单击图形区域或表格时,未选择父QListWidgetItem

查看我正在处理的GUI的图片

顶部QListWidgetItem周围的红色边框表示当前选中的项目

从第二个QListWidgetItem中的表输入中,您可以看到我正在将文本输入到表小部件中

如何使其在QListWidgetItem上的任何位置(包括其子窗口小部件)都被选中

以下是一些相关代码供参考:

class MainWindow(QMainWindow):
    move_splitter = Signal(int, int)

    def __init__(self):
        super().__init__()

        # stuff

        self.panels = QListWidget()
        self.panels.setAcceptDrops(True)
        self.panels.setDragEnabled(True)
        self.panels.setDragDropMode(QAbstractItemView.InternalMove)
        self.panels.setStyleSheet("QListWidget::item:selected \
        { border: 1px solid red }")
        self.panels.setSelectionMode(QAbstractItemView.SingleSelection)
        self.setCentralWidget(self.panels)

        # more stuff


    def add_panel(self):
        insert_item = QListWidgetItem()
        # Panel inherits from QWidget
        new_panel = Panel(parent=insert_item,
                          splitter_pos=self.initialSplitterPosition)
        self.move_splitter.connect(new_panel.setSplitterPosition)
        new_panel.slider_position.connect(self.slotSplitterPosition)
        insert_item.setSizeHint(new_panel.sizeHint())
        insert_item.setFlags(insert_item.flags() | Qt.ItemIsAutoTristate)
        insert_item.setCheckState(Qt.PartiallyChecked)
        self.panels.insertItem(self.panels.currentRow() + 1, insert_item)
        self.panels.setItemWidget(insert_item, new_panel)
编辑:

根据实现事件过滤器的建议,我创建了表的以下子类

class ControlTable(QTableWidget):
    focusReceived = Signal()

    def __init__(self, parent=None):
        super().__init__()

    def focusInEvent(self, event):
        if event.type() == QFocusEvent.gotFocus:
            self.focusReceived.emit()
        QTableWidget.focusInEvent(self, event)
在我的panel函数中,我创建了一个信号和一个插槽来捕获该信号,并向主窗口发出一个信号,应使用该窗口选择QListWidgetItem

class Panel(QWidget):
    slider_position = Signal(int, int)
    select_me = Signal(QObject)

    def __init__(self, parent=None, splitter_pos=[]):
        # stuff
        self.table = ControlTable()
        self.table.focusReceived.connect(self.childWidgetFocus)
        # more stuff

    @Slot()
    def childWidgetFocus(self):
        parent = self.parent_item
        self.select_me.emit(parent)
在我的主窗口类中,我还添加了

def add_panel(self):
    insert_item = QListWidgetItem()
    new_panel = Panel(parent=insert_item,
                      splitter_pos=self.initialSplitterPosition)
    new_panel.parent_item = insert_item
    new_panel.select_me.connect(self.changeSelection)
    # more stuff

@Slot(QObject)
def changeSelection(self, item):
    item.setSelected(True)
当代码运行时,选择没有发生变化,我是否实现了错误的事件过滤器

编辑2:

让它工作起来,使用了错误的事件过滤器类型,我需要使用
QEvent.FocusIn
,但是现在我看了看我的代码,看了看我要覆盖的函数,如果语句是不必要的,那么它看起来是不必要的


我还必须将信号传递类型从QObject更改为QListWidgetItem。

一个可能但很长的方法是在项目小部件的每个子项上设置一个事件过滤器(在您的例子中是它的
面板
),并选择绑定到
父项的
QListWidgetItem
面板
)当焦点位于子元素上时,从该事件筛选器中

您可以将项目引用存储在
面板
小部件的
项目
属性中(您应该创建它),以简化项目选择。因此在
setItemWidget

new_panel.item = insert_item
在事件筛选器中,您可以发出
pyqtSignal
传递
self.parent().item
作为参数,并进一步处理它以选择相应的项

一些参考资料可以帮助您开始:


一个可能但很长的方法是在项目小部件的每个子部件(在您的例子中是其
面板
)上设置事件过滤器,并在焦点位于子元素时从该事件过滤器中选择绑定到
父项
面板
)的
QListWidgetItem

您可以将项目引用存储在
面板
小部件的
项目
属性中(您应该创建它),以简化项目选择。因此在
setItemWidget

new_panel.item = insert_item
在事件筛选器中,您可以发出
pyqtSignal
传递
self.parent().item
作为参数,并进一步处理它以选择相应的项

一些参考资料可以帮助您开始:


您是有意添加这一行的吗<代码>插入项目。设置检查状态(Qt.PartiallyChecked)
。这可能是您出现问题的原因,我在前面的故障排除工作中提到了这一点,但就我所知,出于我的目的,这没有什么区别。我只是通过注释这一行并重新运行来验证这一点。你是有意添加这一行的吗<代码>插入项目。设置检查状态(Qt.PartiallyChecked)。这可能是您出现问题的原因,我在前面的故障排除工作中提到了这一点,但就我所知,出于我的目的,这没有什么区别。我只是通过评论这一行并重新运行来验证这一点。我认为你的思路是正确的,但我不确定我的实现是否正确,我正在更新主要帖子以反映这些更改。我明白了,再次感谢你的帮助!将再次更新父帖子。我认为您的思路正确,但我不确定是否正确实施,我正在更新主帖子以反映更改。我知道了,再次感谢您的帮助!将再次更新父帖子。