Событие DoubleClick в QTreeView не дает результата при попытке зафиксировать положение мыши - PullRequest
3 голосов
/ 25 апреля 2019

Я работаю с Python 3.6 и pyqt 4.11. У меня есть два QTreeView, сложенных в виджет, оба они отображают некоторые пакетные задания, так что каждый шаг может расширяться для отображения всех функций. Я хочу иметь возможность дважды щелкнуть мышью по одной строке дерева и создать всплывающее диалоговое окно, где я могу редактировать параметры функции, по которой я дважды щелкнул.

Если я подключу сигнал двойного щелчка без захвата позиции:

self.connect(self.QTreeView, QtCore.SIGNAL('mouseDoubleClickEvent()'),print('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)

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) было бы способом сделать это, но, поскольку моя простая функция не вызывается вообще, должна быть какая-то другая проблема, которую я не вижу.

1 Ответ

2 голосов
/ 26 апреля 2019

Мне кажется странным, что в вашем первом коде напечатано «OK», что возвращает мне ошибку, потому что connect также ожидает вызываемый вызов, но print ('OK') возвращает None, который не является вызываемым.Кроме того, mouseDoubleClickEvent - это не сигнал, а событие, которое подтверждает мою странность.

Вместо этого вы должны использовать сигнал doubleClicked, который возвращает QModelIndex, связанный с элементом, и чтобы получить позицию, которую вынеобходимо использовать QCursor::pos() рядом с mapFromGlobal() из viewport() из QTreeView.Вы также должны использовать новый синтаксис соединения.

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 Version:

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