(Pyqt5:如何以编程方式设置当前项目时更新选择
(Py)Qt5: How to update selection when current item has been set programatically
用例:我有一个 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
逻辑不变。
用例:我有一个 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
逻辑不变。