Last active
February 27, 2017 15:00
-
-
Save eulersson/768ca84c1387b71f1ec948685f895a2e to your computer and use it in GitHub Desktop.
Drag & Drop Labels
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
import sys | |
import uuid | |
from PySide import QtCore, QtGui | |
COLOR_MAP = { | |
'WIP': '#994', | |
'Unassigned': '#944', | |
'Assigned': '#494', | |
} | |
class Ticket(QtGui.QLabel): | |
ticket_clicked = QtCore.Signal(object) | |
def __init__(self, name, id, status, notes, parent): | |
super(Ticket, self).__init__(name, parent) | |
self.name = name | |
self.id = id | |
self.status = status | |
self.notes = notes | |
self.update_ticket_info() | |
def set_status(self, status): | |
self.status = status | |
def update_ticket_info(self): | |
self.color = COLOR_MAP.get(self.status) | |
self.setToolTip( | |
""" | |
<b>Name:</b> %s<br> | |
<b>Id:</b> %s<br> | |
<b>Status:</b> <span style="color:%s">%s</span>.<br> | |
<b>Notes:</b> %s | |
""" % (self.name, self.id, self.color, self.status, self.notes) | |
) | |
self.setStyleSheet( | |
""" | |
QLabel { | |
background-color: %s; | |
border: none; | |
color: white; | |
border-radius: 10px; | |
padding: 0px 2px; | |
margin: 1px 1px; | |
} | |
""" % (self.color) | |
) | |
def mouseMoveEvent(self, event): | |
hotSpot = event.pos() | |
mimeData = QtCore.QMimeData() | |
mimeData.setText(str(self)) | |
pixmap = QtGui.QPixmap(self.size()) | |
self.render(pixmap) | |
drag = QtGui.QDrag(self) | |
drag.setMimeData(mimeData) | |
drag.setPixmap(pixmap) | |
drag.setHotSpot(hotSpot) | |
dropAction = drag.exec_(QtCore.Qt.MoveAction) | |
def mouseReleaseEvent(self, event): | |
self.ticket_clicked.emit(self) | |
class TicketContainer(QtGui.QWidget): | |
def __init__(self, tickets, parent=None): | |
super(TicketContainer, self).__init__(parent=parent) | |
for t in tickets: | |
ticket = Ticket(t['name'], t['id'], t['status'], t['notes'], self) | |
ticket.ticket_clicked.connect(self.on_ticket_clicked) | |
self.setAcceptDrops(True) | |
self.setMinimumSize(400, 60) | |
self.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) | |
self.setStyleSheet("QWidget {background-color: #3c3c3c; border: 2px solid #5c5c5c;}") | |
self.update_tickets() | |
def dragEnterEvent(self, event): | |
if event.mimeData().hasText(): | |
event.setDropAction(QtCore.Qt.MoveAction) | |
event.accept() | |
else: | |
event.ignore() | |
def dropEvent(self, event): | |
if event.mimeData().hasText(): | |
ticket = event.source() | |
old_parent = event.source().parentWidget() | |
new_parent = self | |
ticket.setParent(new_parent) | |
ticket.set_status(new_parent._status) | |
ticket.update_ticket_info() | |
new_parent.update_tickets() | |
old_parent.update_tickets() | |
else: | |
event.ignore() | |
def on_ticket_clicked(self, ticket): | |
for container in self.parentWidget().findChildren(TicketContainer): | |
if container != self: | |
ticket.setParent(container) | |
ticket.ticket_clicked.connect(container.on_ticket_clicked) | |
ticket.set_status(container._status) | |
ticket.update_ticket_info() | |
container.update_tickets() | |
self.update_tickets() | |
break | |
def paintEvent(self, event): | |
option = QtGui.QStyleOption() | |
option.initFrom(self) | |
painter = QtGui.QPainter(self) | |
self.style().drawPrimitive(QtGui.QStyle.PE_Widget, option, painter, self) | |
def update_tickets(self): | |
x = 5 | |
y = 5 | |
for ticket in self.findChildren(Ticket): | |
ticket.move(x, y) | |
ticket.show() | |
x += ticket.width() + 2 | |
if x >= self.size().width()-ticket.size().width(): | |
x = 5 | |
y += ticket.height() + 2 | |
self.setMinimumSize(400, max(60, y)) | |
def collect_tickets(self): | |
return [ticket for ticket in self.findChildren(Ticket)] | |
class UnassignedTicketsWidget(TicketContainer): | |
def __init__(self, tickets, parent=None): | |
super(UnassignedTicketsWidget, self).__init__(tickets, parent=parent) | |
self._status = 'Unassigned' | |
class AssignedTicketsWidget(TicketContainer): | |
def __init__(self, tickets, parent=None): | |
super(AssignedTicketsWidget, self).__init__(tickets, parent=parent) | |
self._status = 'WIP' | |
class PublishWidget(QtGui.QWidget): | |
def __init__(self, parent=None): | |
super(PublishWidget, self).__init__(parent=parent) | |
layout = QtGui.QVBoxLayout() | |
tickets = [ | |
{ | |
'name': 'fix{}'.format(str(i)), | |
'id': uuid.uuid4().hex, | |
'status': 'Unassigned', | |
'notes': 'notes are cool.' | |
} for i in range(1, 10) | |
] | |
self.unassigned_tickets_widget = UnassignedTicketsWidget(tickets, parent=self) | |
self.assigned_tickets_widget = AssignedTicketsWidget([], parent=self) | |
layout.addWidget(QtGui.QLabel("<b>Unassigned Tickets:</b>")) | |
layout.addWidget(self.unassigned_tickets_widget) | |
layout.addWidget(QtGui.QLabel("<b>Assigned Tickets:</b>")) | |
layout.addWidget(self.assigned_tickets_widget) | |
collect_tickets_button = QtGui.QPushButton("Collect") | |
layout.addWidget(collect_tickets_button) | |
collect_tickets_button.clicked.connect(self.collect_assigned_tickets) | |
self.setLayout(layout) | |
def collect_assigned_tickets(self): | |
print self.assigned_tickets_widget.collect_tickets() | |
if __name__ == '__main__': | |
app = QtGui.QApplication(sys.argv) | |
w = PublishWidget() | |
w.show() | |
app.exec_() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment