在运行时覆盖QListView的虚拟保护槽

问题描述 投票:1回答:1

我正在使用PyQt 5.9.1,我想在运行时将QListView.currentChanged连接到一个函数。但出于某种原因,我只能在致电setModel()之前做到这一点。如果我事先调用setModel()(即使使用None参数),那么我的currentChanged函数永远不会被调用。

# https://www.pythoncentral.io/pyside-pyqt-tutorial-qlistview-and-qstandarditemmodel/
import sys
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import  *

def currentChanged(current, previous):
    print(current, previous)


app = QApplication(sys.argv)

model = QStandardItemModel()
foods = [
    'Cookie dough', # Must be store-bought
    'Hummus', # Must be homemade
    'Spaghetti', # Must be saucy
    'Dal makhani', # Must be spicy
    'Chocolate whipped cream' # Must be plentiful
]
for food in foods:
    item = QStandardItem(food)
    model.appendRow(item)

list = QListView()
list.setWindowTitle('Honey-Do List')
list.setMinimumSize(600, 400)
list.currentChanged = currentChanged  # BEFORE setModel
list.setModel(model)

list.show()
app.exec_()
python pyqt override signals-slots qlistview
1个回答
0
投票

每当调用setModel()时,就会创建一个新的selection model。在内部,新选择模型的currentChanged信号然后连接到列表视图的受保护的currentChanged槽。因此,无论何时设置数据模型,现有的内部信号连接都会自动断开并重新连接。在你的例子中,当你在调用currentChanged之后修补setModel()时,内部信号连接将不会被重新制作,因此你的函数永远不会被调用。

通常,在设置任何模型之前对视图进行更改通常是错误的,因为可能存在不可预测的内部副作用,而这些副作用并不总是记录在案。

你还应该注意,根本不需要修补currentChanged。正确的做事方式是这样的:

list = QListView()
list.setModel(model)
list.selectionModel().currentChanged.connect(currentChanged)

这将与您当前的代码完全相同。

© www.soinside.com 2019 - 2024. All rights reserved.