Nils
3 years ago
11 changed files with 429 additions and 57 deletions
Binary file not shown.
@ -0,0 +1,159 @@ |
|||||
|
#!/usr/bin/env python |
||||
|
|
||||
|
|
||||
|
############################################################################# |
||||
|
## |
||||
|
## Copyright (C) 2013 Riverbank Computing Limited. |
||||
|
## Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). |
||||
|
## All rights reserved. |
||||
|
## |
||||
|
## This file is part of the examples of PyQt. |
||||
|
## |
||||
|
## $QT_BEGIN_LICENSE:BSD$ |
||||
|
## You may use this file under the terms of the BSD license as follows: |
||||
|
## |
||||
|
## "Redistribution and use in source and binary forms, with or without |
||||
|
## modification, are permitted provided that the following conditions are |
||||
|
## met: |
||||
|
## * Redistributions of source code must retain the above copyright |
||||
|
## notice, this list of conditions and the following disclaimer. |
||||
|
## * Redistributions in binary form must reproduce the above copyright |
||||
|
## notice, this list of conditions and the following disclaimer in |
||||
|
## the documentation and/or other materials provided with the |
||||
|
## distribution. |
||||
|
## * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor |
||||
|
## the names of its contributors may be used to endorse or promote |
||||
|
## products derived from this software without specific prior written |
||||
|
## permission. |
||||
|
## |
||||
|
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
|
## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
|
## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
|
## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
|
## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
|
## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
|
## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
|
## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
|
## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
|
## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
|
## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." |
||||
|
## $QT_END_LICENSE$ |
||||
|
## |
||||
|
############################################################################# |
||||
|
|
||||
|
|
||||
|
from PyQt5.QtCore import QPoint, QRect, QSize, Qt |
||||
|
from PyQt5.QtWidgets import (QApplication, QLayout, QPushButton, QSizePolicy, |
||||
|
QWidget) |
||||
|
|
||||
|
|
||||
|
class Window(QWidget): |
||||
|
def __init__(self): |
||||
|
super(Window, self).__init__() |
||||
|
|
||||
|
flowLayout = FlowLayout() |
||||
|
flowLayout.addWidget(QPushButton("Short")) |
||||
|
flowLayout.addWidget(QPushButton("Longer")) |
||||
|
flowLayout.addWidget(QPushButton("Different text")) |
||||
|
flowLayout.addWidget(QPushButton("More text")) |
||||
|
flowLayout.addWidget(QPushButton("Even longer button text")) |
||||
|
self.setLayout(flowLayout) |
||||
|
|
||||
|
self.setWindowTitle("Flow Layout") |
||||
|
|
||||
|
|
||||
|
class FlowLayout(QLayout): |
||||
|
def __init__(self, parent=None, margin=0, spacing=-1): |
||||
|
super(FlowLayout, self).__init__(parent) |
||||
|
|
||||
|
if parent is not None: |
||||
|
self.setContentsMargins(margin, margin, margin, 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 Qt.Orientations(Qt.Orientation(0)) |
||||
|
|
||||
|
def hasHeightForWidth(self): |
||||
|
return True |
||||
|
|
||||
|
def heightForWidth(self, width): |
||||
|
height = self.doLayout(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 = QSize() |
||||
|
|
||||
|
for item in self.itemList: |
||||
|
size = size.expandedTo(item.minimumSize()) |
||||
|
|
||||
|
margin, _, _, _ = self.getContentsMargins() |
||||
|
|
||||
|
size += QSize(2 * margin, 2 * 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(QSizePolicy.PushButton, QSizePolicy.PushButton, Qt.Horizontal) |
||||
|
spaceY = self.spacing() + wid.style().layoutSpacing(QSizePolicy.PushButton, QSizePolicy.PushButton, 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(QRect(QPoint(x, y), item.sizeHint())) |
||||
|
|
||||
|
x = nextX |
||||
|
lineHeight = max(lineHeight, item.sizeHint().height()) |
||||
|
|
||||
|
return y + lineHeight - rect.y() |
||||
|
|
||||
|
|
||||
|
if __name__ == '__main__': |
||||
|
|
||||
|
import sys |
||||
|
|
||||
|
app = QApplication(sys.argv) |
||||
|
mainWin = Window() |
||||
|
mainWin.show() |
||||
|
sys.exit(app.exec_()) |
Loading…
Reference in new issue