python 流式计算框架_python GUI框架pyqt5如何对图片进行流式布局(瀑布流flowlayout)...

流式布局

流式布局,也叫做瀑布流布局,是网页中经常使用的一种页面布局方式,它的原理就是将高度固定,然后图片的宽度自适应,这样加载出来的图片看起来就像瀑布一样整齐的水流淌下来。

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, 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()

封装好的流式布局类,我们只要传入相应的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, 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_())

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值