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创建一个最简单http webserver服务器的方法
May 08 Python
KMP算法精解及其Python版的代码示例
Jun 01 Python
Python生成随机数组的方法小结
Apr 15 Python
在centos7中分布式部署pyspider
May 03 Python
Python3学习笔记之列表方法示例详解
Oct 06 Python
python集合比较(交集,并集,差集)方法详解
Sep 13 Python
Python实现繁体中文与简体中文相互转换的方法示例
Dec 18 Python
Python开发网站目录扫描器的实现
Feb 21 Python
详解Python3 对象组合zip()和回退方式*zip
May 15 Python
详解Python3定时器任务代码
Sep 23 Python
Python3基于print打印带颜色字符串
Jul 06 Python
通过代码实例解析Pytest运行流程
Aug 20 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
一篇有意思的技术文章php介绍篇
2010/10/26 PHP
配置php网页显示各种语法错误
2013/09/23 PHP
php使用CutyCapt实现网页截图保存的方法
2016/10/03 PHP
PHP 文件上传后端处理实用技巧方法
2017/01/06 PHP
PHP实现表单提交数据的验证处理功能【防SQL注入和XSS攻击等】
2017/07/21 PHP
laravel框架路由分组,中间件,命名空间,子域名,路由前缀实例分析
2020/02/18 PHP
javascript 匿名函数的理解(透彻版)
2010/01/28 Javascript
CSS鼠标响应事件经过、移动、点击示例介绍
2013/09/04 Javascript
如何创建一个JavaScript弹出DIV窗口层的效果
2013/09/25 Javascript
jQuery下的动画处理总结
2013/10/10 Javascript
兼容主流浏览器的iframe自适应高度js脚本
2014/01/10 Javascript
jQuery应用之jQuery链用法实例
2015/01/19 Javascript
JavaScript中用getDate()方法返回指定日期的教程
2015/06/09 Javascript
JQuery+Ajax实现数据查询、排序和分页功能
2015/09/27 Javascript
谈谈jQuery Ajax用法详解
2015/11/27 Javascript
JavaScript深度复制(deep clone)的实现方法
2016/02/19 Javascript
一道关于JavaScript变量作用域的面试题
2016/03/08 Javascript
JS之相等操作符详解
2016/09/13 Javascript
简单实现jQuery上传图片显示预览功能
2020/06/29 jQuery
Angular4学习之Angular CLI的安装与使用教程
2018/01/04 Javascript
[15:15]教你分分钟做大人:狙击手
2014/10/30 DOTA
Flask框架学习笔记(一)安装篇(windows安装与centos安装)
2014/06/25 Python
使用Django Form解决表单数据无法动态刷新的两种方法
2017/07/14 Python
Python编程之string相关操作实例详解
2017/07/22 Python
python数据抓取分析的示例代码(python + mongodb)
2017/12/25 Python
读取json格式为DataFrame(可转为.csv)的实例讲解
2018/06/05 Python
python basemap 画出经纬度并标定的实例
2019/07/09 Python
python实现简单井字棋小游戏
2020/03/05 Python
解决pyinstaller打包运行程序时出现缺少plotly库问题
2020/06/02 Python
伊莱克斯阿根廷网上商店:Tienda Electrolux
2021/03/08 全球购物
日语求职信范文
2013/12/17 职场文书
《春天来了》教学反思
2014/04/07 职场文书
会展策划与管理专业求职信
2014/06/09 职场文书
2015年城管个人工作总结范文
2015/04/20 职场文书
2015年暑假工作总结
2015/07/13 职场文书
青岛市的收音机研制与生产
2022/04/07 无线电