Created
August 26, 2014 14:49
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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