2015-10-17 146 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