PyQt5 Program Crashes While Updating QTextEdit via logging










1















I have a large program that takes a long time that needs ample logging. I have a GUI that is on the front end that includes a custom logging handler as defined below:



class QHandler(logging.Handler, QTextEdit):
def __init__(self, parent=None):
QTextEdit.__init__(self, parent)
logging.Handler.__init__(self)

self.setLineWrapMode(QTextEdit.NoWrap)
self.setReadOnly(True)

self.emit_lock = Lock()

def emit(self, record):
with self.emit_lock:
self.append(self.format(record))
self.autoScroll()

def format(self, record):
if (record.levelno <= logging.INFO):
bgcolor = WHITE
fgcolor = BLACK
if (record.levelno <= logging.WARNING):
bgcolor = YELLOW
fgcolor = BLACK
if (record.levelno <= logging.ERROR):
bgcolor = ORANGE
fgcolor = BLACK
if (record.levelno <= logging.CRITICAL):
bgcolor = RED
fgcolor = BLACK
else:
bgcolor = BLACK
fgcolor = WHITE

self.setTextBackgroundColor(bgcolor)
self.setTextColor(fgcolor)
self.setFont(DEFAULT_FONT)
record = logging.Handler.format(self, record)
return record

def autoScroll(self):
self.verticalScrollBar().setSliderPosition(self.verticalScrollBar().maximum())


I have the main gui (QMainWindow) that adds this handler via:



# inside __init__ of main GUI (QMainWindow):
self.status_handler = QHandler()
# Main gui is divided into tabs and the status handler box is added to the second tab
main_tabs.addTab(self.status_handler, 'Status')


And I have the controller function that initializes the logging handler via:



# inside controller initializing function
gui = gui_class() # this is the main gui that initializes the handler among other things
logger = logging.getLogger()
gui.status_handler.setFormatter(file_formatter) # defined elsewhere
logger.addHandler(gui.status_handler)


Once the GUI is raised and logging is initialized, I finish the python execution with:



app = QApplication.instance()
if (app is None):
app = QApplication()
app.setStyle('Fusion')
app.exec_()


The GUI has a few slots connected to pushbutton signals that spawns threads to do the actual processing. Each processing thread has it's own logging call which seems to work as intended. They are defined like follows:



class Subprocess_Thread(Thread):
def __init__(self, <args>):
Thread.__init__(self)
self.logger = logging.getLogger(self.__class__.__name__)
self.logger.info('Subprocess Thread Created')

def run(self):
# does a bunch of stuff
self.logger.info('Running stuff')
# iterates over other objects and calls on them to do stuff
# where they also have a logger attached and called just like above


When I run my application without a GUI or even with the GUI minimized, it runs fine every time. I can see my log messages in the console (either command prompt or spyder).



If I run the same application without minimizing the GUI, I will see the log messages in the GUI for initialization and some of the first parts of the threaded process, but then it will hang at seemingly random times. There is no error message and the CPU usage seems to be maxed out for the single core that is being used. I included a lock just to make sure logging wasn't coming in from different threads, but that also didn't help.



I've tried going to a QPlainTextEdit and a QListWidget but I get the same problem every time.



Does anyone have an idea of why this GUI element would cause the entire Python interpreter to hang when in view and messages are logged to it?










share|improve this question
























  • please provide a Minimal, Complete, and Verifiable example

    – eyllanesc
    Nov 13 '18 at 16:55











  • I added some more code to show how the logger and GUI are initialized. All I basically do is add the handler to a tab in the GUI, raise the GUI, and then add the QHandler to the root logger's handlers with the same format as what I use to log to a file. From there the controller starts a thread to run the processing while the GUI is maintained in the main thread. Logging calls are made in the processing thread and should be received by the GUI. Both the file output and console outputs are working just fine, the GUI handler freezes the whole app when it isn't minimized.

    – Joseph Martin
    Nov 13 '18 at 17:37











  • you say I added some more code, for me that more code does not make it Minimal, Complete, and Verifiable example, so I'll ask you to try a little harder and provide a Minimal, Complete, and Verifiable example, so we'll also try to help you, for My problem is that you are using the logging incorrectly in another thread.

    – eyllanesc
    Nov 13 '18 at 17:41











  • I've added a bit more, but it's hard to add so much because this program is quite large and I can't copy the text directly into this question box. I know for a fact that the logging calls are fine because like I said I can run this with no problem if I don't add the GUI handler to the root logger, or even if I just keep it minimized. The threads don't do anything special, each object I've created whether it is a thread or not creates an attribute named logger that is just getLogger called with the class name string. Let me know what seems to be missing from above and I'll try to add it.

    – Joseph Martin
    Nov 13 '18 at 17:56












  • Although seeing your code I can suspect where the problem is, nobody has asked you to show the code of your project, I have asked you to create a Minimal, Complete, and Verifiable example, that is, a minimum code that verifies your problem and does not need anything else to run.

    – eyllanesc
    Nov 13 '18 at 18:01















1















I have a large program that takes a long time that needs ample logging. I have a GUI that is on the front end that includes a custom logging handler as defined below:



class QHandler(logging.Handler, QTextEdit):
def __init__(self, parent=None):
QTextEdit.__init__(self, parent)
logging.Handler.__init__(self)

self.setLineWrapMode(QTextEdit.NoWrap)
self.setReadOnly(True)

self.emit_lock = Lock()

def emit(self, record):
with self.emit_lock:
self.append(self.format(record))
self.autoScroll()

def format(self, record):
if (record.levelno <= logging.INFO):
bgcolor = WHITE
fgcolor = BLACK
if (record.levelno <= logging.WARNING):
bgcolor = YELLOW
fgcolor = BLACK
if (record.levelno <= logging.ERROR):
bgcolor = ORANGE
fgcolor = BLACK
if (record.levelno <= logging.CRITICAL):
bgcolor = RED
fgcolor = BLACK
else:
bgcolor = BLACK
fgcolor = WHITE

self.setTextBackgroundColor(bgcolor)
self.setTextColor(fgcolor)
self.setFont(DEFAULT_FONT)
record = logging.Handler.format(self, record)
return record

def autoScroll(self):
self.verticalScrollBar().setSliderPosition(self.verticalScrollBar().maximum())


I have the main gui (QMainWindow) that adds this handler via:



# inside __init__ of main GUI (QMainWindow):
self.status_handler = QHandler()
# Main gui is divided into tabs and the status handler box is added to the second tab
main_tabs.addTab(self.status_handler, 'Status')


And I have the controller function that initializes the logging handler via:



# inside controller initializing function
gui = gui_class() # this is the main gui that initializes the handler among other things
logger = logging.getLogger()
gui.status_handler.setFormatter(file_formatter) # defined elsewhere
logger.addHandler(gui.status_handler)


Once the GUI is raised and logging is initialized, I finish the python execution with:



app = QApplication.instance()
if (app is None):
app = QApplication()
app.setStyle('Fusion')
app.exec_()


The GUI has a few slots connected to pushbutton signals that spawns threads to do the actual processing. Each processing thread has it's own logging call which seems to work as intended. They are defined like follows:



class Subprocess_Thread(Thread):
def __init__(self, <args>):
Thread.__init__(self)
self.logger = logging.getLogger(self.__class__.__name__)
self.logger.info('Subprocess Thread Created')

def run(self):
# does a bunch of stuff
self.logger.info('Running stuff')
# iterates over other objects and calls on them to do stuff
# where they also have a logger attached and called just like above


When I run my application without a GUI or even with the GUI minimized, it runs fine every time. I can see my log messages in the console (either command prompt or spyder).



If I run the same application without minimizing the GUI, I will see the log messages in the GUI for initialization and some of the first parts of the threaded process, but then it will hang at seemingly random times. There is no error message and the CPU usage seems to be maxed out for the single core that is being used. I included a lock just to make sure logging wasn't coming in from different threads, but that also didn't help.



I've tried going to a QPlainTextEdit and a QListWidget but I get the same problem every time.



Does anyone have an idea of why this GUI element would cause the entire Python interpreter to hang when in view and messages are logged to it?










share|improve this question
























  • please provide a Minimal, Complete, and Verifiable example

    – eyllanesc
    Nov 13 '18 at 16:55











  • I added some more code to show how the logger and GUI are initialized. All I basically do is add the handler to a tab in the GUI, raise the GUI, and then add the QHandler to the root logger's handlers with the same format as what I use to log to a file. From there the controller starts a thread to run the processing while the GUI is maintained in the main thread. Logging calls are made in the processing thread and should be received by the GUI. Both the file output and console outputs are working just fine, the GUI handler freezes the whole app when it isn't minimized.

    – Joseph Martin
    Nov 13 '18 at 17:37











  • you say I added some more code, for me that more code does not make it Minimal, Complete, and Verifiable example, so I'll ask you to try a little harder and provide a Minimal, Complete, and Verifiable example, so we'll also try to help you, for My problem is that you are using the logging incorrectly in another thread.

    – eyllanesc
    Nov 13 '18 at 17:41











  • I've added a bit more, but it's hard to add so much because this program is quite large and I can't copy the text directly into this question box. I know for a fact that the logging calls are fine because like I said I can run this with no problem if I don't add the GUI handler to the root logger, or even if I just keep it minimized. The threads don't do anything special, each object I've created whether it is a thread or not creates an attribute named logger that is just getLogger called with the class name string. Let me know what seems to be missing from above and I'll try to add it.

    – Joseph Martin
    Nov 13 '18 at 17:56












  • Although seeing your code I can suspect where the problem is, nobody has asked you to show the code of your project, I have asked you to create a Minimal, Complete, and Verifiable example, that is, a minimum code that verifies your problem and does not need anything else to run.

    – eyllanesc
    Nov 13 '18 at 18:01













1












1








1


1






I have a large program that takes a long time that needs ample logging. I have a GUI that is on the front end that includes a custom logging handler as defined below:



class QHandler(logging.Handler, QTextEdit):
def __init__(self, parent=None):
QTextEdit.__init__(self, parent)
logging.Handler.__init__(self)

self.setLineWrapMode(QTextEdit.NoWrap)
self.setReadOnly(True)

self.emit_lock = Lock()

def emit(self, record):
with self.emit_lock:
self.append(self.format(record))
self.autoScroll()

def format(self, record):
if (record.levelno <= logging.INFO):
bgcolor = WHITE
fgcolor = BLACK
if (record.levelno <= logging.WARNING):
bgcolor = YELLOW
fgcolor = BLACK
if (record.levelno <= logging.ERROR):
bgcolor = ORANGE
fgcolor = BLACK
if (record.levelno <= logging.CRITICAL):
bgcolor = RED
fgcolor = BLACK
else:
bgcolor = BLACK
fgcolor = WHITE

self.setTextBackgroundColor(bgcolor)
self.setTextColor(fgcolor)
self.setFont(DEFAULT_FONT)
record = logging.Handler.format(self, record)
return record

def autoScroll(self):
self.verticalScrollBar().setSliderPosition(self.verticalScrollBar().maximum())


I have the main gui (QMainWindow) that adds this handler via:



# inside __init__ of main GUI (QMainWindow):
self.status_handler = QHandler()
# Main gui is divided into tabs and the status handler box is added to the second tab
main_tabs.addTab(self.status_handler, 'Status')


And I have the controller function that initializes the logging handler via:



# inside controller initializing function
gui = gui_class() # this is the main gui that initializes the handler among other things
logger = logging.getLogger()
gui.status_handler.setFormatter(file_formatter) # defined elsewhere
logger.addHandler(gui.status_handler)


Once the GUI is raised and logging is initialized, I finish the python execution with:



app = QApplication.instance()
if (app is None):
app = QApplication()
app.setStyle('Fusion')
app.exec_()


The GUI has a few slots connected to pushbutton signals that spawns threads to do the actual processing. Each processing thread has it's own logging call which seems to work as intended. They are defined like follows:



class Subprocess_Thread(Thread):
def __init__(self, <args>):
Thread.__init__(self)
self.logger = logging.getLogger(self.__class__.__name__)
self.logger.info('Subprocess Thread Created')

def run(self):
# does a bunch of stuff
self.logger.info('Running stuff')
# iterates over other objects and calls on them to do stuff
# where they also have a logger attached and called just like above


When I run my application without a GUI or even with the GUI minimized, it runs fine every time. I can see my log messages in the console (either command prompt or spyder).



