PySide6 QMainWindow与QWidget秒解

我们用盖房子来理解 QMainWindow:

  • QWidget = 毛坯房:四面墙一个顶,什么都没有,所有东西都要自己装
  • QMainWindow = 开发商建好的精装修商品房:自带固定的功能分区(客厅、厨房、阳台),你只需要往里面摆家具就行

一句话核心 :QMainWindow 是 PySide6 专门用来做应用程序主窗口的类,它已经预设好了所有主窗口该有的标准结构,不用你从零搭建。

一、QMainWindow 的 "户型图":固定 5 大功能区

这是 QMainWindow 最关键的知识点 ------ 它有严格固定的布局结构,不能乱改,每个区域都有专属的 API:

⚠️ 最容易踩的坑 :QMainWindow不能直接用 setLayout () 加布局!它有自己内置的布局管理器,所有东西都必须放在上面 5 个区域里。

二、第一步:先 "收房"------ 创建一个空的主窗口

python 复制代码
import sys
from PySide6.QtWidgets import (QApplication, QMainWindow,
                               QLabel, QPushButton, QTextEdit)

# 继承QMainWindow,相当于"收房后开始个性化装修"
class MyMainWindow(QMainWindow):
    def __init__(self):
        super().__init__()  # 先调用父类的构造函数,拿到毛坯房
        self.init_ui()      # 开始装修
    
    def init_ui(self):
        # 设置窗口基本属性(相当于给房子挂门牌号、定大小)
        self.setWindowTitle("我的第一个主窗口")
        self.resize(800, 600)  # 宽800,高600
        # self.showMaximized() # 直接全屏显示

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MyMainWindow()
    window.show()  # 开门迎客
    sys.exit(app.exec())

运行这个代码,你就得到了一个标准的空白主窗口。

三、第二步:装修 "客厅"------ 中心部件 Central Widget

中心部件是 QMainWindow 的灵魂,必须要有! 就像房子不能没有客厅。

  • 所有你想展示的核心内容(文本框、按钮、表格、图片)都要放在这里
  • 一个主窗口只能有一个中心部件
python 复制代码
def init_ui(self):
    self.setWindowTitle("我的第一个主窗口")
    self.resize(800, 600)
    
    # 1. 创建中心部件(相当于买个大沙发放在客厅)
    central_widget = QTextEdit()  # 用文本编辑器当中心部件
    # 2. 把中心部件设置给主窗口
    self.setCentralWidget(central_widget)
    
    # 如果你想放多个控件,就先创建一个QWidget,给它加布局,再设为中心部件
    # central_widget = QWidget()
    # layout = QVBoxLayout(central_widget)
    # layout.addWidget(QPushButton("按钮1"))
    # layout.addWidget(QLabel("标签1"))
    # self.setCentralWidget(central_widget)

菜单栏在窗口最顶部,是所有功能的总入口,就像家里玄关的总开关面板。

python 复制代码
def init_ui(self):
    # ... 前面的代码不变
    
    # 1. 获取主窗口自带的菜单栏(不用自己创建)
    menu_bar = self.menuBar()
    
    # 2. 添加一级菜单(相当于开关面板上的"灯光"、"空调"分组)
    file_menu = menu_bar.addMenu("文件")
    edit_menu = menu_bar.addMenu("编辑")
    help_menu = menu_bar.addMenu("帮助")
    
    # 3. 给菜单添加动作(相当于分组里的具体开关)
    new_action = file_menu.addAction("新建")
    open_action = file_menu.addAction("打开")
    file_menu.addSeparator()  # 添加分隔线
    save_action = file_menu.addAction("保存")
    file_menu.addSeparator()
    exit_action = file_menu.addAction("退出")
    
    # 4. 给动作绑定点击事件(按开关就触发对应的事)
    exit_action.triggered.connect(self.close)  # 点击退出就关闭窗口

五、第四步:放 "工具抽屉"------ 工具栏 Tool Bar

工具栏在菜单栏下面,放最常用的功能按钮,就像你放在茶几上的遥控器、手机,不用每次都去玄关开总开关。

python 复制代码
def init_ui(self):
    # ... 前面的代码不变
    
    # 1. 创建工具栏
    tool_bar = self.addToolBar("常用工具")
    
    # 2. 给工具栏添加动作(可以直接复用菜单栏的动作!)
    tool_bar.addAction(new_action)
    tool_bar.addAction(open_action)
    tool_bar.addAction(save_action)
    tool_bar.addSeparator()
    
    # 3. 也可以添加按钮、标签等其他控件
    tool_bar.addWidget(QPushButton("一键格式化"))
    
    # 4. 设置工具栏特性
    tool_bar.setMovable(True)  # 可以拖动(默认True)
    tool_bar.setFloatable(True) # 可以悬浮成独立窗口

六、第五步:挂 "留言板"------ 状态栏 Status Bar

状态栏在窗口最底部,用来显示临时提示信息或永久状态,就像门口的留言板。

python 复制代码
def init_ui(self):
    # ... 前面的代码不变
    
    # 1. 获取主窗口自带的状态栏
    status_bar = self.statusBar()
    
    # 2. 显示临时消息(5秒后自动消失)
    status_bar.showMessage("欢迎使用本程序", 5000)
    
    # 3. 显示永久消息(一直留在右下角)
    status_bar.addPermanentWidget(QLabel("版本:v1.0.0"))

七、完整可运行的例子

把上面所有部分拼起来,你就得到了一个有模有样的主窗口:

python 复制代码
import sys
from PySide6.QtWidgets import (QApplication, QMainWindow,
                               QLabel, QPushButton, QTextEdit)

class MyMainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.init_ui()
    
    def init_ui(self):
        self.setWindowTitle("迷你记事本")
        self.resize(800, 600)
        
        # 1. 中心部件
        self.text_edit = QTextEdit()
        self.setCentralWidget(self.text_edit)
        
        # 2. 菜单栏
        menu_bar = self.menuBar()
        file_menu = menu_bar.addMenu("文件")
        
        new_action = file_menu.addAction("新建")
        open_action = file_menu.addAction("打开")
        save_action = file_menu.addAction("保存")
        file_menu.addSeparator()
        exit_action = file_menu.addAction("退出")
        exit_action.triggered.connect(self.close)
        
        # 3. 工具栏
        tool_bar = self.addToolBar("工具栏")
        tool_bar.addAction(new_action)
        tool_bar.addAction(open_action)
        tool_bar.addAction(save_action)
        
        # 4. 状态栏
        self.statusBar().showMessage("就绪", 3000)
        self.statusBar().addPermanentWidget(QLabel("迷你记事本 v1.0"))

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MyMainWindow()
    window.show()
    sys.exit(app.exec())

八、一句话总结核心

部件 类比 作用
QMainWindow 精装修商品房 主窗口容器,自带固定结构
中心部件 客厅 放核心内容,必须有且只有一个
菜单栏 玄关总开关 所有功能的总入口
工具栏 茶几遥控器 放最常用的功能,快速访问
状态栏 门口留言板 显示程序状态和提示信息

新手黄金法则:做主窗口就用 QMainWindow,不要用 QWidget;所有控件都放在 5 个固定区域里,永远不要给 QMainWindow 直接 setLayout ()。

PySide6 QWidget:用 "毛坯房" 秒懂所有控件的祖宗

延续之前的 "盖房子" 系列,我们用毛坯房来理解 QWidget,这样你就能一眼看清它和 QMainWindow 的本质区别:

  • QWidget = 纯毛坯房:只有四面墙、一个顶、一个门,什么都没有。水电要自己拉,地板要自己铺,家具要自己买,想怎么装就怎么装
  • QMainWindow = 精装修商品房:开发商已经帮你做好了固定的功能分区(客厅、厨房、阳台),你只需要往里面摆家具就行

一句话核心 :QWidget 是 PySide6 中所有 UI 控件的基类(按钮、标签、文本框、窗口... 全都是 QWidget 的子类)。它是最基础、最灵活、最空白的组件,没有任何预设结构,完全由你自由定制。

一、QWidget 的核心本质

你可以把 QWidget 理解成一个万能的 "容器",它有三重身份:

  1. 独立窗口:就是我们平时看到的各种弹窗、对话框
  2. 子容器:用来分组管理其他控件(比如一个面板、一个功能区)
  3. 基础控件:所有具体控件(QLabel、QPushButton、QTextEdit)本质上都是特殊的 QWidget

⚠️ 最容易踩的坑 :QWidget必须自己设置布局 !否则所有控件都会堆在左上角,窗口缩放时也不会自动调整大小。这和 QMainWindow 正好相反(QMainWindow 不能直接调用setLayout())。

二、第一步:先 "盖好" 一个毛坯房

python 复制代码
import sys
from PySide6.QtWidgets import QApplication, QWidget

# 继承QWidget,相当于"拿到一块地,开始盖毛坯房"
class MyWindow(QWidget):
    def __init__(self):
        super().__init__()  # 先调用父类的构造函数,打好地基
        self.init_ui()      # 开始装修
    
    def init_ui(self):
        # 设置窗口基本属性(相当于给房子挂门牌号、定大小)
        self.setWindowTitle("我的第一个毛坯房窗口")
        self.resize(600, 400)  # 宽600,高400
        # self.setFixedSize(600, 400) # 固定窗口大小,禁止缩放

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MyWindow()
    window.show()  # 开门迎客
    sys.exit(app.exec())

运行这个代码,你就得到了一个最纯粹的空白窗口,什么都没有,干干净净。

三、第二步:最重要的一步 ------"装水电铺地板"(设置布局)

这是 QWidget 最核心、最容易出错的地方。毛坯房不能直接摆家具,必须先铺好地板、走好水电,也就是设置布局管理器

布局管理器就像你给房子画的 "装修平面图",它会自动帮你排列控件,窗口缩放时也会智能调整大小和位置。

PySide6 有 4 种常用布局,对应 4 种不同的排列方式:

布局类型 装修类比 核心作用
QHBoxLayout 横向摆放家具 控件水平排成一排
QVBoxLayout 纵向摆放家具 控件垂直排成一列
QGridLayout 地砖格子 控件排成网格状(几行几列)
QFormLayout 填表格式 专门用来做 "标签 + 输入框" 的表单

我们用最常用的垂直布局来举例:

python 复制代码
from PySide6.QtWidgets import QVBoxLayout

def init_ui(self):
    self.setWindowTitle("我的第一个毛坯房窗口")
    self.resize(600, 400)
    
    # 1. 创建布局管理器(相当于画好装修平面图)
    # 把布局直接绑定到当前窗口(self)
    main_layout = QVBoxLayout(self)
    
    # 2. 设置布局的边距和间距(相当于留好墙距和家具间距)
    main_layout.setContentsMargins(30, 30, 30, 30)  # 左、上、右、下边距
    main_layout.setSpacing(20)  # 控件之间的间距

四、第三步:往里面 "摆家具"(添加控件)

布局设置好之后,就可以往里面添加各种控件了,就像往摆好平面图的房子里放沙发、电视、桌子一样。

python 复制代码
from PySide6.QtWidgets import QLabel, QLineEdit, QPushButton

def init_ui(self):
    # ... 前面的代码不变
    
    # 1. 添加标签(相当于在墙上挂一幅画)
    # 注意:加self.变成实例属性,这样其他方法也能访问到
    self.title_label = QLabel("欢迎来到我的毛坯房")
    # 设置标签样式(相当于给画装个好看的框)
    self.title_label.setStyleSheet("font-size: 24px; font-weight: bold; color: #2563eb;")
    # 把标签添加到布局里
    main_layout.addWidget(self.title_label)
    
    # 2. 添加输入框(相当于装一个洗手池)
    self.name_input = QLineEdit()
    self.name_input.setPlaceholderText("请输入你的名字")
    main_layout.addWidget(self.name_input)
    
    # 3. 添加按钮(相当于装一个电灯开关)
    hello_button = QPushButton("打个招呼")
    main_layout.addWidget(hello_button)
    
    # 4. 添加弹性空间(相当于留一块空地)
    # 这样上面的控件会靠上对齐,下面自动留空
    main_layout.addStretch()

五、第四步:"安装开关"(连接信号与槽)

家具摆好了,开关也装好了,现在需要把开关和电器连接起来,这样按开关的时候电器才会工作。这就是 PySide6 的灵魂 ------信号与槽机制

  • 信号:控件发出的 "通知"(比如按钮被点击了、输入框内容改变了)
  • 槽:接收到信号后要执行的 "动作"(比如弹出提示框、显示一段文字)
python 复制代码
def init_ui(self):
    # ... 前面的代码不变
    
    # 把按钮的"点击"信号,连接到我们自己写的"say_hello"槽函数
    hello_button.clicked.connect(self.say_hello)

# 定义槽函数(相当于开关按下后要做的事)
def say_hello(self):
    # 获取输入框里的名字
    name = self.name_input.text().strip()
    if name:
        self.title_label.setText(f"你好,{name}!欢迎来到我的毛坯房")
    else:
        self.title_label.setText("你好,陌生人!请先输入你的名字")

