一、引言

老猿在前期学习PyQt相关知识时,对每个组件的属性及方法都研究得很透彻,并将学习的感悟都写成了博文,这种方式写了大量博文,但也耽误了太多时间,学习PyQt的时间已经超过了学习Python基础知识和爬虫的时间,而后面还有好多部件,必须得提速了,因此老猿决定以后每种部件都只简单介绍重要的特性和方法,不每个属性和方法都研究了,就从本文开始。

二、概述

QMdiArea部件提供一个包含MDI多文档窗口的区域,在这个区域内管理多个窗口,每个窗口都可以称为激活窗口,可以做自己的事情,如移动、最小化、关闭、打开自己的文档等,而QMdiArea支持对区域内的窗口进行层叠窗口或平铺窗口,并在子窗口切换激活窗口时发射信号。

三、常用属性、方法和信号

3.1、QMdiArea中的子窗口

3.1.1、增加子窗口

QMdiArea中的子窗口类型是QMdiSubWindow的实例,但可以使用addSubWindow()方法将任何QWidget或其派生类的实例添加到MDI区域作为子窗口,此时QMdiArea会自动创建子窗口的QMdiSubWindow实例,并作为addSubWindow()方法的结果返回。

3.1.2、子窗口数量

QMdiArea中的子窗口数量无法直接通过QMdiArea方法获取,必须先通过方法subWindowList()返回所有子窗口的列表,再通过Python的len函数获取子窗口的数量。

3.1.3、子窗口排序和排列

subWindowList()返回的子窗口列表是排序的,有三种排序方式,通过属性activationOrder来控制,排序方式由枚举类型QMdiArea.WindowOrder指定,可通过Designer中就可以设置的属性activationOrder来指定。当使用cascadeSubWindows()和tileSubWindows()层叠或平铺方式来排列区域内的窗口时,也会使用该排序。

3.1.4、活动子窗口

子窗口在获得键盘焦点或调用setFocus()时变为活动状态,用户通过以通常的方式移动焦点来激活窗口。当活动窗口更改时,MDI区域会发出subWindowActivated()信号,active subwindow()函数会返回活动子窗口,槽方法setActiveSubWindow(QMdiSubWindow window)在切换活动窗口时调用。

3.1.5、移除和关闭子窗口

可以通过removeSubWindow(QWidget widget)移除指定子窗口实例,也也可以通过调用槽方法closeAllSubWindows()、closeActiveSubWindow()来关闭子窗口,可以重写这两个方法对子窗口关闭进行相关处理。

3.2、viewMode属性

viewMode属性用于控制子窗口是使用子窗口模式(QMdiArea.SubWindowView)还是选项卡模式(QMdiArea.TabbedView)显示。

如果是子窗口模式,则每个子窗口都是一个带标题栏、窗口G根据addSubWindow指定flag可以设置最大化、最小化和关闭按钮的窗口,可以执行窗口关闭和大小的变化。

如果是选项卡模式,则子窗口最大化后不显示标题栏及操作按钮,但非最大化下会同样显示,另外所有窗口都会在选项卡栏上有个选项。如图:

在选项卡模式下,窗口可以设置documentMode(是否支持文档模式,支持文档模式时窗口无框架,用更多的空间显示文档)、tabsClosable(在选项卡中是否显示关闭标志)、tabsMovable(各子窗口的选项卡在选项卡栏是否可以移动)、tabPosition(选项卡栏所在位置)、tabShape(选项卡形状)这几个属性,而在子窗口模式这几个属性无效。

另外,经老猿验证,在子窗口模式下添加的子窗口必须显示执行show()等方法才能显示子窗口,在选项卡模式无需执行show()等方法就可以显示子窗口。调用show方法时,既可以使用addSubWindow(widget)参数中的widget,也可以用方法返回值对应窗口。

3.3、subWindowActivated信号

subWindowActivated在一个窗口激活(获得焦点)时发射,语法如下:

  • subWindowActivated(QMdiSubWindow window)

如果window参数为None,则表示没有激活的子窗口,如果应用没有disable子窗口,则表示所有子窗口都关闭了。

这个信号比较有用,当开发的应用需要结合子窗口的个数来显示不同的状态时,可以通过这个信号判断window参数是否为None来设置不同的状态。

