2013-03-07 255 views
2

感謝this thread,我可以將小部件添加到view的頂級項目的第二個或更後一列QAbstractItemView(在我的示例中爲QTreeView)。在QTreeView上設置小部件對象

但是可以將小部件添加到子項目嗎?

這是我已經試過這部分進展順利:

#!/usr/bin/env python 
import os 

from PyQt4.QtCore import QModelIndex, Qt 
from PyQt4.QtGui import QApplication, QItemSelectionModel, \ 
         QPushButton, QStandardItem, \ 
         QStandardItemModel, QTreeView 
from PyQt4.uic import loadUi 


class PrvTreeviewNest(QTreeView): 
    def __init__(self): 
     super(PrvTreeviewNest, self).__init__() 

     loadUi('/home/user/yourproject/resource/treeview_nest.ui') 

     # row can be 0 even when it's more than 0. 
     self._datamodel = QStandardItemModel(0, 2) 
     self.setModel(self._datamodel) 

     for i in range(4): 
      self._add_widget(i + 1) 

     self.show() 

    def _add_widget(self, n): 
     std_item = QStandardItem('{}th item'.format(n)) 
     self._datamodel.setItem(n, 0, std_item) 

     node_widget = QPushButton('{}th button'.format(n)) 
     qindex_widget = self._datamodel.index(n, 1, QModelIndex()) 
     self.setIndexWidget(qindex_widget, node_widget) 

     if n == 2: 
      std_item_child = QStandardItem('child') 
      std_item.appendRow(std_item_child) 

      node_widget_child = QPushButton('petit button') 
      qindex_widget_child = self._datamodel.index(n, 1, QModelIndex()) 
      self.setIndexWidget(qindex_widget_child, node_widget_child) 

if __name__ == '__main__': 
    import sys 
    app = QApplication(sys.argv) 
    # window = TreeviewWidgetSelectProve() 
    window = PrvTreeviewNest() 
    # window = TreeviewWidgetSelectProve() 
    window.resize(320, 240) 
    # window.show(); 
    window.setWindowTitle(
     QApplication.translate("toplevel", "Top-level widget")) 
    # window.add_cols() 

    sys.exit(app.exec_()) 

treeview_nest.ui可用。

您在下圖中看到,項目child未顯示按鈕,並且其父按鈕被覆蓋。顯然我不知道如何爲它編寫代碼。

enter image description here


更新)我想出如何小部件添加到孩子。狡猾,使用QStandardItem.insertRow結合索引做的工作。在我上面的示例代碼,替換爲以下_add_widget

def _add_widget(self, n): 
     item_toplevel = QStandardItem('{}th item'.format(n)) 
     self._datamodel.setItem(n, 0, item_toplevel) 

     widget_toplevel = QPushButton('{}th button'.format(n)) 
     qindex_toplevel = self._datamodel.index(n, 1, QModelIndex()) 
     self.setIndexWidget(qindex_toplevel, widget_toplevel) 

     if n == 2: 
      item_child_col0 = QStandardItem('child col0') 
      item_child_col1 = QStandardItem('child col1') 
      #item_toplevel.appendRow(item_child_col0) 

      item_toplevel.insertRow(0, [item_child_col0, item_child_col1]) 

      widget_child = QPushButton('child widget') 
      qindex_child = item_child_col1.index() 
      self.setIndexWidget(qindex_child, widget_child) 

我敢肯定,這是不是最好的/理想的設計方式,但似乎爲我工作。我在@Plulucious的回答之後提出了我的想法。謝謝!

enter image description here

回答

1

你的錯誤是在這條線:

qindex_widget_child = self._datamodel.index(n, 1, QModelIndex()) 
self.setIndexWidget(qindex_widget_child, node_widget_child) 

它給你排索引2列的模型,這是「帖後項目」的1 ,而不是你的孩子。您的孩子在std_item的第1行第1列。在Qt中,尤其是在QStandardItemModel中,兒童是相對於他們的父親存儲的,而不是相對於模型。

我不夠熟悉PyQt的給你確切的代碼,但你應該能夠做這樣的事情:

qindex_widget_child = std_item_child.index(QModelIndex()) 
self.setIndexWidget(qindex_widget_child, node_widget_child) 

或像這樣:

qindex_widget_child = std_item.child(0, 1).index(QModelIndex()) 
self.setIndexWidget(qindex_widget_child, node_widget_child) 
+0

謝謝,我最終選擇你作爲答案,因爲我得到了啓發,並提出了一個解決方法,因爲我修改了我的問題。評論你的想法,不幸的是,前者在列0上添加小部件。後者中的方法不存在(pyqt主要遵循C++ api)。 – IsaacS 2013-03-08 22:26:50

+0

我再次查看代碼並將第二個選項修改爲希望更有可能工作的東西。我對那個人有點sl。。很高興你能夠得到一些有用的東西! – Phlucious 2013-03-08 23:04:47

+0

你的解決方案或多或少是我在C++中所做的,所以我不會說它是馬虎。對於是否可以先調用孩子(0,1)函數而不先指定孩子,我有點朦朧! – Phlucious 2013-03-08 23:07:36

相關問題