QListWidgetItem перетаскивается только при нажатии кнопки

Я пытаюсь создать QListWidget, в котором есть настраиваемые виджеты, каждый из которых содержит кнопку перетаскивания. Идея состоит в том, что QListWidgetItem можно перетаскивать только тогда, когда нажата кнопка внутри него, называемая «перетаскивание». После отпускания мыши/кнопки QListWidgetItem упадет на свое место. Все это должно действовать так же, как обычный QListWidget, за исключением того, что место нажатия мыши должно быть на кнопке, называемой «перетаскивание».

Мой текущий метод состоит в том, чтобы установить все флаги QListWidgetItem в ~Qt.ItemIsDragEnabled при инициализации, а затем снова включить это при нажатии кнопки. Затем, покидая виджет, я отключаю перетаскивание.

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

import sys
import os
from PyQt4 import QtGui
from PyQt4.QtCore import *
from PyQt4.QtGui import *


class DragArea(QFrame):
    """docstring for DragButton"""
    def __init__(self, parent=None, text='Test', index=None):
        super(DragArea, self).__init__()
        self.parent = parent
        self.index = index
        self.layout = QHBoxLayout()
        self.setLayout(self.layout)

        self.label = QLabel()
        self.button = QPushButton()

        self.label.setText(text)
        self.button.setText('Drag')

        self.layout.addWidget(self.label)
        self.layout.addWidget(self.button)

        self.button.pressed.connect(self.drag)

    def drag(self):
        item = self.parent.bodyMap[self.index]
        item.setFlags(
            Qt.ItemIsSelectable |
            Qt.ItemIsEnabled |
            Qt.ItemIsDragEnabled
            )

    def leaveEvent(self, event):
        item = self.parent.bodyMap[self.index]
        item.setFlags(
            item.flags() &
            ~Qt.ItemIsSelectable &
            ~Qt.ItemIsEnabled &
            ~Qt.ItemIsDragEnabled
            )


class QuoteArea(QListWidget):
    def __init__(self, parent=None):
        super(QuoteArea, self).__init__()

        self.bodyMap = {}
        self.setStyleSheet("""
            QListWidget {
                background: gray;
            }

            QListWidget::item:selected {
                background: None;
                }

            """)
        self.setDragDropMode(QAbstractItemView.InternalMove)
        self.setDefaultDropAction(Qt.MoveAction)
        self.setDragDropOverwriteMode(False)
        self.setAcceptDrops(True)
        self.setDropIndicatorShown(True)
        self.setDragEnabled(True)
        self.setSelectionRectVisible(False)
        self.setResizeMode(QListView.Adjust)
        self.setGeometry(30, 40, 400, 500)
        for a in xrange(5):
            self.addQuote(a)


    def addQuote(self, index):
        text = 'Lorum ipsum ' + str(index)
        widget = DragArea(text=text, parent=self, index=index)
        item = QListWidgetItem()
        item.setFlags(item.flags() &
            ~Qt.ItemIsSelectable &
            ~Qt.ItemIsEnabled &
            ~Qt.ItemIsDragEnabled
            )
        self.bodyMap[index] = item
        item.setSizeHint(
            QSize(item.sizeHint().width(), widget.sizeHint().height())
            )
        self.addItem(item)
        self.setItemWidget(item, widget)


def main():
    app = QtGui.QApplication(sys.argv)
    ex = QuoteArea()
    ex.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

person Ethan Kay    schedule 24.11.2015    source источник


Ответы (1)


Я думаю, что кнопка съедает все события мыши. Пресса, а также движения. Я предполагаю, что единственное решение состоит в том, чтобы получить новый класс кнопки из QPushButton и повторно реализовать mouseEvents, потому что вам нужна ваша кнопка, чтобы сообщать о mouseEvents в список.

Ваша кнопка может иметь ссылку на объект, который должен получать события.

Так:

class MyPushButton(QPushButton): # derive from QPushButton

   # .. some more code here

   def mouseEvent(self, event):
      QPushButton.mouseEvent(event) # call mouse event of base class to get the button animation
      self.draggerObject.mouseEvent(event) # call the mouse event of the dragging classes using the event.

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

person Aaron    schedule 25.11.2015