Qt分享一个壁纸页面布局的方式

分享一个壁纸软件的设计思路

QScrollArea中添加一个总体的垂直布局,创建若干个水平布局,使用垂直布局组合,具体如图。在添加QAbstractButton时设置button.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)属性,它会根据窗口大小自动调整。
WebImageLabel参考https://blog.csdn.net/weixin_54217201/article/details/137932686

class ImageLabel(QLabel)换成class ImageLabel(QAbstractButton)删除Clicked事件即可

代码如下

python 复制代码
import math
import sys
from typing import List
from enum import Enum
from PyQt5.QtCore import pyqtSignal, QSize, Qt
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import (QAbstractButton, QWidget, QButtonGroup, QApplication, QGridLayout, QLayoutItem,
                             QSizePolicy, QHBoxLayout, QVBoxLayout, QScrollArea, QPushButton, QLabel)

from qfluentwidgets import SmoothScrollDelegate
from components import WebImageLabel, ReloadWidget


class LayoutPosition(Enum):
    Left = 0
    Center = 1
    Right = 2


class PictureGridWidget(QScrollArea):
    rowWidgetCount = 5
    buttonClicked = pyqtSignal(QAbstractButton)
    buttonPressed = pyqtSignal(QAbstractButton)
    buttonReleased = pyqtSignal(QAbstractButton)
    buttonToggled = pyqtSignal(QAbstractButton)
    reloadClicked = pyqtSignal()

    def __init__(self, parent=None):
        super().__init__(parent)
        self.delegate = SmoothScrollDelegate(self, False)
        self._bigButtons = []
        self._noDataWidget = None
        self.view = QWidget()
        self.buttonGroup = QButtonGroup(self.view)
        self.verticalLayout = QVBoxLayout(self.view)

        self.__initUi()
        self.__initNoDataWidget()

    def __initUi(self):
        self.setWidget(self.view)
        self.setWidgetResizable(True)
        self.setContentsMargins(0, 0, 0, 0)
        self.setObjectName("PictureGridWidget")

        self.verticalLayout.setSpacing(5)
        self.verticalLayout.setContentsMargins(0, 0, 10, 0)
        self.verticalLayout.setAlignment(Qt.AlignTop)

        self.buttonGroup.buttonClicked.connect(self.buttonClicked)
        self.buttonGroup.buttonPressed.connect(self.buttonPressed)
        self.buttonGroup.buttonReleased.connect(self.buttonReleased)
        self.buttonGroup.buttonToggled.connect(self.buttonToggled)

    def __resetRowLayout(self, buttons: list, position: LayoutPosition = LayoutPosition.Left):
        """
        重置行布局
        """
        horizontalLayout = QHBoxLayout()
        verticalLayout_1 = QVBoxLayout()
        verticalLayout_2 = QVBoxLayout()

        horizontalLayout.setSpacing(5)
        verticalLayout_1.setSpacing(5)
        verticalLayout_2.setSpacing(5)
        horizontalLayout.setContentsMargins(0, 0, 0, 0)
        verticalLayout_1.setContentsMargins(0, 0, 0, 0)
        verticalLayout_2.setContentsMargins(0, 0, 0, 0)

        button1 = buttons[0]  # type: QAbstractButton
        button1.setMinimumHeight(300)
        self._bigButtons.append(button1)

        for button in buttons[1:3]:
            verticalLayout_1.addWidget(button)
        for button in buttons[3:5]:
            verticalLayout_2.addWidget(button)

        if position == LayoutPosition.Left:
            horizontalLayout.addWidget(button1)
            horizontalLayout.addLayout(verticalLayout_1)
            horizontalLayout.addLayout(verticalLayout_2)
            horizontalLayout.setStretch(0, 2)
            horizontalLayout.setStretch(1, 1)
            horizontalLayout.setStretch(2, 1)
        elif position == LayoutPosition.Center:
            horizontalLayout.addLayout(verticalLayout_1)
            horizontalLayout.addWidget(button1)
            horizontalLayout.addLayout(verticalLayout_2)
            horizontalLayout.setStretch(0, 1)
            horizontalLayout.setStretch(1, 2)
            horizontalLayout.setStretch(2, 1)
        elif position == LayoutPosition.Right:
            horizontalLayout.addLayout(verticalLayout_1)
            horizontalLayout.addLayout(verticalLayout_2)
            horizontalLayout.addWidget(button1)
            horizontalLayout.setStretch(0, 1)
            horizontalLayout.setStretch(1, 1)
            horizontalLayout.setStretch(2, 2)

        return horizontalLayout

    def __resetLayout(self, buttons: list):
        sum_buttons = len(buttons)
        poses = [i for i in LayoutPosition] * math.ceil(sum_buttons / self.rowWidgetCount)
        for index, value in enumerate(range(0, sum_buttons, self.rowWidgetCount)):
            self.verticalLayout.addLayout(
                self.__resetRowLayout(buttons[value:value + self.rowWidgetCount], poses[index]))

    def __resetBigButtons(self, width: int):
        """
        重置大按钮
        """
        for button in self._bigButtons:  # type: WebImageLabel
            button.scaledToWidth(width // 2)

    def __initNoDataWidget(self):
        if self.count() == 0:
            _noDataWidget = ReloadWidget()
            _noDataWidget.reloadClicked.connect(self.reloadClicked)
            self.verticalLayout.addWidget(_noDataWidget, 0, Qt.AlignVCenter | Qt.AlignHCenter)
            self._noDataWidget = _noDataWidget

        else:
            if self._noDataWidget:
                self._noDataWidget.deleteLater()
                self.verticalLayout.removeWidget(self._noDataWidget)

    def setNoDataWidget(self, widget: QWidget):
        self._noDataWidget = widget
        self.update()

    def noDataWidget(self):
        return self._noDataWidget

    def addButtons(self, buttons: List[QAbstractButton]):
        for button in buttons:
            button.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
            self.buttonGroup.addButton(button)
        self.__resetLayout(buttons)
        self.__resetBigButtons(self.width())
        self.__initNoDataWidget()

    def buttons(self):
        return self.buttonGroup.buttons()

    def takeAt(self, index: int) -> QLayoutItem:
        item = self.verticalLayout.takeAt(index)
        if isinstance(item, QHBoxLayout):
            item.deleteLater()
        return item

    def count(self):
        return self.verticalLayout.count()

    def removeAllWidgets(self):
        while self.count():
            self.takeAt(0)
        for button in self.buttons():
            self.buttonGroup.removeButton(button)
            button.deleteLater()
        self.__initNoDataWidget()

    def resizeEvent(self, a0):
        self.__resetBigButtons(a0.size().width())
        super().resizeEvent(a0)

    def checkedButton(self):
        return self.buttonGroup.checkedButton()

    def checkedId(self):
        return self.buttonGroup.checkedId()


if __name__ == '__main__':
    QApplication.setHighDpiScaleFactorRoundingPolicy(
        Qt.HighDpiScaleFactorRoundingPolicy.PassThrough)
    QApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
    QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)

    app = QApplication(sys.argv)
    demo = PictureGridWidget()
    demo.setMinimumSize(900, 600)
    imgList = [
        r"G:\手机\壁纸\电脑壁纸\79f6134e92bb51d4f1602bb0503898fc.png",
        r"G:\手机\壁纸\电脑壁纸\2b1ccbd66541d46c880560476210e35f.png",
        r"G:\手机\壁纸\电脑壁纸\aa7d1b13c29fee7477f3c3f78d6478be.png",
        r"G:\手机\壁纸\电脑壁纸\64bbc8d0138d99f4512719146b72d14f.jpeg",
        r"G:\手机\壁纸\电脑壁纸\9eb771c6486a4a5d2442b0f997084d55.png"
    ]
    labelList = []
    for img in imgList:
        i = WebImageLabel()
        i.setPixmap(QPixmap(img))
        labelList.append(i)
    demo.addButtons(labelList)
    bu = QPushButton(demo)
    demo.buttonClicked.connect(print)
    bu.clicked.connect(lambda: demo.removeAllWidgets())
    demo.show()
    sys.exit(app.exec_())
相关推荐
小羊没烦恼!1 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
伞伞悦读1 天前
【第38期】Python 模块与包详解:import、from、模块搜索路径、包结构和 __init__
开发语言·python
这个DBA有点耶1 天前
MVCC深入:Read View、版本链与快照读——InnoDB并发控制的内核
数据库·mysql·架构
DBA_G1 天前
从地面到云霄:GBase数据库在民航三大场景的落地实践
数据库
自由能燃气设备1 天前
商用全预混低氮冷凝锅炉免费方案vs付费方案对比+选型避坑指南
大数据·数据库·人工智能
C语言小火车1 天前
C/C++ 为什么需要编译器?
开发语言·c++
科创致远1 天前
科创致远 ESOP 系统核心效能与实战价值展示
大数据·数据库·人工智能·精益工程
霍霍的袁1 天前
【C++】map 和 set 的使用 | 从用法到底层
开发语言·c++·学习·visual studio
孙启超1 天前
【AI开发之Rust】第 11 课:智能指针与内部可变性
开发语言·后端·rust
此生决int1 天前
深入理解C++系列(20)——C++11(下)
开发语言·c++