获取 QTreeWidget 当前选中的单元格

Get currently selected cell of QTreeWidget

我想修改 QTreeWidget 使选定的单元格在按下回车键时可编辑,但保持选择为整行。

我做了一个 hacky 实现,找出最后一次点击的位置并保存值,然后将这些值发送到按键上的 edit_item 函数(也用于 itemDoubleClicked 信号)。虽然不是很好,但我想知道是否有更简单的方法。

郑重声明,点击一个项目仍然会选择整行。默认情况下它可能是隐藏行为,但在 Maya 中有一个可见的选择对象,即在按住鼠标按钮时移动的最后一个单元格。如果我能以某种方式访问​​它,我还可以添加行为以使用箭头键控制它。

这是所选单元格的示例:

到目前为止,这是我的代码:

class QTreeWidget(QtWidgets.QTreeWidget):

    returnPressed = QtCore.Signal(QTreeWidget, int)

    def __init__(self,  *args, **kwargs):
        QtWidgets.QTreeWidget.__init__(self, *args, **kwargs)

    def keyPressEvent(self, event):
        if event.key() == QtCore.Qt.Key_Return:
            self.returnPressed.emit(self._selected_item, self._selected_column)
        else:
            QtWidgets.QTreeWidget.keyPressEvent(self, event)

    def _mouse_pos_calculate(self, x_pos):
        """Find the currently selected column."""
        try:
            item = self.selectedItems()[0]
        except IndexError:
            item = None

        header = self.header()
        total_width = 0
        for i in range(self.columnCount()):
            total_width += header.sectionSize(i)
            if total_width > x_pos:
                return (item, i)

    def mousePressEvent(self, event):
        QtWidgets.QTreeWidget.mousePressEvent(self, event)
        self._selected_item, self._selected_column = self._mouse_pos_calculate(event.pos().x())

    def mouseReleaseEvent(self, event):
        QtWidgets.QTreeWidget.mouseReleaseEvent(self, event)
        self._selected_item, self._selected_column = self._mouse_pos_calculate(event.pos().x())

编辑:由于 eyllanesc

改进了功能
class QTreeWidget(QtWidgets.QTreeWidget):
    """Add ability to edit cells when pressing return."""
    itemEdit = QtCore.Signal(QtWidgets.QTreeWidgetItem, int)

    def __init__(self,  *args, **kwargs):
        QtWidgets.QTreeWidget.__init__(self, *args, **kwargs)

        self._last_item = None
        self._last_column = 0
        self.itemDoubleClicked.connect(self._edit_item_intercept)

    def _edit_item_intercept(self, item=None, column=None):
        if item is None:
            item = self._last_item
        if column is None:
            column = self._last_column
        self.itemEdit.emit(item, column)

    def _store_last_cell(self, pos):
        selected_item = self.itemAt(pos)
        if selected_item is None:
            return
        self._last_item = selected_item
        self._last_column = self.header().logicalIndexAt(pos.x())

    def keyPressEvent(self, event):
        if event.key() == QtCore.Qt.Key_Return:
            return self._edit_item_intercept()
        QtWidgets.QTreeWidget.keyPressEvent(self, event)

    def mouseMoveEvent(self, event):
        QtWidgets.QTreeWidget.mouseMoveEvent(self, event)
        self._store_last_cell(event.pos())

你做了很多不必要的计算,在下一部分我会展示一个更简洁的解决方案:

from PySide2 import QtCore, QtGui, QtWidgets


class QTreeWidget(QtWidgets.QTreeWidget):
    def __init__(self, *args, **kwargs):
        super(TreeWidget, self).__init__(*args, **kwargs)
        self.special_item = None
        self.special_col = 0

    def keyPressEvent(self, event):
        if event.key() == QtCore.Qt.Key_Return:
            self.editItem(self.special_item, self.special_col)
        QtWidgets.QTreeWidget.keyPressEvent(self, event)

    def editEnable(self, pos):
        press_item = self.itemAt(pos)
        if press_item is None:
            return
        if press_item is self.selectedItems()[0]:
            col = self.header().logicalIndexAt(pos.x())
            self.special_item = press_item
            self.special_col = col

    def mousePressEvent(self, event):
        QtWidgets.QTreeWidget.mousePressEvent(self, event)
        self.editEnable(event.pos())