六、完整可运行的例子

把上面所有部分拼起来,你就得到了一个简单但完整的 QWidget 窗口:

python 复制代码
import sys
from PySide6.QtWidgets import (QApplication, QWidget, QVBoxLayout,
                               QLabel, QLineEdit, QPushButton)

class MyWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.init_ui()
    
    def init_ui(self):
        self.setWindowTitle("我的第一个毛坯房窗口")
        self.resize(600, 400)
        
        # 创建垂直布局
        main_layout = QVBoxLayout(self)
        main_layout.setContentsMargins(30, 30, 30, 30)
        main_layout.setSpacing(20)
        
        # 添加标签
        self.title_label = QLabel("欢迎来到我的毛坯房")
        self.title_label.setStyleSheet("font-size: 24px; font-weight: bold; color: #2563eb;")
        main_layout.addWidget(self.title_label)
        
        # 添加输入框
        self.name_input = QLineEdit()
        self.name_input.setPlaceholderText("请输入你的名字")
        main_layout.addWidget(self.name_input)
        
        # 添加按钮
        hello_button = QPushButton("打个招呼")
        hello_button.clicked.connect(self.say_hello)
        main_layout.addWidget(hello_button)
        
        # 添加弹性空间
        main_layout.addStretch()
    
    def say_hello(self):
        name = self.name_input.text().strip()
        if name:
            self.title_label.setText(f"你好,{name}!欢迎来到我的毛坯房")
        else:
            self.title_label.setText("你好,陌生人!请先输入你的名字")

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MyWindow()
    window.show()
    sys.exit(app.exec())

七、QWidget 的独门绝技:嵌套布局

毛坯房的最大优势就是无限灵活,你可以在一个布局里嵌套另一个布局,就像你可以把房子分成客厅、卧室、厨房一样。

比如,我们想在窗口底部放两个并排的按钮,就可以用一个水平布局嵌套在垂直布局里:

python 复制代码
from PySide6.QtWidgets import QHBoxLayout

def init_ui(self):
    # ... 前面的代码不变
    
    # 创建一个水平布局,专门用来放底部的两个按钮
    button_layout = QHBoxLayout()
    
    # 添加两个按钮到水平布局
    button_layout.addWidget(QPushButton("确定"))
    button_layout.addWidget(QPushButton("取消"))
    
    # 把水平布局添加到主垂直布局的最底部
    main_layout.addLayout(button_layout)

八、QWidget vs QMainWindow:一张表搞懂什么时候用哪个

特性 QWidget(毛坯房) QMainWindow(精装修商品房)
预设结构 完全空白,什么都没有 自带菜单栏、工具栏、状态栏、中心部件、停靠区
布局方式 必须自己调用 setLayout () 不能直接调用 setLayout (),有内置布局
灵活性 最高,想怎么装就怎么装 中等,必须使用固定的 5 个区域
适用场景 弹窗、对话框、子窗口、自定义控件 应用程序的主窗口
学习成本 低,简单直接 高,有很多专属 API

九、新手黄金法则

  1. 主窗口用 QMainWindow,其他所有窗口 / 面板 / 控件都用 QWidget
  2. 永远先设置布局,再添加控件,绝对不要手动设置控件的 x、y 坐标
  3. 需要复杂排列时就用嵌套布局,不要试图用一个布局搞定所有事情
  4. 所有需要在多个方法中访问的控件,都要加 self. 变成实例属性
相关推荐
popcorn_min1 小时前
California Housing 可复现回归实验:随机森林预测加州房价
python
吴佳浩 Alben1 小时前
pytorch 你不学?_EP01_环境准备与安装验证
人工智能·pytorch·python
XiaoZhangGOGOGO1 小时前
新的文本编辑方式
python
留白_1 小时前
pandas练习题
python·数据分析·pandas
字节高级特工1 小时前
智能指针原理与使用场景全解析
开发语言·c++·算法
码界索隆1 小时前
Python转Java系列:面向对象基础
java·开发语言·python
逻辑星辰1 小时前
x-ds-pow-response逆向分析
开发语言·人工智能·python·深度学习·算法
c_lb72882 小时前
涨跌停与流动性变差还要不要挂单:quote 涨跌停字段与熔断思路
python·区块链
非生而知之者2 小时前
基于灰狼算法优化的电量预测
python·算法·群体智能算法·电力预测