微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为每一行填充 QListView 触发 SelectionChanged

如何解决为每一行填充 QListView 触发 SelectionChanged

当我填充 QListView 的 QStandardItem 模型时,我注意到它会为出现在所选行之前的每一行触发 selectionChanged。我怎样才能解决这个问题?我尝试在重新填充模型之前调用“clearSelection”,但这也不能解决问题。为什么会发生这种情况?

要测试...

  1. 运行代码
  2. 选择列表中的 30 项或更高的项
  3. 右键单击并单击“清除选择”
  4. 您会在侦听器中看到它打印了 30 次选择更改的内容

enter image description here

你会注意到这个问题

################################################################################
# imports
################################################################################
import os
import sys
from Qt import QtGui,QtWidgets,QtCore


################################################################################
# Widgets
################################################################################
class EntityListView(QtWidgets.QWidget):
    def __init__(self,parent=None):
        super(EntityListView,self).__init__(parent)

        # controls
        self.searchInput = QtWidgets.QLineEdit()
        self.searchInput.setPlaceholderText('Search...')
        self.searchInput.setClearButtonEnabled(True)

        self.itemmodel = QtGui.QStandardItemmodel()
        self.proxyModel = QtCore.QSortFilterProxyModel()
        self.proxyModel.setSortCaseSensitivity(QtCore.Qt.CaseInsensitive)
        self.proxyModel.setSourceModel(self.itemmodel)
        self.proxyModel.setFilterCaseSensitivity(QtCore.Qt.CaseInsensitive)
        self.proxyModel.setDynamicSortFilter(True)

        self.listView = QtWidgets.QListView()
        self.listView.setIconSize(QtCore.QSize(24,24))
        self.listView.setModel(self.proxyModel)
        self.listView.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
        self.listView.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)
        self.listView.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
        self.listView.setSizePolicy(QtWidgets.QSizePolicy.Expanding,QtWidgets.QSizePolicy.Preferred)
        self.listView.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.listView.setMinimumHeight(250)
        self.listView.setSizePolicy(QtWidgets.QSizePolicy.Preferred,QtWidgets.QSizePolicy.Expanding)

        self.selection = self.listView.selectionModel()

        self.listInfo = QtWidgets.QLabel()
        self.listInfo.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)

        # layout
        self.mainLayout = QtWidgets.QVBoxLayout()
        self.mainLayout.setContentsMargins(0,0)
        self.mainLayout.addWidget(self.searchInput)
        self.mainLayout.addWidget(self.listView)
        self.mainLayout.addWidget(self.listInfo)
        self.setLayout(self.mainLayout)

        # menus
        self.createActions()
        self.createMenus()

        # Signals
        self.listView.customContextMenuRequested.connect(self.slotShowContextMenu)
        self.searchInput.textChanged.connect(self.slotSearchInputChanged)
        self.itemmodel.dataChanged.connect(self.slotModelChanged)
        self.itemmodel.rowsInserted.connect(self.slotModelChanged)
        self.itemmodel.rowsRemoved.connect(self.slotModelChanged)
        self.selection.selectionChanged.connect(self.slotSelectionChanged)

        # init
        self.populateListView()
        self.updateInfo()


    # Methods
    def createActions(self):
        self.clearSelectionAct = QtWidgets.QAction('Clear Selection',self)
        self.clearSelectionAct.triggered.connect(self.slotClearSelection)
        # self.addAction(self.clearSelectionAct)


    def createMenus(self):
        self.menu = QtWidgets.QMenu('View',self)
        self.menu.addAction(self.clearSelectionAct)


    def getItemsCount(self):
        return self.itemmodel.rowCount()

    def getSelectedItems(self):
        items = []
        for proxyIndex in self.selection.selectedindexes():
            sourceIndex = self.proxyModel.mapToSource(proxyIndex)
            item = self.itemmodel.itemFromIndex(sourceIndex)
            items.append(item)
        return items


    def getItemFromModelIndex(self,proxyIndex):
        sourceIndex = self.proxyModel.mapToSource(proxyIndex)
        item = self.itemmodel.itemFromIndex(sourceIndex)
        return item


    def setFilter(self,value):
        self.proxyModel.setFilterRegExp(value)


    def updateInfo(self):
        selection = self.selection.selectedindexes()
        count = len(selection)
        total = self.itemmodel.rowCount()
        self.listInfo.setText('<i><font style=font-size:11px;>{} of {} selected<font></i>'.format(count,total))


    # Slots
    def slotClearSelection(self):
        self.listView.clearSelection()
        self.populateListView()


    def slotShowContextMenu(self):
        self.menu.exec_(QtGui.QCursor.pos())     


    def slotSearchInputChanged(self):
        self.setFilter(self.searchInput.text())


    def slotModelChanged(self):
        self.updateInfo()


    def populateListView(self):
        self.itemmodel.clear()

        for x in range(50):
            item = QtGui.QStandardItem('Item {}'.format(x))
            self.itemmodel.appendRow(item)


    def slotSelectionChanged(self,data):
        print('changed...',data.indexes())
        self.updateInfo()


################################################################################
# Widgets
################################################################################
def main():
    app = QtWidgets.QApplication(sys.argv)
    window = EntityListView()
    window.resize(400,600)
    window.show()
    app.exec_()


if __name__ == '__main__':
    pass
    main()

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。