Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

Created April 24, 2015 18:08
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 anonymous/a3b2d7e61c6b3e11742c to your computer and use it in GitHub Desktop.
Save anonymous/a3b2d7e61c6b3e11742c to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import (division, absolute_import, print_function,
unicode_literals)
import os
import sys
# These are only needed for Python v2 but are harmless for Python v3.
import sip
sip.setapi('QString', 2)
sip.setapi('QVariant', 2)
from PyQt4 import QtCore, QtGui, uic
class ContainerWidget(QtGui.QWidget):
def __init__(self, parent=None):
super(ContainerWidget, self).__init__(parent)
self.layout = QtGui.QHBoxLayout(self)
self.layout.setContentsMargins(0, 0, 0, 0)
self.layout.setSpacing(0)
self.containedWidget = None
def setContainedWidget(self, widget):
self.containedWidget = widget
if widget:
widget.setParent(self)
self.layout.addWidget(widget)
def cloneAndPassContainedWidget(self):
cloned = ContainerWidget(self.parent())
cloned.setContainedWidget(self.containedWidget)
self.setContainedWidget(None)
return cloned
class GridWidget(QtGui.QTableWidget):
def resizeEvent(self, event):
total_width = self.viewport().width()
nb_columns = self.columnCount()
for column in range(nb_columns):
self.horizontalHeader().resizeSection(column,
total_width / nb_columns)
def posToRowCol(self, pos):
index = self.indexAt(pos)
if not index:
return None
return (index.row(), index.column())
def dropEvent(self, event):
if event.source() == self and \
(event.dropAction() == QtCore.Qt.MoveAction or
self.dragDropMode() == QtGui.QAbstractItemView.InternalMove):
destPos = self.posToRowCol(event.pos())
if destPos:
index = self.selectedIndexes()[0]
widget = self.cellWidget(index.row(), index.column())
if widget:
cloned_widget = widget.cloneAndPassContainedWidget()
self.setCellWidget(destPos[0], destPos[1], cloned_widget)
self.removeCellWidget(index.row(), index.column())
event.accept()
event.setDropAction(QtCore.Qt.CopyAction)
super(GridWidget, self).dropEvent(event)
def addWidget(self, row, col, widget):
container_widget = ContainerWidget(self)
container_widget.setContainedWidget(widget)
self.setCellWidget(row, col, container_widget)
def firstEmptyCell(self):
empty_cell = (-1, -1)
for row in range(self.rowCount()):
for column in range(self.columnCount()):
if not self.cellWidget(row, column):
empty_cell = (row, column)
break
if empty_cell != (-1, -1):
break
if empty_cell == (-1, -1):
self.insertRow(self.rowCount())
empty_cell = (self.rowCount() - 1, 0)
return empty_cell
class CustomWidget(QtGui.QLabel):
def __init__(self, parent=None):
super(CustomWidget, self).__init__(parent)
self.setStyleSheet('background-color: red; color: yellow;')
TestPanelUi = uic.loadUiType(os.path.join(os.path.dirname(__file__),
'gridwidget.ui'))[0]
class TestPanel(QtGui.QMainWindow, TestPanelUi):
def __init__(self):
super(TestPanel, self).__init__()
self.setupUi(self)
self.pushButton.clicked.connect(self.addWidget)
self.counter = 0
@QtCore.pyqtSlot()
def addWidget(self):
self.counter += 1
widget = CustomWidget(self.gridWidget)
widget.setText('Widget {}'.format(self.counter))
row, col = self.gridWidget.firstEmptyCell()
self.gridWidget.addWidget(row, col, widget)
def main():
app = QtGui.QApplication(sys.argv)
panel = TestPanel()
panel.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>Drag and drop widgets !</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>Add a widget</string>
</property>
</widget>
</item>
<item>
<widget class="GridWidget" name="gridWidget">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="dragEnabled">
<bool>true</bool>
</property>
<property name="dragDropOverwriteMode">
<bool>false</bool>
</property>
<property name="dragDropMode">
<enum>QAbstractItemView::InternalMove</enum>
</property>
<property name="rowCount">
<number>3</number>
</property>
<property name="columnCount">
<number>3</number>
</property>
<attribute name="horizontalHeaderVisible">
<bool>false</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
<row/>
<row/>
<row/>
<column/>
<column/>
<column/>
</widget>
</item>
</layout>
</widget>
</widget>
<customwidgets>
<customwidget>
<class>GridWidget</class>
<extends>QTableWidget</extends>
<header>gridwidget</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment