python GUI框架pyqt5 對圖片進行流式佈局的方法(瀑布流flowlayout)
阿新 • • 發佈:2020-03-12
流式佈局
流式佈局,也叫做瀑布流佈局,是網頁中經常使用的一種頁面佈局方式,它的原理就是將高度固定,然後圖片的寬度自適應,這樣加載出來的圖片看起來就像瀑布一樣整齊的水流淌下來。
pyqt流式佈局
那麼在pyqt5中我們怎麼使用流式佈局呢?pyqt沒有這個控制元件,需要我們自己去封裝,下面是流式佈局的封裝程式碼。
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) 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,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,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()
封裝好的流式佈局類,我們只要傳入相應的layout之後,他就會自動計算頁面的元素,適應頁面的寬度。
下面是我們寫的一個瀑布流顯示圖片的程式碼:
from PyQt5.QtCore import QPoint,QRect,QSize,Qt import os from PyQt5 import QtCore,QtGui,QtWidgets from PyQt5.QtWidgets import ( QApplication,QLayout,QPushButton,QSizePolicy,QWidget,QGridLayout) class Window(QWidget): def __init__(self): self.imageheight = 100 super(Window,self).__init__() self.resize(400,300) flowLayout = FlowLayout() highlight_dir = "./" self.files_it = iter([os.path.join(highlight_dir,file) for file in os.listdir(highlight_dir)]) print() for file in iter(self.files_it): layout = QGridLayout() pixmap = QtGui.QPixmap(file) if not pixmap.isNull(): autoWidth = pixmap.width()*self.imageheight/pixmap.height() label = QtWidgets.QLabel(pixmap=pixmap) label.setScaledContents(True) label.setFixedHeight(self.imageheight) print(autoWidth) label.setFixedWidth(autoWidth) #label.setFixedSize(100,50) layout.addWidget(label) widget = QWidget() widget.setLayout(layout) flowLayout.addWidget(widget) self.setLayout(flowLayout) self.setWindowTitle("Flow Layout") class FlowLayout(QLayout): def __init__(self,spacing=-1): super(FlowLayout,self).__init__(parent) if parent is not None: self.setContentsMargins(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,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,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,Qt.Horizontal) spaceY = self.spacing() + wid.style().layoutSpacing(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,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_())
到此這篇關於python GUI框架pyqt5 對圖片進行流式佈局的方法(瀑布流flowlayout)的文章就介紹到這了,更多相關python pyqt5圖片流式佈局內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!