If I run the same application without minimizing the GUI, I will see the log messages in the GUI for initialization and some of the first parts of the threaded process, but then it will hang at seemingly random times. There is no error message and the CPU usage seems to be maxed out for the single core that is being used. I included a lock just to make sure logging wasn't coming in from different threads, but that also didn't help.



I've tried going to a QPlainTextEdit and a QListWidget but I get the same problem every time.



Does anyone have an idea of why this GUI element would cause the entire Python interpreter to hang when in view and messages are logged to it?










share|improve this question
















I have a large program that takes a long time that needs ample logging. I have a GUI that is on the front end that includes a custom logging handler as defined below:



class QHandler(logging.Handler, QTextEdit):
def __init__(self, parent=None):
QTextEdit.__init__(self, parent)
logging.Handler.__init__(self)

self.setLineWrapMode(QTextEdit.NoWrap)
self.setReadOnly(True)

self.emit_lock = Lock()

def emit(self, record):
with self.emit_lock:
self.append(self.format(record))
self.autoScroll()

def format(self, record):
if (record.levelno <= logging.INFO):
bgcolor = WHITE
fgcolor = BLACK
if (record.levelno <= logging.WARNING):
bgcolor = YELLOW
fgcolor = BLACK
if (record.levelno <= logging.ERROR):
bgcolor = ORANGE
fgcolor = BLACK
if (record.levelno <= logging.CRITICAL):
bgcolor = RED
fgcolor = BLACK
else:
bgcolor = BLACK
fgcolor = WHITE

self.setTextBackgroundColor(bgcolor)
self.setTextColor(fgcolor)
self.setFont(DEFAULT_FONT)
record = logging.Handler.format(self, record)
return record

def autoScroll(self):
self.verticalScrollBar().setSliderPosition(self.verticalScrollBar().maximum())


I have the main gui (QMainWindow) that adds this handler via:



# inside __init__ of main GUI (QMainWindow):
self.status_handler = QHandler()
# Main gui is divided into tabs and the status handler box is added to the second tab
main_tabs.addTab(self.status_handler, 'Status')


And I have the controller function that initializes the logging handler via:



# inside controller initializing function
gui = gui_class() # this is the main gui that initializes the handler among other things
logger = logging.getLogger()
gui.status_handler.setFormatter(file_formatter) # defined elsewhere
logger.addHandler(gui.status_handler)


Once the GUI is raised and logging is initialized, I finish the python execution with:



app = QApplication.instance()
if (app is None):
app = QApplication()
app.setStyle('Fusion')
app.exec_()


The GUI has a few slots connected to pushbutton signals that spawns threads to do the actual processing. Each processing thread has it's own logging call which seems to work as intended. They are defined like follows:



class Subprocess_Thread(Thread):
def __init__(self, <args>):
Thread.__init__(self)
self.logger = logging.getLogger(self.__class__.__name__)
self.logger.info('Subprocess Thread Created')

def run(self):
# does a bunch of stuff
self.logger.info('Running stuff')
# iterates over other objects and calls on them to do stuff
# where they also have a logger attached and called just like above


When I run my application without a GUI or even with the GUI minimized, it runs fine every time. I can see my log messages in the console (either command prompt or spyder).



If I run the same application without minimizing the GUI, I will see the log messages in the GUI for initialization and some of the first parts of the threaded process, but then it will hang at seemingly random times. There is no error message and the CPU usage seems to be maxed out for the single core that is being used. I included a lock just to make sure logging wasn't coming in from different threads, but that also didn't help.



I've tried going to a QPlainTextEdit and a QListWidget but I get the same problem every time.



Does anyone have an idea of why this GUI element would cause the entire Python interpreter to hang when in view and messages are logged to it?







python python-3.x logging pyqt5






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 13 '18 at 17:53







Joseph Martin

















asked Nov 13 '18 at 16:16









Joseph MartinJoseph Martin

133




133












  • please provide a Minimal, Complete, and Verifiable example

    – eyllanesc
    Nov 13 '18 at 16:55











  • I added some more code to show how the logger and GUI are initialized. All I basically do is add the handler to a tab in the GUI, raise the GUI, and then add the QHandler to the root logger's handlers with the same format as what I use to log to a file. From there the controller starts a thread to run the processing while the GUI is maintained in the main thread. Logging calls are made in the processing thread and should be received by the GUI. Both the file output and console outputs are working just fine, the GUI handler freezes the whole app when it isn't minimized.

    – Joseph Martin
    Nov 13 '18 at 17:37











  • you say I added some more code, for me that more code does not make it Minimal, Complete, and Verifiable example, so I'll ask you to try a little harder and provide a Minimal, Complete, and Verifiable example, so we'll also try to help you, for My problem is that you are using the logging incorrectly in another thread.

    – eyllanesc
    Nov 13 '18 at 17:41











  • I've added a bit more, but it's hard to add so much because this program is quite large and I can't copy the text directly into this question box. I know for a fact that the logging calls are fine because like I said I can run this with no problem if I don't add the GUI handler to the root logger, or even if I just keep it minimized. The threads don't do anything special, each object I've created whether it is a thread or not creates an attribute named logger that is just getLogger called with the class name string. Let me know what seems to be missing from above and I'll try to add it.

    – Joseph Martin
    Nov 13 '18 at 17:56












  • Although seeing your code I can suspect where the problem is, nobody has asked you to show the code of your project, I have asked you to create a Minimal, Complete, and Verifiable example, that is, a minimum code that verifies your problem and does not need anything else to run.

    – eyllanesc
    Nov 13 '18 at 18:01

















  • please provide a Minimal, Complete, and Verifiable example

    – eyllanesc
    Nov 13 '18 at 16:55











  • I added some more code to show how the logger and GUI are initialized. All I basically do is add the handler to a tab in the GUI, raise the GUI, and then add the QHandler to the root logger's handlers with the same format as what I use to log to a file. From there the controller starts a thread to run the processing while the GUI is maintained in the main thread. Logging calls are made in the processing thread and should be received by the GUI. Both the file output and console outputs are working just fine, the GUI handler freezes the whole app when it isn't minimized.

    – Joseph Martin
    Nov 13 '18 at 17:37











  • you say I added some more code, for me that more code does not make it Minimal, Complete, and Verifiable example, so I'll ask you to try a little harder and provide a Minimal, Complete, and Verifiable example, so we'll also try to help you, for My problem is that you are using the logging incorrectly in another thread.

    – eyllanesc
    Nov 13 '18 at 17:41











  • I've added a bit more, but it's hard to add so much because this program is quite large and I can't copy the text directly into this question box. I know for a fact that the logging calls are fine because like I said I can run this with no problem if I don't add the GUI handler to the root logger, or even if I just keep it minimized. The threads don't do anything special, each object I've created whether it is a thread or not creates an attribute named logger that is just getLogger called with the class name string. Let me know what seems to be missing from above and I'll try to add it.

    – Joseph Martin
    Nov 13 '18 at 17:56












  • Although seeing your code I can suspect where the problem is, nobody has asked you to show the code of your project, I have asked you to create a Minimal, Complete, and Verifiable example, that is, a minimum code that verifies your problem and does not need anything else to run.

    – eyllanesc
    Nov 13 '18 at 18:01
















