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_())
相关推荐
GBASE10 小时前
G术时刻 |GBase 8s数据库事务并发控制之封锁技术介绍(下)
数据库
用户8055336980318 小时前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner18 小时前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
xiezhr20 小时前
逛GitHub发现了一款免费的带AI功能的数据库管理工具
数据库·ai编程·dba
吃糖的小孩2 天前
给 QQ AI 机器人设计“可控记忆”:会话摘要、手动长期记忆与角色卡边界
数据库
笃行3502 天前
金仓数据库数据安全双防线:静态存储加密与传输加密实战
数据库
笃行3502 天前
金仓数据库物理备份实战:sys_rman 全流程演练与误覆盖抢救
数据库
笃行3503 天前
金仓数据库逻辑备份实战:从全库导出到 Schema 替换的完整闭环
数据库
SelectDB3 天前
阶跃星辰基于 SelectDB 构建 PB 级 Agent 可观测平台
大数据·数据库·aigc