【问题标题】:DoubleClick event on QTreeView has no result when trying to capture mouse position尝试捕获鼠标位置时,QTreeView 上的 DoubleClick 事件没有结果
【发布时间】:2019-09-14 17:34:46
【问题描述】:

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

如果我连接双击信号而不捕获位置:

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

它可以工作,并打印 OK。

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


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)

但是双击同一个小部件没有结果

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

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

【问题讨论】:

    标签: python pyqt pyqt4 qtreeview


    【解决方案1】:

    我觉得奇怪的是,在您的第一个代码中打印“OK”,返回给我的是一个错误,因为 connect 也需要一个可调用的,但 print('OK') 返回的 None 不是可调用的。此外,mouseDoubleClickEvent 不是信号,而是再次确认我的陌生感的事件。

    相反,您必须使用返回与项目关联的QModelIndexdoubleClicked 信号,并且要获得您必须使用mapFromGlobal()viewport()viewport() 旁边的QCursor::pos() 的位置@。您还必须使用新的连接语法。

    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_())
    

    【讨论】:

    • 你好@eyllanesc,谢谢你的回复!我忽略了一个非常重要的细节,该项目使用了pyside,据此link QWidget 只有一个信号 customContextMenuRequested 这也解释了为什么我在使用 doubleClicked 时会出现属性错误。我想我必须使用 doubleClick 事件
    • @E_A 你指出的部分正确,部分正确,因为 QTreeView 是一个 QWidget,但它也是一个 QAbstractItemView,如果它具有 doubleClicked signal,则为后者。我已经更新了 PySide 的答案。
    • 是的,抱歉,我已设法修改解决方案以使其与 PySide 一起使用,但在此过程中,我混淆了树视图和包含它的 Widget,因此 doubleClicked 信号产生了错误。有用!谢谢!
    • @E_A 另一方面,对于下一个问题,使用适当的标签,如果您使用 pyside,则使用 pyside 标签,如果您使用 pyqt4,则使用 pqqt4 标签
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-31
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    • 2018-12-14
    • 2013-01-10
    相关资源
    最近更新 更多