please provide a Minimal, Complete, and Verifiable example

– eyllanesc
Nov 13 '18 at 16:55





please provide a Minimal, Complete, and Verifiable example

– eyllanesc
Nov 13 '18 at 16:55













I added some more code to show how the logger and GUI are initialized. All I basically do is add the handler to a tab in the GUI, raise the GUI, and then add the QHandler to the root logger's handlers with the same format as what I use to log to a file. From there the controller starts a thread to run the processing while the GUI is maintained in the main thread. Logging calls are made in the processing thread and should be received by the GUI. Both the file output and console outputs are working just fine, the GUI handler freezes the whole app when it isn't minimized.

– Joseph Martin
Nov 13 '18 at 17:37





I added some more code to show how the logger and GUI are initialized. All I basically do is add the handler to a tab in the GUI, raise the GUI, and then add the QHandler to the root logger's handlers with the same format as what I use to log to a file. From there the controller starts a thread to run the processing while the GUI is maintained in the main thread. Logging calls are made in the processing thread and should be received by the GUI. Both the file output and console outputs are working just fine, the GUI handler freezes the whole app when it isn't minimized.

– Joseph Martin
Nov 13 '18 at 17:37













you say I added some more code, for me that more code does not make it Minimal, Complete, and Verifiable example, so I'll ask you to try a little harder and provide a Minimal, Complete, and Verifiable example, so we'll also try to help you, for My problem is that you are using the logging incorrectly in another thread.

– eyllanesc
Nov 13 '18 at 17:41





you say I added some more code, for me that more code does not make it Minimal, Complete, and Verifiable example, so I'll ask you to try a little harder and provide a Minimal, Complete, and Verifiable example, so we'll also try to help you, for My problem is that you are using the logging incorrectly in another thread.

– eyllanesc
Nov 13 '18 at 17:41













I've added a bit more, but it's hard to add so much because this program is quite large and I can't copy the text directly into this question box. I know for a fact that the logging calls are fine because like I said I can run this with no problem if I don't add the GUI handler to the root logger, or even if I just keep it minimized. The threads don't do anything special, each object I've created whether it is a thread or not creates an attribute named logger that is just getLogger called with the class name string. Let me know what seems to be missing from above and I'll try to add it.

– Joseph Martin
Nov 13 '18 at 17:56






I've added a bit more, but it's hard to add so much because this program is quite large and I can't copy the text directly into this question box. I know for a fact that the logging calls are fine because like I said I can run this with no problem if I don't add the GUI handler to the root logger, or even if I just keep it minimized. The threads don't do anything special, each object I've created whether it is a thread or not creates an attribute named logger that is just getLogger called with the class name string. Let me know what seems to be missing from above and I'll try to add it.

– Joseph Martin
Nov 13 '18 at 17:56














Although seeing your code I can suspect where the problem is, nobody has asked you to show the code of your project, I have asked you to create a Minimal, Complete, and Verifiable example, that is, a minimum code that verifies your problem and does not need anything else to run.

– eyllanesc
Nov 13 '18 at 18:01





Although seeing your code I can suspect where the problem is, nobody has asked you to show the code of your project, I have asked you to create a Minimal, Complete, and Verifiable example, that is, a minimum code that verifies your problem and does not need anything else to run.

– eyllanesc
Nov 13 '18 at 18:01












1 Answer
1






active

oldest

votes


















0














The QHandler that samples is not thread-safe so it will generate problems if you call it from another thread since it is a GUI, a possible solution is to send the data from the secondary thread(def emit(self, record):) to the thread of the GUI through QMetaObject for this you must use pyqtSlot:



class QHandler(logging.Handler, QtWidgets.QTextEdit):
def __init__(self, parent=None):
QtWidgets.QTextEdit.__init__(self, parent)
logging.Handler.__init__(self)

self.setLineWrapMode(QtWidgets.QTextEdit.NoWrap)
self.setReadOnly(True)

self.emit_lock = threading.Lock()

def emit(self, record):
with self.emit_lock:
QtCore.QMetaObject.invokeMethod(self,
"append",
QtCore.Qt.QueuedConnection,
QtCore.Q_ARG(str, self.format(record)))
QtCore.QMetaObject.invokeMethod(self,
"autoScroll",
QtCore.Qt.QueuedConnection)

def format(self, record):
if record.levelno == logging.INFO:
bgcolor = WHITE
fgcolor = BLACK
elif record.levelno == logging.WARNING:
bgcolor = YELLOW
fgcolor = BLACK
elif record.levelno == logging.ERROR:
bgcolor = ORANGE
fgcolor = BLACK
elif record.levelno == logging.CRITICAL:
bgcolor = RED
fgcolor = BLACK
else:
bgcolor = BLACK
fgcolor = WHITE

self.setTextBackgroundColor(bgcolor)
self.setTextColor(fgcolor)
self.setFont(DEFAULT_FONT)
record = logging.Handler.format(self, record)
return record

@QtCore.pyqtSlot()
def autoScroll(self):
self.verticalScrollBar().setSliderPosition(self.verticalScrollBar().maximum())


Example:



import random
import logging
import threading
from PyQt5 import QtCore, QtGui, QtWidgets

WHITE, BLACK, YELLOW, ORANGE, RED = QtGui.QColor("white"), QtGui.QColor("black"), QtGui.QColor("yellow"), QtGui.QColor("orange"), QtGui.QColor("red")
DEFAULT_FONT = QtGui.QFont()

