参考

《PyQT5快速开发与实战》

pyqt5官网:https://doc.qt.io/qtforpython

如果有许多的控件无法在一个页面中全部显示,可以考虑使用容器,装载更多的控件。

1. QTabWidget

QTabWidget控件提供了一个选项卡和一个页面区域(类似于平时看到的浏览器布局),默认显示第一个选项卡的页面。通过单击各个选项卡可以查看对应的页面。

QTabWidget常用方法:

​ 表1

方法描述
addTab()将一个控件添加到Tab控件的选项卡中。
insertTab()将一个Tab控件的选项卡插入到指定的位置。
removeTab()根据指定的索引删除Tab控件。
setCurrentIndex()设置当前可见的选项卡所在的索引。
setCurrentWidget()设置当前可见的页面。
setTabBar()设置选项卡栏的小控件。
setTabPosition()设置选项卡的位置:
QTabWidget.North :显示在页面的上方。
QTabWidget.South : 显示在页面的下方。
QTabWidget.West:显示在页面的左侧。
QTabWidget.Ease:显示在页面的右侧。
setTabText()定义Tab选项卡的显示值。

QTabWidget的常用信号:

​ 表2

信号描述
currentChanged切换当前页面时发射信号。

示例代码1.

# -*- coding=utf-8 -*-
import sys
from PyQt5.QtWidgets import *


class TabDemo(QTabWidget):  # 继承自QTabWidget
    def __init__(self, parent=None):
        super(TabDemo, self).__init__(parent)
        self.resize(320, 240)  # 窗口大小:宽320,高240
        self.setTabPosition(QTabWidget.West)  # 设置选项卡显示在页面的左侧
        self.contact_tab = QWidget()  # 每个选项卡界面其实都是一个QWidget
        self.personal_details_tab = QWidget()
        # “contact_tab”是对添加进去的contact_tab的描述
        self.addTab(self.contact_tab, "contact_tab")  # 添加“联系方式”的QWidget到QTabWidget中,成为选项卡
        self.addTab(self.personal_details_tab, "personal_details_tab")
        self.contact_tab_ui()  # 绘制“联系方式”选项卡界面
        self.personal_details_tab_ui()  # 绘制“个人信息”选项卡界面

    def contact_tab_ui(self):
        layout = QFormLayout()
        layout.addRow("姓名", QLineEdit())
        layout.addRow("地址", QLineEdit())
        self.setTabText(0, "联系方式")  # 定义选项卡的显示值
        self.contact_tab.setLayout(layout)

    def personal_details_tab_ui(self):
        layout = QFormLayout()
        sex = QHBoxLayout()
        sex.addWidget(QRadioButton("男"))
        sex.addWidget(QRadioButton("女"))
        layout.addRow(QLabel("性别"), sex)
        layout.addRow("生日", QLineEdit())
        self.setTabText(1, "个人详细信息")
        self.personal_details_tab.setLayout(layout)


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

运行截图:
图1“联系方式”选项卡
在这里插入图片描述
​ 图2“个人信息”选项卡

在这里插入图片描述

2. QStackedWidget

QStackedWidget是一个堆栈窗口控件,可以填充一些小控件,但是同一时间只能有一个小控件可以显示。

QStackedWidget使用QStackedLayout布局。

QStackedWidget和QTabWidget类似。

在这里插入图片描述
​ 图3 QStackedWidget的继承关系

QStackedWidget的常用方法:

​ 表3

方法描述
addWidget()添加widget到QStackedWidget中,返回索引位置。
count()返回QStackedWidget中widget的个数。
currentIndex()返回QStackedWidget中当前显示widget的索引。
currentWidget()返回QStackedWidget中当前显示的widget。
indexOf()返回指定widget在QStackedWidget中的索引。
insertWidget()在QStackedWidget中指定位置插入widget。
removeWidget()从QStackedWidget中删除指定widget(并没有实际删除,只是移除,相当于隐藏该widget)
widget()返回指定索引位置的widget。

QStackedWidget的常用槽函数:

​ 表4

描述
setCurrentIndex()设置当前要显示widget的索引。
setCurrentWidget()设置当前要显示的widget。

QStackedWidget的常用信号:

​ 表5

信号描述
currentChanged()当前显示widget发生变化。
widgetRemoved()widget被从QStackedWidget中移除。

示例代码2.

# -*-coding:utf-8 -*-
import sys
from PyQt5.QtWidgets import *


