如何通过点击QTreeWidgetItem的子部件选择它

1 投票
1 回答
2315 浏览
提问于 2025-04-18 16:46

这段代码创建了一个 QTreeWidget,里面有 QComboBoxQLineEdit 作为 item widgets(项目小部件)。如果按照以下步骤操作:

  1. 在这个对话框打开后...

  2. 点击某个项目(不要点击它的小部件)。这个项目的背景颜色会变成蓝色。

  3. 现在点击另一个项目的小部件(可以是下拉框或文本框)。

这个小部件所对应的项目会被选中(变成蓝色)。如果你尝试通过点击它的小部件来选择其他项目,会失败。你必须关闭对话框然后再重新打开,因为这种情况只会发生一次。

有没有办法让这个功能持续有效... 也就是说,每次点击一个小部件时,包含它的项目也会被选中,这样就能给人一种项目和它的小部件是同一个东西的感觉。因为按照默认设置,我必须点击项目本身才能让它被选中。

enter image description here

    from PyQt4 import QtCore, QtGui
    app = QtGui.QApplication([])

    class Tree(QtGui.QTreeWidget):
        def __init__(self, *args, **kwargs):
            super(Tree, self).__init__()
            for each in ['Item_1','Item_2','Item_3','Item_4','Item_5']:
                item=QtGui.QTreeWidgetItem()
                item.setText(0, each)
                self.addTopLevelItem(item)
                self.setItemWidget(item, 1, QtGui.QComboBox())
                self.setItemWidget(item, 2, QtGui.QLineEdit())
            self.setColumnCount(5)
            self.resize(360,240)
            self.show()

    tree=Tree()
    sys.exit(app.exec_())

1 个回答

2

你需要使用 mousePressEvent(再次强调)来处理当小部件中的项目被按下时的事件;

.
.
.
comboBox = QtGui.QComboBox()
lineEdit = QtGui.QLineEdit()
self.setItemWidget(item, 1, comboBox)
self.setItemWidget(item, 2, lineEdit)
# Set new event
comboBox.mousePressEvent = partial(self.mousePressEventChild, currentQTreeWidgetItem = item, child = comboBox)
lineEdit.mousePressEvent = partial(self.mousePressEventChild, currentQTreeWidgetItem = item, child = lineEdit)
.
.
.

def mousePressEventChild (self, QMouseEvent, currentQTreeWidgetItem = None, child = None):
    if isinstance(currentQTreeWidgetItem, QtGui.QTreeWidgetItem): # <- Check this widget has QTreeWidgetItem.
        self.setCurrentItem(currentQTreeWidgetItem) # <- set current index by QTreeWidgetItem.
    super(child.__class__, child).mousePressEvent(QMouseEvent) # <- Default old mouse press event.

完整示例代码;

import sys
from functools import partial
from PyQt4 import QtCore, QtGui

class Tree(QtGui.QTreeWidget):
    def __init__(self, *args, **kwargs):
        super(Tree, self).__init__()
        for each in ['Item_1','Item_2','Item_3','Item_4','Item_5']:
            item=QtGui.QTreeWidgetItem([each])
            self.addTopLevelItem(item)
            comboBox = QtGui.QComboBox()
            lineEdit = QtGui.QLineEdit()
            self.setItemWidget(item, 1, comboBox)
            self.setItemWidget(item, 2, lineEdit)
            comboBox.mousePressEvent = partial(self.mousePressEventChild, currentQTreeWidgetItem = item, child = comboBox)
            lineEdit.mousePressEvent = partial(self.mousePressEventChild, currentQTreeWidgetItem = item, child = lineEdit)
        self.setColumnCount(5)
        self.resize(360,240)
        self.show()

    def mousePressEventChild (self, QMouseEvent, currentQTreeWidgetItem = None, child = None):
        if isinstance(currentQTreeWidgetItem, QtGui.QTreeWidgetItem):
            self.setCurrentItem(currentQTreeWidgetItem)
        super(child.__class__, child).mousePressEvent(QMouseEvent)

app = QtGui.QApplication([])
tree=Tree()
sys.exit(app.exec_())

点击事件参考 : http://pyqt.sourceforge.net/Docs/PyQt4/qwidget.html#mousePressEvent


祝好,

撰写回答