尝试捕获鼠标位置时,QTreeView 上的 DoubleClick 事件没有结果

DoubleClick event on QTreeView has no result when trying to capture mouse position

我正在使用 Python 3.6 和 pyqt 4.11。我有两个 QTreeViews 堆叠在一个小部件中,它们都显示一些批处理作业,因此每个步骤都可以展开以显示所有功能。我希望能够双击树视图的一行并生成一个弹出对话框,我可以在其中编辑我双击的函数的参数。

如果我没有捕获位置就连接双击信号:

self.connect(self.QTreeView, QtCore.SIGNAL('mouseDoubleClickEvent()'),print('OK'))

它工作正常并且打印了 OK。

然而,一旦我尝试捕捉光标位置,就再也没有任何反应。我已经尝试将整个小部件和 treeView 连接到一个简单的测试函数。它根本不起作用,连 OK 都打印不出来。


self.connect(self.QTreeView, QtCore.SIGNAL('mouseDoubleClickEvent(const QPoint &)'),self.showDlg)

def showDlg (self, point):
        print ('OK')
        treeidx=self.treeview.indexAt(point)
        print (treeidx)

右键单击整个 Widget 会触发 ContextMenu,它可以工作

self.QTreeWidget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)   

self.connect(self.QTreeWidget, QtCore.SIGNAL('customContextMenuRequested(const QPoint &)'), self.customMyContextMenu)

但是双击同一个 Widget 没有结果

self.connect(self.QTreeWidget, QtCore.SIGNAL('mouseDoubleClickEvent(const QPoint &)'),self.showDlg)

我想使用指针位置来了解必须在树视图的哪个叶子中发生更改,我想 treeview.indexAt(point) 将是这样做的方法,但由于我的简单函数根本没有被调用,所以一定有其他我没有看到的问题。

我觉得很奇怪,在你的第一个代码中打印了 "OK",returns 对我来说是一个错误,因为 connect 也需要一个可调用的,但是 print('OK') returns None 这不是可调用的。此外,mouseDoubleClickEvent不是一个信号,而是一个事件,再次证实了我的陌生。

相反,您必须使用 doubleClicked 信号表明 returns 与该项目关联的 QModelIndex,并且要获得位置,您必须接下来使用 QCursor::pos()QTreeViewviewport()mapFromGlobal()。您还必须使用新的连接语法。

from PyQt4 import QtCore, QtGui


def create_model(parent):
    model = QtGui.QStandardItemModel(parent)
    for i in range(3):
        parent_item = QtGui.QStandardItem("Family {}".format(i))
        for j in range(3):
            child1 = QtGui.QStandardItem("Child {}".format(i * 3 + j))
            child2 = QtGui.QStandardItem("row: {}, col: {}".format(i, j + 1))
            child3 = QtGui.QStandardItem("row: {}, col: {}".format(i, j + 2))
        parent_item.appendRow([child1, child2, child3])
        model.appendRow(parent_item)
    return model


class Widget(QtGui.QWidget):
    def __init__(self, parent=None):
        super(Widget, self).__init__(parent)
        self._tree_view = QtGui.QTreeView()
        self._tree_view.setModel(create_model(self))
        self._tree_view.expandAll()
        lay = QtGui.QVBoxLayout(self)
        lay.addWidget(self._tree_view)

        self._tree_view.doubleClicked.connect(self.on_doubleClicked)

    @QtCore.pyqtSlot("QModelIndex")
    def on_doubleClicked(self, ix):
        print(ix.data())

        gp = QtGui.QCursor.pos()
        lp = self._tree_view.viewport().mapFromGlobal(gp)
        ix_ = self._tree_view.indexAt(lp)
        if ix_.isValid():
            print(ix_.data())


if __name__ == "__main__":
    import sys

    app = QtGui.QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())

PySide 版本:

from PySide import QtCore, QtGui


def create_model(parent):
    model = QtGui.QStandardItemModel(parent)
    for i in range(3):
        parent_item = QtGui.QStandardItem("Family {}".format(i))
        for j in range(3):
            child1 = QtGui.QStandardItem("Child {}".format(i * 3 + j))
            child2 = QtGui.QStandardItem("row: {}, col: {}".format(i, j + 1))
            child3 = QtGui.QStandardItem("row: {}, col: {}".format(i, j + 2))
        parent_item.appendRow([child1, child2, child3])
        model.appendRow(parent_item)
    return model


class Widget(QtGui.QWidget):
    def __init__(self, parent=None):
        super(Widget, self).__init__(parent)
        self._tree_view = QtGui.QTreeView()
        self._tree_view.setModel(create_model(self))
        self._tree_view.expandAll()
        lay = QtGui.QVBoxLayout(self)
        lay.addWidget(self._tree_view)

        self._tree_view.doubleClicked.connect(self.on_doubleClicked)

    @QtCore.Slot("QModelIndex")
    def on_doubleClicked(self, ix):
        print(ix.data())

        gp = QtGui.QCursor.pos()
        lp = self._tree_view.viewport().mapFromGlobal(gp)
        ix_ = self._tree_view.indexAt(lp)
        if ix_.isValid():
            print(ix_.data())


if __name__ == "__main__":
    import sys

    app = QtGui.QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())