我正在尝试创建一个QListView,其中显示项目列表以及是否启用了这些项目。下面的代码可以做到这一点,但我也希望在用户单击复选框时能够切换项目的启用状态(不仅仅是在列表项目的任何位置,特别是在复选框上),我如何才能做到这一点
import sys
from dataclasses import dataclass
from typing import Dict, List, Union
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import Qt
@dataclass
class Filter:
expr: str
enabled: bool
class Store:
def __init__(self):
super().__init__()
self.filter_viewer: Union["FilterViewer", None] = None
self.filters: List[Filter] = []
def update(self):
if self.filter_viewer is not None:
self.filter_viewer.list_model.dataChanged.emit(QtCore.QModelIndex(), QtCore.QModelIndex())
def add_filter(self, expr: str, enabled=True):
filt = Filter(expr=expr, enabled=enabled)
self.filters.append(filt)
self.update()
def remove_filter(self, index: int):
self.filters.pop(index)
self.update()
def toggle_filter(self, index: int):
self.filters[index].enabled = not self.filters[index].enabled
self.update()
class FilterViewer(QtWidgets.QWidget):
def __init__(self, pgdf: Store):
super().__init__()
pgdf.filter_viewer = self
self.pgdf = pgdf
self.list_view = self.ListView()
self.list_model = self.ListModel(pgdf)
self.list_view.setModel(self.list_model)
self.text_input = QtWidgets.QLineEdit()
self.submit_button = QtWidgets.QPushButton("Add Filter")
self.submit_button.clicked.connect(self.add_filter)
self.text_input.returnPressed.connect(self.add_filter)
self.layout = QtWidgets.QVBoxLayout()
self.layout.addWidget(self.list_view)
self.layout.addWidget(self.text_input)
self.layout.addWidget(self.submit_button)
self.setLayout(self.layout)
def add_filter(self):
expr = self.text_input.text()
self.text_input.setText("")
self.pgdf.add_filter(expr=expr)
print(self.pgdf.filters)
class ListView(QtWidgets.QListView):
pass
class ListModel(QtCore.QAbstractListModel):
def __init__(self, pgdf: Store):
super().__init__()
self.pgdf = pgdf
def data(self, index: QtCore.QModelIndex, role: int):
row = index.row()
if role == Qt.DisplayRole:
filt = self.pgdf.filters[row]
return filt.expr
if role == Qt.CheckStateRole:
filt = self.pgdf.filters[row]
if filt.enabled:
return Qt.Checked
else:
return Qt.Unchecked
def rowCount(self, parent):
return len(self.pgdf.filters)
def flags(self, index):
return (QtCore.Qt.ItemIsEnabled |
QtCore.Qt.ItemIsUserCheckable)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
pgdf = Store()
pgdf.add_filter('Generation > 3', enabled=True)
pgdf.add_filter('Size > 50', enabled=False)
fv = FilterViewer(pgdf)
fv.show()
app.exec_()
QListView复选框的状态由模型决定,因此要更改模型信息,必须覆盖setData()方法:
相关问题 更多 >
编程相关推荐