class QHandler(logging.Handler, QtWidgets.QTextEdit):
def __init__(self, parent=None):
QtWidgets.QTextEdit.__init__(self, parent)
logging.Handler.__init__(self)

self.setLineWrapMode(QtWidgets.QTextEdit.NoWrap)
self.setReadOnly(True)

self.emit_lock = threading.Lock()

def emit(self, record):
with self.emit_lock:
QtCore.QMetaObject.invokeMethod(self,
"append",
QtCore.Qt.QueuedConnection,
QtCore.Q_ARG(str, self.format(record)))
QtCore.QMetaObject.invokeMethod(self,
"autoScroll",
QtCore.Qt.QueuedConnection)

def format(self, record):
if record.levelno == logging.INFO:
bgcolor = WHITE
fgcolor = BLACK
elif record.levelno == logging.WARNING:
bgcolor = YELLOW
fgcolor = BLACK
elif record.levelno == logging.ERROR:
bgcolor = ORANGE
fgcolor = BLACK
elif record.levelno == logging.CRITICAL:
bgcolor = RED
fgcolor = BLACK
else:
bgcolor = BLACK
fgcolor = WHITE

self.setTextBackgroundColor(bgcolor)
self.setTextColor(fgcolor)
self.setFont(DEFAULT_FONT)
record = logging.Handler.format(self, record)
return record

@QtCore.pyqtSlot()
def autoScroll(self):
self.verticalScrollBar().setSliderPosition(self.verticalScrollBar().maximum())


class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.status_handler = QHandler()
self.setCentralWidget(self.status_handler)

logging.getLogger().addHandler(self.status_handler)
self.status_handler.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))
logging.getLogger().setLevel(logging.DEBUG)
timer = QtCore.QTimer(self, interval=1000, timeout=self.on_timeout)
timer.start()

def on_timeout(self):
logging.info('From Gui Thread '.format(QtCore.QDateTime.currentDateTime().toString()))


class Subprocess_Thread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.logger = logging.getLogger(self.__class__.__name__)
self.logger.info('Subprocess Thread Created')

def run(self):
while True:
t = random.choice(["info", "warning", "error", "critical"])
msg = "Type: , thread: ".format(t, threading.currentThread())
getattr(self.logger, t)(msg)
QtCore.QThread.sleep(1)

if __name__ == '__main__':
import sys
app = QtWidgets.QApplication.instance()
if app is None:
app = QtWidgets.QApplication(sys.argv)
app.setStyle('Fusion')
w = MainWindow()
w.show()
th = Subprocess_Thread()
th.daemon = True
th.start()
sys.exit(app.exec_())





share|improve this answer























  • This answer put me on the right path. I created my own pyqtSignal that is emitted when the emit function is called. Then I created a display method that is a custom pyqt5Slot that handles the actual GUI update. This seems to make it thread safe.

    – Joseph Martin
    Nov 14 '18 at 12:07












  • @JosephMartin that is the other option, but for me it is easier to use QMetaObject.InvokedMethod since no connection or new signals are needed. both are thread-safe :-)

    – eyllanesc
    Nov 14 '18 at 12:10










Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53285181%2fpyqt5-program-crashes-while-updating-qtextedit-via-logging%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









0














The QHandler that samples is not thread-safe so it will generate problems if you call it from another thread since it is a GUI, a possible solution is to send the data from the secondary thread(def emit(self, record):) to the thread of the GUI through QMetaObject for this you must use pyqtSlot:



class QHandler(logging.Handler, QtWidgets.QTextEdit):
def __init__(self, parent=None):
QtWidgets.QTextEdit.__init__(self, parent)
logging.Handler.__init__(self)

self.setLineWrapMode(QtWidgets.QTextEdit.NoWrap)
self.setReadOnly(True)

self.emit_lock = threading.Lock()

def emit(self, record):
with self.emit_lock:
QtCore.QMetaObject.invokeMethod(self,
"append",
QtCore.Qt.QueuedConnection,
QtCore.Q_ARG(str, self.format(record)))
QtCore.QMetaObject.invokeMethod(self,
"autoScroll",
QtCore.Qt.QueuedConnection)

def format(self, record):
if record.levelno == logging.INFO:
bgcolor = WHITE
fgcolor = BLACK
elif record.levelno == logging.WARNING:
bgcolor = YELLOW
fgcolor = BLACK
elif record.levelno == logging.ERROR:
bgcolor = ORANGE
fgcolor = BLACK
elif record.levelno == logging.CRITICAL:
bgcolor = RED
fgcolor = BLACK
else:
bgcolor = BLACK
fgcolor = WHITE

self.setTextBackgroundColor(bgcolor)
self.setTextColor(fgcolor)
self.setFont(DEFAULT_FONT)
record = logging.Handler.format(self, record)
return record

@QtCore.pyqtSlot()
def autoScroll(self):
self.verticalScrollBar().setSliderPosition(self.verticalScrollBar().maximum())


Example:



import random
import logging
import threading
from PyQt5 import QtCore, QtGui, QtWidgets

WHITE, BLACK, YELLOW, ORANGE, RED = QtGui.QColor("white"), QtGui.QColor("black"), QtGui.QColor("yellow"), QtGui.QColor("orange"), QtGui.QColor("red")
DEFAULT_FONT = QtGui.QFont()

class QHandler(logging.Handler, QtWidgets.QTextEdit):
def __init__(self, parent=None):
QtWidgets.QTextEdit.__init__(self, parent)
logging.Handler.__init__(self)

self.setLineWrapMode(QtWidgets.QTextEdit.NoWrap)
self.setReadOnly(True)

self.emit_lock = threading.Lock()

def emit(self, record):
with self.emit_lock:
QtCore.QMetaObject.invokeMethod(self,
"append",
QtCore.Qt.QueuedConnection,
QtCore.Q_ARG(str, self.format(record)))
QtCore.QMetaObject.invokeMethod(self,
"autoScroll",
QtCore.Qt.QueuedConnection)

def format(self, record):
if record.levelno == logging.INFO:
bgcolor = WHITE
fgcolor = BLACK
elif record.levelno == logging.WARNING:
bgcolor = YELLOW
fgcolor = BLACK
elif record.levelno == logging.ERROR:
bgcolor = ORANGE
fgcolor = BLACK
elif record.levelno == logging.CRITICAL:
bgcolor = RED
fgcolor = BLACK
else:
bgcolor = BLACK
fgcolor = WHITE