如下代码是将该信号连接一个槽方法,在槽方法中根据window参数设置actionclose对应按钮和菜单的状态:

    def __init__(self):
super().__init__()
self.setupUi(self)
self.mdiArea.subWindowActivated.connect(self.setButtonsStatus) def setButtonsStatus(self,win):
if win:self.actionclose.setEnabled(True)
else:self.actionclose.setEnabled(False)

四、案例

4.1、案例说明

老猿做了个QMidiArea的测试程序,在这个应用内,可以打开一次打开一个图像文件显示,如果打开的文件没有关闭,再打开就可以显示多个图像文件。

4.2、UI设计

界面为一个QMainWindow,带菜单、工具栏:



从界面看到,包括了打开文件、关闭窗口、排列窗口等功能,下面窗口上部署了QMidiArea实例,没有在Designer中定义子窗口。另外定义了菜单对应action的triggered信号和槽方法的连接,注意级联窗口和平铺窗口直接连接的是QMidiArea的槽方法cascadeSubWindows和tileSubWindows()。

4.3、子窗口的设计

为了简单,子窗口复用了《第15.35节 PyQt编程实战:结合QDial实现的QStackedWidget堆叠窗口程序例子》中的ui_GraphicFileView.ui,相关界面及类graphicFileView在此不重复介绍。

4.4、主界面派生类

主界面派生类主要完成了如下工作:

  • 在构造方法连接了QMdiArea的subWindowActivated和槽方法
  • 实现槽方法setButtonsStatus,根据是否有子窗口设置两个关闭窗口的菜单和按钮的状态
  • 实现了打开图像文件的槽方法openGraphicFile,支持选择一个图片文件打开显示
  • 实现了关闭当前窗口的槽方法closeCurrentWindow
基础代码如下:
class mainWin(QtWidgets.QMainWindow,ui_mainWin.Ui_MainWindow):
def __init__(self):
super().__init__()
self.setupUi(self) self.mdiArea.subWindowActivated.connect(self.setButtonsStatus) def setButtonsStatus(self,win):
if win:
self.actionclose.setEnabled(True)
self.actioncloseAllWindow.setEnabled(True)
else:
self.actionclose.setEnabled(False)
self.actioncloseAllWindow.setEnabled(False) def closeCurrentWindow(self):
w = self.mdiArea.activeSubWindow()
if w: w.close() def openGraphicFile(self):
fileName = .....
......
w = graphicFileView.graphicFileView(fileName) win = self.mdiArea.addSubWindow(w)
win.show()

4.5、运行截图

五、小结

本部分重点介绍了QMdiArea的用途、重要特性和方法、信号,我们在开发时,先做好UI设计,然后通过代码实现QMdiArea子窗口的管理,通过信号subWindowActivated判断QMdiArea实例内是否有可用子窗口来设置相关操作菜单的状态。具体使用可以参考案例。

广告

老猿关于PyQt的付费专栏《使用PyQt开发图形界面Python应用》只需要9.9元,该部分与第十五章的内容基本对应,但同样内容在付费专栏上总体来说更详细、案例更多。本节内容对应付费专栏的《第三十章、containers容器类部件QMdiArea多文档界面部件功能介绍及编程应用》。如果有兴趣也愿意支持老猿的读者,欢迎购买付费专栏。

老猿Python,跟老猿学Python!

