【问题标题】:(Py)Qt5: How to update selection when current item has been set programatically(Pyqt5:如何在当前项目已以编程方式设置时更新选择
【发布时间】:2019-01-24 14:50:28
【问题描述】:

用例:我有一个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 论坛上也没有找到答案。

【问题讨论】:

    标签: python pyqt pyqt5 qlistwidget


    【解决方案1】:

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

    【讨论】:

    • 谢谢,我的真实用例有点复杂,但我也可以在那里应用你的解决方案。似乎QTimer.singleShot(0, ...) 使 Qt 能够在我再次更改当前行之前计算所有必要的选择更改。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-25
    • 1970-01-01
    • 1970-01-01
    • 2011-06-02
    相关资源
    最近更新 更多