pyqt5 QStackedWidget QStackedLayout 阴影 覆盖 透明

本文展示了一个使用PyQt5创建透明窗口的示例代码,包括三个子窗口,每个窗口都有不同的透明背景设置和布局。通过调整窗口属性和样式表,可以实现窗口的透明效果,同时保持窗口内容的清晰可见。

代码如下:

import sys
from PyQt5.QtWidgets import QWidget, QToolTip, QApplication
from PyQt5.QtGui import QFont
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
import sys


class ChildOneWin(QWidget):
    def __init__(self, parent=None):
        super(ChildOneWin, self).__init__(parent)

        self.main_layout = QVBoxLayout()
        self.top_widget = QWidget()
        self.setLayout(self.main_layout)
        self.top_widget.setObjectName("ChildOneWin_wdt")
        self.top_widget.setStyleSheet("#ChildOneWin_wdt{background:rgb(255,255,255)}")
        self.main_layout.addWidget(self.top_widget)
        self.main_layout.setContentsMargins(0, 0, 0, 0)
        self.main_layout.setSpacing(0)
        top_widget_layout = QVBoxLayout()
        self.top_widget.setLayout(top_widget_layout)

        self.test_btn = QPushButton('窗口1')
        top_widget_layout.addStretch(1)
        top_widget_layout.addWidget(self.test_btn)

class ChildTwoWin(QWidget):
    def __init__(self, parent=None):
        super(ChildTwoWin, self).__init__(parent)

        self.setWindowFlags(Qt.FramelessWindowHint | Qt.BypassWindowManagerHint | Qt.Tool | Qt.WindowStaysOnTopHint)
        self.setAttribute(Qt.WA_TranslucentBackground)
        self.wdt = QWidget()
        #self.wdt.setAttribute(Qt.WA_TranslucentBackground)
        self.wdt.setObjectName("ChildTwoWin_wdt")
        self.wdt.setStyleSheet("#ChildTwoWin_wdt{background:rgba(0,0,0,0.2)}")

        self.layout = QGridLayout(self)
        self.layout.addWidget(self.wdt)
        self.layout.setContentsMargins(0, 0, 0, 0)
        self.layout.setSpacing(0)

        main_layout = QVBoxLayout()

        self.wdt.setLayout(main_layout)

        self.test_btn = QPushButton('窗口2')
        main_layout.addStretch(1)
        main_layout.addWidget(self.test_btn)
        main_layout.addStretch(1)




# class ChildTwoWin(QWidget):
#     def __init__(self, parent=None):
#         super(ChildTwoWin, self).__init__(parent)
#
#         self.main_layout = QVBoxLayout()
#
#         self.top_widget = QWidget()
#         self.setLayout(self.main_layout)
#         self.top_widget.setObjectName("ChildTwoWin_wdt")
#         self.top_widget.setStyleSheet("#ChildTwoWin_wdt{background:rgb(255,255,255)}")
#         self.main_layout.addWidget(self.top_widget)
#
#         self.main_layout.setContentsMargins(0, 0, 0, 0)
#         self.main_layout.setSpacing(0)
#
#         top_widget_layout = QVBoxLayout()
#         self.top_widget.setLayout(top_widget_layout)
#
#         self.test_btn = QPushButton('窗口2')
#         top_widget_layout.addStretch(1)
#         top_widget_layout.addWidget(self.test_btn)
#         top_widget_layout.addStretch(1)


class ChildThreeWin(QWidget):
    def __init__(self, parent=None):
        super(ChildThreeWin, self).__init__(parent)

        self.setWindowFlags(Qt.FramelessWindowHint | Qt.BypassWindowManagerHint | Qt.Tool | Qt.WindowStaysOnTopHint)
        self.setAttribute(Qt.WA_TranslucentBackground)
        self.wdt = QWidget()
        #self.wdt.setAttribute(Qt.WA_TranslucentBackground)
        self.wdt.setObjectName("tipWaitingWindow_back")
        self.wdt.setStyleSheet("#tipWaitingWindow_back{background:rgba(0,0,0,0.2)}")

        self.layout = QGridLayout(self)
        self.layout.addWidget(self.wdt)
        self.layout.setContentsMargins(0, 0, 0, 0)
        self.layout.setSpacing(0)

        main_layout = QVBoxLayout()

        self.wdt.setLayout(main_layout)

        self.test_btn = QPushButton('窗口3')
        main_layout.addWidget(self.test_btn)
        main_layout.addStretch(1)


