2015-10-17 148 views
2

所以我一直在嘗試實現一個適當的TreeView,根據用戶輸入顯示目錄和文件 - 我允許用戶遞歸或以其他方式添加目錄和文件到他的「項目」之後,我創建了我自己的該項目內容的樹視圖。PyQt treeview編輯文本雙擊

現在,我的問題是,儘管我在這個主題上找到的大多數文檔和其他問題似乎都想禁用treeview項目的可編輯性,但我試圖(和失敗)找到一種方法來啓用它。我想讓用戶能夠雙擊我的樹形視圖中任何列的任何單元格,然後編輯其內容。有誰知道如何做到這一點?

下面是我用來在tabView Widget中生成一個選項卡的代碼,之後我添加了TreeView。 TreeView的項目稍後通過AddParent和AddChild方法添加。

class treeTab(QtWidgets.QWidget): 
def __init__(self,core,main,label): 
    super (treeTab,self).__init__() 
    self.label = label 
    self.core = core 

    self.sizes = core.UISizes 

    self.tab_sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding,QtWidgets.QSizePolicy.Expanding) 

    self.tree = QtWidgets.QTreeWidget(self) 
    self.tree.setColumnCount(len(self.sizes.projectTreeColumnLabels)) 
    self.tree.setHeaderLabels(self.sizes.projectTreeColumnLabels) 
    self.tree.setSizePolicy(self.tab_sizePolicy) 
    self.tree_layout = QtWidgets.QGridLayout() 
    self.tree_layout.objectName = self.label + "TreeGridLayout" 
    self.tree.setLayout(self.tree_layout) 
    self.treeroot = self.tree.invisibleRootItem() 
    self.tree.setSelectionMode(Qt.QAbstractItemView.ContiguousSelection) 

def addParent(self, parent, column, title, data): 
    item = QtWidgets.QTreeWidgetItem(parent, [title]) 
    item.setData(column, QtCore.Qt.UserRole, data) 
    item.setChildIndicatorPolicy(QtWidgets.QTreeWidgetItem.ShowIndicator) 
    item.setExpanded (True) 
    return item 

def addChild(self, parent, column, title, data): 
    item = QtWidgets.QTreeWidgetItem(parent, [title]) 
    item.setData(column, QtCore.Qt.UserRole, data) 
    item.setText(1,data.print_tags()) 
    item.setText(2,data.category.name) 
    item.setText(3,data.format) 
    item.setCheckState (column, QtCore.Qt.Unchecked) 
    item.setFlags(item.flags() or QtCore.Qt.ItemIsEditable) 
    return item 

回答

2

您有困惑binary operators and Boolean operators。布爾運算符(例如andor)與布爾值(例如TrueFalse)一起使用以生成單個TrueFalse,一旦評估表達式。

但是,標誌和不是布爾值。它們是2的冪(或只有一個位集的二進制數)的整數,這樣它們可以組合成一個整數,表示每個標記是啓用還是禁用。例如,2以二進制表示爲0b010。 4表示爲0b100。如果你按位或這些一起,你得到0b110,表示標誌等於2和標誌等於4被設置。然而,等於1的標誌未被設置(0b110中的0)。

總之,你應該用位或操作員(|)設置的標誌:

item.setFlags(item.flags() | QtCore.Qt.ItemIsEditable) 
1

所以我設法弄清楚這一個 - 它竟然是在年底相當簡單:)

爲了創建一個'可編輯'的TreeView項目,您可以在其中雙擊特定項目的文本進行編輯,您只需將包含在該項目特定列中的小部件更改爲刪除QLineEdit小部件本身在按下輸入。造成這種情況的代碼如下:

這是對雙擊事件連接到獲取當前選定的項目和一個QLineEdit的小部件替換它的方法的代碼:

self.tree.itemDoubleClicked.connect(self.editItem) 

def editItem(self,*args): 
    itm = self.tree.itemFromIndex(self.tree.selectedIndexes()[0]) 
    column = self.tree.currentColumn() 
    edit = QtWidgets.QLineEdit() 
    edit.returnPressed.connect(lambda*_:self.project.setData(column,edit.text(),itm,column,self.tree)) 
    edit.returnPressed.connect(lambda*_:self.update()) 
    self.tree.setItemWidget(itm,column,edit) 

尤其要注意組合下面的代碼:

itm = self.tree.itemFromIndex(self.tree.selectedIndexes()[0]) 
    column = self.tree.currentColumn() 

此代碼實際上使你倆行和當前選中的項目,如果要單獨編輯欄中的項目,這是有用的列。

現在你會問自己爲什麼我要將這麼多參數傳遞給'setData'方法:這純粹是爲了我的特定項目的目的,所以不要擔心。 'returnPressed'事件只需連接到正確的方法來處理它包含的任何數據,然後刪除它自己。在我的代碼,這看起來是這樣的:

def setData(self,dataTypeIndex,data,item,column,tree): 
    if dataTypeIndex == 0: 
     # filename 
     self.name = data 
    elif dataTypeIndex == 1: 
     # tags 
     data = data.split(",") 
     self.tags = [] 
     for tag in data: 
      self.tags.append(Tag(tag)) 
    elif dataTypeIndex == 2: 
     # category 
     self.category.name = data 

    tree.setItemWidget(item,column,None) 

的代碼最後一行(tree.setItemWidget(項目,列,無))是其中QLineEdit的是unparented,因此有效地去除。

+0

很簡單嗎?你真正需要做的就是用'|'替換'或',按照three_pineapples的答案... – ekhumoro

+0

在任何情況下,我的方式可能會更長,但它也可以工作 – MaVCArt

+0

事實上,使用我的方法,你可以實際上捕捉到雙擊事件並阻止某些列可編輯,或者實現編輯某個列值的不同方法 - 比如,在雙擊時彈出一個新窗口,而不是直接編輯它包含的任何值。這打開了幾個選項,簡單的文本編輯防止:) – MaVCArt