1. 當頁面消息比較多時候,會報錯
QPainter::begin: Paint device returned engine == 0, type: 3 QPainter::setCompositionMode: Painter not active QPainter::end: Painter not active, aborted QPainter::begin: Paint device returned engine == 0, type: 3 QPainter::scale: Painter not active QPainter::setRenderHint: Painter must be active to set rendering hints QPainter::end: Painter not active, aborted QPainter::begin: Paint device returned engine == 0, type: 3 QPainter::setCompositionMode: Painter not active QPainter::end: Painter not active, aborted QThread::start: Failed to create thread (Unknown error 0x00000022.)
==========> ExitInstance :gLayerInfo delete 113286984<==============Unload CSProxy from Client.exe... terminate called after throwing an instance of 'std::bad_alloc' what(): std::bad_alloc
2. 注意觀察,總結什么情況下報錯
一秒一條消息進來 10秒刷新一次,10分鍾都沒有異常 5秒刷新一次,10分鍾都沒有異常 2秒刷新一次,10分鍾都沒有異常===>13分鍾崩潰 1秒刷新一次,6分鍾后有問題 一秒四條消息進來 2秒刷新一次,第4分鍾出現異常 5秒刷新一次,第4分鍾出現異常 10秒刷新一次,第4分鍾出現異常
3. 在不確定什么緣由導致時,注釋整塊、部分代碼去排除出問題的代碼
出問題的代碼如下
if(!soundName.isEmpty()){
QMediaPlayer *player = new QMediaPlayer();;//播放器
QMediaPlaylist *playlist = new QMediaPlaylist();//播放列表
player->setPlaylist(playlist);
if (player->state()!=QMediaPlayer::PlayingState){
playlist->setCurrentIndex(0);
}
playlist->setPlaybackMode(QMediaPlaylist::Sequential); //循環模式
QString audiosPath = QCoreApplication::applicationDirPath() + "/audios/";
playlist->clear();
//放3遍
playlist->addMedia(QUrl::fromLocalFile(audiosPath+soundName+".mp3"));
playlist->addMedia(QUrl::fromLocalFile(audiosPath+soundName+".mp3"));
playlist->addMedia(QUrl::fromLocalFile(audiosPath+soundName+".mp3"));
player->play();
}
結合網上資料
class Q_CORE_EXPORT QInternal {
public:
enum PaintDeviceFlags {
UnknownDevice = 0x00,
Widget = 0x01,
Pixmap = 0x02,
Image = 0x03,
Printer = 0x04,
Picture = 0x05,
Pbuffer = 0x06, // GL pbuffer
FramebufferObject = 0x07, // GL framebuffer object
CustomRaster = 0x08,
MacQuartz = 0x09,
PaintBuffer = 0x0a,
OpenGL = 0x0b
};
QPainter::begin: Paint device returned engine == 0, type: 3
UnknownDevice==>
每條消息會初始化QMediaPlayer,多個QMediaPlayer;播放會造成設備UnknownDevice;並且std::bad_alloc 表示程序分配內存異常。

4.解決方法
使用QMutex mutex,lock()、unlock()對上述代碼塊加鎖,並對QMediaPlayer等復用。
static QMutex mutex;
static QMediaPlayer *player = new QMediaPlayer();//播放器
static QMediaPlaylist *playlist = new QMediaPlaylist();//播放列表
void XXX::playSound(QString soundName){
if(!soundName.isEmpty()){
mutex.lock();
qDebug() << "【AlarmMessage::playSound】 start " << soundName;
player->setPlaylist(playlist);
if (player->state()!=QMediaPlayer::PlayingState){
playlist->setCurrentIndex(0);
}
playlist->setPlaybackMode(QMediaPlaylist::Sequential); //循環模式
QString audiosPath = QCoreApplication::applicationDirPath() + "/audios/";
playlist->clear();
//放3遍
playlist->addMedia(QUrl::fromLocalFile(audiosPath+soundName+".mp3"));
playlist->addMedia(QUrl::fromLocalFile(audiosPath+soundName+".mp3"));
playlist->addMedia(QUrl::fromLocalFile(audiosPath+soundName+".mp3"));
player->play();
qDebug() << "【AlarmMessage::playSound】 end " << soundName;
mutex.unlock();
}
}
