Python:PyQt QTreeview 示例 - 选择

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23993895/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 03:47:21  来源:igfitidea点击:

Python: PyQt QTreeview example - selection

pythonqttreeqtreeview

提问by Harry Lime

I'm using Python 2.7 and Qt designer and I'm new to MVC: I have a View completed within Qt to give me a directory tree list, and the controller in place to run things. My question is:

我正在使用 Python 2.7 和 Qt 设计器,并且我是 MVC 的新手:我在 Qt 中完成了一个视图,它为我提供了一个目录树列表,以及适当的控制器来运行东西。我的问题是:

Given a Qtree view, how may I obtain a directory once a dir is selected?

给定 Qtree 视图,选择目录后如何获取目录?

enter image description here

在此处输入图片说明

Code snap shot is below, I suspect it's SIGNAL(..) though I'm unsure:

代码快照如下,我怀疑它是 SIGNAL(..) 虽然我不确定:

class Main(QtGui.QMainWindow):
  plot = pyqtSignal()

  def __init__(self):
    QtGui.QMainWindow.__init__(self)
    self.ui = Ui_MainWindow()
    self.ui.setupUi(self)

    # create model
    model = QtGui.QFileSystemModel()
    model.setRootPath( QtCore.QDir.currentPath() )

    # set the model
    self.ui.treeView.setModel(model)

    **QtCore.QObject.connect(self.ui.treeView, QtCore.SIGNAL('clicked()'), self.test)**

  def test(self):
    print "hello!"

采纳答案by Raydel Miranda

The signal you're looking for is selectionChangedemmited by the selectionModelowned by your tree. This signal is emmited with the selecteditem as first argument and the deselectedas second, both are instances of QItemSelection.

您正在寻找的信号是由您的树拥有的selectionModel发出的selectionChanged。此信号以选定项作为第一个参数和取消选定项作为第二个参数发出,两者都是QItemSelection 的实例。

So you might want to change the line:

所以你可能想改变这一行:

QtCore.QObject.connect(self.ui.treeView, QtCore.SIGNAL('clicked()'), self.test)

to

QtCore.QObject.connect(self.ui.treeView.selectionModel(), QtCore.SIGNAL('selectionChanged()'), self.test)

Also I recommend you to use the new style for signals and slots. Redefine your testfunction as:

此外,我建议您对信号和插槽使用新样式。将您的test功能重新定义为:

 @QtCore.pyqtSlot("QItemSelection, QItemSelection")
 def test(self, selected, deselected):
     print("hello!")
     print(selected)
     print(deselected)

Here you have a working example:

这里有一个工作示例:

from PyQt4 import QtGui
from PyQt4 import QtCore

class Main(QtGui.QTreeView):

  def __init__(self):

    QtGui.QTreeView.__init__(self)
    model = QtGui.QFileSystemModel()
    model.setRootPath( QtCore.QDir.currentPath() )
    self.setModel(model)
    QtCore.QObject.connect(self.selectionModel(), QtCore.SIGNAL('selectionChanged(QItemSelection, QItemSelection)'), self.test)

  @QtCore.pyqtSlot("QItemSelection, QItemSelection")
  def test(self, selected, deselected):
      print("hello!")
      print(selected)
      print(deselected)

if __name__ == '__main__':
    import sys
    app = QtGui.QApplication(sys.argv)
    w = Main()
    w.show()
    sys.exit(app.exec_())

PyQt5

PyQt5

In PyQt5 is a little bit different (thanks to Carel and saldenisov for comments and aswer.)

在 PyQt5 中有点不同(感谢 Carel 和 saldenisov 的评论和回答。)

... connect moved from being an object method to a method acting upon the attribute when PyQt went from 4 to 5

... 当 PyQt 从 4 变为 5 时,connect 从对象方法转变为作用于属性的方法

So instead the known:

所以取而代之的是已知的:

QtCore.QObject.connect(self.ui.treeView, QtCore.SIGNAL('clicked()'), self.test)

now you write:

现在你写:

class Main(QTreeView):
    def __init__(self):
        # ...  
        self.setModel(model)
        self.doubleClicked.connect(self.test)  # Note that the the signal is now a attribute of the widget.

Here is a the example (by saldenisov) using PyQt5.

这是使用 PyQt5 的示例(由 saldenisov)。

from PyQt5.QtWidgets import QTreeView,QFileSystemModel,QApplication

class Main(QTreeView):
    def __init__(self):
        QTreeView.__init__(self)
        model = QFileSystemModel()
        model.setRootPath('C:\')
        self.setModel(model)
        self.doubleClicked.connect(self.test)

    def test(self, signal):
        file_path=self.model().filePath(signal)
        print(file_path)


if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    w = Main()
    w.show()
    sys.exit(app.exec_())

回答by ngulam

If I understand the question correctly you would like the directory or file name selected.

如果我正确理解了问题,您希望选择目录或文件名。

This is what I do:

这就是我所做的:

from PyQt4 import QtGui
from PyQt4 import QtCore

# ---------------------------------------------------------------------
class MainWindow(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.resize(600,400)
        self.setWindowTitle("Treeview Example")

        self.treeview = QtGui.QTreeView(self)

        self.treeview.model = QtGui.QFileSystemModel()
        self.treeview.model.setRootPath( QtCore.QDir.currentPath() )
        self.treeview.setModel(self.treeview.model)
        self.treeview.setColumnWidth(0, 200)

        self.setCentralWidget(self.treeview)

        self.treeview.clicked.connect(self.on_treeview_clicked)

# ---------------------------------------------------------------------

    @QtCore.pyqtSlot(QtCore.QModelIndex)
    def on_treeview_clicked(self, index):
        indexItem = self.treeview.model.index(index.row(), 0, index.parent())

        # path or filename selected
        fileName = self.treeview.model.fileName(indexItem)
        # full path/filename selected
        filePath = self.treeview.model.filePath(indexItem)

        print(fileName)
        print(filePath)

# ---------------------------------------------------------------------

if __name__ == '__main__':
    import sys
    app = QtGui.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

回答by Martin Alexandersson

I tried this alternative to get the file name...

我尝试了这个替代方法来获取文件名...

Instead of:

代替:

indexItem = self.treeview.model.index(index.row(), 0, index.parent())

# path or filename selected
fileName = self.treeview.model.fileName(indexItem)

I tried:

我试过:

# path or filename selected
fileName = index.internalPointer().fileName

Which also seems to work...

这似乎也有效......

回答by saldenisov

In PyQt5 it can be done in this way:

在 PyQt5 中,它可以通过这种方式完成:

from PyQt5.QtWidgets import QTreeView,QFileSystemModel,QApplication

class Main(QTreeView):
    def __init__(self):
        QTreeView.__init__(self)
        model = QFileSystemModel()
        model.setRootPath('C:\')
        self.setModel(model)
        self.doubleClicked.connect(self.test)

    def test(self, signal):
        file_path=self.model().filePath(signal)
        print(file_path)


if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    w = Main()
    w.show()
    sys.exit(app.exec_())