QApplication.exec()
在main.py中,实例化app对象,然后在 sys.exit(app.exec())中调用app.exec(),
if __name__ == '__main__':# 实例化应用app = QApplication(sys.argv)# 实例化MyMainFormmyw = MyMainForm()myw.show()# 启动应用程序的事件循环并等待用户交互,直到应用程序关闭。sys.exit(app.exec())
当调用app.exec()时,进入主函数事件循环并且等待exit()调用。当exit()被调用时,app.exec()的返回值会被exit() 设置。
exec()函数的逻辑结构伪代码
def exec():while True:#main events looppassreturn exit()
主要事件循环从窗口系统接收事件,然后将这些事件分发到应用程序小部件。 部件通过被调用它们的 event() 函数来接收事件。
QObject.event()
QWidget继承于QObject,QObject在里面有event函数的描述,用户可以重写event
QEvent
在QEvent有两个函数常用到,也就是accept()和 ignore(),设置事件接收器是否接收或者清除事件标志,默认QEvent被设置为“accept”标志
需求
实现点击窗口的“X”按钮,关闭不了窗口
方法一:重写event函数
def event(self, a0):if(a0.type()==QEvent.Type.Close):a0.ignore()return True #一定要加上否者会出错else:return super().event(a0) # 调用基类的 event() 函数处理其他事件
注event,需要有返回值否者会出错。
方法二:重写closeEvent函数
# # 重写event事件def closeEvent(self, a0):print("widget, close event")a0.ignore()
实现
event与closeEvent函数的关系
# # 重写event事件def closeEvent(self, a0):print(f"{a0.type()}, closeEvent")def event(self, a0):if(a0.type()==QEvent.Type.Close):print("event")super().event(a0)return True #一定要加上否者会出错else:return super().event(a0) # 调用基类的 event() 函数处理其他事件
在上面的代码执行中,可以看到先执行event,在再执行closeEvent。event调用了父类的event将QEvent按照之前的路径传递。QEvent会被传递到closeEvent,这时a0.type()只有一个类型。
因此当事件类型 = QEvent.Type.Close,无论是event中清除标记(调用a0.ignore()),还是在closeEvent清除标记(调用a0.ignore()),都是清除一样的标记。