如何在保持程序化行选择的同时防止用户点击行选择?
Posted
技术标签:
【中文标题】如何在保持程序化行选择的同时防止用户点击行选择?【英文标题】:how to prevent row selection by user's click while keeping programmatic row selection? 【发布时间】:2019-05-03 17:54:11 【问题描述】:在我的应用程序中,我有一个 QTableView,其中包含以编程方式选择的行,例如在对数据执行查询之后。
如何防止用户在点击时更改选定的行,同时保持以编程方式选择行的能力?
这是我的代码:
self.table = QTableView()
pandas_model: QAbstractTableModel = PandasTableModel(self.data_frame, self)
self.table.setModel(pandas_model)
self.table.setSortingEnabled(False)
self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) # full width table
self.table.setSelectionMode(QAbstractItemView.MultiSelection)
self.table.setSelectionBehavior(QAbstractItemView.SelectRows)
我是否应该覆盖它的 ItemSelectionModel 以防止用户单击时的默认行为,同时保持编程选择模式?我怎样才能做到这一点?
【问题讨论】:
您能不能更好地解释一下,您想在什么时候禁用选择?以编程方式选择代码的哪一部分?编程的选择延迟多长时间?一般通过编程选择几乎到现在。也许minimal reproducible example 可以帮助我们了解您 @eyllanesc,我会尽量解释清楚。该表用于显示从 .csv 加载的一些数据,然后用户可以对这些数据执行查询。执行查询后,我在 QTableView 上选择结果集的行。现在,用户还可以选择/取消选择某些行,从而使执行查询的“视图”无效。出于这个原因,我正在寻找一种方法来防止用户通过单击来选择/取消选择行。这里github.com/izio7/AttributedGraphprofiler/blob/maurizio/…完整的源代码。 1) 据我了解,您希望用户不能修改选择,只有程序选择必须保留,例如,如果根据查询选择了第 1.3 行和第 5 行,那么用户应该无法选择其他行或取消选择第 1,3 和 5 行中的任何一行我对吗? 2)我没有要你项目的源代码,我已经要了一个MCVE。 3)如果1)是正确的,那么我将提出我的解决方案,而不是基于任何MCVE。 是的,没错。谢谢 还有一个问题:QTableView可以被用户编辑还是只读? 【参考方案1】:如果您想避免用户选择项目、行或列,您应该执行以下操作:
覆盖委托 editorEvent 方法,使其不通知视图点击。
停用点击标题部分的功能
from PyQt5 import QtCore, QtGui, QtWidgets
class Delegate(QtWidgets.QStyledItemDelegate):
def editorEvent(self, event, model, option, index):
res = super(Delegate, self).editorEvent(event, model, option, index)
if event.type() in (
QtCore.QEvent.MouseButtonPress,
QtCore.QEvent.MouseButtonRelease,
QtCore.QEvent.MouseButtonDblClick,
QtCore.QEvent.MouseMove,
QtCore.QEvent.KeyPress
):
return True
return res
class TableView(QtWidgets.QTableView):
def __init__(self, parent=None):
super(TableView, self).__init__(parent)
self.setSortingEnabled(False)
self.horizontalHeader().setSectionResizeMode(
QtWidgets.QHeaderView.Stretch
)
self.setSelectionMode(QtWidgets.QAbstractItemView.MultiSelection)
self.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
delegate = Delegate(self)
self.setItemDelegate(delegate)
self.horizontalHeader().setSectionsClickable(False)
self.verticalHeader().setSectionsClickable(False)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
model = QtGui.QStandardItemModel()
for i in range(15):
for j in range(6):
it = QtGui.QStandardItem("-".format(i, j))
model.setItem(i, j, it)
table = TableView()
table.setModel(model)
# emulate select by query
import random
for row in random.sample(range(model.rowCount()), 5):
table.selectRow(row)
table.resize(640, 480)
table.show()
sys.exit(app.exec_())
【讨论】:
我还注意到按空格键可能会影响一行的选择/取消选择,所以我在要忽略的事件中添加了QEvent.KeyPress
。以上是关于如何在保持程序化行选择的同时防止用户点击行选择?的主要内容,如果未能解决你的问题,请参考以下文章