当前位置: 首页 > article >正文

PyQt4学习笔记4】窗口布局 和 QSplitter

目录

一、常见的布局方式

1. 水平布局(QHBoxLayout)

2. 垂直布局(QVBoxLayout)

3. 网格布局(QGridLayout)

4. 表单布局(QFormLayout)

5. 嵌套布局

布局管理器的优点

二、QSplitter的使用

1. QSplitter 的基本用法

2. QSplitter 的属性和方法

1. 设置分割方向

2. 添加控件

3. 设置控件的大小比例

4. 获取控件的当前大小

5. 获取控件数量

6. 获取特定控件

7. 设置分割条的宽度

8. 禁用用户调整大小

示例:具有垂直和水平分割器的复杂布局

三、QSplitter 的高级用法

1. 保存和恢复分割器状态

2. 设置分割条的样式

3. 响应分割器大小变化

总结


一、常见的布局方式

在 PyQt4 中,窗口布局用于组织窗口中的控件(如按钮、文本框、标签等),使其能够合理地排列在窗口中,并且在窗口大小变化时能够自动调整。PyQt4 提供了多种布局管理器,用于实现不同的布局效果。以下是几种常用的布局方式:

1. 水平布局(QHBoxLayout)

水平布局会将控件从左到右排列在同一行中。

from PyQt4 import QtGui, QtCore

class Example(QtGui.QWidget):
    def __init__(self):
        super(Example, self).__init__()
        self.initUI()

    def initUI(self):
        # 创建控件
        button1 = QtGui.QPushButton("Button 1")
        button2 = QtGui.QPushButton("Button 2")
        button3 = QtGui.QPushButton("Button 3")

        # 创建水平布局
        hbox = QtGui.QHBoxLayout()
        hbox.addWidget(button1)
        hbox.addWidget(button2)
        hbox.addWidget(button3)

        # 将布局设置为窗口的主布局
        self.setLayout(hbox)

        # 设置窗口属性
        self.setWindowTitle("Horizontal Layout")
        self.resize(300, 200)

if __name__ == "__main__":
    app = QtGui.QApplication([])
    ex = Example()
    ex.show()
    app.exec_()

2. 垂直布局(QVBoxLayout)

垂直布局会将控件从上到下排列在同一列中。

from PyQt4 import QtGui, QtCore

class Example(QtGui.QWidget):
    def __init__(self):
        super(Example, self).__init__()
        self.initUI()

    def initUI(self):
        # 创建控件
        button1 = QtGui.QPushButton("Button 1")
        button2 = QtGui.QPushButton("Button 2")
        button3 = QtGui.QPushButton("Button 3")

        # 创建垂直布局
        vbox = QtGui.QVBoxLayout()
        vbox.addWidget(button1)
        vbox.addWidget(button2)
        vbox.addWidget(button3)

        # 将布局设置为窗口的主布局
        self.setLayout(vbox)

        # 设置窗口属性
        self.setWindowTitle("Vertical Layout")
        self.resize(300, 200)

if __name__ == "__main__":
    app = QtGui.QApplication([])
    ex = Example()
    ex.show()
    app.exec_()

3. 网格布局(QGridLayout)

网格布局会将控件放置在一个二维网格中,允许更复杂的排列。

from PyQt4 import QtGui, QtCore

class Example(QtGui.QWidget):
    def __init__(self):
        super(Example, self).__init__()
        self.initUI()

    def initUI(self):
        # 创建控件
        button1 = QtGui.QPushButton("Button 1")
        button2 = QtGui.QPushButton("Button 2")
        button3 = QtGui.QPushButton("Button 3")
        button4 = QtGui.QPushButton("Button 4")

        # 创建网格布局
        grid = QtGui.QGridLayout()
        grid.addWidget(button1, 0, 0)  # 行 0,列 0
        grid.addWidget(button2, 0, 1)  # 行 0,列 1
        grid.addWidget(button3, 1, 0)  # 行 1,列 0
        grid.addWidget(button4, 1, 1)  # 行 1,列 1

        # 将布局设置为窗口的主布局
        self.setLayout(grid)

        # 设置窗口属性
        self.setWindowTitle("Grid Layout")
        self.resize(300, 200)

if __name__ == "__main__":
    app = QtGui.QApplication([])
    ex = Example()
    ex.show()
    app.exec_()

