问题:
PyQt5和matplotlib使用报警告
以下代码执行,关闭窗口后,能看到控制台中有报的警告:
QGuiApplication::font(): no QGuiApplication instance and no application font set.
main.py
#coding:utf-8
import os
import sys
from PyQt5 import QtGui
from PyQt5.QtWidgets import QApplication
from mainWindow import MainWindow
# 运行程序
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()
mainWindow.py
from PyQt5 import QtCore, QtWidgets,QtGui
from PyQt5.QtWidgets import QMainWindow,QWidget,QAction
from PyQt5.QtGui import QIcon
print('ggggg')
from a import A
print('rrrrr')
from b import B
class MainWindow(QMainWindow):
def __init__(self,parent=None) -> None:
super(MainWindow,self).__init__(parent)
self.resize(800,408)
print('aaaa')
# bb=B(A())
bb1=B()
# bb2=B()
a.py
import matplotlib.pyplot as plt
class A:
def __init__(self) -> None:
print('xxxxx')
self.f=plt.figure()
b.py
from a import A
class B:
#如果fig给默认值 A(),则会报错:
#QGuiApplication::font(): no QGuiApplication instance and no application font set.
def __init__(self,fig=A()) -> None:
if fig==None:
pass
# fig=A()
pass
但是把 Class B 的 _init_()中的 fig的默认参数取消掉,就不会再报警告
问题分析:
这个问题的出现是因为在使用matplotlib时,需要一个GUI环境,而在没有调用QGuiApplication之前调用了matplotlib,导致抛出该异常。
要解决这个问题,可以参考以下两种方法:
1.在调用matplotlib前初始化QApplication
在使用matplotlib之前,将下面的语句插入到程序中,并先执行该语句。
python
import sys
from PyQt5.QtWidgets import QApplication
app = QApplication(sys.argv) # 初始化
该语句将创建一个QApplication实例,此时便完成了GUI环境的初始化。然后你就可以正常使用matplotlib了。
2.设置matplotlib不依赖GUI
在执行matplotlib绘图代码前,添加以下代码即可。
python
import matplotlib
matplotlib.use('Agg')
这个设置将matplotlib的渲染器设置为'Agg',这样matplotlib就不会再绑定GUI,而是直接输出图片文件。
综上所述,如果碰到 QGuiApplication::font(): no QGuiApplication instance and no application font set 的问题,可以通过对QApplication初始化或者设置matplotlib不依赖GUI来解决。
问题根源:
python函数默认值生成的时机:在import当前模块的时候,模块内的所有函数默认值都会产生实例
即Class B 的 def __init__(self,fig=A()) -> None: 中的 fig=A() 对象产生于 import b 的时候
注意:python 函数默认值如果是可变类型,那么其实例将只有一个,即无论 B()调用几次,其fig的默认值都是同一个 A()。