一点背景知识(不是理解问题完全必要的(:
在我今年早些时候开发的 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 项目悬停/基于当前颜色的选定背景颜色