【问题标题】:How to disable a row in QTreeview?如何禁用 QTreeview 中的一行?
【发布时间】:2016-08-30 12:45:35
【问题描述】:

我继承自QtCore.QAbstractItemModel,显示一个树形结构。

下面我尝试为每个节点/行添加“启用/禁用”功能。

有谁知道如何禁用 QTreeView Widget 中的某些

为了更清楚,“禁用”是指变灰,仍然可以右键单击,可见,不可编辑,如图所示。

【问题讨论】:

  • 你已经看过这里了吗:doc.qt.io/qt-4.8/qtreewidget.html 哎呀,在我完成之前发布了……这里:doc.qt.io/qt-4.8/qtreewidgetitem.html 看看itemAt() 中的QTreeWidgetsetDisabled 中的QTreeWidgetItem
  • @busfault OP 正在使用 qabstractitemmodel ...也就是说,OP 应该更清楚:“禁用”是指显示但不能选择吗?还是不显示?包括一个最小的自包含示例可能会有所帮助(stackoverflow.com/help/mcve)。虽然我认为最重要的是包括更精确地说明“禁用”的含义。
  • 谢谢大家的回复!很抱歉不清楚。我试图使用层次结构来表示父子关系。如果我右键单击joint2,我有两个动作“启用,禁用”。我单击“禁用”和joint2,它的子项显示为灰色,但可见且可右键单击。然后,如果我右键单击joint2 并选择“启用”,joint2 及其子项将变为绿色并且再次可选择/可编辑。

标签: user-interface pyqt treeview pyside


【解决方案1】:

我使用的是树视图,而不是 QTreeWidget

我的代码:

import sys
from PyQt4 import QtGui
from PyQt4 import QtCore

class TREEWIDGET (QtGui.QWidget):

def __init__(self):
    super(TREEWIDGET, self).__init__()        
    self.initUI()        

def initUI(self):

    self.treeView = QtGui.QTreeView (self)
    self.treeView.setGeometry(QtCore.QRect(10, 10, 311, 321))
    self.treeView.setObjectName('treeWidget')

    self.model = QtGui.QStandardItemModel()
    self.addItems(self.model)
    self.treeView.setModel(self.model)
    self.treeView.expandAll ()
    self.treeView.setSelectionMode (QtGui.QAbstractItemView.ExtendedSelection)

    self.button_disable = QtGui.QPushButton(self)
    self.button_disable.setGeometry(QtCore.QRect(20, 340, 121, 23))
    self.button_disable.setObjectName('pushButton')
    self.button_disable.setText ('Disable')

    self.button_enable = QtGui.QPushButton(self)
    self.button_enable.setGeometry(QtCore.QRect(160, 340, 111, 23))
    self.button_enable.setObjectName('pushButton')
    self.button_enable.setText ('Ensable All')

    self.button_disable.clicked.connect (self.disable)
    self.button_enable.clicked.connect (self.enable)


    self.resize(350, 400)
    #self.addItems () 
    self.show()            

def addItems (self, parentWidget) :
    rootA        = QtGui.QStandardItem ('Joint1')
    parentWidget.appendRow (rootA)         
    cParent     = rootA      

    for loop in range (2, 6) :
        child   = QtGui.QStandardItem ('Joint' + str(loop))
        cParent.appendRow (child)         
        cParent     = child

    rootB        = QtGui.QStandardItem ('Joint_1')
    parentWidget.appendRow (rootB)         
    cParent     = rootB      

    for loop in range (2, 6) :
        child   = QtGui.QStandardItem ('Joint_' + str(loop))
        cParent.appendRow (child)         
        cParent     = child


def disable (self) :        
    selectedItem    = self.treeView.selectedIndexes  ()        
    for eachItem in selectedItem :   
        print   eachItem   
        currentItem     = eachItem.model().itemFromIndex(eachItem)
        currentItem.setEnabled(0)

def enable (self) :
    self.allItemElements    = [] 
    model           = self.treeView.model()        
    widget          = model.invisibleRootItem ()        
    existsItems     = self.collectItems (widget)

    for eachItem in existsItems :   
        eachItem.setEnabled(1)


