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生成器(Generator)详解
Apr 13 Python
python实现线程池的方法
Jun 30 Python
python实现多线程的两种方式
May 22 Python
Python自动化开发学习之三级菜单制作
Jul 14 Python
老生常谈Python startswith()函数与endswith函数
Sep 08 Python
Tensorflow实现AlexNet卷积神经网络及运算时间评测
May 24 Python
Python访问MongoDB,并且转换成Dataframe的方法
Oct 15 Python
python之pyqt5通过按钮改变Label的背景颜色方法
Jun 13 Python
python自动化测试之异常及日志操作实例分析
Nov 09 Python
python GUI库图形界面开发之PyQt5复选框控件QCheckBox详细使用方法与实例
Feb 28 Python
python Matplotlib数据可视化(2):详解三大容器对象与常用设置
Sep 30 Python
详解Python遍历列表时删除元素的正确做法
Jan 07 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
多文件上载系统完整版
2006/10/09 PHP
php实现微信公众号无限群发
2015/10/11 PHP
弹出广告特效(一个IP只弹出一次)的代码
2007/07/27 Javascript
extJs 下拉框联动实现代码
2010/04/09 Javascript
javascript 自动填写表单的实现方法
2010/04/09 Javascript
JavaScript 面向对象编程(2) 定义类
2010/05/18 Javascript
JavaScript格式化数字的函数代码
2010/11/30 Javascript
动感效果的TAB选项卡jquery 插件
2011/07/09 Javascript
javascript学习(一)构建自己的JS库
2013/01/02 Javascript
js解析与序列化json数据(二)序列化探讨
2013/02/01 Javascript
jquery常用方法及使用示例汇总
2014/11/08 Javascript
通过JS判断联网类型和连接状态的实现代码
2015/04/01 Javascript
js实现touch移动触屏滑动事件
2015/04/17 Javascript
javaScript基础详解
2017/01/19 Javascript
AngularJs用户登录问题处理(交互及验证、阻止FQ处理)
2017/10/26 Javascript
js中如何完美的解析数据
2018/03/18 Javascript
vue使用vue-i18n实现国际化的实现代码
2018/04/08 Javascript
vue+echarts实现动态折线图的方法与注意
2020/09/01 Javascript
[05:04]DOTA2上海特级锦标赛主赛事第二日TOP10
2016/03/04 DOTA
[02:29]大剑、皮鞭、女装,这届DOTA2勇士令状里都有
2020/07/17 DOTA
Python中的异常处理简明介绍
2015/04/13 Python
使用Python对Excel进行读写操作
2017/03/30 Python
使用Python的SymPy库解决数学运算问题的方法
2019/03/27 Python
安装PyInstaller失败问题解决
2019/12/14 Python
Python内置函数property()如何使用
2020/09/01 Python
下述程序的作用是计算机数组中的最大元素值及其下标
2012/11/26 面试题
社会实践自我鉴定
2013/11/07 职场文书
导游实习生自荐书
2014/01/28 职场文书
《和田的维吾尔》教学反思
2014/04/14 职场文书
庆祝三八妇女节标语
2014/10/09 职场文书
迟到检讨书范文
2015/01/27 职场文书
2015年销售助理工作总结
2015/05/11 职场文书
2016年感恩母亲节活动总结
2016/04/01 职场文书
2019求职信:应届生求职信范文
2019/04/24 职场文书
在Centos 8.0中安装Redis服务器的教程详解
2022/03/21 Redis
zabbix配置nginx监控的实现
2022/05/25 Servers