使 QTableView 中的项目可拖动但不可选择
Make an Item in a QTableView draggable but not selectable
一点背景知识(不是理解问题所必需的):
在我今年早些时候开发的 PySide2 应用程序中,我有一个与自定义模型一起使用的 QTableView。
可以选择其中的一些项目,然后单击按钮对所选项目执行批量操作。
其他一些项目作为数据存在的视觉指示,但执行批量操作的函数不知道如何处理它们,所以我将它们设为非选择 table。
我的程序中有另一个区域可以接受来自外部文件或来自我的 TableView 中的项目的丢弃。在这种情况下,table 中的每一项都应该能够被拖放到另一个区域。
问题:
当一个Item不被选择时table,它似乎也不可拖动。
我试过的:
代码方面不多,因为我真的不知道如何处理那个代码。
我尝试了很多Flags的组合都没有成功。
我已经用谷歌搜索和浏览 Whosebug 几个小时了,但找不到任何相关的东西,我只是被人们询问如何通过拖放重新排序 table 的帖子淹没了.
最小复制码:
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_()
有没有人对如何使项目启用拖动但禁用选择有建议?
谢谢
我找到了一个解决方法,虽然不一定是完美的答案,但它对我有用。
我没有使项目无法 select,而是使用自定义数据角色在 select 处理它时使它在视觉上看起来不像 select。
我在批量函数中使用相同的数据标志来过滤掉 select离子。
为了让项目看起来像没有 selected,即使它们是,我使用了自定义样式的项目委托:
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)
并且在 table 我设置:
delegate = MyDelegate()
table_view.setItemDelegate(delegate)
我从这个post改编了这个解决方案:
一点背景知识(不是理解问题所必需的):
在我今年早些时候开发的 PySide2 应用程序中,我有一个与自定义模型一起使用的 QTableView。 可以选择其中的一些项目,然后单击按钮对所选项目执行批量操作。 其他一些项目作为数据存在的视觉指示,但执行批量操作的函数不知道如何处理它们,所以我将它们设为非选择 table。 我的程序中有另一个区域可以接受来自外部文件或来自我的 TableView 中的项目的丢弃。在这种情况下,table 中的每一项都应该能够被拖放到另一个区域。
问题:
当一个Item不被选择时table,它似乎也不可拖动。
我试过的:
代码方面不多,因为我真的不知道如何处理那个代码。 我尝试了很多Flags的组合都没有成功。
我已经用谷歌搜索和浏览 Whosebug 几个小时了,但找不到任何相关的东西,我只是被人们询问如何通过拖放重新排序 table 的帖子淹没了.
最小复制码:
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_()
有没有人对如何使项目启用拖动但禁用选择有建议?
谢谢
我找到了一个解决方法,虽然不一定是完美的答案,但它对我有用。
我没有使项目无法 select,而是使用自定义数据角色在 select 处理它时使它在视觉上看起来不像 select。
我在批量函数中使用相同的数据标志来过滤掉 select离子。
为了让项目看起来像没有 selected,即使它们是,我使用了自定义样式的项目委托:
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)
并且在 table 我设置:
delegate = MyDelegate()
table_view.setItemDelegate(delegate)
我从这个post改编了这个解决方案: