9

QListWidget次のように初期化された を含む Qt4 アプリケーション (PyQt バインディングを使用) があります。

class MyList(QtGui.QListWidget):
    def __init__(self):
        QtGui.QListWidget.__init__(self)
        self.setDragDropMode(self.InternalMove)

アイテムを追加できます。これにより、ドラッグ アンド ドロップしてリストを並べ替えることができます。しかし、リストがユーザーによって並べ替えられたときに通知を受け取るにはどうすればよいでしょうか? dropMimeData(self, index, data, action)クラスにメソッドを追加しようとしましたが、呼び出されません。

4

6 に答える 6

15

もっと簡単な方法があります。:)

実際には listwidget の内部モデルにアクセスできますmyList->model()- そしてそこから利用可能なシグナルがたくさんあります。

ドラッグ アンド ドロップだけが必要な場合は、 に接続しlayoutChangedます。移動ボタン (通常は削除 + 追加で実装される) がある場合は、rowsInsertedあまりにも接続します。

何が動いたのか知​​りたければ、rowsMovedより良いかもしれませんlayoutChanged

于 2012-11-13T20:20:53.403 に答える
7

私はこれに対処しなければならず、お尻の痛みですが、ここで何をすべきかです:

サブクラスに をインストールしてからeventFilter、イベントListWidgetを監視する必要があります。ChildRemovedこのイベントは移動と削除をカバーするため、リスト内でドラッグ アンド ドロップを使用して項目を再配置する場合に機能するはずです。

私は C++ で Qt を書いていますが、ここに pythonification バージョンがあります:

class MyList(QtGui.QListWidget):
    def __init__(self):
        QtGui.QListWidget.__init__(self)
        self.setDragDropMode(self.InternalMove)
        self.installEventFilter(self)

    def eventFilter(self, sender, event):
        if (event.type() == QEvent.ChildRemoved):
            self.on_order_changed()
        return False # don't actually interrupt anything

    def on_order_changed(self):
        # do magic things with our new-found knowledge

このリストを含む他のクラスがある場合は、イベント フィルター メソッドをそこに移動することをお勧めします。これが役立つことを願っています.これを理解する前に、これと1日戦わなければならなかったことを知っています.

于 2009-10-06T21:31:22.773 に答える
5

Trey Stout の答えがうまくいったことがわかりましたが、リストの順序が実際に変更されていないときに明らかにイベントを取得していました。必要に応じて機能するChaniの回答に目を向けましたが、コードがないとPythonで実装するのに少し手間がかかりました。

将来の訪問者を助けるために、コード スニペットを共有すると思いました。

class MyList(QListWidget):
    def __init__(self):
        QListWidget.__init__(self)
        self.setDragDropMode(self.InternalMove)
        list_model = self.model()
        list_model.layoutChanged.connect(self.on_layout_changed)

    def on_layout_changed(self):
        print "Layout Changed"

これは PySide でテストされていますが、PyQt で動作しない理由はありません。

于 2012-12-01T16:04:45.193 に答える
1

私はこれが古いことを知っていますが、Treyの答えを使用してコードを機能させることができ、Pythonソリューションを共有したいと思いました。これは、サブクラス化されたものではなく、QListWidget内部用です。QDialog

class NotesDialog(QtGui.QDialog):
    def __init__(self, notes_list, notes_dir):
        QtGui.QDialog.__init__(self)
        self.ui=Ui_NotesDialog()
        # the notesList QListWidget is created here (from Qt Designer)
        self.ui.setupUi(self) 

        # install an event filter to catch internal QListWidget drop events
        self.ui.notesList.installEventFilter(self)

    def eventFilter(self, sender, event):
        # this is the function that processes internal drop in notesList
        if event.type() == QtCore.QEvent.ChildRemoved:
            self.update_views() # do something
        return False # don't actually interrupt anything
于 2012-09-19T21:39:25.380 に答える
1

解決策ではありませんが、いくつかのアイデア:

supportedDropActions メソッドによって何が返されるかを確認する必要があります。Qt::MoveAction または Qt::CopyAction を含めるために、そのメソッドを上書きする必要があるかもしれません。

QListView::indexesMoved シグナルがありますが、QListWidget を使用している場合に送信されるかどうかはわかりません。チェックする価値があります。

于 2009-08-05T08:20:15.617 に答える