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

时间:2017-04-22 20:20:40

标签: python pyqt

我有一个GUI,其中QListWidget是中央小部件。 QListWidgetItems由包含Graphics区域和QTable的自定义小部件组成。

当我点击图形区域或表格时,未选择父级QListWidgetItem

参见我正在使用的GUI图片

Gui

顶部QListWidgetItem周围的红色边框表示当前选择的那个。

从第二个QListWidgetItem中表的Input中,您可以看到我在那里输入文本到表格小部件中。

如何点击该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)

在我的面板功能中,我创建了一个信号和一个插槽来捕获该信号并向MainWindow发出一个信号,应该选择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)

当代码运行时,选择的更改没有发生,我是否实现了错误的事件过滤器?

EDIT2:

搞定了,使用了错误的事件过滤器类型,我需要使用QEvent.FocusIn,但现在我查看我的代码,并查看我覆盖的函数,if if语句是它似乎是不必要的。

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

1 个答案:

答案 0 :(得分:0)

一种可能但很长的方法是在项目窗口小部件的每个子项上设置事件过滤器(在您的情况下为Panel)并选择QListWidgetItem边界当焦点在子元素上时,从该事件过滤器到parentPanel)。

您可以将项目引用存储在item小部件的Panel属性中(您应该创建它),以便更轻松地选择项目。所以在setItemWidget之前添加

new_panel.item = insert_item

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

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

How to change a parent widget's background when a child widget has focus?

相关问题