PyQt入门(9)-窗口属性浅析和创建子窗口

目录

一、模态和非模态

二、窗口属性浅析

三、创建子窗口


一、模态和非模态

枚举类WindowModality用于指定窗口的模态行为。模态是指阻止其他窗口获取输入。

widget通过setWindowModality()来设置自己的模态属性。

注意:模态中的阻塞只是说阻塞其他窗口获取事件输入,而不是阻塞整个应用的执行

常量描述
Qt::NonModal0非模态,普通的新建窗口都是非模态的。
Qt::WindowModal1窗口模态,只要记住3点:1、如果widget没有parent,那窗口模态就无意义了,相当于非模态2、模态窗口会阻塞其最高祖先往下的整棵窗口树3、模态窗口不会阻塞其子窗口。具体解释看下图。
Qt::ApplicationModal2应用模态,会阻塞整个应用的所有窗口

 

二、窗口属性浅析

WindowType是qt的一个枚举类,里面包含了各种类型,这些类型用于指定QWidget的各种窗口属性,这些属性决定窗口的外观。

WindowFlags是一个WindowType中各种类型的组合类,用于设置给QWidget,可以说WindowFlags就是QWidget的窗口属性。QWidget可以通过windowFlags()来获取窗口属性,用setWindowFlags()来设置窗口属性,setWindowFlag(a0, on=True)来设置或取消某个属性a0,on=True是设置属性,on=False是取消属性。

窗口属性这一块可能并不常用,但是在某些情况下,它们是必须的。其中有些类型是否有用还取决于操作系统底层窗口管理器是否支持。

完整列表见:WindowType完整列表

下面列举和说明一些常用类型:

常量描述
Qt::Widget0x00000000这是所有QWidget都拥有的的默认属性
Qt::Window0x00000001使widget成为一个窗口。widget要显示出来,不管是自己单独作为一个窗口,还是嵌入父widget依托父widget的窗口,都必须有一个窗口。所以如果widget有父widget的话,是可以取消这个属性的,没有就无法取消这个属性,很好理解,没有窗口,widget就没地方显示。
Qt::Dialog0x00000002 | Window使widget成为一个对话框样式的窗口,仅此而已。要注意,对话框和模态可没啥关系,这是两个概念。
Qt::Popup0x00000008 | Window使widget作为一个顶层窗口弹出,并且不管widget有没有parent,它都将作为模态窗口阻塞其他窗口(一般模态窗口只能阻塞父窗口)。窗口没有标题栏,如果要关闭窗口的话,只能代码关闭,或者点击外部区域,使qt的窗口失焦,那弹出窗口自动关闭
Qt::ToolPopup | Dialog使widget作为一个tool窗口(有标题栏)弹出,widget基本算是一个独立的窗口,即不会失焦自动退出,也不会阻塞其他窗口;如果widget有parent的话,widget窗口永远显示在parent窗口之上。
Qt::FramelessWindowHint0x00000800使窗口无边框、无标题栏。我们都知道,windows系统本身的标题栏是不怎么好看而且无法定制样式的,为了做一些比较好看的标题栏,就可以使用这个type来得到一个无边框的窗口,然后自己定制一个标题栏。
Qt::WindowMinimizeButtonHint0x00004000标题栏上添加一个最小化按钮,windows系统默认就有这个按钮,有些平台是没有的;Windows系统可以通过取消这个类型来禁用最小化按钮,没法完全不显示。如果同时禁用Qt::WindowMaximizeButtonHint那最小化和最大化按钮就都不显示。
Qt::WindowMaximizeButtonHint0x00008000标题栏上添加一个最大化按钮,windows系统默认就有这个按钮,有些平台是没有的;Windows系统可以通过取消这个类型来禁用最大化按钮,没法完全不显示。如果同时禁用Qt::WindowMinimizeButtonHint那最小化和最大化按钮就都不显示。
Qt::WindowMinMaxButtonsHintWindowMinimizeButtonHint | WindowMaximizeButtonHint标题栏上添加一个最大化按钮和一个最小化按钮,windows系统默认就有这两个按钮,有些平台是没有的;Windows系统可以通过取消这个类型来不显示最小化按钮和最大化按钮
Qt::WindowCloseButtonHint0x08000000标题栏上添加一个关闭按钮,windows系统默认就有这个按钮,有些平台是没有的;Windows系统可以通过取消这个类型来禁用关闭按钮,没法完全不显示
Qt::WindowStaysOnTopHint0x00040000窗口置顶
Qt::WindowStaysOnBottomHint0x04000000窗口置底

三、创建子窗口

方式1:

    def showChild(self):
        child = Child()
        child.show()

这种方式其实child并不是parent的子窗口,因为parent和child没有任何关联,当showChild执行完毕后,依据python的内存回收机制,child会被立即回收,体现在界面上就是子窗口一闪而过

方式2:

    def showChild(self):
        self.child = Child()
        self.child.show()

这种方式child仍然不是parent的子窗口,直观体现就是设置self.child.setWindowModality(Qt.WindowModal)并不能阻塞parent事件,只不过parent通过成员变量持有了Child,Child不会被回收,所以child是能够正常显示的。而当再次调用showChild的时候,会重新实例化一个新的Child,原来的会被回收。

方式3:

    def showChild(self):
        child = Child(self)
        child.show()

这种方式child才真正是parent的子窗口,child设置Qt.WindowModal可以阻塞parent事件,而且在任务栏上是没有child的图标的(子窗口在任务栏上是没有图标的,真正的独立主窗口才有)。

这时child.parent()指向parent,parent.children()也包含child。因为这些都是pyqt内部实现的,并不会因为child.close()而取消,所以需要重写child的close函数,

    def close(self) -> bool:
        self.setParent(None)
        self.deleteLater()
        return super(Child, self).close()

来断开child和parent的连接,否则每次打开child都会实例化一个新的对象,旧的child又无法回收,造成内存泄露。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值