2017-04-22 70 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

我明白了,再次感謝您的幫助!將再次更新父郵件。 –

相關問題