def collectItems (self, widget) :
    itemCount   = widget.rowCount()         
    for itLoop in range (0, itemCount, 1) :            
        self.allItemElements.append (widget.child(itLoop))
        self.collectItems (widget.child(itLoop))                       
    return  self.allItemElements

def main():

    app = QtGui.QApplication(sys.argv)
    ex = TREEWIDGET()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

【讨论】:

  • 嗨,苏宾。再次感谢您的帮助!它非常接近我的需要!但是,一旦我禁用某个项目,我的右键单击功能就无法再在该项目上触发。但是,我还是树视图的新手,感谢您与我分享您的知识!
【解决方案2】:

这会禁用所有子级的行(与其他答案不同)。

import sys
from PyQt4 import QtGui
from PyQt4 import QtCore

class TREEWIDGET (QtGui.QWidget):

    def __init__(self):
        super(TREEWIDGET, self).__init__()        
        self.initUI()        

    def initUI(self):         
        self.treeWidget = QtGui.QTreeWidget(self)
        self.treeWidget.setGeometry(QtCore.QRect(10, 10, 311, 321))
        self.treeWidget.setObjectName('treeWidget')
        self.treeWidget.setSelectionMode (QtGui.QAbstractItemView.ExtendedSelection)

        self.button_disable = QtGui.QPushButton(self)
        self.button_disable.setGeometry(QtCore.QRect(20, 340, 121, 23))
        self.button_disable.setObjectName('pushButton')
        self.button_disable.setText ('Disable')

        self.button_enable = QtGui.QPushButton(self)
        self.button_enable.setGeometry(QtCore.QRect(160, 340, 111, 23))
        self.button_enable.setObjectName('pushButton')
        self.button_enable.setText ('Ensable All')

        self.button_disable.clicked.connect (self.disable)
        self.button_enable.clicked.connect (self.enable)

        self.resize(350, 400)
        self.addItems () 
        self.show()          

    def addItems (self) :
        parentA = QtGui.QTreeWidgetItem (self.treeWidget)
        parentA.setText (0, 'Joint1')   
        parentA.setExpanded (1)    
        cParentA    = parentA        
        for loop in range (2, 6) :
            childA = QtGui.QTreeWidgetItem (cParentA)
            childA.setText (0, 'Joint' + str(loop)) 
            childA.setExpanded (1)
            cParentA     = childA

        parentB = QtGui.QTreeWidgetItem (self.treeWidget)
        parentB.setText (0, 'Joint_1') 
        parentB.setExpanded (1)    
        cParentB     = parentB        
        for loop in range (2, 6) :
            childB = QtGui.QTreeWidgetItem (cParentB)
            childB.setText (0, 'Joint_' + str(loop))
            childB.setExpanded (1)
            cParentB     = childB        

    def disable (self) :        
        selectedItem    = self.treeWidget.selectedItems ()
        for eachItem in selectedItem :
            eachItem.setDisabled (1)            
            eachItem.setSelected (0)     

    def enable (self) :  
        self.allItemElements    = [] 
        widget              = self.treeWidget.invisibleRootItem()
        existsItems         = self.collectItems (widget)          
        if existsItems :  
            for eachItem in existsItems :
                eachItem.setDisabled (0)         

    def collectItems (self, widget) :            
        itemCount           = widget.childCount ()       
        for itLoop in range (0, itemCount, 1) :
            self.allItemElements.append (widget.child(itLoop))
            self.collectItems (widget.child(itLoop))                       
        return  self.allItemElements

def main():

    app = QtGui.QApplication(sys.argv)
    ex = TREEWIDGET()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

【讨论】:

  • 这与您发布的其他答案有何不同?不知道为什么你有两个答案 Subin...
  • 在第一个代码最后一些行丢失,这就是我再次发布的原因。与其他没有什么不同。如果您同时检查两者,您可以理解。在第二个代码中,我附加了下面的代码。 def main(): app = QtGui.QApplication(sys.argv) ex = TREEWIDGET() sys.exit(app.exec_()) if name == 'main ': main()
  • 你应该删除错误的答案然后。将来,只需编辑您的答案以更正它,不要放新答案。这就是堆栈溢出的美妙之处!我们想要的是一个带有完整解决方案的单一答案...您可以编辑一个答案来做到这一点,然后删除另一个答案吗?
  • 这段代码更像问题中的图片。干得好。
