为什么 QListView 在尝试检索文本时给我一个 NoneType?

Why QListView gives me a NoneType while trying to retrive text?

我正在用 PyQt5 编写一个简单的文件搜索器(完整代码在此处)。

# -*- coding: utf-8 -*-

import sys, os, platform, fnmatch
from PyQt5 import QtCore, QtGui, QtWidgets

sep = os.sep
Ot = platform.system()
file_name = os.path.basename(__file__)
file_path = __file__.replace(file_name, '')

def find(ext, path):
    result = []
    for root, dirs, files in os.walk(path):
        for name in files:
            if fnmatch.fnmatch(name, ext):
                result.append(os.path.join(root, name))
    _ = dirs # For PyLint
    return result

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(804, 554)
        icon = QtGui.QIcon()
        icon.addPixmap(QtGui.QPixmap("C:/Users/Luger/Pictures/ico/search.ico"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        MainWindow.setWindowIcon(icon)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.centralwidget)
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        self.verticalLayout_2 = QtWidgets.QVBoxLayout()
        self.verticalLayout_2.setObjectName("verticalLayout_2")
        self.verticalLayout = QtWidgets.QVBoxLayout()
        self.verticalLayout.setObjectName("verticalLayout")
        self.horizontalLayout = QtWidgets.QHBoxLayout()
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.folderButton = QtWidgets.QPushButton(self.centralwidget)
        font = QtGui.QFont()
        font.setPointSize(9)
        self.folderButton.setFont(font)
        self.folderButton.setObjectName("folderButton")
        self.horizontalLayout.addWidget(self.folderButton)
        self.extensionLineEdit = QtWidgets.QLineEdit(self.centralwidget)
        font = QtGui.QFont()
        font.setPointSize(9)
        self.extensionLineEdit.setFont(font)
        self.extensionLineEdit.setMaxLength(25)
        self.extensionLineEdit.setAlignment(QtCore.Qt.AlignCenter)
        self.extensionLineEdit.setObjectName("extensionLineEdit")
        self.horizontalLayout.addWidget(self.extensionLineEdit)
        self.verticalLayout.addLayout(self.horizontalLayout)
        self.searchButton = QtWidgets.QPushButton(self.centralwidget)
        self.searchButton.setObjectName("searchButton")
        self.verticalLayout.addWidget(self.searchButton)
        self.verticalLayout_2.addLayout(self.verticalLayout)
        self.listView = QtWidgets.QListView(self.centralwidget)
        self.listView.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
        self.listView.setIconSize(QtCore.QSize(16, 16))
        self.listView.setObjectName("listView")
        self.entry = QtGui.QStandardItemModel()
        self.listView.setModel(self.entry)
        self.verticalLayout_2.addWidget(self.listView)
        self.horizontalLayout_2.addLayout(self.verticalLayout_2)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 804, 21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)
        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)
        self.folderButton.clicked.connect(self.fileChooserFunct)
        self.searchButton.clicked.connect(self.searchButtonFunct)
        self.listView.clicked[QtCore.QModelIndex].connect(self.on_clicked)

    def fileChooserFunct(self):
        _translate = QtCore.QCoreApplication.translate
        self.dir_to_scan = QtWidgets.QFileDialog.getExistingDirectory(None, 'Select A folder:', f'{file_path[0]}:{sep}', QtWidgets.QFileDialog.ShowDirsOnly)
        self.folderButton.setText(_translate("MainWindow", f" Selected: {self.dir_to_scan} "))
        self.folderButton.adjustSize()
        if Ot == 'Windows': self.dir_to_scan = self.dir_to_scan.replace('/', '\')

    def searchButtonFunct(self):
        _translate = QtCore.QCoreApplication.translate
        self.searchButton.setText(_translate("MainWindow", "Searching, please wait..."))
        MainWindow.setWindowTitle(_translate("MainWindow", "File Searcher - Searching"))
        self.searchButton.adjustSize()
        self.userExtension = self.extensionLineEdit.text()
        result = find(f'*.{self.userExtension}', self.dir_to_scan)

        model = QtGui.QStandardItemModel()
        self.listView.setModel(model)

        for i in result:
            item = QtGui.QStandardItem(i)
            model.appendRow(item)

        self.searchButton.setText(_translate("MainWindow", "Search"))
        MainWindow.setWindowTitle(_translate("MainWindow", "File Searcher"))
        self.searchButton.adjustSize()

    def on_clicked(self, index):
        item = self.entry.itemFromIndex(index)
        print(f"itemText='{item.text()}'")


    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "File Searcher"))
        self.folderButton.setText(_translate("MainWindow", " Select a folder "))
        self.extensionLineEdit.setPlaceholderText(_translate("MainWindow", "Extension of the file"))
        self.searchButton.setText(_translate("MainWindow", "Search"))


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

根据用户的回答,我添加了这个 MRE(我希望它是正确的)

        self.listView = QtWidgets.QListView(self.centralwidget) #create the widget
        self.listView.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) #paths cannot be modified by the user
        self.listView.setObjectName("listView") # Set his name
        self.entry = QtGui.QStandardItemModel() #Those two I don't really know what are for
        self.listView.setModel(self.entry)

        self.listView.clicked[QtCore.QModelIndex].connect(self.on_clicked) #User clicked something in QListView, calling on_clicked


    def on_clicked(self, index):
        item = self.entry.itemFromIndex(index)
        print(f"itemText='{item.text()}'") #Error is given here

我使用了 QtDesigner 并使用 pyuic5.exe 转换了 UI 文件,稍作修改,现在我无法在 QListView 中检索用户选择的对象。

我用了一点S.Nick in this answer的代码。 即使使用他的代码并使用相同的变量名称,当我单击一个对象时我得到 AttributeError: 'NoneType' object has no attribute 'text'(他的代码没有任何问题)。

这里报错

    def on_clicked(self, index):
        item = self.entry.itemFromIndex(index)
        print(f"itemText='{item.text()}'")

我在 2 天前开始搜索解决方案,我查看了大多数 Whosebug 的答案、站点、示例、视频(甚至两个家伙说俄语 1 小时),但我仍然在这里被阻止。
有谁知道如何解决这一问题?谢谢

问题在于,在 searchButtonFunct 方法中,您正在为 QListView 创建一个新模型,以便 QModelIndex 属于该新模型,因此将 self.entry.itemFromIndex() 与不属于该模型的 QModelIndex 一起使用将 return None.

解决方法是使用同一个模型:

def searchButtonFunct(self):
    self.entry.clear()
    _translate = QtCore.QCoreApplication.translate
    self.searchButton.setText(_translate("MainWindow", "Searching, please wait..."))
    MainWindow.setWindowTitle(_translate("MainWindow", "File Searcher - Searching"))
    self.searchButton.adjustSize()
    self.userExtension = self.extensionLineEdit.text()
    result = find(f"*.{self.userExtension}", self.dir_to_scan)

    for i in result:
        item = QtGui.QStandardItem(i)
        self.entry.appendRow(item)

    self.searchButton.setText(_translate("MainWindow", "Search"))
    MainWindow.setWindowTitle(_translate("MainWindow", "File Searcher"))
    self.searchButton.adjustSize()