1. 程式人生 > 程式設計 >Pyqt5 關於流式佈局和滾動條的綜合使用示例程式碼

Pyqt5 關於流式佈局和滾動條的綜合使用示例程式碼

流式佈局

所謂流式佈局指的是容器中的元素像流水一樣,是可以浮動的,當元素一行或者一列佔滿的時候,它會自動流入到下一行或者下一列。

pyqt5流式佈局

pyqt中採用流式佈局的方法原理是,通過contentsMargins獲取到子元素距離佈局的上下左右寬度,然後我們將所有子元素進行遍歷,如果它加上邊距可以在一行放入的話,那麼就放在一行內,如果不能,就放入到下一行,具體程式碼如下:

m = self.contentsMargins()
effective_rect = rect.adjusted(+m.left(),+m.top(),-m.right(),-m.bottom())
    x = effective_rect.x()
    y = effective_rect.y()
    line_height = 0

    for item in self._item_list:
      wid = item.widget()

      space_x = self.spacing()
      space_y = self.spacing()
      if wid is not None:
        space_x += wid.style().layoutSpacing(
          QSizePolicy.PushButton,QSizePolicy.PushButton,Qt.Horizontal)
        space_y += wid.style().layoutSpacing(
          QSizePolicy.PushButton,Qt.Vertical)

      next_x = x + item.sizeHint().width() + space_x
      if next_x - space_x > effective_rect.right() and line_height > 0:
        x = effective_rect.x()
        y = y + line_height + space_y
        next_x = x + item.sizeHint().width() + space_x
        line_height = 0

      if not test_only:
        item.setGeometry(QRect(QPoint(x,y),item.sizeHint()))

      x = next_x
      line_height = max(line_height,item.sizeHint().height())

滾動條的設定

pyqt中有專門的滾動條元件QScrollBar,這個元件需要配合其他元件使用,我們這裡使用QScrollArea這個元件進行滾動條的設定。

滾動條的使用方法

首先,我們需要宣告QScrollArea

然後,我們需要設定QScrollArea的位置大小

最後,我們將需要產生滾動條的元素放入它的內部。

q = QWidget()
qscrollarea = QtWidgets.QScrollArea(q)   qscrollarea.setGeometry(QRect(50,100,600,500))
qscrollarea.setWidgetResizable(True)
listWidget = QtWidgets.QListWidget()
qscrollarea.setWidget(listWidget)

流式佈局和滾動條的結合案例:

在檔案當前目錄建立一個images資料夾,然後放入想要展示的多張圖片,然後執行當前程式,就會看到帶有滾動條的流式佈局介面。

執行程式,需要安裝pyqt5

Pyqt5 關於流式佈局和滾動條的綜合使用示例程式碼

from PyQt5.QtCore import QPoint,QRect,QSize,Qt,pyqtSignal
import os
from PyQt5 import QtCore,QtGui,QtWidgets
from PyQt5.QtWidgets import (
  QApplication,QLayout,QPushButton,QSizePolicy,QWidget,QGridLayout)
import sys
class Window(QWidget):
  def __init__(self):
    self.imageheight = 100
    super(Window,self).__init__()
    self.resize(800,600)

    #self.listwidget = QtWidgets.QListWidget(self)
    #self.listwidget.resize(400,300)
    #self.listwidget.setGeometry(QtCore.QRect(0,300,200))
    #self.listwidget.addItem("test")

    highlight_dir = r"./images"
    self.files_it = iter([os.path.join(highlight_dir,file)
               for file in os.listdir(highlight_dir)])

    # self.centralwidget = QtWidgets.QWidget(MainWindow)
    # self.gongzuomoshi = QtWidgets.QGroupBox(self.centralwidget)
    self.listWidget = QtWidgets.QListWidget(self)
    #self.listWidget.setFixedWidth(600)
    container_layout = QtWidgets.QVBoxLayout()
    g = QtWidgets.QGroupBox('')
    l = FlowLayout()
    g.setLayout(l)
    for file in iter(self.files_it):
      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)
        label.setFixedWidth(autoWidth)
        l.addWidget(label)

    container_layout.addWidget(g)
    container_layout.addStretch()
    self.listWidget.setLayout(container_layout)

    self.qscrollarea = QtWidgets.QScrollArea(self)
    self.qscrollarea.setGeometry(QRect(50,500))
    self.qscrollarea.setWidgetResizable(True)
    self.qscrollarea.setWidget(self.listWidget)
    self.setWindowTitle("Flow Layout Scroll")

class FlowLayout(QLayout):
  """流式佈局,使用說明
  1.宣告流式佈局 layout = FlowLayout
  2.將元素放入流式佈局中
  3.將QGroupBox應用流式佈局
  4.如果期望水平流式,將QGroupBox放入到QHBoxLayout,如果期望垂直佈局,將QGroupBox放入到QVBoxLayout
  """
  heightChanged = pyqtSignal(int)

  def __init__(self,parent=None,margin=0,spacing=-1):
    super().__init__(parent)
    if parent is not None:
      self.setContentsMargins(margin,margin,margin)
    self.setSpacing(spacing)

    self._item_list = []

  def __del__(self):
    while self.count():
      self.takeAt(0)

  def addItem(self,item): # pylint: disable=invalid-name
    self._item_list.append(item)

  def addSpacing(self,size): # pylint: disable=invalid-name
    self.addItem(QSpacerItem(size,QSizePolicy.Fixed,QSizePolicy.Minimum))

  def count(self):
    return len(self._item_list)

  def itemAt(self,index): # pylint: disable=invalid-name
    if 0 <= index < len(self._item_list):
      return self._item_list[index]
    return None

  def takeAt(self,index): # pylint: disable=invalid-name
    if 0 <= index < len(self._item_list):
      return self._item_list.pop(index)
    return None

  def expandingDirections(self): # pylint: disable=invalid-name,no-self-use
    return Qt.Orientations(Qt.Orientation(0))

  def hasHeightForWidth(self): # pylint: disable=invalid-name,no-self-use
    return True

  def heightForWidth(self,width): # pylint: disable=invalid-name
    height = self._do_layout(QRect(0,width,0),True)
    return height

  def setGeometry(self,rect): # pylint: disable=invalid-name
    super().setGeometry(rect)
    self._do_layout(rect,False)

  def sizeHint(self): # pylint: disable=invalid-name
    return self.minimumSize()

  def minimumSize(self): # pylint: disable=invalid-name
    size = QSize()

    for item in self._item_list:
      minsize = item.minimumSize()
      extent = item.geometry().bottomRight()
      size = size.expandedTo(QSize(minsize.width(),extent.y()))

    margin = self.contentsMargins().left()
    size += QSize(2 * margin,2 * margin)
    return size

  def _do_layout(self,rect,test_only=False):
    m = self.contentsMargins()
    effective_rect = rect.adjusted(+m.left(),item.sizeHint().height())

    new_height = y + line_height - rect.y()
    self.heightChanged.emit(new_height)
    return new_height

if __name__ == '__main__':
  app = QApplication(sys.argv)
  mainWin = Window()

  mainWin.show()
  sys.exit(app.exec_())

到此這篇關於Pyqt5 關於流式佈局和滾動條的綜合使用示例程式碼的文章就介紹到這了,更多相關Pyqt5 流式佈局和滾動條內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!