Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. [solved] Queued Signals

[solved] Queued Signals

Scheduled Pinned Locked Moved General and Desktop
13 Posts 3 Posters 6.5k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • N Offline
    N Offline
    NarimanN2
    wrote on last edited by
    #1

    Hi

    I wrote a program that Share a QString between 2 threads using signal/slot and in the slot I just print the Qstring. the problem is when I run the program, nothing displayed until the threads stop working and then all of the prints display immediately.

    is that a problem or that is the way Queued Signals work?

    1 Reply Last reply
    0
    • sierdzioS Offline
      sierdzioS Offline
      sierdzio
      Moderators
      wrote on last edited by
      #2

      Are you printing using printf()? Then this is normal and has nothing to do with QueuedConnections. Use qDebug() or cerr instead.

      (Z(:^

      1 Reply Last reply
      0
      • N Offline
        N Offline
        NarimanN2
        wrote on last edited by
        #3

        No I am using qDebug()

        1 Reply Last reply
        0
        • sierdzioS Offline
          sierdzioS Offline
          sierdzio
          Moderators
          wrote on last edited by
          #4

          Ok, then there can be a lot of issues. Let's move go through a checklist :)

          Is this a console application?

          Is the sending thread busy (does it have a chance to enter the event loop)?

          Is the receiving thread busy (does it have a chance to enter the event loop)?

          (Z(:^

          1 Reply Last reply
          0
          • N Offline
            N Offline
            NarimanN2
            wrote on last edited by
            #5
            1. yes

            2. in it's run method there's a while loop that keep emitting writeText signals... is that called "busy"?

            3.recivieng thread is just a simple thread that call exec() in run method and call quit in a slot that I wrote for it called stop. and has another slot called write that is in charge of printing texts...

            1 Reply Last reply
            0
            • sierdzioS Offline
              sierdzioS Offline
              sierdzio
              Moderators
              wrote on last edited by
              #6

              It may be that you are not giving the meta object system a chance to send your signals.

              In GUI applications, everything revolves around the even loop, so QueuedConnections ususally work without any problems, because every time a function ends, the event loop kicks in and processes all signals.

              In console applications, the flow is often much more linear and "packed" with things to do. There are many ways to make it work for you, but we will start small.

              First, I suggest reding "the documentation":http://qt-project.org/doc/qt-5/qthread.html, because it looks like you have subclassed QThread, which is not needed/ recommended in most cases.

              Second. Try adding this line after you emit the signal:
              @
              QCoreApplication::instance()->processEvents();
              @
              it will work through the queue in the event loop and process all signals. If that does not "unblock" your printing, then the problem lies on the other side (the thread).

              Please note that in many cases calling processEvents() can lead to unexpected results, so I recommend using it with care. Here I mention it because it should allow us to quickly determine the cause of your problem.

              (Z(:^

              1 Reply Last reply
              0
              • N Offline
                N Offline
                NarimanN2
                wrote on last edited by
                #7

                using QCoreApplication::instance()->processEvents(); after emiiting didn't work either! do you think if I stop subclassing Qthread and use them as documentation says, it's gonna work ?

                1 Reply Last reply
                0
                • sierdzioS Offline
                  sierdzioS Offline
                  sierdzio
                  Moderators
                  wrote on last edited by
                  #8

                  OK, so it may be that the receiving thread is blocking here. Add the same line there, somewhere in your loop inside run() function.

                  ... oh wait, it may be that you don't have any loop in your thread, just exec(). If yes, then please remove it and see what happens. I do recommend doing it without subclassing, yes, it is usually simpler, creates nicer code, and is easier to understand.

                  (Z(:^

                  1 Reply Last reply
                  0
                  • JKSHJ Offline
                    JKSHJ Offline
                    JKSH
                    Moderators
                    wrote on last edited by
                    #9

                    Hi,

                    It could also be that your output stream is not flushed. Where do you print the messages to? (The console? Or Qt Creator's application output pane? Or Somewhere else?)

                    Anyway, could you please post your code? That makes it much easier to find the issue.

                    Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                    1 Reply Last reply
                    0
                    • N Offline
                      N Offline
                      NarimanN2
                      wrote on last edited by
                      #10

                      removing exec() and add thath line in receiving thread didn't wotk either! here is my code :

                      @#ifndef TEXTANDNUMBER_H
                      #define TEXTANDNUMBER_H

                      #include <QtCore>

                      class TextAndNumber
                      {
                      public:
                      TextAndNumber();
                      TextAndNumber(int, QString);

                      int number;
                      QString text;
                      

                      };

                      Q_DECLARE_METATYPE(TextAndNumber);

                      #endif // TEXTANDNUMBER_H
                      @
                      @#include "textandnumber.h"

                      TextAndNumber::TextAndNumber()
                      {
                      }

                      TextAndNumber::TextAndNumber(int num, QString txt)
                      {
                      number = num;
                      text = txt;
                      }
                      @
                      @#ifndef TEXTDEVICE_H
                      #define TEXTDEVICE_H

                      #include <QThread>
                      #include "textandnumber.h"

                      class TextDevice : public QThread
                      {
                      Q_OBJECT

                      public:
                      TextDevice();
                      void run();
                      void stop();

                      public slots:
                      void write(TextAndNumber tan);

                      private:
                      int count;
                      };

                      #endif // TEXTDEVICE_H
                      @
                      @#include "textdevice.h"
                      #include <QtCore>

                      TextDevice::TextDevice() : QThread()
                      {
                      count = 0;
                      }

                      void TextDevice::run()
                      {
                      exec();

                      void TextDevice::stop()
                      {
                      quit();
                      }

                      void TextDevice::write(TextAndNumber tan)
                      {
                      qDebug() << QString("Call %1 (%3) : %2").arg(tan.number).arg(tan.text).arg(count++);
                      }
                      @
                      @#ifndef TEXTTHREAD_H
                      #define TEXTTHREAD_H

                      #include <QThread>
                      #include <QDebug>
                      #include "textdevice.h"

                      class TextThread : public QThread
                      {
                      Q_OBJECT

                      public:
                      TextThread(const QString &text);
                      void run();
                      void stop();

                      signals:
                      void writeText(TextAndNumber);

                      private:
                      QString m_text;
                      bool m_stop;
                      int m_count;
                      };

                      #endif // TEXTTHREAD_H
                      @
                      @#include "textthread.h"

                      TextThread::TextThread(const QString &text) : QThread()
                      {
                      m_text = text;
                      m_stop = false;
                      m_count = 0;
                      }

                      void TextThread::run()
                      {
                      while(!m_stop)
                      {
                      emit writeText(TextAndNumber(m_count++, m_text));
                      sleep(1);

                      }
                      

                      }

                      void TextThread::stop()
                      {
                      m_stop = true;
                      }

                      @

                      @#include <QCoreApplication>
                      #include "textthread.h"
                      #include "textandnumber.h"
                      #include <iostream>
                      #include <QtCore>

                      int main(int argc, char *argv[])
                      {
                      QCoreApplication a(argc, argv);

                      qRegisterMetaType<TextAndNumber> ("TextAndNumber");
                      
                      TextDevice device;
                      TextThread foo( "Foo" ), bar( "Bar" );
                      
                      QObject::connect( &foo, SIGNAL(writeText(TextAndNumber)), &device, SLOT(write(TextAndNumber)));
                      QObject::connect( &bar, SIGNAL(writeText(TextAndNumber)), &device, SLOT(write(TextAndNumber)));
                      
                      
                      foo.start();
                      bar.start();
                      device.start();
                      
                      char ch;
                      std::cin >> ch;
                      
                      foo.stop();
                      bar.stop();
                      device.stop();
                      
                      foo.wait();
                      bar.wait();
                      device.wait();
                      
                      return a.exec(&#41;;
                      

                      }
                      @

                      1 Reply Last reply
                      0
                      • sierdzioS Offline
                        sierdzioS Offline
                        sierdzio
                        Moderators
                        wrote on last edited by
                        #11

                        Well, there are some issues with this code.
                        First, I recommend explicitly adding Qt::QueuedConnection to both of your connect statements.

                        Second, please consider this quote from the documentation:
                        [quote]It is important to remember that a QThread instance lives in the old thread that instantiated it, not in the new thread that calls run(). This means that all of QThread's queued slots will execute in the old thread. Thus, a developer who wishes to invoke slots in the new thread must use the worker-object approach; new slots should not be implemented directly into a subclassed QThread.[/quote]

                        Third. TextThread::stop() is changing m_stop variable while run() is using it - dangerous.

                        (Z(:^

                        1 Reply Last reply
                        0
                        • N Offline
                          N Offline
                          NarimanN2
                          wrote on last edited by
                          #12

                          I write this code like documentation says and it's totally work! thanks for your help!

                          1 Reply Last reply
                          0
                          • sierdzioS Offline
                            sierdzioS Offline
                            sierdzio
                            Moderators
                            wrote on last edited by
                            #13

                            Great, good to hear that! I have marked the thread as solved. Happy coding :-)

                            (Z(:^

                            1 Reply Last reply
                            0

                            • Login

                            • Login or register to search.
                            • First post
                              Last post
                            0
                            • Categories
                            • Recent
                            • Tags
                            • Popular
                            • Users
                            • Groups
                            • Search
                            • Get Qt Extensions
                            • Unsolved