![PyQt5 예제 - FlowLayout](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcELbWO%2FbtsyVjkBF1y%2F9oBtrKsafXZPq4ubmuU030%2Fimg.png)
PyQt5 예제 - FlowLayoutQt/PyQt5 강좌2023. 10. 22. 05:27
Table of Contents
반응형
PyQt5에서 사용할 수 있는 FlowLayout 예제 코드입니다.
2022. 7. 23 최초작성
우선 실행 결과입니다. 창의 크기가 변경됨에 따라 FlowLayout에 추가된 자식 위젯의 배치가 달라지게 됩니다.
FlowLayout 생성시 orientation의 아규먼트에 따라 배치 방법이 다르니 아래 캡처 사진으로 확인하세요.
flowLayout = FlowLayout(orientation=QtCore.Qt.Horizontal)
flowLayout = FlowLayout(orientation=QtCore.Qt.Vertical)
전체 소스 코드입니다. 소스코드가 있는 곳에 이미지 파일을 하나 저장하고 다음 부분을 수정하세요.
pixmap = QtGui.QPixmap('apple.jpeg')
from PyQt5 import QtCore from PyQt5 import QtWidgets from PyQt5 import QtGui class Window(QtWidgets.QWidget): def __init__(self): super(Window, self).__init__() self.resize(1024, 768) image_viewer1 = QtWidgets.QLabel() image_viewer2 = QtWidgets.QLabel() image_viewer3 = QtWidgets.QLabel() image_viewer4 = QtWidgets.QLabel() image_viewer5 = QtWidgets.QLabel() flowLayout = FlowLayout(orientation=QtCore.Qt.Horizontal) # flowLayout = FlowLayout(orientation=QtCore.Qt.Vertical) flowLayout.addWidget(image_viewer1) flowLayout.addWidget(image_viewer2) flowLayout.addWidget(image_viewer3) flowLayout.addWidget(image_viewer4) flowLayout.addWidget(image_viewer5) self.setLayout(flowLayout) pixmap = QtGui.QPixmap('apple.jpeg') pixmap = pixmap.scaledToWidth(160) image_viewer1.setPixmap(pixmap) image_viewer2.setPixmap(pixmap) image_viewer3.setPixmap(pixmap) image_viewer4.setPixmap(pixmap) image_viewer5.setPixmap(pixmap) self.setWindowTitle("Flow Layout") class FlowLayout(QtWidgets.QLayout): def __init__(self, orientation=QtCore.Qt.Horizontal, parent=None, margin=0, spacing=-1): super().__init__(parent) self.orientation = orientation 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 QtCore.Qt.Orientations(QtCore.Qt.Orientation(0)) def hasHeightForWidth(self): return self.orientation == QtCore.Qt.Horizontal def heightForWidth(self, width): return self.doLayout(QtCore.QRect(0, 0, width, 0), True) def hasWidthForHeight(self): return self.orientation == QtCore.Qt.Vertical def widthForHeight(self, height): return self.doLayout(QtCore.QRect(0, 0, 0, height), True) def setGeometry(self, rect): super().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()) margin, _, _, _ = self.getContentsMargins() size += QtCore.QSize(2 * margin, 2 * margin) return size def doLayout(self, rect, testOnly): x = rect.x() y = rect.y() lineHeight = columnWidth = heightForWidth = 0 for item in self.itemList: wid = item.widget() spaceX = self.spacing() + wid.style().layoutSpacing(QtWidgets.QSizePolicy.PushButton, QtWidgets.QSizePolicy.PushButton, QtCore.Qt.Horizontal) spaceY = self.spacing() + wid.style().layoutSpacing(QtWidgets.QSizePolicy.PushButton, QtWidgets.QSizePolicy.PushButton, QtCore.Qt.Vertical) if self.orientation == QtCore.Qt.Horizontal: 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()) else: nextY = y + item.sizeHint().height() + spaceY if nextY - spaceY > rect.bottom() and columnWidth > 0: x = x + columnWidth + spaceX y = rect.y() nextY = y + item.sizeHint().height() + spaceY columnWidth = 0 heightForWidth += item.sizeHint().height() + spaceY if not testOnly: item.setGeometry(QtCore.QRect(QtCore.QPoint(x, y), item.sizeHint())) y = nextY columnWidth = max(columnWidth, item.sizeHint().width()) if self.orientation == QtCore.Qt.Horizontal: return y + lineHeight - rect.y() else: return heightForWidth - rect.y() if __name__ == '__main__': import sys app = QtWidgets.QApplication(sys.argv) mainWin = Window() mainWin.show() sys.exit(app.exec_()) |
참고
https://github.com/baoboa/pyqt5/blob/master/examples/layouts/flowlayout.py
https://www.pythonfixing.com/2022/04/fixed-pyqt-oriented-flow-layout.html
반응형
'Qt > PyQt5 강좌' 카테고리의 다른 글
PyQt5 예제 - QTreeView으로 json 로드하기 및 저장하기 (0) | 2023.10.22 |
---|---|
PyQt5 예제 - QListWidget (0) | 2023.10.22 |
PyQt5 예제 - connect에서 slot 함수에 아규먼트 전달하기 (0) | 2023.10.22 |
PyQt5 예제 - QStackedWidget (0) | 2023.10.22 |
PyQt5 예제 - QProgressDialog (0) | 2023.10.22 |