Code for qInstallMessageHandler()
-
I have a couple of questions about my own
qInstallMessageHandler()
function. I program in Python3/PyQt5, I don't have the Qt sources and I don't fancy downloading them and looking through myself, so I hope someone will be kind enough to enlighten me....def qtMessageHandler(type: QtCore.QtMsgType, context: QtCore.QMessageLogContext, msg: str): # Message handler for Qt qDebug() etc. # see https://evileg.com/en/post/154/, # https://stackoverflow.com/questions/35894171/redirect-qdebug-output-to-file-with-pyqt5, # http://thispageintentionally.blogspot.co.uk/2014/03/trapping-qt-log-messages.html if type == QtCore.QtCriticalMsg: # qCritical() level = logging.CRITICAL elif type == QtCore.QtFatalMsg: # qFatal() level = logging.ERROR elif type == QtCore.QtWarningMsg: # qWarning() level = logging.WARNING elif type == QtCore.QtInfoMsg: # qInfo() level = logging.INFO elif type == QtCore.QtDebugMsg: # qDebug() level = logging.DEBUG else: level = logging.DEBUG rootLogger.log(level, "%s", msg) if type == QtCore.QtFatalMsg: # this is the C++ "abort()" they tell you to do for a "fatal" message... import sys sys.exit("abort") rootLogger = logging.getLogger() # install qtMessageHandler() to handle qDebug() etc. QtCore.qInstallMessageHandler(qtMessageHandler)
-
I do not want to call the original, default handler from my code. In the code example http://doc.qt.io/qt-5/qtglobal.html#qInstallMessageHandler they tell you to call
abort()
forQtFatalMsg
but not forQtCriticalMsg
(I think they are the same log level). Is that correct? Or shouldQtCriticalMsg
level alsoabort()
after its message? -
[Python question, see also https://docs.python.org/3/library/logging.html] The code is all great. However, because I call
rootLogger.log()
viaQtCore.qInstallMessageHandler(qtMessageHandler)
, and my output for all log formatters isformat="%(levelname)s %(name)s [%(filename)s, %(lineno)d, %(funcName)s()]: %(message)s"
the output isWARNING root [errfunctions.py, 56, qtMessageHandler()]: ...
, i.e. it tells us it came fromqtMessageHandler()
; I want it to appear to come from the caller ofqtMessageHandler()
, i.e. somewhere in the outside world. Is there a simple way to achieve this? (Probably not...)
-
-
Hi,
-
They do not call any default handler. What is done is that they keep the same behaviour for fatal level message. Critical means that something bad happened but your application may continue to work, a fatal condition is that, everything has to stop otherwise bad consequence could happen.
-
I don't know.
-
-
Hi
When i need to look at Qt code, i like
https://code.woboq.org/ -
Hi,
-
They do not call any default handler. What is done is that they keep the same behaviour for fatal level message. Critical means that something bad happened but your application may continue to work, a fatal condition is that, everything has to stop otherwise bad consequence could happen.
-
I don't know.
@SGaist said in Code for qInstallMessageHandler():
Hi,
- They do not call any default handler. What is done is that they keep the same behaviour for fatal level message. Critical means that something bad happened but your application may continue to work, a fatal condition is that, everything has to stop otherwise bad consequence could happen.
Thanks. Got it! To me, in computer-speak "critical" sounded more serious than "fatal" (though now that I come to think about it for humans, maybe not...) :)
#2 remains unanswered. If there are any Python gurus out there, please let me know your thoughts on the traceback output in
logger.log()
. -
-
@SGaist said in Code for qInstallMessageHandler():
Hi,
- They do not call any default handler. What is done is that they keep the same behaviour for fatal level message. Critical means that something bad happened but your application may continue to work, a fatal condition is that, everything has to stop otherwise bad consequence could happen.
Thanks. Got it! To me, in computer-speak "critical" sounded more serious than "fatal" (though now that I come to think about it for humans, maybe not...) :)
#2 remains unanswered. If there are any Python gurus out there, please let me know your thoughts on the traceback output in
logger.log()
.@JNBarchan For two maybe this can help: https://stackoverflow.com/questions/1156023/print-current-call-stack-from-a-method-in-python-code
-
@JNBarchan For two maybe this can help: https://stackoverflow.com/questions/1156023/print-current-call-stack-from-a-method-in-python-code
@jsulm
Thanks, I do use that principle already when when I'm doing my own explicit stuff. However, the issue here is to get it integrated (nicely) with what what Python'slogger.log()
does.It's printing out
%(funcName)s
, which is the calling function's name:def myMethod(): logger.log("Whoops")
shows
myMethod
as calling function --- good. However:def myMethod(): # Call something in Qt which does an internal `qDebug()` # e.g. some widget does not like the `setStyleSheet()` it's been given widget.show() qInstallMessageHandler(qtMessageHandler)
Now the caller of
logger.log()
isqtMessageHandler()
, and that's the function name output. I'd like the function name to bemyMethod
(else I have no idea where in my code it was called from), which is the caller of the caller, so I'd like something like%(funcName[1])s
inlogger.log()
, but I don't think that exists.I can probably do it all by writing explicit code in
logger.log()
(I think), but wanted to leverage its existing neatness. Thanks anyway! -
@jsulm
Thanks, I do use that principle already when when I'm doing my own explicit stuff. However, the issue here is to get it integrated (nicely) with what what Python'slogger.log()
does.It's printing out
%(funcName)s
, which is the calling function's name:def myMethod(): logger.log("Whoops")
shows
myMethod
as calling function --- good. However:def myMethod(): # Call something in Qt which does an internal `qDebug()` # e.g. some widget does not like the `setStyleSheet()` it's been given widget.show() qInstallMessageHandler(qtMessageHandler)
Now the caller of
logger.log()
isqtMessageHandler()
, and that's the function name output. I'd like the function name to bemyMethod
(else I have no idea where in my code it was called from), which is the caller of the caller, so I'd like something like%(funcName[1])s
inlogger.log()
, but I don't think that exists.I can probably do it all by writing explicit code in
logger.log()
(I think), but wanted to leverage its existing neatness. Thanks anyway!@JNBarchan That's why I suggested to print the whole call stack, then you will see all function calls.
-
@JNBarchan That's why I suggested to print the whole call stack, then you will see all function calls.