首页 > 解决方案 > (Py)Qt5:如何在以编程方式设置当前项目时更新选择

问题描述

用例:我有一个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()类似的东西,但没有任何效果。我在 Google 或 Qt 论坛上也没有找到答案。

标签: pythonpyqtpyqt5qlistwidget

解决方案


在这种情况下使用 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


推荐阅读