Сделать элемент в QTableView перетаскиваемым, но не выбираемым - PullRequest
0 голосов
/ 22 сентября 2019

Немного предыстории (не обязательно для понимания проблемы):

В приложении 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_()

У кого-нибудь есть предложения относительно того, как включить перетаскивание элементов?но выбор отключен?

Спасибо

1 Ответ

0 голосов
/ 29 сентября 2019

Я нашел обходной путь, хотя и не обязательно идеальный ответ, он мне помогает.

Вместо того, чтобы сделать элемент невыбираемым, я визуально выгляжу так, как будто он не выбирается при выборе, используя пользовательскую роль данных.

Я использую тот же флаг данных в своей функции массовых операций, чтобы отфильтровать выбор.

Чтобы выглядело, что элементы не выбраны, даже если они есть,Я использовал делегат пользовательского стиля:

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цвет в зависимости от текущего цвета

...