【解决方案3】:

覆盖QAbstractItemModel 后代的flags 方法。像这样的:

def flags(self, index):

    if not index.isValid():
        return 0

    # Disable even rows, enable odd rows
    if index.row() % 2 == 0:
        return QtCore.Qt.NoItemFlags
    else:
        return QtCore.Qt.ItemIsEnabled

【讨论】:

    【解决方案4】:
    import sys
    from PyQt4 import QtGui
    from PyQt4 import QtCore
    
    class TREEWIDGET (QtGui.QWidget):
    
        def __init__(self):
            super(TREEWIDGET, self).__init__()        
            self.initUI()        
    
        def initUI(self):         
            self.treeWidget = QtGui.QTreeWidget(self)
            self.treeWidget.setGeometry(QtCore.QRect(10, 10, 311, 321))
            self.treeWidget.setObjectName('treeWidget')
            self.treeWidget.setSelectionMode (QtGui.QAbstractItemView.ExtendedSelection)
    
            self.button_disable = QtGui.QPushButton(self)
            self.button_disable.setGeometry(QtCore.QRect(20, 340, 121, 23))
            self.button_disable.setObjectName('pushButton')
            self.button_disable.setText ('Disable')
    
            self.button_enable = QtGui.QPushButton(self)
            self.button_enable.setGeometry(QtCore.QRect(160, 340, 111, 23))
            self.button_enable.setObjectName('pushButton')
            self.button_enable.setText ('Ensable All')
    
            self.button_disable.clicked.connect (self.disable)
            self.button_enable.clicked.connect (self.enable)
    
            self.resize(350, 400)
            self.addItems () 
            self.show()          
    
        def addItems (self) :
            parentA = QtGui.QTreeWidgetItem (self.treeWidget)
            parentA.setText (0, 'Joint1')   
            parentA.setExpanded (1)    
            cParentA    = parentA        
            for loop in range (2, 6) :
                childA = QtGui.QTreeWidgetItem (cParentA)
                childA.setText (0, 'Joint' + str(loop)) 
                childA.setExpanded (1)
                cParentA     = childA
    
            parentB = QtGui.QTreeWidgetItem (self.treeWidget)
            parentB.setText (0, 'Joint_1') 
            parentB.setExpanded (1)    
            cParentB     = parentB        
            for loop in range (2, 6) :
                childB = QtGui.QTreeWidgetItem (cParentB)
                childB.setText (0, 'Joint_' + str(loop))
                childB.setExpanded (1)
                cParentB     = childB        
    
        def disable (self) :        
            selectedItem    = self.treeWidget.selectedItems ()
            for eachItem in selectedItem :
                eachItem.setDisabled (1)            
                eachItem.setSelected (0)     
    
        def enable (self) :  
            self.allItemElements    = [] 
            widget              = self.treeWidget.invisibleRootItem()
            existsItems         = self.collectItems (widget)          
            if existsItems :  
                for eachItem in existsItems :
                    eachItem.setDisabled (0)         
    
        def collectItems (self, widget) :            
            itemCount           = widget.childCount ()       
            for itLoop in range (0, itemCount, 1) :
                self.allItemElements.append (widget.child(itLoop))
                self.collectItems (widget.child(itLoop))                       
            return  self.allItemElements
    

    【讨论】:

    • 苏斌,感谢您的回复! :) 与我最初的想法不同的一件事是,我正在使用 QTreeView 而您的代码正在使用 QTreeWidget。我正在尝试实现您的 disable() 方法的功能,但使用 QTreeView 进行显示。这就是我获得物品的方式。项目 = self.window.treeView.selectedIndexes()[0].internalPointer()。并且 QModelIndex() 没有 setDisable() 函数。
    • 给我时间我会帮你的。
    猜你喜欢
    • 1970-01-01
    • 2022-09-28
    • 1970-01-01
    • 1970-01-01
    • 2012-02-20
    • 1970-01-01
    • 1970-01-01
    • 2012-09-22
    • 1970-01-01
    相关资源
    最近更新 更多