class StackedExample(QWidget):
    def __init__(self):
        super(StackedExample, self).__init__()
        self.resize(320, 240)
        self.setWindowTitle("StackedWidget例子")

        self.left_list = QListWidget()
        self.left_list.insertItem(0, '联系方式')
        self.left_list.insertItem(1, '个人信息')
        self.contact_stack = QWidget()
        self.personal_detail_stack = QWidget()
        self.contact_stack_ui()
        self.personal_detail_stack_ui()
        self.stack = QStackedWidget(self)
        self.stack.addWidget(self.contact_stack)
        self.stack.addWidget(self.personal_detail_stack)
        hbox = QHBoxLayout(self)
        hbox.addWidget(self.left_list)
        hbox.addWidget(self.stack)
        self.setLayout(hbox)
        self.left_list.currentRowChanged.connect(self.display)

    def contact_stack_ui(self):
        layout = QFormLayout()
        layout.addRow('姓名', QLineEdit())
        layout.addRow('地址', QLineEdit())
        self.contact_stack.setLayout(layout)

    def personal_detail_stack_ui(self):
        layout = QFormLayout()
        sex = QHBoxLayout()
        sex.addWidget(QRadioButton('男'))
        sex.addWidget(QRadioButton('女'))
        layout.addRow(QLabel('性别'), sex)
        self.personal_detail_stack.setLayout(layout)

    def display(self, i):
        self.stack.setCurrentIndex(i)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    demo = StackedExample()
    demo.show()
    sys.exit(app.exec_())

运行结果:

​ 图4.“联系方式”界面
在这里插入图片描述

​ 图5.“个人信息”界面
在这里插入图片描述

3. QDockWidget

QDockWidget是一个可以停靠在QMainWindow内的窗口控件,他可以保持在浮动状态或者在指定位置作为子窗口附加到主窗口中。

在这里插入图片描述
​ 图6.QDockWidget的继承关系

在这里插入图片描述
​ 图7. QMainWindow 结构图

QMainWindow类的主窗口对象保留有一个用于停靠窗口的区域,这个区域位于控件的中央周围,即(Dock Windows)。

​ 表6.QDockWidget的常用方法

方法描述
setWidget()在Dock窗口区域设置QWidget.
setFloating()设置Dock窗口是否可以浮动,如果设置为True,则表示可以浮动。
setAllowedAreas()设置窗口可以停靠的区域:
1.LeftDockWidgetArea,左边停靠区域。
2.RightDockWidgetArea,右边停靠区域。
3.TopDockWidgetArea,顶部停靠区域。
4.BottomDockWidgetArea,底部停靠区域。
5.NoDockWidgetArea,不显示Widget。
setFeatures()设置停靠窗口的功能属性:
1.DockWidgetClosable,可关闭。
2.DockWidgetMovable,可移动。
3.DockWidgetFloatable,可漂浮。
4.DockWidgetVerticalTitleBar,在左边显示垂直的标签栏。
5.AllDockWidgetFeatures,具有前3种属性的所有功能。
6.NoDockWidgetFeatures,无法关闭,无法移动,无法漂移。

示例代码3

# -*-coding:utf-8 -*-
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *


class DockExample(QMainWindow): # 顶层窗口是一个QMainWindow对象
    def __init__(self, parent=None):
        super(DockExample, self).__init__(parent)
        self.resize(320, 240)
        self.setWindowTitle("DockWidget例子")

        layout = QHBoxLayout()
        bar = self.menuBar()
        file = bar.addMenu('Files')
        file.addAction('New')
        file.addAction('save')
        file.addAction('quit')

        self.items = QDockWidget('Dockable', self)  # 创建可停靠的窗口

        # 在停靠窗口items内添加QListWidget对象。
        self.list_widget = QListWidget()
        self.list_widget.addItem('item1')
        self.list_widget.addItem('item2')
        self.list_widget.addItem('item3')
        self.items.setWidget(self.list_widget)

        self.items.setFloating(False)
        self.setCentralWidget(QTextEdit())  # QTextEdit对象是QMainWindow对象的中央小控件
        # 将停靠窗口items放置在中央小控件的右侧。
        self.addDockWidget(Qt.RightDockWidgetArea, self.items)
        self.setLayout(layout)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    demo = DockExample()
    demo.show()
    sys.exit(app.exec_())

运行结果:

在这里插入图片描述
​ 图8.Dockable窗口可以拖动

