Results 1 to 2 of 2

Thread: Message log console used in different threads

  1. #1
    Join Date
    Dec 2017
    Location
    Cesena, Italy
    Posts
    13
    Thanks
    4
    Thanked 1 Time in 1 Post
    Qt products
    Qt5
    Platforms
    MacOS X Windows

    Default Message log console used in different threads

    Hello,
    Premise: about 6 months ago I changed my job, so I inherited some pretty big C++ project using qt libraries and I started learning qt that moment.

    My issue: the project I'm working on consists of several sub-projects and most of them make use of multi-threading to handle asynchronous events from the GUI and from connected devices.
    The guy who developed the project in the first place has implemented a message handler for qInfo, qDebug and qCritical in the following way:
    main.cpp
    Qt Code:
    1. Console * console;
    2.  
    3. void messageHandler(QtMsgType type, const QMessageLogContext &, const QString & msg) {
    4. switch (type) {
    5. case QtDebugMsg:
    6. // formatting for debug messages
    7. break;
    8.  
    9. case QtInfoMsg:
    10. // formatting for info messages
    11. break;
    12.  
    13. case QtCriticalMsg:
    14. // formatting for critical messages
    15. break;
    16.  
    17. default:
    18. break;
    19. }
    20.  
    21. if (console) {
    22. console->addLine(msg);
    23. }
    24. }
    25.  
    26. int main(int argc, char * argv[]) {
    27. QApplication a(argc, argv);
    28. qInstallMessageHandler(QtMessageHandler(messageHandler));
    29.  
    30. console = new Console();
    31. MainWindow mainwindow;
    32.  
    33. mainwindow.showMaximized();
    34. mainwindow.setConsole(console);
    35. a.exec();
    36. }
    To copy to clipboard, switch view to plain text mode 
    console.ui declares a QListWidget * consoleWidget for the class Console.
    console.h:
    Qt Code:
    1. namespace Ui {
    2. class Console;
    3. }
    4.  
    5. class Console : public QWidget {
    6. Q_OBJECT
    7.  
    8. public:
    9. explicit Console(QWidget * parent = 0);
    10.  
    11. void addLine(QString line);
    12.  
    13. private:
    14. Ui::Console * ui;
    15. };
    To copy to clipboard, switch view to plain text mode 
    console.cpp:
    Qt Code:
    1. Console::Console(QWidget * parent) : QWidget(parent), ui(new Ui::Console) {
    2. ui->setupUi(this);
    3. }
    4.  
    5. void Console::addLine(QString line) {
    6. ui->consoleWidget->addItem(line);
    7. ui->consoleWidget->scrollToBottom();
    8. }
    To copy to clipboard, switch view to plain text mode 

    So the aim is to redirect all of the messages, properly formatted, to a console.
    At some point I noticed that disabling the addLine on the console prevented a lot of extemporary crashes of the application, preceded by some warnings complaining about QTimers being started or stopped from different threads.
    So I decided to disable the console with an ifdef, hoping to find a solution later on, and the warnings and crashes actually ceased.

    Today I realized the problem may be due to the fact that qInfo, qDebug and qCritical are called all over the code, so they actually allow pieces of code running in different threads to directly call a method (addLine) on a GUI object (Console).
    So I wanted to try and replace console->addLine(msg); within messageHandler with a signal emit to keep safe the GUI thread, but I don't know how to do it, since messageHandler is a non-member function so, afaik, it cannot emit signals. Moreover, I think that if I created a class and made messageHandler one of its members I could experience problems due to having the method of a single object called in different threads.

    So lastly, my questions:
    1) Is my analysis of the problem correct or the crashes may be due to something else?
    2) Is the requirement of redirecting all messages to a console something intrinsically wrong and should I give up to a different solution for my logs?
    3) If no, what would be the proper implementation to obtain such behaviour?

    Thanks for your help and best regards!

  2. #2
    Join Date
    Dec 2017
    Location
    Cesena, Italy
    Posts
    13
    Thanks
    4
    Thanked 1 Time in 1 Post
    Qt products
    Qt5
    Platforms
    MacOS X Windows

    Default Re: Message log console used in different threads

    Maybe I solved the problem on my own.
    I found that QMetaObject::invokeMethod(QObject *object, const char *member, Qt::ConnectionType type), called with type = Qt::QueuedConnection, posts an event to object, that tells object to execute member as soon as it enters its main event loop.
    So I tried to substitute
    Qt Code:
    1. console->addLine(msg);
    To copy to clipboard, switch view to plain text mode 
    with
    Qt Code:
    1. QMetaObject::invokeMethod(console, "addLine", Qt::QueuedConnection, Q_ARG(QString, msg));
    To copy to clipboard, switch view to plain text mode 
    and declaring addLine as Q_INVOKABLE, and now my application seems to work fine even if I spam the message logger from a while(true) loop living in its own thread.
    Of course, with the spam active, the application slows down, but it doesn't crash and doesn't write the warnings I talked about in the previous post: for the sake of completeness they are
    Qt Code:
    1. "QBasicTimer::stop: Failed. Possibly trying to stop from a different thread"
    To copy to clipboard, switch view to plain text mode 
    and
    Qt Code:
    1. "QBasicTimer::start: Timers cannot be started from another thread"
    To copy to clipboard, switch view to plain text mode 
    I've seen them now for the first time after a long while...

    So now my question becomes: am I doing something horribly wrong which I will pay for in the long run or am I just doing things right?

    Bests

Similar Threads

  1. Replies: 8
    Last Post: 21st August 2012, 14:31
  2. Two threads in a console application
    By msr in forum Qt Programming
    Replies: 3
    Last Post: 30th September 2011, 17:16
  3. Qt Threads vs Native Threads performance
    By StackOverflow in forum Qt Programming
    Replies: 1
    Last Post: 14th November 2010, 13:14
  4. Replies: 4
    Last Post: 12th October 2008, 14:47
  5. console message
    By mickey in forum Qt Programming
    Replies: 6
    Last Post: 29th July 2006, 15:14

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.