4. 表单布局(QFormLayout)

表单布局适合创建表单,用于对齐标签和输入框。

from PyQt4 import QtGui, QtCore

class Example(QtGui.QWidget):
    def __init__(self):
        super(Example, self).__init__()
        self.initUI()

    def initUI(self):
        # 创建控件
        nameLabel = QtGui.QLabel("Name:")
        nameEdit = QtGui.QLineEdit()

        ageLabel = QtGui.QLabel("Age:")
        ageEdit = QtGui.QLineEdit()

        addressLabel = QtGui.QLabel("Address:")
        addressEdit = QtGui.QLineEdit()

        # 创建表单布局
        form = QtGui.QFormLayout()
        form.addRow(nameLabel, nameEdit)
        form.addRow(ageLabel, ageEdit)
        form.addRow(addressLabel, addressEdit)

        # 将布局设置为窗口的主布局
        self.setLayout(form)

        # 设置窗口属性
        self.setWindowTitle("Form Layout")
        self.resize(300, 200)

if __name__ == "__main__":
    app = QtGui.QApplication([])
    ex = Example()
    ex.show()
    app.exec_()

5. 嵌套布局

你可以将多个布局嵌套在一起,以实现更复杂的界面。

from PyQt4 import QtGui, QtCore

class Example(QtGui.QWidget):
    def __init__(self):
        super(Example, self).__init__()
        self.initUI()

    def initUI(self):
        # 创建控件
        button1 = QtGui.QPushButton("Button 1")
        button2 = QtGui.QPushButton("Button 2")
        button3 = QtGui.QPushButton("Button 3")

        # 创建水平布局
        hbox = QtGui.QHBoxLayout()
        hbox.addWidget(button1)
        hbox.addWidget(button2)

        # 创建垂直布局
        vbox = QtGui.QVBoxLayout()
        vbox.addLayout(hbox)
        vbox.addWidget(button3)

        # 将布局设置为窗口的主布局
        self.setLayout(vbox)

        # 设置窗口属性
        self.setWindowTitle("Nested Layout")
        self.resize(300, 200)

if __name__ == "__main__":
    app = QtGui.QApplication([])
    ex = Example()
    ex.show()
    app.exec_()

布局管理器的优点

  • 自动调整控件大小:当窗口大小改变时,控件会自动调整位置和大小。

  • 简化代码:无需手动计算控件的坐标位置。

  • 易于维护:布局管理器可以方便地添加或删除控件。

通过这些布局管理器,你可以快速构建出美观且功能性强的用户界面。

二、QSplitter的使用

QSplitter 是 PyQt4 中用于创建可调整大小的分割窗口的控件。它允许用户通过拖动分割条来调整子控件的大小。QSplitter 支持垂直和水平布局,并且可以嵌套使用。

1. QSplitter 的基本用法

QSplitter 的基本用法包括以下步骤:

  1. 创建一个 QSplitter 实例。

  2. 将子控件添加到 QSplitter 中。

  3. QSplitter 设置为父窗口的中央窗口部件或其他布局的一部分。

以下是一个简单的示例:

from PyQt4 import QtGui, QtCore

class Example(QtGui.QWidget):
    def __init__(self):
        super(Example, self).__init__()
        self.initUI()

    def initUI(self):
        # 创建水平分割器
        splitter = QtGui.QSplitter(QtCore.Qt.Horizontal)

        # 添加子控件到分割器
        widget1 = QtGui.QWidget()
        widget1.setStyleSheet("background-color: lightblue;")
        splitter.addWidget(widget1)

        widget2 = QtGui.QWidget()
        widget2.setStyleSheet("background-color: lightgreen;")
        splitter.addWidget(widget2)

        # 设置布局
        hbox = QtGui.QHBoxLayout()
        hbox.addWidget(splitter)
        self.setLayout(hbox)

        self.setGeometry(300, 300, 600, 400)
        self.setWindowTitle('QSplitter Example')

if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    ex = Example()
    ex.show()
    sys.exit(app.exec_())

2. QSplitter 的属性和方法

以下是一些常用的 QSplitter 属性和方法:

1. 设置分割方向

  • setOrientation(QtCore.Qt.Horizontal):设置水平分割。

  • setOrientation(QtCore.Qt.Vertical):设置垂直分割。

