为什么这个角色总是这么大?

2024-06-01 03:19:31 发布

您现在位置:Python中文网/ 问答频道 /正文

我一直在为PySide2制作C++示例代码

我一遍又一遍地复习fetchMore example

这种转换的错误点在哪里

最大的问题是数据方法

角色总是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_())

Tags: pathselfindexmodelreturnifdefparent
2条回答

问题出在data()的最后一次返回中,它不应该返回0

返回0时,视图或其委托尝试将值转换为适合该角色的类型,并且由于视图请求的第一个角色之一是大小提示(并且无法将返回的“0”转换为有效的大小提示),因此它不会请求任何其他数据:因为大小无效,该项被认为是隐藏的,因此不需要请求其他角色

只需删除data()末尾的return 0,因为隐式的return就足够了

PS:您使用的self.emit语法被认为已经过时,请将其更改为self.numberPopulated.emit(itemsToFetch);此外,仅具有单个签名的信号不需要显式重载,因此您可以从textChanged中删除["QString"],从numberPopulated中删除[int]
我还建议您在函数之间至少留一行空白,因为这样可以使代码更具可读性

我的回答将进一步解释musicamante's answer

QVariant是一种Qt/C++对象,允许处理各种类型的数据,但在python中,由于语言的动态类型,该对象类型不再是必需的,因此没有必要将其导出到python(尽管PyQt5有)。QVariant()生成了一个无效的QVariant,python等价物是None,因此return QVariant()可以转换为return None或简单地return

同样可以颠倒,因为当返回{{4CD>}时,C++中转换为^ {< CD4}},然后转换为^ {CD6>},其含义与^ {CD7>}不同,因为第一个存储了0个,第二个不存储任何东西,因为它是无效的q变体。p>

相关问题 更多 >