Python (Py)Qt5:当当前项目已通过编程设置时,如何更新选择

Python (Py)Qt5:当当前项目已通过编程设置时,如何更新选择,python,pyqt,pyqt5,qlistwidget,Python,Pyqt,Pyqt5,Qlistwidget,用例:我有一个QListWidget。当用户选择任何行时,我想将当前项目和选择重置为第3行: from PyQt5.QtWidgets import QApplication, QListWidget app = QApplication([]) l = QListWidget() l.setSelectionMode(QListWidget.SingleSelection) l.addItems(list('abcde')) def slot(current, previous):

用例:我有一个
QListWidget
。当用户选择任何行时,我想将当前项目和选择重置为第3行:

from PyQt5.QtWidgets import QApplication, QListWidget

app = QApplication([])
l = QListWidget()
l.setSelectionMode(QListWidget.SingleSelection)
l.addItems(list('abcde'))

def slot(current, previous):
    # sm = l.selectionModel()
    l.blockSignals(True)
    l.setCurrentRow(3)
    l.blockSignals(False)
    # sm.select(l.currentIndex(), sm.Select)  # Does not work
    # sm.setCurrentIndex(l.currentIndex(), sm.Select)  # Does not work

l.currentItemChanged.connect(slot)
l.show()
app.exec()

上面的示例将第三行设置为当前行,但将所选行保留为用户单击的行。我已经尝试了
QItemModel.select()
QItemModel.setCurrentIndex()
以及类似的东西的各种组合,但都没有效果。我在谷歌或Qt论坛上也没有找到答案。

在这种情况下使用blockSignals是一把双刃剑,因为我认为你用它来避免无限循环。但这也不会生成模型更新,因为
setCurrentRow()
仅在与以前的值不同时才更新,从而避免了该问题

解决方案是使用
QTimer.singleShot()
更新更改:

import sys
from functools import partial
from PyQt5.QtWidgets import QApplication, QListWidget
from PyQt5.QtCore import QTimer


app = QApplication(sys.argv)
l = QListWidget()
l.setSelectionMode(QListWidget.SingleSelection)
l.addItems(list('abcde'))

row = 3

def onCurrentRowChanged():
    QTimer.singleShot(0, partial(l.setCurrentRow, row))

l.currentRowChanged.connect(onCurrentRowChanged)
l.show()
sys.exit(app.exec_())

注意:如果将
currentRowChanged
信号更改为
currentItemChanged

Thx,则逻辑不会更改,我的实际用例稍微复杂一些,但我也可以在那里应用您的解决方案。似乎是
QTimer.singleShot(0,…)
使Qt能够在我再次更改当前行之前计算所有必要的选择更改。