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_())
相关推荐
东风破_5 小时前
danci 2:创建的单词书到底存在哪里?从 Supabase 一路理解 ORM、Drizzle 和 RLS
数据库·后端·node.js
CoderIsArt5 小时前
C#中UI 线程与 Dispatcher
开发语言·ui·c#
橙子家7 小时前
OSS 文件上传的几个风险点和解决方案
数据库
AI情绪识别开源8 小时前
检信 ALLEMOTION OS 加密打包可执行程序 — 全面测试报告版本: v1.3功能测试 / 性能测试 /
开发语言·数据结构·人工智能·功能测试
2601_962066498 小时前
【Sql Server】Update中的From语句,以及常见更新操作方式
android·java·数据库
「QT(C++)开发工程师」9 小时前
C++ auto 用法详解
开发语言·c++
愤怒的苹果ext9 小时前
MySQL Shell备份恢复数据库
数据库·mysql·备份恢复·mysqlsh
OPEN-F9 小时前
C++STL教程:容器适配器与实用工具
开发语言·c++
yaoxin5211239 小时前
507. Java 反射 - 在 BeanFactory 中实现依赖注入
java·开发语言