2. 添加控件

  • addWidget(widget):将控件添加到 QSplitter

3. 设置控件的大小比例

  • setStretchFactor(index, stretch):设置特定控件的伸缩因子。

  • setSizes(sizes):设置控件的初始大小。

4. 获取控件的当前大小

  • sizes():返回控件的当前大小列表。

5. 获取控件数量

  • count():返回 QSplitter 中控件的数量。

6. 获取特定控件

  • widget(index):返回指定索引的控件。

7. 设置分割条的宽度

  • setHandleWidth(width):设置分割条的宽度。

8. 禁用用户调整大小

  • setChildrenCollapsible(True/False):设置是否允许用户通过拖动调整控件大小。

示例:具有垂直和水平分割器的复杂布局

以下是一个更复杂的示例,展示了如何使用嵌套的 QSplitter 创建一个包含垂直和水平分割器的布局:

from PyQt4 import QtGui, QtCore

class Example(QtGui.QWidget):
    def __init__(self):
        super(Example, self).__init__()
        self.initUI()

    def initUI(self):
        # 创建垂直分割器
        splitter1 = QtGui.QSplitter(QtCore.Qt.Vertical)

        # 添加子控件到垂直分割器
        widget1 = QtGui.QWidget()
        widget1.setStyleSheet("background-color: lightblue;")
        splitter1.addWidget(widget1)

        widget2 = QtGui.QWidget()
        widget2.setStyleSheet("background-color: lightgreen;")
        splitter1.addWidget(widget2)

        # 创建水平分割器
        splitter2 = QtGui.QSplitter(QtCore.Qt.Horizontal)

        # 添加垂直分割器到水平分割器
        splitter2.addWidget(splitter1)

        # 添加更多控件到水平分割器
        widget3 = QtGui.QWidget()
        widget3.setStyleSheet("background-color: lightyellow;")
        splitter2.addWidget(widget3)

        # 设置布局
        hbox = QtGui.QHBoxLayout()
        hbox.addWidget(splitter2)
        self.setLayout(hbox)

        self.setGeometry(300, 300, 800, 600)
        self.setWindowTitle('QSplitter Example')

if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    ex = Example()
    ex.show()
    sys.exit(app.exec_())

三、QSplitter 的高级用法

1. 保存和恢复分割器状态

你可以使用 saveState()restoreState() 方法保存和恢复 QSplitter 的状态,包括控件的大小和位置。

# 保存状态
state = splitter.saveState()

# 恢复状态
splitter.restoreState(state)

2. 设置分割条的样式

可以通过样式表设置分割条的样式,例如:

splitter.setStyleSheet("""
    QSplitter::handle {
        background-color: gray;
        width: 5px;
    }
""")

3. 响应分割器大小变化

可以通过 splitterMoved 信号响应分割器的大小变化:

splitter.splitterMoved.connect(self.on_splitterMoved)

def on_splitterMoved(self, pos, index):
    print("Splitter moved to position", pos, "at index", index)

总结

QSplitter 是一个非常强大的控件,适合用于需要动态调整布局的复杂界面。通过嵌套使用 QSplitter,可以创建复杂的多区域布局。

实际案例

使用PyQt4完成以下布局: 整个项目窗体分为:标题、菜单栏、工具栏、 左侧资源显示区、右侧资源显示区、中间主窗体、底部状态显示栏七大部分。
1. 注意这是Python2环境,而且PyQt4要使用Python2的Unicode字符串,就是在中午字符串前面加u
2. 中间主体窗口不是表格,要加上网格线
3. 左右侧资源显示区是一个停靠窗口,标题分别为"资源显示区", "原图"
4. 左侧资源显示区主体是一个QListView且要加上滚动条

# -*- coding: utf-8 -*-
from PyQt4 import QtGui, QtCore

