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 |
시간날때마다 틈틈이 이것저것 해보며 블로그에 글을 남깁니다.
블로그의 문서는 종종 최신 버전으로 업데이트됩니다.
여유 시간이 날때 진행하는 거라 언제 진행될지는 알 수 없습니다.
영화,책, 생각등을 올리는 블로그도 운영하고 있습니다.
https://freewriting2024.tistory.com
제가 쓴 책도 한번 검토해보세요 ^^
@webnautes :: 멈춤보단 천천히라도
그렇게 천천히 걸으면서도 그렇게 빨리 앞으로 나갈 수 있다는 건.
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!