Мой qfilesystemmodel не работает, как ожидалось в Pyqt
-
27-09-2019 - |
Вопрос
Редактировать2: model.hasChildren(parentIndex)
возвращается True
, но model.rowCount(parentIndex)
возвращается 0
. Отказ Qfilesystemmodel просто fubar в Pyqt?
РЕДАКТИРОВАТЬ: С небольшим адаптацией это все работает именно так, как следует, если я буду использовать QDirmodel. Это устарено, но, возможно, QfilesystemModel не был полностью реализован в Pyqt?
Я изучаю модель QT Model / просмотреть архитектуру в данный момент, и я нашел что-то, что не работает, как я ожидаю. У меня есть следующий код (адаптированный из QT модели классов):
from PyQt4 import QtCore, QtGui
model = QtGui.QFileSystemModel()
parentIndex = model.index(QtCore.QDir.currentPath())
print model.isDir(parentIndex) #prints True
print model.data(parentIndex).toString() #prints name of current directory
rows = model.rowCount(parentIndex)
print rows #prints 0 (even though the current directory has directory and file children)
Вопрос:
Это проблема с PYQT, я только что сделал что-то не так, или я полностью не понимаю, qfilesystemmodel? Согласно документации, model.rowCount(parentIndex)
следует вернуть количество детей в текущем каталоге. (Я бегу на это под Ubuntu с Python 2.6)
Документы QfilesystemModel говорят, что ему нужен экземпляр приложения GUI, поэтому я также разместил вышеуказанный код в QWidget следующим образом, но с тем же результатом:
import sys
from PyQt4 import QtCore, QtGui
class Widget(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
model = QtGui.QFileSystemModel()
parentIndex = model.index(QtCore.QDir.currentPath())
print model.isDir(parentIndex)
print model.data(parentIndex).toString()
rows = model.rowCount(parentIndex)
print rows
def main():
app = QtGui.QApplication(sys.argv)
widget = Widget()
widget.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
Решение
Я решил это.
Причина использования QFILESYSTEMMODEL в отличие от QDirmodel, является то, что QFilesystemModel загружает данные из файловой системы в отдельном потоке. Проблема с тем, что если вы попытаетесь распечатать количество детей сразу после того, как он был построен, состоит в том, что он еще не загрузил детей. Способ исправления вышеуказанного кода - добавить следующее:
self.timer = QtCore.QTimer(self)
self.timer.singleShot(1, self.printRowCount)
до конца конструктора, и добавьте метод printRowcount, который напечатает правильное количество детей. Флаг
Другие советы
Поскольку вы уже выяснили его, просто пару дополнительных мыслей о том, что происходит с вашей моделью: QFILESYSTEMMODEL :: RowCount возвращает строки из коллекции Visiblechildren; Я предполагаю, что вы правильно определили проблему: в то время, когда вы проверяете количество строк, его еще не заполнено. Я изменил свой пример без использования таймеров; Пожалуйста, проверьте, работает ли это для вас:
class Widget(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.model = QtGui.QFileSystemModel()
self.model.setRootPath(QtCore.QDir.currentPath())
def checkParent(self):
parentIndex = self.model.index(QtCore.QDir.currentPath())
print self.model.isDir(parentIndex)
print self.model.data(parentIndex).toString()
rows = self.model.rowCount(parentIndex)
print "row count:", rows
def main():
app = QtGui.QApplication(sys.argv)
widget = Widget()
widget.show()
app.processEvents(QtCore.QEventLoop.AllEvents)
widget.checkParent()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
Я считаю, что ваш код должен правильно работать на любом событии UI после того, как виджет построен на экране
С Уважением