第15.37节 PyQt(Python+Qt)入门学习:containers容器类部件QMdiArea多文档界面部件详解及编程开发案例的更多相关文章

  1. 第15.18节 PyQt(Python+Qt)入门学习:Model/View架构中视图Item Views父类详解

    老猿Python博文目录 老猿Python博客地址 一.概述 在PyQt图形界面中,支持采用Model/View架构实现数据和界面逻辑分离,其中Model用于处理数据存储,View用于界面数据展现,当 ...

  2. 第15.28节 PyQt(Python+Qt)入门学习:Model/View架构中的便利类QTableWidget详解

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.引言 表格部件为应用程序提供标准的表格显示工具,在表格内可以管理基于行和列的数据项,表格中的最大 ...

  3. 第15.27节 PyQt(Python+Qt)入门学习:Model/View架构中的便利类QTreeWidget详解

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.引言 树部件(Tree Widget)是Qt Designer中 Item Widgets(It ...

  4. 第15.26节 PyQt(Python+Qt)入门学习:Model/View架构中的便利类QListWidget详解

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.概述 列表部件(List Widget)对应类QListWidget,是从QListView派生 ...

  5. 第15.25节 PyQt(Python+Qt)入门学习:Model/View开发实战--使用QTableView展示Excel文件内容

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.概述 在前面的订阅专栏<第十九章.Model/View开发:QTableView的功能及属 ...

  6. 第15.38节 PyQt(Python+Qt)入门学习:containers容器类部件QDockWidget停靠窗功能详解

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 一.概述 QDockWidget类提供了一个可以停靠在QMainWin ...

  7. 第15.33节 PyQt(Python+Qt)入门学习:containers容器类部件QTabWidget选项窗部件简介

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.概述 容器部件就是可以在部件内放置其他部件的部件,在Qt Designer中可以使用的容器部件有 ...

  8. 第15.31节 PyQt(Python+Qt)入门学习:containers容器类部件GroupBox分组框简介

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.概述 容器部件就是可以在部件内放置其他部件的部件,在Qt Designer中可以使用的容器部件有 ...

  9. 第15.29节 PyQt(Python+Qt)入门学习:containers容器类部件QScrollArea滚动区域详解

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.概述 Scroll Area提供了一个呈现在其他部件上的可滚动区域视图,滚动区域用于显示框架内的 ...

随机推荐

  1. 剑指Offer-Python(16-20)

    16.合并另个排序链表 # -*- coding:utf-8 -*- class ListNode: def __init__(self, x): self.val = x self.next = N ...

  2. 《我想进大厂》之Java基础夺命连环16问

    说好了面试系列已经完结了,结果发现还是真香,嗯,以为我发现我的Java基础都没写,所以这个就算作续集了,续集第一篇请各位收好. 说说进程和线程的区别? 进程是程序的一次执行,是系统进行资源分配和调度的 ...

  3. Martini初步

    部分内容来自http://jerkwin.github.io/9999/08/01/Martini%E7%B2%97%E7%B2%92%E5%8C%96%E5%8A%9B%E5%9C%BA%E4%BD ...

  4. MySQL全面瓦解12:连接查询的原理和应用

    概述 MySQL最强大的功能之一就是能在数据检索的执行中连接(join)表.大部分的单表数据查询并不能满足我们的需求,这时候我们就需要连接一个或者多个表,并通过一些条件过滤筛选出我们需要的数据. 了解 ...

  5. 系统运行后修改linux系统时区

    在网上看了很多改时间的帖子,都没能最终解决问题.最后还是下面的博客最终解决的时间的问题,感谢原作者 安装系统过程时没有选对当前的时区,即CST,Asia/Shanghai,而是按默认的,EDT时区,这 ...

  6. CSS属性(字体与文本属性)

    1.字体属性 (1)font-family 把要对这个网站要设置的字体都写上,如果这个浏览器支持第一个字体,则会用,如果不支持则会尝试第二个,如果设置的字体系统都不支持则会使用系统默认的字体作为网站的 ...

  7. Nacos一致性算法

    1. CAP原则 又称CAP定理,指的是在一个分布式系统中,一致性(Consistency).可用性(Availability).分区容错性(Partition tolerance).CAP 原则指的 ...

  8. List、Tuple、Set、Dictionary数据类型

    一.List数据类型 1.概述:list(列表)中可以包含多个元素,且元素类型可以不相同. 每一元素可以是任意数据类型,包括列表(即列表嵌套)及后面要介绍的元组.集合.字典. 所有元素都写在一对方括号 ...

  9. DOM XSS详解

    DOM XSS简介 DOM XSS与反射性XSS.存储型XSS的主要区别在于DOM XSS的XSS代码不需要服务端解析响应的直接参与,触发XSS的是浏览器端的DOM解析. DOM XSS复现 环境搭建 ...

  10. 给力啊!这篇Spring Bean的依赖注入方式笔记总结真的到位,没见过写的这么细的

    1. Bean的依赖注入概念 依赖注入(Dependency Injection):它是 Spring 框架核心 IOC 的具体实现.在编写程序时,通过控制反转,把对象的创建交给了 Spring,但是 ...