python - 使 QTableView 中的项目可拖动但不可选择
问题描述
一些背景知识(理解问题不是完全必要的):
在我今年早些时候开发的 PySide2 应用程序中,我有一个与自定义模型一起使用的 QTableView。可以选择其中的一些项目,然后单击按钮对所选项目执行批量操作。其他一些项目作为数据存在的视觉指示,但执行批量操作的函数不知道如何处理它们,所以我将它们设为不可选择。我的程序中有另一个区域可以接受来自外部文件或来自我的 TableView 中的项目的丢弃。在这种情况下,表中的每一个项目都应该能够被拖放到另一个区域。
问题:
当一个项目不可选择时,它似乎也不可拖动。
我试过的:
在代码方面不多,因为我真的不知道如何处理那个。我尝试了很多标志组合但没有成功。
我已经用谷歌搜索和浏览 StackOverflow 几个小时了,但找不到任何相关的东西,我只是被人们询问如何通过拖放重新排序表格的帖子所淹没。
最小复制代码:
from PySide2 import QtCore, QtWidgets, QtGui
class MyWindow(QtWidgets.QWidget):
def __init__(self):
QtWidgets.QWidget.__init__(self)
self.setGeometry(300, 200, 570, 450)
self.setWindowTitle("Drag Example")
model = QtGui.QStandardItemModel(2, 1)
table_view = QtWidgets.QTableView()
selectable = QtGui.QStandardItem("I'm selectable and draggable")
selectable.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsDragEnabled)
model.setItem(0, 0, selectable)
non_selectable = QtGui.QStandardItem("I'm supposed to be draggable, but I'm not")
non_selectable.setFlags(QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsDragEnabled)
model.setItem(1, 0, non_selectable)
table_view.setModel(model)
table_view.setDragDropMode(table_view.DragOnly)
layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(table_view)
self.setLayout(layout)
app = QtWidgets.QApplication([])
win = MyWindow()
win.show()
app.exec_()
有没有人有关于如何使项目启用拖动但禁用选择的建议?
谢谢
解决方案
我找到了一种解决方法,虽然不一定是完美的答案,但它对我有用。
我没有使项目不可选择,而是使用自定义数据角色使其在视觉上看起来像是在选择它时没有选择。
我在批量函数中使用相同的数据标志来过滤选择。
为了使它看起来即使项目没有被选中,我使用了自定义样式的项目委托:
class MyDelegate(QtWidgets.QStyledItemDelegate):
def __init__(self, parent=None):
super(MyDelegate, self).__init__(parent)
def paint(self, painter, option, index):
if option.state & QtWidgets.QStyle.State_Selected:
if index.data(Qt.UserRole) == 2: # Some random flag i'm using
text_brush = option.palette.brush(QtGui.QPalette.Text)
if index.row() % 2 == 0:
bg_brush = option.palette.brush(QtGui.QPalette.Base)
else:
bg_brush = option.palette.brush(QtGui.QPalette.AlternateBase)
# print brush
option.palette.setBrush(QtGui.QPalette.Highlight, bg_brush)
option.palette.setBrush(QtGui.QPalette.HighlightedText, text_brush)
super(MyDelegate, self).paint(painter, option, index)
在我设置的表格中:
delegate = MyDelegate()
table_view.setItemDelegate(delegate)
我从这篇文章中改编了这个解决方案:QTreeView Item Hover/Selected background color based on current color
推荐阅读
- sql - 用过程替换触发器
- maven - 排除 AnnotationProcessorPaths 中的依赖项
- c# - 如何使用 automapper 9.0.0.0 根据句柄属性自动映射两个列表
- sql-server - 使用 Azure Data Lake Store Gen1 中的 SSIS 包将文件从一个目录移动到另一个目录
- wordpress - 仅删除单页上的 Yoast Breadcrumb 最后一项
- vba - 是否可以将先前代码生成的文件名用作下一行代码的变量?
- sql-server - 解析 SQL 脚本以查找表依赖项和输出
- javascript - 如何在某个属性设置为 false 的对象数组中找到下一个对象?
- python - 如何从当前获取所有提交到gitpython中的特定标签
- google-calendar-api - 为什么在尝试将 webCal 添加到 Google 日历时出现错误“不是有效的 URL”?