4.多文档界面

QTabWidget和QStackedWidget控件允许一次使用其中的一个窗口,不过其它窗口是隐藏的。

如果要同时显示多个窗口,就得创建多个独立的窗口,这需要消耗较多的内存资源。

独立的窗口称为SDI(single document interface,单文档界面)

包含这些SDI的窗口称为MDI(multiple document interface,多文档界面)。

​ MDI应用程序占用较少的内存资源,相比于同时创建多个窗口,MDI的子窗口都可以放在主窗口容器内。该主窗口容器称为QMdiArea。

​ QMdiArea控件一般放在QMainWindow对象的中央位置,其子窗口在这个区域内是QMdiSubWindow类的实例,,可以设置任何QWidget作为子窗口对象的内部控件,子窗口在MDI区域进行级联排列布局。

在这里插入图片描述
​ 图9.QMdiArea类的继承关系

在这里插入图片描述
​ 图10.QMdiSubWindow的继承关系

在这里插入图片描述

​ 图11.多文档界面

QMdiArea类和QMdiSubWindow类的常用方法:

更多信息得看官网。

​ 表7

方法描述
addSubWindow()将一个小控件添加在MDI区域作为一个新的子窗口。
removeSubWindow()删除一个子窗口中的小控件。
setActiveSubWindow()激活一个子窗口。
cascadeSubWindow()安排子窗口在MDI区域级联显示。
tileSubWindows()安排子窗口在MDI区域平铺显示。
closeActiveSubWindow()关闭活动的窗口。
subWindowList()返回MDI区域的子窗口列表。
setWidget()设置一个小控件作为QMdiSubWindow实例对象的内部控件。

代码示例4:

# -*-coding:utf-8 -*-
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *


class MainWindow(QMainWindow):  # 顶层窗口是一个QMainWindow对象
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.resize(320, 240)
        self.setWindowTitle("多文档界面例子")

        self.count = 0  # 记录子窗口的数量
        self.mdi = QMdiArea()
        self.setCentralWidget(self.mdi)
        bar = self.menuBar()
        file = bar.addMenu('File')
        file.addAction('New')
        file.addAction('cascade')
        file.addAction('Tiled')
        # 单击菜单控件时触发triggered信号,连接到槽函数window_action
        file.triggered[QAction].connect(self.window_action)

    def window_action(self, action):
        print('triggered')

        if action.text() == 'New':  # 添加一个新的SDI,每个SDI都有标题,主窗口内会增加SDI数量
            self.count = self.count + 1
            sub = QMdiSubWindow()
            sub.setWidget(QTextEdit())
            sub.setWindowTitle('sub window' + str(self.count))
            self.mdi.addSubWindow(sub)
            sub.show()
        elif action.text() == 'cascade':  # 级联显示子窗口
            self.mdi.cascadeSubWindows()
        elif action.text() == 'Tiled':  # 平铺显示子窗口
            self.mdi.tileSubWindows()


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

运行结果:

在这里插入图片描述
​ 图12.点击New,创建新窗口

在这里插入图片描述
​ 图13.子窗口的级联布局

在这里插入图片描述
​ 图14.子窗口的平铺布局

5. QScrollBar

前4个窗口控件的共同点:新建一些窗口来装在更多的控件。

QScrollBar:提供水平/垂直的滚动条,扩大当前窗口的有效装载面积,从而装载更多控件。

在这里插入图片描述
​ 图15. QScrollBar的继承关系

​ 表8. QScrollBar常用信号

信号含义
valueChanged()当滑动条的值改变时发射此信号。
sliderMoved()当用户拖动滑块时发射此信号。

示例代码5:

# -*-coding:utf-8 -*-
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *


class ScrollExample(QWidget):
    def __init__(self, parent=None):
        super(ScrollExample, self).__init__(parent)
        self.resize(320, 240)
        self.setWindowTitle("滚动条例子")
        self.scroll_bar = QScrollBar(self)
        self.scroll_bar.resize(20, 240)
        self.scroll_bar.valueChanged.connect(self.slider_slot)
        self.pushbutton = QPushButton('测试', self)
        self.pushbutton.setGeometry(40, 0, 40, 30)

    def slider_slot(self, value):
        self.pushbutton.move(40, value)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    demo = ScrollExample()
    demo.show()
    sys.exit(app.exec_())

运行结果:

在这里插入图片描述
​ 图16.拖动滚动条,“测试”按钮一起移动

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