2015-11-24 4 views
0

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

Мой текущий метод заключается в том, чтобы установить все флаги 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() 

ответ

0

Я думаю, что кнопка съедает все события мыши. Пресса, а также движения. Я думаю, единственное решение состоит в том, чтобы вывести новый класс кнопок из 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. 

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