QAudioOutput constructor hangs in PyQt6
ekhumoro
ekhumoro at gmx.com
Thu Apr 9 15:30:25 BST 2026
Hello
I have encountered some problems when creating an instance of QAudioOutput in PyQt6, which result in the program hanging
without producing any error messages. I am testing on Linux using PyQt-6.11.0 / Sip-6.15.2, although I suspect the issue
may be difficult to reproduce on other platforms. However, it seems reasonable to assume PyQt6 must be at least partly
responsible, as an equivalent C++ example doesn't show any of the problematic behaviours. Any insights regarding the
cause of this rather strange issue would be gratefully received.
The two examples are given below. Note that it's not really necessary to try to play an audio file.
PyQt6 example:
#!/usr/bin/python3
import sys, signal
signal.signal(signal.SIGINT, signal.SIG_DFL)
print('Press Ctrl+C to quit\n')
from PyQt6.QtCore import (
qInstallMessageHandler, QUrl, QTimer, QtMsgType, qDebug
)
from PyQt6.QtWidgets import QApplication
from PyQt6.QtMultimedia import QMediaPlayer, QAudioOutput
def messageHandler(mode, context, message):
if mode == QtMsgType.QtInfoMsg:
print(f'INFO: {message}\n')
elif mode == QtMsgType.QtDebugMsg:
print(f'DEBUG: {message}\n')
elif mode == QtMsgType.QtWarningMsg:
print(f'WARNING: {message}\n')
elif mode == QtMsgType.QtCriticalMsg:
print(f'CRITICAL: {message}\n')
elif mode == QtMsgType.QtFatalMsg:
print(f'FATAL: {message}\n')
# PyQt6 hangs with a message-handler set, unlike C++
# qInstallMessageHandler(messageHandler)
app = QApplication(['Test'])
def main():
global player, audio
player = QMediaPlayer()
qDebug('creating audio output...')
audio = QAudioOutput()
qDebug('audio output created')
qInstallMessageHandler(messageHandler)
player.setAudioOutput(audio)
if len(sys.argv) > 1:
player.setSource(QUrl.fromLocalFile(sys.argv[1]))
player.play()
else:
qDebug("cancelled: no audio source provided")
app.quit()
# PyQt6 hangs without the following, unlike C++
# QTimer.singleShot(100, main)
main()
app.exec()
C++ example:
#include <QDebug>
#include <QTimer>
#include <QApplication>
#include <QMediaPlayer>
#include <QAudioOutput>
#include <QtLogging>
#include <QMessageLogContext>
#include <QString>
void messageHandler(QtMsgType type, const QMessageLogContext &, const QString &str)
{
const char * msg = qPrintable(str);
switch (type)
{
case QtInfoMsg:
fprintf(stderr, "INFO: %s\n\n", msg);
break;
case QtDebugMsg:
fprintf(stderr, "DEBUG: %s\n\n", msg);
break;
case QtWarningMsg:
fprintf(stderr, "WARNING: %s\n\n", msg);
break;
case QtCriticalMsg:
fprintf(stderr, "CRITICAL: %s\n\n", msg);
break;
case QtFatalMsg:
fprintf(stderr, "FATAL: %s\n\n", msg);
abort();
}
}
int main(int argc, char *argv[])
{
qInstallMessageHandler(messageHandler);
QApplication app(argc, argv);
QMediaPlayer *player = new QMediaPlayer;
qDebug("creating audio output...");
QAudioOutput *audioOutput = new QAudioOutput;
qDebug("audio output created");
player->setAudioOutput(audioOutput);
if (argc > 1) {
QUrl source = QUrl::fromLocalFile(QApplication::arguments().at(1));
player->setSource(source);
qDebug() << "source url: " << player->source();
player->play();
QTimer::singleShot(15000, app.quit);
app.exec();
} else {
qInfo() << "cancelled: no source file provided";
}
}
More information about the PyQt
mailing list