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_())
相关推荐
Ashlee_code9 分钟前
什么是Web3?金融解决方案
开发语言·金融·架构·eclipse·web3·区块链·php
Evand J22 分钟前
【MATLAB例程】AOA与TDOA混合定位例程,适用于三维环境、4个锚点的情况,附下载链接
开发语言·matlab
机器视觉知识推荐、就业指导23 分钟前
Qt 与Halcon联合开发八: 结合Qt与Halcon实现海康相机采图显示(附源码)
开发语言·数码相机·qt
Heartoxx1 小时前
c语言-指针与一维数组
c语言·开发语言·算法
hqxstudying1 小时前
Java创建型模式---原型模式
java·开发语言·设计模式·代码规范
charlie1145141911 小时前
如何使用Qt创建一个浮在MainWindow上的滑动小Panel
开发语言·c++·qt·界面设计
神仙别闹1 小时前
基于Python实现LSTM对股票走势的预测
开发语言·python·lstm
保持学习ing1 小时前
day1--项目搭建and内容管理模块
java·数据库·后端·docker·虚拟机
宇钶宇夕2 小时前
EPLAN 电气制图:建立自己的部件库,添加部件-加SQL Server安装教程(三)上
运维·服务器·数据库·程序人生·自动化
chao_7892 小时前
回溯题解——子集【LeetCode】二进制枚举法
开发语言·数据结构·python·算法·leetcode