从 python 中的 PYQT5 QListview 获取选定文件的文件名

Posted

技术标签:

【中文标题】从 python 中的 PYQT5 QListview 获取选定文件的文件名【英文标题】:Get selected files' filenames from PYQT5 QListview in python 【发布时间】:2018-11-26 15:22:12 【问题描述】:

我在从选定的 QListview 中检索文件名时遇到问题,我想要获取我从列表中选择的文件的名称,以便我可以通过调用检索到的文件名来打开文件。但是,这不起作用...

另外,如何设置多选模式并检索所有选定文件的文件名??

from PyQt5 import QtCore, QtGui, QtWidgets
import PandasModel
import pandas as pd


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(450, 550)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        MainWindow.setCentralWidget(self.centralwidget)
        self.listview = QtWidgets.QListView(self.centralwidget)
        self.listview.setGeometry(QtCore.QRect(10,10,400,300))
        self.listview.setObjectName("listview")

        path = r'\\desktop\file'

        self.fileModel = QtWidgets.QFileSystemModel(self.centralwidget)
        self.fileModel.setRootPath(path)
        self.fileModel.setFilter(QtCore.QDir.NoDotAndDotDot | QtCore.QDir.Files)
        self.listview.setModel(self.fileModel)
        self.listview.setRootIndex(self.fileModel.index(path))
        self.listview.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)


        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setObjectName("pushButton")
        self.pushButton.setGeometry(QtCore.QRect(300,380,100,20))

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)


    def retranslateUi(self, MainWindow):
         _translate = QtCore.QCoreApplication.translate
         MainWindow.setWindowTitle(_translate("MainWindow", "App"))

         self.pushButton.setText(_translate("MainWindow", "Retrieve data"))

         self.pushButton.clicked.connect(self.btn_clk)

         MainWindow.show()

    def get_name(self,index):
        return index.data.toString

    def btn_clk(self,selected):

        filename =self.get_name(self.listview.clicked)
        print(filename)

        SecondWindow = QtWidgets.QMainWindow(MainWindow)
        self.SW = Ui_SecondWindow()
        self.SW.setupUi(SecondWindow)

        SecondWindow.show()
        df = pd.read_csv(filename)
        model = PandasModel(df)
        self.SW.tableView.setModel(model)

class Ui_SecondWindow(object):
    def setupUi(self,SecondWindow):
        SecondWindow.setObjectName("SecondWindow")
        SecondWindow.resize(600, 400)
        self.centralwidget = QtWidgets.QWidget(SecondWindow)
        self.centralwidget.setObjectName("centralwidget")
        SecondWindow.setCentralWidget(self.centralwidget)

        self.tableView = QtWidgets.QTableView(self.centralwidget)
        self.tableView.setGeometry(QtCore.QRect(10,10,580,370))

        self.retranslateUi(SecondWindow)
        QtCore.QMetaObject.connectSlotsByName(SecondWindow)

    def retranslateUi(self,SecondWindow):
        _translate = QtCore.QCoreApplication.translate
        SecondWindow.setWindowTitle(_translate("SecondWindow", "Table"))

        SecondWindow.show()


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

【问题讨论】:

【参考方案1】:

首先不要按照文档的指示修改 Qt Designer 提供的代码,而是创建一个继承适当小部件的类并使用以前的类来填充它。进入问题,必须使用返回 QModelIndex 的函数 selectedIndexes() 通过模型的 filePath 获取名称。

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(450, 550)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        MainWindow.setCentralWidget(self.centralwidget)
        self.listview = QtWidgets.QListView(self.centralwidget)
        self.listview.setGeometry(QtCore.QRect(10,10,400,300))
        self.listview.setObjectName("listview")
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setObjectName("pushButton")
        self.pushButton.setGeometry(QtCore.QRect(300,380,100,20))

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
         _translate = QtCore.QCoreApplication.translate
         MainWindow.setWindowTitle(_translate("MainWindow", "App"))
         self.pushButton.setText(_translate("MainWindow", "Retrieve data"))

