2017-04-22 128 views
1

我有一个GUI,其中一个QListWidget是中央部件。 QListWidgetItems由包含Graphics区域和QTable的自定义小部件组成。如何在点击子窗口小部件时选择父QListWidgetItem?

当我点击图形区域,或放在桌子上,家长QListWidgetItem没有选择我的工作

Gui

红色边框的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) 

在我的面板功能中,我创建了一个信号和一个插槽来捕获该信号,并向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,但现在,我看我的代码,看着我重写功能,如果语句这似乎是不必要的。我也不得不将信号传递类型从QObject更改为QListWidgetItem。

+0

你有意添加这一行吗? ''insert_item.setCheckState(Qt.PartiallyChecked)''。这可能是你的问题的原因 – Luchko

+0

我把这一行作为早期故障排除工作的一部分,但就我的目的而言,这并没有什么区别。我只是通过评论这条线并重新运行来验证。 –

回答

0

一种可能,但很长的路可以设定在该项目的小部件的每个孩子的事件过滤器(在你的情况下,其Panel),然后选择从该事件过滤器时,对焦界限的parentPanel)的QListWidgetItem在子元素上。

您可以在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?

+0

我认为你在正确的轨道上,但我不确定我是否正确实施,我正在更新主帖以反映更改。 –

+1

我明白了,再次感谢您的帮助!将再次更新父邮件。 –

相关问题