2017-03-16 13 views
1

私は、ドロップされたテキストを受け入れる単純なQListWidgetを作成しようとしました。それを働かせることはできません。ドロップイベントは起動されませんが、ドラッグイベントはもう一方のイベントです。 誰かが私を正しい方向に向けることができますか?私は何を間違えたのですか?Python PyQt5:QListWidgetはドロップを受け付けません

ありがとうございます。

import sys 
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QLineEdit, QLabel, QListWidget 
from PyQt5.QtGui import QIcon 
from PyQt5.QtCore import pyqtSlot 

class App(QWidget): 

    def __init__(self): 
     super().__init__() 
     self.title = 'PyQt5 drag and drop' 
     self.left = 500 
     self.top = 400 
     self.width = 400 
     self.height = 250 
     self.initUI() 

    def initUI(self): 
     self.setWindowTitle(self.title) 
     self.setGeometry(self.left, self.top, self.width, self.height) 

     editBox = QLineEdit('Drag this', self) 
     editBox.setDragEnabled(True) 
     editBox.move(10, 10) 
     editBox.resize(100,32) 

     listwidget = CustomLabel(self) 
     listwidget.move(130,15) 

     self.show() 


class CustomLabel(QListWidget): 

    def __init__(self, parent): 
     super().__init__(parent) 
     self.setAcceptDrops(True) 

    def dragEnterEvent(self, e): 
     if e.mimeData().hasFormat('text/plain'): 
      print("dragged") 
      e.accept() 
     else: 
      e.ignore() 


    def dropEvent(self, e): 
     print("dropped") 

     self.addItem(event.mimeData().text()) 

if __name__ == '__main__': 
    app = QApplication(sys.argv) 
    ex = App() 
    sys.exit(app.exec_()) 
+0

何らかの理由でドラッグを開始する必要があります。 [ドラッグ&ドロップの文書](http://doc.qt.io/qt-5/dnd.html)を見てください。 –

+0

それを得ることはできません...ごめんなさい – Arwed

+0

これは、特定のウィジェットに*受け入れ*ドロップを伝えるだけです。実際にドラッグ操作を開始することとは関係ありません。私の最初のコメントにリンクされているドキュメントをお読みください。 –

答えて

1

デフォルトでは、QListWidgetはドロップされたテキストを処理しないため、次のようにMIMEデータ処理を再実装する必要があります。

class CustomLabel(QListWidget):  
    def __init__(self, parent): 
     super().__init__(parent) 
     self.setAcceptDrops(True) 

    def mimeTypes(self): 
     mimetypes = super().mimeTypes() 
     mimetypes.append('text/plain') 
     return mimetypes 

    def dropMimeData(self, index, data, action): 
     if data.hasText(): 
      self.addItem(data.text()) 
      return True 
     else: 
      return super().dropMimeData(index, data, action) 
0

あなたのコードはthis exampleに基づいているようです。

主な違いはCustomLabelQLabelではなくQListWidgetから継承されていることです。残念ながらQListWidgetQAbstractScrollAreaから継承され、それはQListWidgetではなく、さまざまなドラッグ/ドロップイベントを受け取るスクロールエリアに関連付けられたビューポートウィジェットです。

あなたの最善の策は....ビューポート上のイベントフィルタをインストールするかもしれません

class CustomLabel(QListWidget): 
    def __init__(self, parent): 
     super().__init__(parent) 
     self.setAcceptDrops(True) 

     # Install the event filter. 
     self.viewport().installEventFilter(self) 

    def dragEnterEvent(self, e): 
     if e.mimeData().hasFormat('text/plain'): 
      print("dragged") 
      e.accept() 
     else: 
      e.ignore() 

    def eventFilter (self, obj, event): 
     if obj == self.viewport(): 
      print("event") 
      if event.type() == QEvent.DragMove: 
       print("moved") 
       event.accept() 

       # Your drag enter event processing code goes here 
       return True 
      if event.type() == QEvent.Drop: 
       print("dropped") 
       event.accept() 

       # Your drop event processing code goes here 
       return True 
     return super(CustomLabel, self).eventFilter(obj, event) 

編集1:あなたはおそらくも追加する必要があります

...

from PyQt5.QtCore import QEvent 
+0

あなたはそうです、その例のわずかに変更されたバージョンです。私はあなたのコードでCustomLabelクラスを置き換えると、CustomLabelから何か他のクラスにリネームするのを忘れてしまった。 – Arwed

+0

**編集1 **を参照してください。 –

0

素晴らしい。今、それは動作します。 お世話になりました。 それでは、コード全体をまとめる:

import sys 
from PyQt5.QtWidgets import QApplication, QWidget, QLineEdit, QListWidget 


class App(QWidget): 

    def __init__(self): 
     super().__init__() 
     self.title = 'PyQt5 drag and drop' 
     self.left = 500 
     self.top = 400 
     self.width = 400 
     self.height = 250 
     self.initUI() 

    def initUI(self): 
     self.setWindowTitle(self.title) 
     self.setGeometry(self.left, self.top, self.width, self.height) 

     editBox = QLineEdit('Drag this', self) 
     editBox.setDragEnabled(True) 
     editBox.move(10, 10) 
     editBox.resize(100,32) 

     listwidget = CustomList(self) 
     listwidget.move(130,15) 

     self.show() 


class CustomList(QListWidget): 

    def __init__(self, parent): 
     super().__init__(parent) 
     self.setAcceptDrops(True) 

    def mimeTypes(self): 
     mimetypes = super().mimeTypes() 
     mimetypes.append('text/plain') 
     return mimetypes 

    def dropMimeData(self, index, data, action): 
     if data.hasText(): 
      self.addItem(data.text()) 
      return True 
     else: 
      return super().dropMimeData(index, data, action) 


if __name__ == '__main__': 
    app = QApplication(sys.argv) 
    ex = App() 
    sys.exit(app.exec_()) 
関連する問題