class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setupUi(self)
        self.pushButton.clicked.connect(self.btn_clk)
        path = r'\\desktop\file'
        self.fileModel = QtWidgets.QFileSystemModel(self.centralwidget)
        self.fileModel.setRootPath(path)
        self.fileModel.setFilter(QtCore.QDir.NoDotAndDotDot | QtCore.QDir.Files)
        self.listview.setModel(self.fileModel)
        self.listview.setRootIndex(self.fileModel.index(path))
        self.listview.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)

    @QtCore.pyqtSlot()
    def btn_clk(self):
        for ix in self.listview.selectedIndexes():
            print(self.fileModel.filePath(ix), ix.data())

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

更新:

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(450, 550)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        MainWindow.setCentralWidget(self.centralwidget)
        self.listview = QtWidgets.QListView(self.centralwidget)
        self.listview.setGeometry(QtCore.QRect(10,10,400,300))
        self.listview.setObjectName("listview")
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setObjectName("pushButton")
        self.pushButton.setGeometry(QtCore.QRect(300,380,100,20))

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
         _translate = QtCore.QCoreApplication.translate
         MainWindow.setWindowTitle(_translate("MainWindow", "App"))
         self.pushButton.setText(_translate("MainWindow", "Retrieve data"))


class Ui_SecondWindow(object):
    def setupUi(self,SecondWindow):
        SecondWindow.setObjectName("SecondWindow")
        SecondWindow.resize(600, 400)
        self.centralwidget = QtWidgets.QWidget(SecondWindow)
        self.centralwidget.setObjectName("centralwidget")
        SecondWindow.setCentralWidget(self.centralwidget)

        self.tableView = QtWidgets.QTableView(self.centralwidget)
        self.tableView.setGeometry(QtCore.QRect(10,10,580,370))

        self.retranslateUi(SecondWindow)
        QtCore.QMetaObject.connectSlotsByName(SecondWindow)

    def retranslateUi(self,SecondWindow):
        _translate = QtCore.QCoreApplication.translate
        SecondWindow.setWindowTitle(_translate("SecondWindow", "Table"))

class SecondWindow(QtWidgets.QMainWindow, Ui_SecondWindow):
    def __init__(self, parent=None):
        super(SecondWindow, self).__init__(parent)
        self.setupUi(self)

class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setupUi(self)
        self.pushButton.clicked.connect(self.btn_clk)
        path = r'\\desktop\file'
        self.fileModel = QtWidgets.QFileSystemModel(self.centralwidget)
        self.fileModel.setRootPath(path)
        self.fileModel.setFilter(QtCore.QDir.NoDotAndDotDot | QtCore.QDir.Files)
        self.listview.setModel(self.fileModel)
        self.listview.setRootIndex(self.fileModel.index(path))
        self.listview.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
        self.sw = SecondWindow()

    @QtCore.pyqtSlot()
    def btn_clk(self):
        for ix in self.listview.selectedIndexes():
            filename = self.fileModel.filePath(ix) 
            df = pd.read_csv(filename)
            self.model = PandasModel(df)
            self.sw.tableView.setModel(self.model)
            self.sw.show()
            return

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

【讨论】:

嗨,我修改了我的代码以显示完整的应用程序,我希望单击按钮,python 读取所选文件的文件名并将其显示在第二个窗口中,我使用 PandasModel 这是一个 python 文件把 pd.dataframe 放到一个可以在 Qtableview 中显示的模型中,我把我的代码改成了上面的代码但是现在第二个窗口不显示了 @Cindy,如果您选择了 n 个项目,应该显示哪些项目? 假设我一次只选择一项。如何解决这个问题? @eyllanesc 为什么我点击按钮后第二个窗口没有出现? @Cindy 我没有调用show()方法,更新代码,再试一次

以上是关于从 python 中的 PYQT5 QListview 获取选定文件的文件名的主要内容,如果未能解决你的问题,请参考以下文章

将python函数作为arg传递给PyQt5中的函数

Python 小白从零开始 PyQt5 项目实战布局管理

PyQt5 和 QML 中的嵌套 ListView

从 PySide 移动到 PyQt5 后图像不显示

从 python 脚本调用 python 脚本,提供输入和获取输出,PyQt5,GUI

PyQt5 中的 QWebEngineView 和 QWidget