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读取键盘输入的2种方法
Jun 16 Python
Python随机生成带特殊字符的密码
Mar 02 Python
Python+Selenium+PIL+Tesseract自动识别验证码进行一键登录
Sep 20 Python
分数霸榜! python助你微信跳一跳拿高分
Jan 08 Python
小白如何入门Python? 制作一个网站为例
Mar 06 Python
Pycharm如何打断点的方法步骤
Jun 13 Python
python3 tcp的粘包现象和解决办法解析
Dec 09 Python
不到20行实现Python代码即可制作精美证件照
Apr 24 Python
Python嵌入C/C++进行开发详解
Jun 09 Python
如何利用Python matplotlib绘制雷达图
Dec 21 Python
Pytest实现setup和teardown的详细使用详解
Apr 17 Python
Python实现排序方法常见的四种
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
php设计模式 Mediator (中介者模式)
2011/06/26 PHP
用Json实现PHP与JavaScript间数据交换的方法详解
2013/06/20 PHP
显示youtube视频缩略图和Vimeo视频缩略图代码分享
2014/02/13 PHP
ThinkPHP的L方法使用简介
2014/06/18 PHP
ThinkPHP模板IF标签用法详解
2014/07/01 PHP
PHP实现的最大正向匹配算法示例
2017/12/19 PHP
php PDO属性设置与操作方法分析
2018/12/27 PHP
在Javascript中为String对象添加trim,ltrim,rtrim方法
2006/09/22 Javascript
DOM2非标准但却支持很好的几个属性小结
2012/01/21 Javascript
常用Extjs工具:Extjs.util.Format使用方法
2012/03/22 Javascript
浅谈JS闭包中的循环绑定处理程序
2014/11/09 Javascript
node.js中的path.resolve方法使用说明
2014/12/08 Javascript
JavaScript中的操作符==与===介绍
2014/12/31 Javascript
Jquery动态添加输入框的方法
2015/05/29 Javascript
由浅入深讲解Javascript继承机制与simple-inheritance源码分析
2015/12/13 Javascript
javascript显示系统当前时间代码
2016/12/29 Javascript
angularjs的select使用及默认选中设置
2017/04/08 Javascript
微信小程序实现图片压缩
2019/12/03 Javascript
如何配置vue.config.js 处理static文件夹下的静态文件
2020/06/19 Javascript
Python中利用函数装饰器实现备忘功能
2015/03/30 Python
安装Python的web.py框架并从hello world开始编程
2015/04/25 Python
Python3处理文件中每个词的方法
2015/05/22 Python
Python 的描述符 descriptor详解
2016/02/27 Python
Python实现多进程共享数据的方法分析
2017/12/04 Python
python调用Matplotlib绘制分布点并且添加标签
2018/05/31 Python
一款纯css3实现的非常实用的鼠标悬停特效演示
2014/11/05 HTML / CSS
Office DEPOT法国官网:欧迪办公用品采购
2018/01/03 全球购物
linux面试题参考答案(8)
2016/04/19 面试题
英语自荐信常用语句
2013/12/13 职场文书
优秀的2014年两会精神解读
2014/03/17 职场文书
会议接待欢迎词范文
2015/01/26 职场文书
肖申克救赎观后感
2015/06/02 职场文书
2016大一新生军训心得体会
2016/01/11 职场文书
浅谈Python数学建模之数据导入
2021/06/23 Python
分析SQL窗口函数之聚合窗口函数
2022/04/21 Oracle
利用Apache Common将java对象池化的问题
2022/06/16 Servers