self.setTextBackgroundColor(bgcolor)
self.setTextColor(fgcolor)
self.setFont(DEFAULT_FONT)
record = logging.Handler.format(self, record)
return record

@QtCore.pyqtSlot()
def autoScroll(self):
self.verticalScrollBar().setSliderPosition(self.verticalScrollBar().maximum())


class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.status_handler = QHandler()
self.setCentralWidget(self.status_handler)

logging.getLogger().addHandler(self.status_handler)
self.status_handler.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))
logging.getLogger().setLevel(logging.DEBUG)
timer = QtCore.QTimer(self, interval=1000, timeout=self.on_timeout)
timer.start()

def on_timeout(self):
logging.info('From Gui Thread '.format(QtCore.QDateTime.currentDateTime().toString()))


class Subprocess_Thread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.logger = logging.getLogger(self.__class__.__name__)
self.logger.info('Subprocess Thread Created')

def run(self):
while True:
t = random.choice(["info", "warning", "error", "critical"])
msg = "Type: , thread: ".format(t, threading.currentThread())
getattr(self.logger, t)(msg)
QtCore.QThread.sleep(1)

if __name__ == '__main__':
import sys
app = QtWidgets.QApplication.instance()
if app is None:
app = QtWidgets.QApplication(sys.argv)
app.setStyle('Fusion')
w = MainWindow()
w.show()
th = Subprocess_Thread()
th.daemon = True
th.start()
sys.exit(app.exec_())





share|improve this answer























  • This answer put me on the right path. I created my own pyqtSignal that is emitted when the emit function is called. Then I created a display method that is a custom pyqt5Slot that handles the actual GUI update. This seems to make it thread safe.

    – Joseph Martin
    Nov 14 '18 at 12:07












  • @JosephMartin that is the other option, but for me it is easier to use QMetaObject.InvokedMethod since no connection or new signals are needed. both are thread-safe :-)

    – eyllanesc
    Nov 14 '18 at 12:10















0














The QHandler that samples is not thread-safe so it will generate problems if you call it from another thread since it is a GUI, a possible solution is to send the data from the secondary thread(def emit(self, record):) to the thread of the GUI through QMetaObject for this you must use pyqtSlot:



class QHandler(logging.Handler, QtWidgets.QTextEdit):
def __init__(self, parent=None):
QtWidgets.QTextEdit.__init__(self, parent)
logging.Handler.__init__(self)

self.setLineWrapMode(QtWidgets.QTextEdit.NoWrap)
self.setReadOnly(True)

self.emit_lock = threading.Lock()

def emit(self, record):
with self.emit_lock:
QtCore.QMetaObject.invokeMethod(self,
"append",
QtCore.Qt.QueuedConnection,
QtCore.Q_ARG(str, self.format(record)))
QtCore.QMetaObject.invokeMethod(self,
"autoScroll",
QtCore.Qt.QueuedConnection)

def format(self, record):
if record.levelno == logging.INFO:
bgcolor = WHITE
fgcolor = BLACK
elif record.levelno == logging.WARNING:
bgcolor = YELLOW
fgcolor = BLACK
elif record.levelno == logging.ERROR:
bgcolor = ORANGE
fgcolor = BLACK
elif record.levelno == logging.CRITICAL:
bgcolor = RED
fgcolor = BLACK
else:
bgcolor = BLACK
fgcolor = WHITE

self.setTextBackgroundColor(bgcolor)
self.setTextColor(fgcolor)
self.setFont(DEFAULT_FONT)
record = logging.Handler.format(self, record)
return record

@QtCore.pyqtSlot()
def autoScroll(self):
self.verticalScrollBar().setSliderPosition(self.verticalScrollBar().maximum())


Example:



import random
import logging
import threading
from PyQt5 import QtCore, QtGui, QtWidgets

WHITE, BLACK, YELLOW, ORANGE, RED = QtGui.QColor("white"), QtGui.QColor("black"), QtGui.QColor("yellow"), QtGui.QColor("orange"), QtGui.QColor("red")
DEFAULT_FONT = QtGui.QFont()

class QHandler(logging.Handler, QtWidgets.QTextEdit):
def __init__(self, parent=None):
QtWidgets.QTextEdit.__init__(self, parent)
logging.Handler.__init__(self)

self.setLineWrapMode(QtWidgets.QTextEdit.NoWrap)
self.setReadOnly(True)

self.emit_lock = threading.Lock()

def emit(self, record):
with self.emit_lock:
QtCore.QMetaObject.invokeMethod(self,
"append",
QtCore.Qt.QueuedConnection,
QtCore.Q_ARG(str, self.format(record)))
QtCore.QMetaObject.invokeMethod(self,
"autoScroll",
QtCore.Qt.QueuedConnection)

def format(self, record):
if record.levelno == logging.INFO:
bgcolor = WHITE
fgcolor = BLACK
elif record.levelno == logging.WARNING:
bgcolor = YELLOW
fgcolor = BLACK
elif record.levelno == logging.ERROR:
bgcolor = ORANGE
fgcolor = BLACK
elif record.levelno == logging.CRITICAL:
bgcolor = RED
fgcolor = BLACK
else:
bgcolor = BLACK
fgcolor = WHITE

self.setTextBackgroundColor(bgcolor)
self.setTextColor(fgcolor)
self.setFont(DEFAULT_FONT)
record = logging.Handler.format(self, record)
return record

@QtCore.pyqtSlot()
def autoScroll(self):
self.verticalScrollBar().setSliderPosition(self.verticalScrollBar().maximum())


class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.status_handler = QHandler()
self.setCentralWidget(self.status_handler)

logging.getLogger().addHandler(self.status_handler)
self.status_handler.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))
logging.getLogger().setLevel(logging.DEBUG)
timer = QtCore.QTimer(self, interval=1000, timeout=self.on_timeout)
timer.start()

def on_timeout(self):
logging.info('From Gui Thread '.format(QtCore.QDateTime.currentDateTime().toString()))


class Subprocess_Thread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.logger = logging.getLogger(self.__class__.__name__)
self.logger.info('Subprocess Thread Created')

def run(self):
while True:
t = random.choice(["info", "warning", "error", "critical"])
msg = "Type: , thread: ".format(t, threading.currentThread())
getattr(self.logger, t)(msg)
QtCore.QThread.sleep(1)

if __name__ == '__main__':
import sys
app = QtWidgets.QApplication.instance()
if app is None:
app = QtWidgets.QApplication(sys.argv)
app.setStyle('Fusion')
w = MainWindow()
w.show()
th = Subprocess_Thread()
th.daemon = True
th.start()
sys.exit(app.exec_())





share|improve this answer























  • This answer put me on the right path. I created my own pyqtSignal that is emitted when the emit function is called. Then I created a display method that is a custom pyqt5Slot that handles the actual GUI update. This seems to make it thread safe.

    – Joseph Martin
    Nov 14 '18 at 12:07












  • @JosephMartin that is the other option, but for me it is easier to use QMetaObject.InvokedMethod since no connection or new signals are needed. both are thread-safe :-)

    – eyllanesc
    Nov 14 '18 at 12:10













0












0








0







The QHandler that samples is not thread-safe so it will generate problems if you call it from another thread since it is a GUI, a possible solution is to send the data from the secondary thread(def emit(self, record):) to the thread of the GUI through QMetaObject for this you must use pyqtSlot:



class QHandler(logging.Handler, QtWidgets.QTextEdit):
def __init__(self, parent=None):
QtWidgets.QTextEdit.__init__(self, parent)
logging.Handler.__init__(self)

self.setLineWrapMode(QtWidgets.QTextEdit.NoWrap)
self.setReadOnly(True)

self.emit_lock = threading.Lock()

def emit(self, record):
with self.emit_lock:
QtCore.QMetaObject.invokeMethod(self,
"append",
QtCore.Qt.QueuedConnection,
QtCore.Q_ARG(str, self.format(record)))
QtCore.QMetaObject.invokeMethod(self,
"autoScroll",
QtCore.Qt.QueuedConnection)

def format(self, record):
if record.levelno == logging.INFO:
bgcolor = WHITE
fgcolor = BLACK
elif record.levelno == logging.WARNING:
bgcolor = YELLOW
fgcolor = BLACK
elif record.levelno == logging.ERROR:
bgcolor = ORANGE
fgcolor = BLACK
elif record.levelno == logging.CRITICAL:
bgcolor = RED
fgcolor = BLACK
else:
bgcolor = BLACK
fgcolor = WHITE

self.setTextBackgroundColor(bgcolor)
self.setTextColor(fgcolor)
self.setFont(DEFAULT_FONT)
record = logging.Handler.format(self, record)
return record

@QtCore.pyqtSlot()
def autoScroll(self):
self.verticalScrollBar().setSliderPosition(self.verticalScrollBar().maximum())


Example:



import random
import logging
import threading
from PyQt5 import QtCore, QtGui, QtWidgets

WHITE, BLACK, YELLOW, ORANGE, RED = QtGui.QColor("white"), QtGui.QColor("black"), QtGui.QColor("yellow"), QtGui.QColor("orange"), QtGui.QColor("red")
DEFAULT_FONT = QtGui.QFont()

class QHandler(logging.Handler, QtWidgets.QTextEdit):
def __init__(self, parent=None):
QtWidgets.QTextEdit.__init__(self, parent)
logging.Handler.__init__(self)

self.setLineWrapMode(QtWidgets.QTextEdit.NoWrap)
self.setReadOnly(True)

self.emit_lock = threading.Lock()

def emit(self, record):
with self.emit_lock:
QtCore.QMetaObject.invokeMethod(self,
"append",
QtCore.Qt.QueuedConnection,
QtCore.Q_ARG(str, self.format(record)))
QtCore.QMetaObject.invokeMethod(self,
"autoScroll",
QtCore.Qt.QueuedConnection)

def format(self, record):
if record.levelno == logging.INFO:
bgcolor = WHITE
fgcolor = BLACK
elif record.levelno == logging.WARNING:
bgcolor = YELLOW
fgcolor = BLACK
elif record.levelno == logging.ERROR:
bgcolor = ORANGE
fgcolor = BLACK
elif record.levelno == logging.CRITICAL:
bgcolor = RED
fgcolor = BLACK
else:
bgcolor = BLACK
fgcolor = WHITE

self.setTextBackgroundColor(bgcolor)
self.setTextColor(fgcolor)
self.setFont(DEFAULT_FONT)
record = logging.Handler.format(self, record)
return record

@QtCore.pyqtSlot()
def autoScroll(self):
self.verticalScrollBar().setSliderPosition(self.verticalScrollBar().maximum())


class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.status_handler = QHandler()
self.setCentralWidget(self.status_handler)

logging.getLogger().addHandler(self.status_handler)
self.status_handler.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))
logging.getLogger().setLevel(logging.DEBUG)
timer = QtCore.QTimer(self, interval=1000, timeout=self.on_timeout)
timer.start()

def on_timeout(self):
logging.info('From Gui Thread '.format(QtCore.QDateTime.currentDateTime().toString()))


class Subprocess_Thread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.logger = logging.getLogger(self.__class__.__name__)
self.logger.info('Subprocess Thread Created')

def run(self):
while True:
t = random.choice(["info", "warning", "error", "critical"])
msg = "Type: , thread: ".format(t, threading.currentThread())
getattr(self.logger, t)(msg)
QtCore.QThread.sleep(1)

if __name__ == '__main__':
import sys
app = QtWidgets.QApplication.instance()
if app is None:
app = QtWidgets.QApplication(sys.argv)
app.setStyle('Fusion')
w = MainWindow()
w.show()
th = Subprocess_Thread()
th.daemon = True
th.start()
sys.exit(app.exec_())





share|improve this answer













The QHandler that samples is not thread-safe so it will generate problems if you call it from another thread since it is a GUI, a possible solution is to send the data from the secondary thread(def emit(self, record):) to the thread of the GUI through QMetaObject for this you must use pyqtSlot:



class QHandler(logging.Handler, QtWidgets.QTextEdit):
def __init__(self, parent=None):
QtWidgets.QTextEdit.__init__(self, parent)
logging.Handler.__init__(self)

self.setLineWrapMode(QtWidgets.QTextEdit.NoWrap)
self.setReadOnly(True)

self.emit_lock = threading.Lock()

def emit(self, record):
with self.emit_lock:
QtCore.QMetaObject.invokeMethod(self,
"append",
QtCore.Qt.QueuedConnection,
QtCore.Q_ARG(str, self.format(record)))
QtCore.QMetaObject.invokeMethod(self,
"autoScroll",
QtCore.Qt.QueuedConnection)

def format(self, record):
if record.levelno == logging.INFO:
bgcolor = WHITE
fgcolor = BLACK
elif record.levelno == logging.WARNING:
bgcolor = YELLOW
fgcolor = BLACK
elif record.levelno == logging.ERROR:
bgcolor = ORANGE
fgcolor = BLACK
elif record.levelno == logging.CRITICAL:
bgcolor = RED
fgcolor = BLACK
else:
bgcolor = BLACK
fgcolor = WHITE

self.setTextBackgroundColor(bgcolor)
self.setTextColor(fgcolor)
self.setFont(DEFAULT_FONT)
record = logging.Handler.format(self, record)
return record

@QtCore.pyqtSlot()
def autoScroll(self):
self.verticalScrollBar().setSliderPosition(self.verticalScrollBar().maximum())


Example:



import random
import logging
import threading
from PyQt5 import QtCore, QtGui, QtWidgets

WHITE, BLACK, YELLOW, ORANGE, RED = QtGui.QColor("white"), QtGui.QColor("black"), QtGui.QColor("yellow"), QtGui.QColor("orange"), QtGui.QColor("red")
DEFAULT_FONT = QtGui.QFont()

class QHandler(logging.Handler, QtWidgets.QTextEdit):
def __init__(self, parent=None):
QtWidgets.QTextEdit.__init__(self, parent)
logging.Handler.__init__(self)

self.setLineWrapMode(QtWidgets.QTextEdit.NoWrap)
self.setReadOnly(True)

self.emit_lock = threading.Lock()

def emit(self, record):
with self.emit_lock:
QtCore.QMetaObject.invokeMethod(self,
"append",
QtCore.Qt.QueuedConnection,
QtCore.Q_ARG(str, self.format(record)))
QtCore.QMetaObject.invokeMethod(self,
"autoScroll",
QtCore.Qt.QueuedConnection)

def format(self, record):
if record.levelno == logging.INFO:
bgcolor = WHITE
fgcolor = BLACK
elif record.levelno == logging.WARNING:
bgcolor = YELLOW
fgcolor = BLACK
elif record.levelno == logging.ERROR:
bgcolor = ORANGE
fgcolor = BLACK
elif record.levelno == logging.CRITICAL:
bgcolor = RED
fgcolor = BLACK
else:
bgcolor = BLACK
fgcolor = WHITE

self.setTextBackgroundColor(bgcolor)
self.setTextColor(fgcolor)
self.setFont(DEFAULT_FONT)
record = logging.Handler.format(self, record)
return record

@QtCore.pyqtSlot()
def autoScroll(self):
self.verticalScrollBar().setSliderPosition(self.verticalScrollBar().maximum())


class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.status_handler = QHandler()
self.setCentralWidget(self.status_handler)

logging.getLogger().addHandler(self.status_handler)
self.status_handler.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))
logging.getLogger().setLevel(logging.DEBUG)
timer = QtCore.QTimer(self, interval=1000, timeout=self.on_timeout)
timer.start()

def on_timeout(self):
logging.info('From Gui Thread '.format(QtCore.QDateTime.currentDateTime().toString()))


class Subprocess_Thread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.logger = logging.getLogger(self.__class__.__name__)
self.logger.info('Subprocess Thread Created')

def run(self):
while True:
t = random.choice(["info", "warning", "error", "critical"])
msg = "Type: , thread: ".format(t, threading.currentThread())
getattr(self.logger, t)(msg)
QtCore.QThread.sleep(1)

if __name__ == '__main__':
import sys
app = QtWidgets.QApplication.instance()
if app is None:
app = QtWidgets.QApplication(sys.argv)
app.setStyle('Fusion')
w = MainWindow()
w.show()
th = Subprocess_Thread()
th.daemon = True
th.start()
sys.exit(app.exec_())






share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 13 '18 at 18:38









eyllanesceyllanesc

75.6k103156




75.6k103156












  • This answer put me on the right path. I created my own pyqtSignal that is emitted when the emit function is called. Then I created a display method that is a custom pyqt5Slot that handles the actual GUI update. This seems to make it thread safe.

    – Joseph Martin
    Nov 14 '18 at 12:07












  • @JosephMartin that is the other option, but for me it is easier to use QMetaObject.InvokedMethod since no connection or new signals are needed. both are thread-safe :-)

    – eyllanesc
    Nov 14 '18 at 12:10

















  • This answer put me on the right path. I created my own pyqtSignal that is emitted when the emit function is called. Then I created a display method that is a custom pyqt5Slot that handles the actual GUI update. This seems to make it thread safe.

    – Joseph Martin
    Nov 14 '18 at 12:07












  • @JosephMartin that is the other option, but for me it is easier to use QMetaObject.InvokedMethod since no connection or new signals are needed. both are thread-safe :-)

    – eyllanesc
    Nov 14 '18 at 12:10
















This answer put me on the right path. I created my own pyqtSignal that is emitted when the emit function is called. Then I created a display method that is a custom pyqt5Slot that handles the actual GUI update. This seems to make it thread safe.

– Joseph Martin
Nov 14 '18 at 12:07






This answer put me on the right path. I created my own pyqtSignal that is emitted when the emit function is called. Then I created a display method that is a custom pyqt5Slot that handles the actual GUI update. This seems to make it thread safe.

– Joseph Martin
Nov 14 '18 at 12:07














@JosephMartin that is the other option, but for me it is easier to use QMetaObject.InvokedMethod since no connection or new signals are needed. both are thread-safe :-)

– eyllanesc
Nov 14 '18 at 12:10





@JosephMartin that is the other option, but for me it is easier to use QMetaObject.InvokedMethod since no connection or new signals are needed. both are thread-safe :-)

– eyllanesc
Nov 14 '18 at 12:10

















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53285181%2fpyqt5-program-crashes-while-updating-qtextedit-via-logging%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Top Tejano songwriter Luis Silva dead of heart attack at 64

政党

天津地下鉄3号線