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
QtFatalMsgbut not for
QtCriticalMsg(I think they are the same log level). Is that correct? Or should
abort()after its message?
[Python question, see also https://docs.python.org/3/library/logging.html] The code is all great. However, because I call
QtCore.qInstallMessageHandler(qtMessageHandler), and my output for all log formatters is
format="%(levelname)s %(name)s [%(filename)s, %(lineno)d, %(funcName)s()]: %(message)s"the output is
WARNING root [errfunctions.py, 56, qtMessageHandler()]: ..., i.e. it tells us it came from
qtMessageHandler(); I want it to appear to come from the caller of
qtMessageHandler(), i.e. somewhere in the outside world. Is there a simple way to achieve this? (Probably not...)
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.
When i need to look at Qt code, i like
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
@JNBarchan For two maybe this can help: https://stackoverflow.com/questions/1156023/print-current-call-stack-from-a-method-in-python-code
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's
It's printing out
%(funcName)s, which is the calling function's name:
def myMethod(): logger.log("Whoops")
myMethodas 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
qtMessageHandler(), and that's the function name output. I'd like the function name to be
myMethod(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
logger.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.
%(funcName)ssupport for calling function name, but not inbuilt support for whole stack. Which is why I'd have to rewrite the logging. But thanks anyway.