[英]what triggers a QTreeView to ask for a SizeHintRole in the QAbstractItemModel.data() function
[英]Why is this role always sizeHintRole?
我一直在為PySide2
制作C++
示例代碼。
我一遍又一遍地查看fetchMore 示例。
這種轉換的錯誤點在哪里?
最大的問題在於數據方法。
角色始終是SizeHintRole
。
為什么?
這是代碼。
# -*- coding: utf-8 -*-
import sys, os, PySide2
from PySide2 import QtCore, QtWidgets, QtGui
dirname = os.path.dirname(PySide2.__file__)
plugin_path = os.path.join(dirname, 'plugins', 'platforms')
os.environ['QT_QPA_PLATFORM_PLUGIN_PATH'] = plugin_path
class Window(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Window, self).__init__(parent)
self.model = FileListModel()
#6.0
# self.model.setDirPath(QtCore.QLibraryInfo.path(QtCore.QLibraryInfo.PrefixPath))
self.model.setDirPath(QtCore.QLibraryInfo.location(QtCore.QLibraryInfo.PrefixPath))
self.label = QtWidgets.QLabel("&Directory:")
self.lineEdit = QtWidgets.QLineEdit()
self.label.setBuddy(self.lineEdit)
self.view = QtWidgets.QListView()
self.view.setModel(self.model)
self.logViewer = QtWidgets.QTextBrowser(self)
self.logViewer.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
self.lineEdit.textChanged["QString"].connect(self.model.setDirPath)
self.lineEdit.textChanged["QString"].connect(self.logViewer.clear)
self.model.numberPopulated[int].connect(self.updateLog)
layout = QtWidgets.QGridLayout()
layout.addWidget(self.label, 0, 0)
layout.addWidget(self.lineEdit, 0, 1)
layout.addWidget(self.view, 1, 0, 1, 2)
layout.addWidget(self.logViewer, 2, 0, 1, 2)
self.setLayout(layout)
self.setWindowTitle("Fetch More Example")
def updateLog(self, number):
self.logViewer.append("{0} items added.".format(number))
class FileListModel(QtCore.QAbstractListModel):
numberPopulated = QtCore.Signal(int)
def __init__(self, parent=None):
super(FileListModel, self).__init__(parent)
self.fileCount = 0
self.fileList = []
def rowCount(self, parent=QtCore.QModelIndex()):
return 0 if parent.isValid() else self.fileCount
def data(self, index, role=QtCore.Qt.DisplayRole):
if not index.isValid():
return 0
if (index.row() >= len(self.fileList) or index.row() < 0):
return 0
#Why is the role only SizeHintRole?
if role == QtCore.Qt.DisplayRole:
return self.fileList[index.row()]
elif role == QtCore.Qt.BackgroundRole:
batch = (index.row() / 100) % 2
if batch == 0:
return QtWidgets.QApplication.palette().base()
else:
return QtWidgets.QApplication.palette().alternateBase()
return 0
def canFetchMore(self, parent):
if parent.isValid():
return False
return self.fileCount < len(self.fileList)
def fetchMore(self, parent):
if parent.isValid():
return
remainder = len(self.fileList) - self.fileCount
itemsToFetch = min(100, remainder)
if itemsToFetch <= 0:
return
self.beginInsertRows(QtCore.QModelIndex(), self.fileCount, self.fileCount + itemsToFetch - 1)
self.fileCount += itemsToFetch
self.endInsertRows()
self.emit(QtCore.SIGNAL("numberPopulated(int)"), itemsToFetch)
def setDirPath(self, path):
dir_ = QtCore.QDir(path)
self.beginResetModel()
self.fileList = dir_.entryList()
self.fileCount = 0
self.endResetModel()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv) if QtWidgets.QApplication.instance() is None else QtWidgets.QApplication.instance()
mainWin = Window()
mainWin.show()
sys.exit(app.exec_())
QVariant is a type of Qt/C++ object that allows handling various types of data but in python that object type is no longer necessary given the dynamic typing of the language, so it is not unnecessary to export it to python (although PyQt5 does). QVariant() 構建了一個無效的 QVariant,它的 python 等效項是 None 因此return QVariant()
可以轉換為return None
或簡單地return
。
同樣可以反轉,因為當返回0
時,它在 C++ 中轉換為0
,然后轉換為QVariant(0)
,其含義與QVariant()
不同,因為第一個存儲數字 0 而第二個不存儲存儲任何內容,因為它是無效的 QVariant。
問題在於data()
的最后一次返回,它不應該返回 0。
返回 0 時,視圖或其委托嘗試將值轉換為適合該角色的類型,並且由於視圖請求的第一個角色之一是大小提示(並且無法將返回的“0”轉換為一個有效的大小提示),結果是它不會請求任何其他數據:由於大小無效,該項目被認為是隱藏的,因此無需請求其他角色。
只需刪除data()
末尾的return 0
,因為隱式return
就足夠了。
PS:您使用的self.emit
語法被認為已過時,將其更改為self.numberPopulated.emit(itemsToFetch)
; 此外,只有一個簽名的信號不需要顯式重載,因此您可以從textChanged
中刪除["QString"]
並從numberPopulated
中刪除[int]
。
我還建議您始終在函數之間至少留一個空白行,因為它使您的代碼更具可讀性。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.