PyQt listView 复选框在选中/取消选中时连接 [英] PyQt listView checkbox connect when checked/unchecked

查看:89
本文介绍了PyQt listView 复选框在选中/取消选中时连接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以弄清楚如何通过迭代 QListView 来检查 所有 复选框是否被选中,就像解释的 这里

I can figure out how to check if all checkboxes are checked, by iterating over a QListView, like explained here

但是有没有办法在选中单个框时连接到函数,该框也可能与 QListView 中当前选择的对象不同?例如.相当于 self.listview.clicked.connect(foo)

But is there a way to connect to a function, right at the time of checking an individual box, which also might not be the same as the currently selected object in the QListView? E.g. the equivalent of self.listview.clicked.connect(foo)

Minimal 结合上面的链接示例:

Minimal combined with linked example above:

from PyQt5 import QtCore

from PyQt5 import QtGui
from PyQt5.QtCore import QTimer
from PyQt5.QtWidgets import QApplication, QWizardPage, QListView


class AppRemovalPage(QWizardPage):
    def __init__( self, parent ):
        super(AppRemovalPage, self).__init__(parent)
        self.setTitle('Apps to Remove')
        self.setSubTitle('Listview')
        self.list_view = QListView(self)
        self.list_view.setMinimumSize(465, 200)
        self.isWritten = False

        self.model = QtGui.QStandardItemModel(self.list_view)
        for line in ('a', 'b', 'c', 'd', 'e'):
            self.item = QtGui.QStandardItem(line)
            self.item.setCheckable(True)
            self.item.setCheckState(QtCore.Qt.Unchecked)
            self.model.appendRow(self.item)

        self.list_view.setModel(self.model)
        self.list_view.clicked.connect(self.getSelectedListItem)

        self.list_view.show()


    def print_checked_items(self):
        for index in range(self.model.rowCount()):
            item = self.model.item(index)
            if item.checkState() == QtCore.Qt.Checked:
                print(item.text(), "was checked")
        print("rerun timed script to list checked objects again")



    def getSelectedListItem(self):
        """
        Gets the name and row of the selected object.
        """
        currentSelection = self.list_view.selectedIndexes()

        name  = None
        row   = None
        index = None

        # Set name for currently selected object in listview
        for obj_index in currentSelection:
            item  = self.model.itemFromIndex(obj_index)
            row   = item.row()
            index = self.model.index(row, 0)
            name  = self.model.data(index)

        self.currName  = name
        self.currRow   = row
        self.currIndx  = index

        print(self.currName)


app = QApplication([])
listview = AppRemovalPage(None)
listview.show()
QTimer.singleShot(5000, listview.print_checked_items)
app.exec_()

推荐答案

对于这种情况,我们可以使用委托来检测状态的变化,另一种解决方案是使用模型,但这会更烦人,因为每个模型将不得不修改.下一个解决方案

For this case we can use a delegate to detect the change of state, another solution is to use the model but this would be more annoying to implement since each model would have to be modified. The solution is the next

import sys

from PyQt5 import QtCore, QtGui, QtWidgets


class Delegate(QtWidgets.QStyledItemDelegate):
    def editorEvent(self, event, model, option, index):
        checked = index.data(QtCore.Qt.CheckStateRole)
        ret = QtWidgets.QStyledItemDelegate.editorEvent(self, event, model, option, index)
        if checked != index.data(QtCore.Qt.CheckStateRole):
            self.parent().checked.emit(index)
        return ret


class ListView(QtWidgets.QListView):
    checked = QtCore.pyqtSignal(QtCore.QModelIndex)
    def __init__(self, *args, **kwargs):
        super(ListView, self).__init__(*args, **kwargs)
        self.setItemDelegate(Delegate(self))


class AppRemovalPage(QtWidgets.QWizardPage):
    def __init__( self, parent=None):
        super(AppRemovalPage, self).__init__(parent)
        self.setTitle('Apps to Remove')
        self.setSubTitle('Listview')
        self.list_view = ListView(self)
        self.list_view.setMinimumSize(465, 200)

        self.model = QtGui.QStandardItemModel(self)
        for line in ('a', 'b', 'c', 'd', 'e'):
            self.item = QtGui.QStandardItem(line)
            self.item.setCheckable(True)
            self.item.setCheckState(QtCore.Qt.Unchecked)
            self.model.appendRow(self.item)

        self.list_view.setModel(self.model)
        self.list_view.checked.connect(self.onChecked)

    @QtCore.pyqtSlot(QtCore.QModelIndex)
    def onChecked(self, index):
        item = self.model.itemFromIndex(index)
        if item.checkState() == QtCore.Qt.Checked:
            print(item.text(), "was checked")
        else:
            print(item.text(), "was unchecked")

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    listview = AppRemovalPage()
    listview.show()
    sys.exit(app.exec_())

这篇关于PyQt listView 复选框在选中/取消选中时连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