Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save oglops/bfc39625913ed301bcbd to your computer and use it in GitHub Desktop.
Save oglops/bfc39625913ed301bcbd to your computer and use it in GitHub Desktop.
enable drag and drop / extended selection at the same time by setting QAbstractItemView.DragSelectingState, set optimum dragging hotzone, fix single click after dragging selection
from PyQt4 import QtGui, QtCore
from PyQt4.QtCore import Qt, QString
import sys
import os
class ThumbListWidget(QtGui.QListWidget):
_rows_to_del = []
def __init__(self, type, parent=None):
super(ThumbListWidget, self).__init__(parent)
self.setIconSize(QtCore.QSize(124, 124))
self.setDragDropMode(QtGui.QAbstractItemView.DragDrop)
self.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
self.setAcceptDrops(True)
self._dropping = False
self.setSelectionRectVisible(True)
self.connect(self, QtCore.SIGNAL("dropped"), self.items_dropped)
def dragEnterEvent(self, event):
if event.mimeData().hasUrls():
event.accept()
else:
super(ThumbListWidget, self).dragEnterEvent(event)
def dragMoveEvent(self, event):
if event.mimeData().hasUrls():
event.setDropAction(QtCore.Qt.CopyAction)
event.accept()
else:
super(ThumbListWidget, self).dragMoveEvent(event)
def dropEvent(self, event):
if event.mimeData().hasUrls():
event.setDropAction(QtCore.Qt.CopyAction)
event.accept()
links = []
for url in event.mimeData().urls():
links.append(str(url.toLocalFile()))
self.emit(QtCore.SIGNAL("dropped"), links)
else:
if event.source() is self:
event.setDropAction(QtCore.Qt.MoveAction)
else:
event.setDropAction(QtCore.Qt.CopyAction)
self._dropping = True
super(ThumbListWidget, self).dropEvent(event)
self._dropping = False
def rowsInserted(self, parent, start, end):
if self._dropping:
self.emit(QtCore.SIGNAL("dropped"), (start, end))
super(ThumbListWidget, self).rowsInserted(parent, start, end)
def dataChanged(self, start, end):
if self._dropping:
for row in range(start.row(), end.row() + 1):
index = self.indexFromItem(self.item(row))
shot = index.data().toString()
# print len(self.findItems(shot, Qt.MatchExactly))
if len(self.findItems(shot, Qt.MatchExactly)) > 1:
self._rows_to_del.append(row)
self._rows_to_del.reverse()
for row in self._rows_to_del:
self.takeItem(row)
self._rows_to_del = []
def items_dropped(self, arg):
start, end = arg
print range(start, end + 1)
for row in range(start, end + 1):
item = self.item(row)
item.setFlags(item.flags() | Qt.ItemIsUserCheckable)
item.setCheckState(Qt.Checked)
def keyPressEvent(self, event):
if event.key() == Qt.Key_Space:
if self.selectedItems():
new_state = Qt.Unchecked if self.selectedItems()[0].checkState() else Qt.Checked
for item in self.selectedItems():
if item.flags() & Qt.ItemIsUserCheckable:
# print 'set new state:', new_state
item.setCheckState(new_state)
self.reset()
elif event.key() == Qt.Key_Delete:
for item in self.selectedItems():
self.takeItem(self.row(item))
def mousePressEvent(self, event):
QtGui.QListWidget.mousePressEvent(self, event)
self.mousePressPos = (event.pos())
def mouseMoveEvent(self, event):
if (event.pos() - self.mousePressPos).manhattanLength() > QtGui.QApplication.startDragDistance():
item = self.itemAt(event.pos())
if item:
rect = self.visualItemRect(item)
# offset = 100
char_width = QtGui.QFontMetricsF(QtGui.QFont(self.font())).width('a')
offset = len(item.data(0).toString()) * char_width
if rect.translated(offset, 0).contains(event.pos()):
self.setState(QtGui.QAbstractItemView.DragSelectingState)
QtGui.QListWidget.mouseMoveEvent(self, event)
class Dialog_01(QtGui.QMainWindow):
def __init__(self):
super(QtGui.QMainWindow, self).__init__()
self.listItems = {}
myQWidget = QtGui.QWidget()
myBoxLayout = QtGui.QVBoxLayout()
myQWidget.setLayout(myBoxLayout)
self.setCentralWidget(myQWidget)
self.listWidgetA = ThumbListWidget(self)
for i in range(12):
QtGui.QListWidgetItem('Item ' + str(i), self.listWidgetA)
all_items = self.listWidgetA.findItems(QString('*'), Qt.MatchWrap | Qt.MatchWildcard)
for item in all_items:
item.setFlags(item.flags() & ~Qt.ItemIsUserCheckable)
myBoxLayout.addWidget(self.listWidgetA)
self.listWidgetB = ThumbListWidget(self)
self.listWidgetA.setAcceptDrops(False)
myBoxLayout.addWidget(self.listWidgetB)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
dialog_1 = Dialog_01()
dialog_1.show()
dialog_1.resize(480, 320)
sys.exit(app.exec_())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment