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中的并发编程实例
Jul 07 Python
python采用getopt解析命令行输入参数实例
Sep 30 Python
python通过BF算法实现关键词匹配的方法
Mar 13 Python
python实现雨滴下落到地面效果
Jun 21 Python
浅析python3字符串格式化format()函数的简单用法
Dec 07 Python
Python实现FTP弱口令扫描器的方法示例
Jan 31 Python
Python+Tensorflow+CNN实现车牌识别的示例代码
Oct 11 Python
PyQt5.6+pycharm配置以及pyinstaller生成exe(小白教程)
Jun 02 Python
python中strip(),lstrip(),rstrip()函数的使用讲解
Nov 17 Python
python实现马丁策略的实例详解
Jan 15 Python
TensorFlow低版本代码自动升级为1.0版本
Feb 20 Python
pyx文件 生成pyd 文件用于 cython调用的实现
Mar 04 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实现的返回数据格式化类实例
2014/09/22 PHP
必须收藏的php实用代码片段
2016/02/02 PHP
Yii2组件之多图上传插件FileInput的详细使用教程
2016/06/20 PHP
thinkphp跨库操作的简单代码实例
2016/09/22 PHP
php获取目录下所有文件及目录(多种方法)(推荐)
2019/05/14 PHP
json的前台操作和后台操作实现代码
2012/01/20 Javascript
Jquery实现的tab效果可以指定默认显示第几页
2013/10/16 Javascript
浅谈JavaScript数据类型
2015/03/03 Javascript
在for循环中length值是否需要缓存
2015/07/27 Javascript
jQuery中trigger()与bind()用法分析
2015/12/18 Javascript
js判断某个字符出现的次数的简单实例
2016/06/03 Javascript
javascript数组对象常用api函数小结(连接,插入,删除,反转,排序等)
2016/09/20 Javascript
js中数组的常用方法小结
2016/12/30 Javascript
JS去掉字符串前后空格或去掉所有空格的用法
2017/03/25 Javascript
Angular4 组件通讯方法大全(推荐)
2018/07/12 Javascript
vue-cli脚手架的安装教程图解
2018/09/02 Javascript
微信小程序中使用Async-await方法异步请求变为同步请求方法
2019/03/28 Javascript
Layer UI表格列日期格式化及取消自动填充日期的实现方法
2020/05/10 Javascript
详解如何在Javascript中使用Object.freeze()
2020/10/18 Javascript
介绍Python中几个常用的类方法
2015/04/08 Python
python 系统调用的实例详解
2017/07/11 Python
Python切片索引用法示例
2018/05/15 Python
Pytorch使用MNIST数据集实现基础GAN和DCGAN详解
2020/01/10 Python
Pytorch中.new()的作用详解
2020/02/18 Python
Python 解决火狐浏览器不弹出下载框直接下载的问题
2020/03/09 Python
CSS3实现多重边框的方法总结
2016/05/31 HTML / CSS
html标签之Object和EMBED标签详解
2013/07/04 HTML / CSS
Kneipp克奈圃美国官网:德国百年精油配方的传承
2018/02/07 全球购物
Kate Spade澳大利亚官方网站:美国设计师手袋品牌
2019/09/10 全球购物
介绍下Java的输入输出流
2014/01/22 面试题
Android笔试题总结
2014/11/29 面试题
新闻记者实习自我鉴定
2013/09/19 职场文书
自考毕业自我鉴定范文
2013/10/27 职场文书
护士毕业实习感言
2014/03/05 职场文书
无毒社区工作方案
2014/05/23 职场文书
分享几种python 变量合并方法
2022/03/20 Python