python - (Pyqt5 : How to update selection when current item has been set programatically

标签 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):
    # 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 论坛上也没有找到答案。

最佳答案

在这种情况下使用 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,逻辑不会改变。

关于python - (Pyqt5 : How to update selection when current item has been set programatically,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51897455/

相关文章:

python - 为什么 .find() 不能与 python 3 中的 urllib.request.urlopen() 一起使用?

python - QWebEngineView:显示加载进度

python - 在小部件中嵌入 QGraphics

python - 通过使用 pandas 在 python 中使用特定列来获取数据框中的过滤结果

python - 使用 ffmpeg 处理的视频不是标志指定的 1080p

layout - Qt formlayout 不垂直扩展 qplaintextedit

python - 获取 QTableView 单元格值

python - 将 QScrollArea 添加到 QTabWidget

python - PyQt 相当于 WinForms 激活事件是什么?

python - 如何调整子图的高度和宽度以紧密配合?