class Winform(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle('透明窗口测试')
        self.resize(330, 350)

        main_layout = QVBoxLayout()

        self.setLayout(main_layout)

        top_widget = QWidget()
        top_widget_layout = QHBoxLayout()
        top_widget.setLayout(top_widget_layout)

        self.test_btn = QPushButton('测试')
        self.test_btn.clicked.connect(self.call_back_test_btn)

        self.control_btn = QPushButton('控制')
        self.control_btn.clicked.connect(self.call_back_control_btn)

        self.show_btn = QPushButton('显示')
        self.show_btn.clicked.connect(self.call_back_show_btn)

        top_widget_layout.addWidget(self.test_btn)
        top_widget_layout.addStretch(1)
        top_widget_layout.addWidget(self.control_btn)
        top_widget_layout.addStretch(1)
        top_widget_layout.addWidget(self.show_btn)

        bottom_widget = QWidget()
        self.bottom_widget_layout = QStackedLayout()
        self.bottom_widget_layout.setStackingMode(QStackedLayout.StackAll)
        bottom_widget.setLayout(self.bottom_widget_layout)

        main_layout.addWidget(top_widget)
        main_layout.addWidget(bottom_widget)
        main_layout.setStretch(0, 1)
        main_layout.setStretch(1, 5)

        child_one_win = ChildOneWin()
        child_two_win = ChildTwoWin()
        child_three_win = ChildThreeWin()
        self.bottom_widget_layout.addWidget(child_one_win)
        self.bottom_widget_layout.addWidget(child_two_win)
        self.bottom_widget_layout.addWidget(child_three_win)

        self.bottom_widget_layout.setCurrentIndex(0)

    def call_back_show_btn(self):
        self.bottom_widget_layout.setCurrentIndex(2)

    def call_back_test_btn(self):
        self.bottom_widget_layout.setCurrentIndex(0)

    def call_back_control_btn(self):
        pass
        self.bottom_widget_layout.setCurrentIndex(1)



class WinUIform(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle('透明窗口测试')
        self.resize(330, 350)

        main_layout = QVBoxLayout()

        self.setLayout(main_layout)

        top_widget = QWidget()
        top_widget_layout = QHBoxLayout()
        top_widget.setLayout(top_widget_layout)

        self.test_btn = QPushButton('测试')
        self.test_btn.clicked.connect(self.call_back_test_btn)

        self.control_btn = QPushButton('控制')
        self.control_btn.clicked.connect(self.call_back_control_btn)

        self.show_btn = QPushButton('显示')
        self.show_btn.clicked.connect(self.call_back_show_btn)

        top_widget_layout.addWidget(self.test_btn)
        top_widget_layout.addStretch(1)
        top_widget_layout.addWidget(self.control_btn)
        top_widget_layout.addStretch(1)
        top_widget_layout.addWidget(self.show_btn)

        self.bottom_widget = QStackedWidget()
        # self.bottom_widget.layout().setStackingMode(QStackedLayout.StackAll)
        bottom_widget_layout = self.bottom_widget.layout()
        bottom_widget_layout.setStackingMode(QStackedLayout.StackAll)

        main_layout.addWidget(top_widget)
        main_layout.addWidget(self.bottom_widget)
        main_layout.setStretch(0, 1)
        main_layout.setStretch(1, 5)

        child_one_win = ChildOneWin()
        child_two_win = ChildTwoWin()
        child_three_win = ChildThreeWin()
        self.bottom_widget.addWidget(child_one_win)
        self.bottom_widget.addWidget(child_two_win)
        self.bottom_widget.addWidget(child_three_win)

        self.bottom_widget.setCurrentIndex(0)

    def call_back_show_btn(self):
        self.bottom_widget.setCurrentIndex(2)

    def call_back_test_btn(self):
        self.bottom_widget.setCurrentIndex(0)

    def call_back_control_btn(self):
        pass
        self.bottom_widget.setCurrentIndex(1)



if __name__ == '__main__':
    app = QApplication(sys.argv)
    # 下面两种方法都可以
    win = WinUIform()
    #win = Winform()
    win.show()
    sys.exit(app.exec_())

演示效果如下:
在这里插入图片描述

<think>好的,用户想了解QStackedWidgetQStackedLayout的用法和区别。首先,我需要回忆这两个类的基本信息。QStackedWidgetQStackedLayout都是Qt框架中用于管理多个子控件,但一次只显示一个的组件。它们的核心功能类似,但使用场景可能不同。 先从QStackedWidget开始,记得它是一个继承自QWidget的容器控件,内部使用QStackedLayout来管理子控件。用户可以直接将QStackedWidget添加到界面中,像其他QWidget一样使用。它的主要方法包括addWidget、insertWidget、removeWidget,以及设置当前显示索引的setCurrentIndex和setCurrentWidget。适用于需要直接替换整个页面,比如向导界面或标签页切换。 然后是QStackedLayout,这是一个布局管理器,继承自QLayout。它本身不是一个控件,所以需要嵌入到其他容器控件中使用。比如可以创建一个QWidget,然后设置它的布局为QStackedLayout。它的接口和QStackedWidget类似,但需要手动添加到父控件中。可能更适合需要自定义布局结构的情况,比如在复杂的界面组合中使用不同的布局管理器。 接下来需要比较它们的区别。首先,继承关系:QStackedWidget是QWidget的子类,而QStackedLayout是QLayout的子类。使用方式上,QStackedWidget可以直接作为控件使用,而QStackedLayout需要依附于一个父控件。灵活性方面,QStackedLayout可以和其他布局组合使用,比如嵌套在QHBoxLayout中,而QStackedWidget本身已经是一个完整的控件。 应用场景方面,QStackedWidget适合需要快速实现页面切换的简单情况,比如设置向导或标签页。而QStackedLayout适合需要更灵活布局管理的复杂界面,比如动态调整布局结构或与其他布局混合使用。 用户可能需要示例代码来理解两者的用法。需要分别给出两者的代码示例,展示如何添加控件和切换页面。同时,要提到切换索引的方法,比如使用按钮的信号连接到setCurrentIndex。 另外,用户可能不清楚何时选择哪一个。需要总结两者的优缺点,比如QStackedWidget更简单直接,而QStackedLayout更灵活,但需要更多设置。同时,注意QStackedWidget内部已经使用了QStackedLayout,所以如果已经有QStackedWidget,可能不需要直接使用QStackedLayout。 最后,生成相关问题,帮助用户进一步学习。例如,如何在Qt中动态切换布局,或者如何结合其他布局管理器使用QStackedLayout。同时,检查引用资料是否相关,但看起来提供的引用可能没有直接提到这两个类,可能需要忽略引用部分,或者指出参考资料中没有直接信息,但根据Qt文档进行回答。</think>### QStackedWidgetQStackedLayout的用法与区别 #### 1. **核心功能** 两者均用于管理多个子控件(如页面或视图),但**一次只显示其中一个**。这种特性适用于需要动态切换界面的场景,例如: - 向导式对话框 - 标签页切换 - 状态相关的视图切换 #### 2. **QStackedWidget详解** - **继承关系**:`QStackedWidget`直接继承自`QWidget`,本质是一个容器控件。 - **直接使用**:可直接添加到界面中,无需额外布局容器。 - **典型方法**: ```cpp addWidget(QWidget *widget) // 添加子控件 setCurrentIndex(int index) // 设置当前显示的子控件索引 currentWidget() const // 获取当前显示的子控件 ``` - **示例代码**(Python/PyQt): ```python stacked_widget = QStackedWidget() page1 = QLabel("页面1") page2 = QLineEdit("页面2") stacked_widget.addWidget(page1) stacked_widget.addWidget(page2) stacked_widget.setCurrentIndex(1) # 显示第二个页面 ``` #### 3. **QStackedLayout详解** - **继承关系**:`QStackedLayout`继承自`QLayout`,是一个布局管理器。 - **依赖父容器**:需依附于某个`QWidget`才能生效。 - **典型方法**: ```cpp addWidget(QWidget *widget) // 添加子控件 setCurrentIndex(int index) // 设置当前显示的子控件索引 ``` - **示例代码**(Python/PyQt): ```python container = QWidget() stacked_layout = QStackedLayout() container.setLayout(stacked_layout) page1 = QLabel("页面1") page2 = QPushButton("页面2") stacked_layout.addWidget(page1) stacked_layout.addWidget(page2) stacked_layout.setCurrentIndex(0) # 显示第一个页面 ``` #### 4. **关键区别** | **特性** | QStackedWidget | QStackedLayout | |------------------|-----------------------------------------|------------------------------------| | **类型** | 控件(QWidget子类) | 布局管理器(QLayout子类) | | **使用方式** | 直接作为独立控件使用 | 需绑定到父容器的布局 | | **灵活性** | 适合简单页面切换 | 可与其他布局嵌套组合 | | **典型场景** | 标签页、向导界面 | 动态布局重组(如响应窗口尺寸变化) | #### 5. **选择建议** - **优先选择QStackedWidget**:若只需简单页面切换且无需复杂布局管理。 - **选择QStackedLayout**:若需要将页面切换功能集成到更复杂的布局结构中(例如与`QHBoxLayout`或`QGridLayout`嵌套使用)。 #### 6. **性能与实现** - QStackedWidget内部封装了QStackedLayout[^1],因此两者底层实现一致。 - 直接使用QStackedLayout可减少一层控件嵌套,适合对性能敏感的场景。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值