I read some topics, and now I know I have to use Signals
and Slots
, but I'm having some trouble doing it.
At my user interface I have a Q List Widget
and I need to add items to it from another thread; I'm using the following code into my tela_chat.cpp
that corresponds to the screen where my QList
is inserted:
//tela_chat.cpp
#include <QThread>
#incluede "tela_chat.h"
tela_chat::tela_chat(QWidget *parent) :
QFrame(parent),
ui(new Ui::tela_chat)
{
ui->setupUi(this);
connect(this, SIGNAL(call_chatReceived(QString)), this, SLOT(receivedChat(QString))); //Connect signal to slot function into the constructor of the class
}
tela_chat::~tela_chat()
{
delete ui;
}
void tela_chat::receivedChat(QString mensagem)
{
//The signal has been received
ui->lstWdgt_chat->addItem("Professor: " + mensagem); //Add item to QList
}
void tela_chat::on_btn_conectar_clicked()
{
//Creating an other thread
class ThreadChat : public QThread {
void run() override {
//Cóigo para rodar na thread separada:
QString mensagem = "This is what I want to put into QList";
emit call_receivedChat(mensagem);
}
};
//INICIALIZATING THE NEW THREAD
ThreadChat *thread = new ThreadChat;
thread -> start(); //Inicia a thread (chamando o run())
//thread -> wait();
}
And this is the linked header file:
//tela_chat.h
#include <QString>
namespace Ui {
class tela_chat;
}
class tela_chat : public QFrame
{
Q_OBJECT
public:
explicit tela_chat(QWidget *parent = nullptr);
~tela_chat();
private slots:
void receivedChat(QString mensagem);
void on_btn_conectar_clicked();
private:
Ui::tela_chat *ui;
signals:
void call_receivedChat(QString mensagem);
};
There are some other functions like a socket connection script, but I removed it to make the code as the minimum reproducible amount of code.
In your constructor, you connect call_chatReceived (signal) to receivedChat (slot), but your signal is defined as call_receivedChat. Make sure the signal and slot names match. Also you should connect the signal in your tela_chat constructor, not in the method. The connection should be in the constructor to establish the connection once when the object is created.
Here's the corrected code:
// tela_chat.cpp
#include <QThread>
#include "tela_chat.h"
tela_chat::tela_chat(QWidget *parent) :
QFrame(parent),
ui(new Ui::tela_chat)
{
ui->setupUi(this);
// Connect the signal and slot in the constructor
connect(this, SIGNAL(call_receivedChat(QString)), this, SLOT(receivedChat(QString));
}
void tela_chat::receivedChat(QString mensagem)
{
// The signal has been received
ui->lstWdgt_chat->addItem("Professor: " + mensagem); // Add item to QList
}
void tela_chat::on_btn_conectar_clicked() {
// Creating another thread
class ThreadChat : public QThread {
public:
ThreadChat(tela_chat* chatInstance) : chatInstance(chatInstance) {}
void run() override {
QString mensagem = "This is what I want to put into QList";
emit chatInstance->call_receivedChat(mensagem);
}
private:
tela_chat* chatInstance;
};
// Initializing the new thread
ThreadChat* thread = new ThreadChat(this); // Pass the instance of tela_chat
thread->start(); // Starts the thread (calling run())
}
By passing the tela_chat instance to the ThreadChat constructor, you can then use it to emit the signal. This ensures that you have a valid instance to work with when emitting the signal from the nested class.