#!/usr/bin/env python ############################################################################# ## ## Copyright (C) 2004-2005 Trolltech AS. All rights reserved. ## ## This file is part of the example classes of the Qt Toolkit. ## ## This file may be used under the terms of the GNU General Public ## License version 2.0 as published by the Free Software Foundation ## and appearing in the file LICENSE.GPL included in the packaging of ## this file. Please review the following information to ensure GNU ## General Public Licensing requirements will be met: ## http://www.trolltech.com/products/qt/opensource.html ## ## If you are unsure which license is appropriate for your use, please ## review the following information: ## http://www.trolltech.com/products/qt/licensing.html or contact the ## sales department at sales@trolltech.com. ## ## This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ## WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ## ############################################################################# import sys from PyQt4 import QtCore, QtGui class ItemWrapper(object): def __init__(self, i, p): self.item = i self.position = p class BorderLayout(QtGui.QLayout): West, North, South, East, Center = range(5) MinimumSize, SizeHint = range(2) def __init__(self, parent=None, margin=0, spacing=-1): QtGui.QLayout.__init__(self, parent) self.setMargin(margin) self.setSpacing(spacing) self.list = [] def __del__(self): l = self.takeAt(0) while l: l = self.takeAt(0) def addItem(self, item): self.add(item, BorderLayout.West) def addWidget(self, widget, position): self.add(QtGui.QWidgetItem(widget), position) def expandingDirections(self): return QtCore.Qt.Horizontal | QtCore.Qt.Vertical def hasHeightForWidth(self): return False def count(self): return len(self.list) def itemAt(self, index): if index < len(self.list): return self.list[index].item return None def minimumSize(self): return self.calculateSize(BorderLayout.MinimumSize) def setGeometry(self, rect): center = 0 eastWidth = 0 westWidth = 0 northHeight = 0 southHeight = 0 centerHeight = 0 QtGui.QLayout.setGeometry(self, rect) for wrapper in self.list: item = wrapper.item position = wrapper.position if position == BorderLayout.North: item.setGeometry(QtCore.QRect(rect.x(), northHeight, rect.width(), item.sizeHint().height())) northHeight += item.geometry().height() + self.spacing() elif position == BorderLayout.South: item.setGeometry(QtCore.QRect(item.geometry().x(), item.geometry().y(), rect.width(), item.sizeHint().height())) southHeight += item.geometry().height() + self.spacing() item.setGeometry(QtCore.QRect(rect.x(), rect.y() + rect.height() - southHeight + self.spacing(), item.geometry().width(), item.geometry().height())) elif position == BorderLayout.Center: center = wrapper centerHeight = rect.height() - northHeight - southHeight for wrapper in self.list: item = wrapper.item position = wrapper.position if position == BorderLayout.West: item.setGeometry(QtCore.QRect(rect.x() + westWidth, northHeight, item.sizeHint().width(), centerHeight)) westWidth += item.geometry().width() + self.spacing() elif position == BorderLayout.East: item.setGeometry(QtCore.QRect(item.geometry().x(), item.geometry().y(), item.sizeHint().width(), centerHeight)) eastWidth += item.geometry().width() + self.spacing() item.setGeometry(QtCore.QRect(rect.x() + rect.width() - eastWidth + self.spacing(), northHeight, item.geometry().width(), item.geometry().height())) if center: center.item.setGeometry(QtCore.QRect(westWidth, northHeight, rect.width() - eastWidth - westWidth, centerHeight)) def sizeHint(self): return self.calculateSize(BorderLayout.SizeHint) def takeAt(self, index): if index >= 0 and index < len(self.list): layoutStruct = self.list.pop(index) return layoutStruct.item return None def add(self, item, position): self.list.append(ItemWrapper(item, position)) def calculateSize(self, sizeType): totalSize = QtCore.QSize() for wrapper in self.list: position = wrapper.position itemSize = QtCore.QSize() if sizeType == BorderLayout.MinimumSize: itemSize = wrapper.item.minimumSize() else: # sizeType == BorderLayout.SizeHint itemSize = wrapper.item.sizeHint() if position == BorderLayout.North or position == BorderLayout.South or position == BorderLayout.Center: totalSize.setHeight(totalSize.height() + itemSize.height()) if position == BorderLayout.West or position == BorderLayout.East or position == BorderLayout.Center: totalSize.setWidth(totalSize.width() + itemSize.width()) return totalSize class Window(QtGui.QWidget): def __init__(self, parent=None): QtGui.QWidget.__init__(self, parent) centralWidget = QtGui.QTextBrowser() centralWidget.setPlainText(self.tr("Central widget")) layout = BorderLayout() layout.addWidget(centralWidget, BorderLayout.Center) # Qt takes ownership of the widgets in the layout when setLayout() is # called. Therefore we keep a local reference to each label to prevent # it being garbage collected until the call to setLayout(). label_n = self.createLabel("North") layout.addWidget(label_n, BorderLayout.North) label_w = self.createLabel("West") layout.addWidget(label_w, BorderLayout.West) label_e1 = self.createLabel("East 1") layout.addWidget(label_e1, BorderLayout.East) label_e2 = self.createLabel("East 2") layout.addWidget(label_e2, BorderLayout.East) label_s = self.createLabel("South") layout.addWidget(label_s, BorderLayout.South) self.setLayout(layout) self.setWindowTitle(self.tr("Border Layout")) def createLabel(self, text): label = QtGui.QLabel(text) label.setFrameStyle(QtGui.QFrame.Box | QtGui.QFrame.Raised) return label if __name__ == "__main__": app = QtGui.QApplication(sys.argv) window = Window() window.show() sys.exit(app.exec_())