Gareth Williams
Gareth Williams

Reputation: 262

PyQt5 QListWidget with checkboxes and drag and drop

I'm trying to build a PyQt5 app, I'd like to create a list widget whose elements are drag-and-drop-able, but where each widget is also associated with a checkbox.

I can create a drag-and-drop-able QListWidget like so:

import sys

from PyQt5.QtWidgets import QApplication, QListWidget


if __name__ == '__main__':
    app = QApplication(sys.argv)

    lw = QListWidget()
    for i in range(5):
        text = f'Item {i}'
        lw.addItem(text)

    lw.setDragDropMode(lw.InternalMove)
    lw.show()

    sys.exit(app.exec_())

However, when I try to add checkboxes to each item, the drag and drop functionality seems to break. Drag and drop doesn't work with the below code:

import sys

from PyQt5.QtWidgets import QApplication, QListWidget, QListWidgetItem
from PyQt5.QtCore import Qt


if __name__ == '__main__':
    app = QApplication(sys.argv)

    lw = QListWidget()
    for i in range(5):
        text = f'Item {i}'
        item = QListWidgetItem(text)
        item.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled)
        lw.addItem(item)

    lw.setDragDropMode(lw.InternalMove)  # Drag and drop doesn't work...
    lw.show()

    sys.exit(app.exec_())

Is there a way to get drag-and-drop-able elements which also each contain a checkbox?

Thanks in advance

Upvotes: 1

Views: 4640

Answers (1)

eyllanesc
eyllanesc

Reputation: 243897

By default, a QListWidgetItem has the following flags activated:

Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled

But you are overwriting it by removing the ItemIsDragEnabled flag, preventing the items from being dragged.

So the solution is to activate the flag using a | operator:

item.setFlags(item.flags() | Qt.ItemIsUserCheckable | Qt.ItemIsEnabled)

Although you see it is unnecessary since these flags are activated by default, the simplest thing is to activate the initial state:

import sys

from PyQt5.QtWidgets import QApplication, QListWidget, QListWidgetItem
from PyQt5.QtCore import Qt

if __name__ == '__main__':
    app = QApplication(sys.argv)

    lw = QListWidget()
    for i in range(5):
        text = f'Item {i}'
        item = QListWidgetItem(text)
        item.setCheckState(Qt.Unchecked)
        lw.addItem(item)
    lw.setDragDropMode(lw.InternalMove)
    lw.show()
    sys.exit(app.exec_())

Upvotes: 1

Related Questions