class MainWindow(QtGui.QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.initUI()

    def initUI(self):
        # 设置主窗口的标题
        self.setWindowTitle(u"项目窗体")

        # 1. 标题栏(QMainWindow 默认包含标题栏)

        # 2. 菜单栏
        menubar = self.menuBar()
        file_menu = menubar.addMenu(u"文件")
        file_menu.addAction(u"打开", self.openFile)
        file_menu.addAction(u"保存", self.saveFile)

        # 3. 工具栏
        toolbar = self.addToolBar(u"工具栏")
        toolbar.addAction(u"工具1", self.tool1)
        toolbar.addAction(u"工具2", self.tool2)

        # 4. 左侧资源显示区(停靠窗口)
        left_dock = QtGui.QDockWidget(u"资源显示区", self)
        self.addDockWidget(QtCore.Qt.LeftDockWidgetArea, left_dock)

        # 左侧资源显示区主体是一个 QListView,且带有滚动条
        left_widget = QtGui.QListView()
        model = QtGui.QStringListModel([u"资源1", u"资源2", u"资源3", u"资源4", u"资源5"])
        left_widget.setModel(model)
        left_dock.setWidget(left_widget)

        # 5. 右侧资源显示区(停靠窗口)
        right_dock = QtGui.QDockWidget(u"原图", self)
        self.addDockWidget(QtCore.Qt.RightDockWidgetArea, right_dock)

        # 右侧资源显示区主体是一个 QLabel
        right_widget = QtGui.QLabel(u"右侧资源显示区")
        right_widget.setAlignment(QtCore.Qt.AlignCenter)
        right_dock.setWidget(right_widget)

        # 6. 中间主窗体(带有网格线的 QGraphicsView)
        main_view = QtGui.QGraphicsView()
        scene = QtGui.QGraphicsScene(self)
        main_view.setScene(scene)
        main_view.setStyleSheet("background-color: white;")

        # 绘制网格线
        spacing = 50  # 网格线间距
        width = 800
        height = 600
        pen = QtGui.QPen()
        pen.setStyle(QtCore.Qt.DashLine)  # 设置虚线样式

        for x in range(0, width, spacing):
            scene.addLine(x, 0, x, height, pen)  # 绘制垂直线

        for y in range(0, height, spacing):
            scene.addLine(0, y, width, y, pen)  # 绘制水平线

        # 设置中央窗口部件
        self.setCentralWidget(main_view)

        # 7. 底部状态显示栏
        self.statusBar().showMessage(u"准备就绪")

        # 设置窗口大小
        self.resize(800, 600)

    def openFile(self):
        print "打开文件"

    def saveFile(self):
        print "保存文件"

    def tool1(self):
        print "工具1 被点击"

    def tool2(self):
        print "工具2 被点击"

if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    mainWin = MainWindow()
    mainWin.show()
    sys.exit(app.exec_())

 ------------------------END-------------------------

才疏学浅,谬误难免,欢迎各位批评指正。


http://www.kler.cn/a/534119.html

相关文章:

  • JavaScript前后端交互-AJAX/fetch
  • Java进阶笔记(中级)
  • 深度探索 C 语言操作符:从基础到实战应用
  • C# List 列表综合运用实例⁓Hypak原始数据处理编程小结
  • 深度求索DeepSeek横空出世
  • 【25考研】南开软件考研复试复习重点!
  • JAVAweb学习日记(九) MySQL-事务索引
  • 低代码提升交付效率的公式计算
  • 响应式编程_05 Project Reactor 框架
  • 永久免费语音服务!微软 Azure 注册实操,零成本实现TTS自由
  • Page Assist实现deepseek离线部署的在线搜索功能
  • Mac 基于Ollama 本地部署DeepSeek离线模型
  • MyBatis Plus 输出完整 SQL(带参数)的 3 种方案
  • Boosting 框架
  • 硬件工程师思考笔记02-器件的隐秘角落:磁珠与电阻噪声
  • 堆的实现——堆的应用(堆排序)
  • CTFSHOW-WEB入门-PHP特性89-100
  • 基于SpringBoot+MySQL的图书借阅管理系统源代码+数据库
  • 稳定Android Studio2021.1.2.16的安装
  • flutter 专题四十四 关于MacOs Catalina “无法打开***,因为无法验证开发者...”的解决方案
  • C语言:把两个16位的数据合成32位浮点型数据
  • 基于 docker 的mysql 5.7 主备集群搭建
  • 【PDF多区域识别】如何批量PDF指定多个区域识别改名,基于Windows自带的UWP的文字识别实现方案
  • 第五十八节 k8s1.30.x 安装Redis集群
  • Redis --- 使用Feed流实现社交平台的新闻流
  • 【C++】STL——list底层实现