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
Tim Meyer
  • 12,210
  • 8
  • 64
  • 97
Dragno
  • 3,027
  • 1
  • 27
  • 41
  • 1
    You have a typo in your connection: `SLOT(receiveMsg(Qstring&))` should be `SLOT(receiveMsg(QString&))`. You should launch your application in debugger or in console to see what Qt writes on stdout and stderr – Kamil Klimek Nov 29 '12 at 13:54

2 Answers2

2

Two things:

  1. In your second connect call, Qstring must be changed to QString
  2. Qt cannot deliver QString& accross threads by default. There's two ways to fix this:
    1. Change your Signals and Slots and the connect to use QString rather than QString&
    2. Use qRegisterMetaType in order to make QString& usable.

I still recommend reading

https://www.qt.io/blog/2010/06/17/youre-doing-it-wrong

and Kari's comment

https://www.qt.io/blog/2010/06/17/youre-doing-it-wrong#commento-comment-name-a6fad43dec11ebe375cde77a9ee3c4331eb0c5f0bcac478ecbe032673e8ebc82

when working with threads, though.

ololuki
  • 377
  • 1
  • 7
  • 14
Tim Meyer
  • 12,210
  • 8
  • 64
  • 97
  • I have tried adding the exec() call but nothing happened. Also the Mandelbrot Example in Qt documentation does not use exec(). – Dragno Nov 29 '12 at 10:09
  • Your second connect() call returns false. I'm trying to find out why. – Tim Meyer Nov 29 '12 at 11:50
  • see also http://stackoverflow.com/questions/4093159/what-is-the-correct-way-to-implement-a-qthread-example-please – g19fanatic Nov 29 '12 at 12:36
  • @Tim Meyer Could you please change "http" to "https"? So the pointers will work directly – katang Jul 22 '19 at 18:49
1

First of all use const qualifier for arguments if you're not planning to modify it. After fixing typo in connection SLOT(receiveMsg(Qstring&)) and changing signals and slots signature to const references everything works fine

Kamil Klimek
  • 12,884
  • 2
  • 43
  • 58