Python: PyQt- FlowLayout
#! /usr/bin/python2 | |
# -*- coding: utf-8 -*- | |
from PyQt4 import QtCore, QtGui | |
class FlowLayout(QtGui.QLayout): | |
def __init__(self, parent=None, margin=0, spacing=-1): | |
super(FlowLayout, self).__init__(parent) | |
if parent is not None: | |
self.setMargin(margin) | |
self.setSpacing(spacing) | |
self.itemList = [] | |
def __del__(self): | |
item = self.takeAt(0) | |
while item: | |
item = self.takeAt(0) | |
def addItem(self, item): | |
self.itemList.append(item) | |
def count(self): | |
return len(self.itemList) | |
def itemAt(self, index): | |
if index >= 0 and index < len(self.itemList): | |
return self.itemList[index] | |
return None | |
def takeAt(self, index): | |
if index >= 0 and index < len(self.itemList): | |
return self.itemList.pop(index) | |
return None | |
def expandingDirections(self): | |
return QtCore.Qt.Orientations(QtCore.Qt.Orientation(0)) | |
def hasHeightForWidth(self): | |
return True | |
def heightForWidth(self, width): | |
height = self._doLayout(QtCore.QRect(0, 0, width, 0), True) | |
return height | |
def setGeometry(self, rect): | |
super(FlowLayout, self).setGeometry(rect) | |
self._doLayout(rect, False) | |
def sizeHint(self): | |
return self.minimumSize() | |
def minimumSize(self): | |
size = QtCore.QSize() | |
for item in self.itemList: | |
size = size.expandedTo(item.minimumSize()) | |
size += QtCore.QSize(2 * self.margin(), 2 * self.margin()) | |
return size | |
def _doLayout(self, rect, testOnly): | |
x = rect.x() | |
y = rect.y() | |
lineHeight = 0 | |
for item in self.itemList: | |
wid = item.widget() | |
spaceX = self.spacing() + wid.style().layoutSpacing( | |
QtGui.QSizePolicy.PushButton, | |
QtGui.QSizePolicy.PushButton, | |
QtCore.Qt.Horizontal) | |
spaceY = self.spacing() + wid.style().layoutSpacing( | |
QtGui.QSizePolicy.PushButton, | |
QtGui.QSizePolicy.PushButton, | |
QtCore.Qt.Vertical) | |
nextX = x + item.sizeHint().width() + spaceX | |
if nextX - spaceX > rect.right() and lineHeight > 0: | |
x = rect.x() | |
y = y + lineHeight + spaceY | |
nextX = x + item.sizeHint().width() + spaceX | |
lineHeight = 0 | |
if not testOnly: | |
item.setGeometry( | |
QtCore.QRect(QtCore.QPoint(x, y), item.sizeHint())) | |
x = nextX | |
lineHeight = max(lineHeight, item.sizeHint().height()) | |
return y + lineHeight - rect.y() | |
if __name__ == '__main__': | |
import sys | |
class Window(QtGui.QWidget): | |
def __init__(self): | |
super(Window, self).__init__() | |
flowLayout = FlowLayout() | |
flowLayout.addWidget(QtGui.QPushButton("Short")) | |
flowLayout.addWidget(QtGui.QPushButton("Longer")) | |
flowLayout.addWidget(QtGui.QPushButton("Different text")) | |
flowLayout.addWidget(QtGui.QPushButton("More text")) | |
flowLayout.addWidget(QtGui.QPushButton("Even longer button text")) | |
self.setLayout(flowLayout) | |
self.setWindowTitle("Flow Layout") | |
app = QtGui.QApplication(sys.argv) | |
mainWin = Window() | |
mainWin.show() | |
sys.exit(app.exec_()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment