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. How to use signals & slots in Qt for inter-threading communication?
Forum Updated to NodeBB v4.3 + New Features

How to use signals & slots in Qt for inter-threading communication?

Scheduled Pinned Locked Moved General and Desktop
3 Posts 3 Posters 2.8k Views 1 Watching
  • 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.
  • L Offline
    L Offline
    leonardodavinci
    wrote on last edited by
    #1

    I want to make an application where the user will hit a QPushButton and this will trigger a secondary thread which will add some text to a QListWidget in the main window. But for a reason that I cannot figure out ,although the signal from the thread to the main window is emitted it never reaches the destination. Probably because the connection fails. But why this happens? Here is my code(my application is compiled using Visual Studio 2010):

    mythread.h:
    @#ifndef MY_THREAD_H
    #define MY_THREAD_H
    #include <QThread>
    #include <QString>
    class mythread:public QThread
    {
    Q_OBJECT

    public:
    void setName(QString& name);
    signals:
    void sendMsg(QString& msg);
    protected:
    void run();
    private:
    QString m_name;
    QString msg;
    };
    #endif@

    mythread.cpp:

    @#include "mythread.h"
    void mythread::setName(QString& name)
    {
    m_name=name;
    }
    void mythread::run()
    {
    msg="Hello "+m_name;
    emit sendMsg(msg);
    }@

    mydialog.h:

    @#ifndef MY_DIALOG_H
    #define MY_DIALOG_H
    #include <QtGui>
    #include "mythread.h"
    class mydialog:public QDialog
    {
    Q_OBJECT
    public:
    mydialog();
    public slots:
    void receiveMsg(QString& msg);
    void fillList();
    private:
    QListWidget list1;
    QPushButton btn1;
    QGridLayout layout;
    mythread thread;
    };
    #endif@

    mydialog.cpp:

    @#include "mydialog.h"
    mydialog::mydialog()
    {
    layout.addWidget(&list1,0,0);
    btn1.setText("Find");
    layout.addWidget(&btn1,0,1);
    setLayout(&layout);
    QString myname="leonardo";
    thread.setName(myname);
    connect(&btn1,SIGNAL(clicked()),this,SLOT(fillList()));
    connect(&thread,SIGNAL(sendMsg(QString&)),this,SLOT(receiveMsg(Qstring&)));
    }
    void mydialog::fillList()
    {
    thread.start();
    }
    void mydialog::receiveMsg(QString& msg)
    {
    list1.addItem(msg);
    }@

    find.cpp:

    @#include <QApplication>
    #include "mydialog.h"
    int main(int argc,char* argv[])
    {
    QApplication app(argc,argv);
    mydialog window;
    window.setWindowTitle("Find");
    window.show();
    return app.exec();
    }@

    find.pro:

    @TEMPLATE = app
    TARGET =
    DEPENDPATH += .
    INCLUDEPATH += .

    Input

    HEADERS += mydialog.h mythread.h
    SOURCES += find.cpp mydialog.cpp mythread.cpp@

    1 Reply Last reply
    0
    • K Offline
      K Offline
      KA51O
      wrote on last edited by
      #2

      You have fallen victim to a common mistake. "You're doing it wrong":http://blog.qt.digia.com/blog/2010/06/17/youre-doing-it-wrong/. Don't subclass QThread but rather use the new "best practise for QThreads":http://developer.qt.nokia.com/wiki/QThreads_general_usage.

      I think your problem is that you forgot to call exec() in your run() function implementation. Therefor your thread doesn't have an eventloop, and therefor the signal is not emitted. It's just one of the many pitfalls that often arise when people follow the old approach of subclassing QThread rather than just moving a worker object to a QThread. There is also a "doc note in the QThread reference":http://qt-project.org/doc/qt-4.8/QThread.html#notes.

      1 Reply Last reply
      0
      • T Offline
        T Offline
        terenty
        wrote on last edited by
        #3

        Hi! This approach is vicious:

        @private:
        QListWidget list1;
        QPushButton btn1;
        QGridLayout layout;
        @

        You should always allocate QObjects dynamically (using new):

        @private:
        QListWidget* list1;
        QPushButton* btn1;
        QGridLayout* layout;
        //...

        // in constructor
        list1 = new QListWidget();
        btn1 = new QPushButton();
        layout = new QGridLayout();@

        This is because you usually add widgets to a parent widget making them its children and QObject automatically deletes its children.
        Therefore, anything that becomes someone's child should be allocated dynamically using operator new.
        Although in your particular case you didn't explicitly set parent to your button, listwidget and layout but you used addWidget and setLayout on them which implicitly made them dialog's children.
        "Official docs on QObject destructor":http://qt-project.org/doc/qt-4.8/qobject.html#dtor.QObject

        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