python GUI框架pyqt5 对图片进行流式布局的方法(瀑布流flowlayout)


Posted in Python onMarch 12, 2020

流式布局

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

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

到此这篇关于python GUI框架pyqt5 对图片进行流式布局的方法(瀑布流flowlayout)的文章就介绍到这了,更多相关python pyqt5图片流式布局内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python函数参数类型*、**的区别
Apr 11 Python
理解生产者消费者模型及在Python编程中的运用实例
Jun 26 Python
Python语言描述连续子数组的最大和
Jan 04 Python
Python编程中NotImplementedError的使用方法
Apr 21 Python
django DRF图片路径问题的解决方法
Sep 10 Python
对python 自定义协议的方法详解
Feb 13 Python
python实现两个经纬度点之间的距离和方位角的方法
Jul 05 Python
如何用Python来搭建一个简单的推荐系统
Aug 07 Python
Python3 xml.etree.ElementTree支持的XPath语法详解
Mar 06 Python
TensorFlow2.1.0最新版本安装详细教程
Apr 08 Python
Python接口测试文件上传实例解析
May 22 Python
解决导入django_filters不成功问题No module named 'django_filter'
Jul 15 Python
解决pycharm不能自动补全第三方库的函数和属性问题
Mar 12 #Python
Matplotlib使用Cursor实现UI定位的示例代码
Mar 12 #Python
PyCharm中Matplotlib绘图不能显示UI效果的问题解决
Mar 12 #Python
pycharm实现在子类中添加一个父类没有的属性
Mar 12 #Python
Python3 获取文件属性的方式(时间、大小等)
Mar 12 #Python
Python获取对象属性的几种方式小结
Mar 12 #Python
深入浅析Python 命令行模块 Click
Mar 11 #Python
You might like
现磨咖啡骗局!现磨咖啡=新鲜咖啡?现磨咖啡背后的猫腻你不懂!
2019/03/28 冲泡冲煮
zf框架的校验器InArray使用示例
2014/03/13 PHP
js计数器代码
2006/11/04 Javascript
jQuery 剧场版 你必须知道的javascript
2009/05/27 Javascript
jquery中选择块并改变属性值的方法
2013/07/31 Javascript
JS实现切换标签页效果实例代码
2013/11/01 Javascript
js设置cookie过期当前时间减去一秒相当于立即过期
2014/09/04 Javascript
推荐一个封装好的getElementsByClassName方法
2014/12/02 Javascript
jQuery中:focus选择器用法实例
2014/12/30 Javascript
jQuery中end()方法用法实例
2015/01/08 Javascript
JavaScript判断变量是否为数组的方法(Array)
2016/02/24 Javascript
全面介绍javascript实用技巧及单竖杠
2016/07/18 Javascript
JavaScript随机打乱数组顺序之随机洗牌算法
2016/08/02 Javascript
JavaScript中的return布尔值的用法和原理解析
2017/08/14 Javascript
js实现QQ面板拖拽效果(慕课网DOM事件探秘)(全)
2017/09/19 Javascript
js生成word中图片处理方法
2018/01/06 Javascript
Vue中$refs的用法详解
2018/06/24 Javascript
小程序实现订单倒计时功能
2019/04/23 Javascript
vue中实现上传文件给后台实例详解
2019/08/22 Javascript
微信小程序swiper禁止用户手动滑动代码实例
2019/08/23 Javascript
[01:59]DOTA2首部纪录片《Free to play》预告片
2014/03/12 DOTA
python搭建简易服务器分析与实现
2012/12/15 Python
python可视化实现代码
2019/01/15 Python
简单了解python单例模式的几种写法
2019/07/01 Python
Python实现CNN的多通道输入实例
2020/01/17 Python
Python + opencv对拍照得到的图片进行背景去除的实现方法
2020/11/18 Python
CSS3制作轮播图的一种方法
2019/11/11 HTML / CSS
阿玛尼美妆英国官网:Giorgio Armani Beauty英国
2019/03/28 全球购物
印度尼西亚最完整和最大的在线药房网站:Farmaku.com
2019/11/23 全球购物
师德个人剖析材料
2014/02/02 职场文书
法人委托书
2014/07/31 职场文书
2014年政风行风自查自纠报告
2014/10/21 职场文书
工程安全生产协议书
2014/11/21 职场文书
经典搞笑版检讨书
2015/02/19 职场文书
靠谱的活动总结
2019/04/16 职场文书
Python进度条的使用
2021/05/17 Python