Qt slot connected successful but wasn't fired - qt

I try to call slot of my class via newConnection() signal of QTcpServer class. connect() function returns true, but the slot weren't executed.
Here's what i made:
class server : QObject
{
Q_OBJECT
public:
server();
QTcpServer *srv;
void run();
public slots:
void handleClient();
}
Bind the slot:
void server::run()
{
srv = new QTcpServer();
bool status = connect(srv, SIGNAL(newConnection()), this, SLOT(handleClient()));
// status contains true now
srv->listen(QHostAddress::Any, port);
}
Slot's body:
void server::handleClient()
{
/* This code is not being executed */
qDebug() << "zxc";
QMessageBox msg;
msg.setText("zxc");
msg.exec();
}
Why doesn't it work?

I'm not quite sure what you're doing wrong try adding public in the inheritance line (: public QObject).
The following code works for me:
server.hpp
#ifndef _SERVER_HPP_
#define _SERVER_HPP_
#include <QtNetwork>
class Server : public QObject
{
Q_OBJECT
public:
Server();
private slots:
void handleClient();
private:
QTcpServer* mServer;
};
#endif
server.cpp
#include "server.hpp"
Server::Server() : mServer(new QTcpServer())
{
connect(mServer, SIGNAL(newConnection()), this, SLOT(handleClient()));
mServer->listen(QHostAddress::Any, 10000);
}
void Server::handleClient()
{
while (mServer->hasPendingConnections())
{
QTcpSocket* skt = mServer->nextPendingConnection();
skt->write("READY\n");
skt->waitForReadyRead(5000);
qDebug() << skt->readAll();
skt->write("OK\n");
skt->waitForBytesWritten();
skt->close();
skt->deleteLater();
}
}
main.cpp
#include "server.hpp"
int main(int argc, char** argv)
{
QCoreApplication app(argc, argv);
Server srv;
return app.exec();
}

Related

QThread created in other QThread not calling destructor

I have a code:
#include <QApplication>
#include <QThread>
#include <QDebug>
class ChildThread : public QThread {
Q_OBJECT
public:
ChildThread() {
connect(this, &QThread::finished, this, &ChildThread::deleteLater);
}
~ChildThread() {
qDebug() << "~TR()";
}
protected:
void run() {
qDebug() << "RUN";
}
};
class ParentThread : public QThread {
Q_OBJECT
public:
protected:
void run() {
for (int i = 0; i < 10; i++) {
ChildThread *t = new ChildThread();
t->start();
msleep(1000);
}
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
ParentThread *t = new ParentThread();
t->start();
for (int i = 0; i < 10; i++) {
ChildThread *t = new ChildThread();
t->start();
QThread::msleep(1000);
}
return a.exec();
}
And I havnt understand, why all of the ChildThread that created in the ParentThread after reaching end of run() function not ending and desctructor of the ChildThread not called, but if I create ChildThread outside of ParentThread, deststructor of ChildThread was called?
Thank You!
The thread will not be destroyed when the run() function due to the
fact that the deleteLater() function is called when the parent (main) loop
get back the control.
Creating the ChildThread from main(), the QThread::msleep() call
give back the control to the main loop, so the destructor can be
called.

Qt Signal Slot connection issue

Trying to create 2 objects (clients) living in different threads and communicating with 1 object(server) living on the main thread.
However I'm not seeing any activity on the server object.
The main goal of this code is to see how the signal slot will behave when 2 signals coming from 2 different threads are communicating with a single object on the main thread.
objects.cpp:
#include "objects.h"
Objects::Objects(QObject* parent): QObject (parent)
{
}
void Objects::printData(const QString& data)
{
qDebug() << data;
}
void Objects::process(const QString& data)
{
emit sendData(data+":processed");
}
Q_NORETURN void Objects::run()
{
while (true) {
//qDebug() << "hit" << m_rate;
emit sendData("test"+QString::number(m_rate));
QThread::sleep(m_rate);
}
}
objects.h:
#ifndef OBJECTS_H
#define OBJECTS_H
#include <QObject>
#include <QDebug>
#include <QThread>
class Objects: public QObject
{
Q_OBJECT
public:
explicit Objects(QObject* parent = Q_NULLPTR);
signals:
void sendData(const QString&);
public slots:
void printData(const QString&);
void process(const QString&);
void run();
public:
ulong m_rate;
};
#endif // OBJECTS_H
main.cpp:
#include <QCoreApplication>
#include "objects.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Objects ser;
Objects cl1;
Objects cl2;
cl1.m_rate = 1;
cl2.m_rate = 2;
QThread cl1_t;
QThread cl2_t;
QObject::connect(&cl1_t, &QThread::started, &cl1, &Objects::run);
QObject::connect(&cl2_t, &QThread::started, &cl2, &Objects::run);
QObject::connect(&cl1, &Objects::sendData, &ser, &Objects::process);
QObject::connect(&cl2, &Objects::sendData, &ser, &Objects::process);
QObject::connect(&ser, &Objects::sendData, &cl1, &Objects::printData);
QObject::connect(&ser, &Objects::sendData, &cl2, &Objects::printData);
cl1.moveToThread(&cl1_t);
cl2.moveToThread(&cl2_t);
cl1_t.start();
cl2_t.start();
return a.exec();
}
Looks like your void run() function-member blocks Qt internal event queue. Just add QCoreApplication::processEvents(); in to your void run() and it will solve your problem.
void Objects::run()
{
while (true) {
qDebug() << "hit" << m_rate;
emit sendData("test" + QString::number(m_rate));
QThread::sleep(m_rate);
QCoreApplication::processEvents();
}
}
UPD:
I will suggest you to read THIS wiki article for more detailed explanation on your problem.

declaring qtcpsocket class object as global

I am working on qt to develop a socket programming.i am posting the code here.
"mainwindow.h"
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
namespace Ui {
class MainWindow;
}
static void handler(int sig, siginfo_t *si, void *uc);
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
QTcpSocket *socket;
void timer();
void config();
private slots:
void newconnection();
private:
Ui::MainWindow *ui;
QTcpServer *server;
};
#endif // MAINWINDOW_H
"mainwindow.cpp"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
static char i;
ui->setupUi(this);
sock=socket;
// if(!i)
// {
// connect(ui->start_button,SIGNAL(clicked()),this,SLOT(config()));
// }
// i=1;
qDebug()<<i;
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow ::newconnection()
{
static int i;
socket=server->nextPendingConnection();
//connect(socket,SIGNAL(readyRead()),this,SLOT(timer_data_recieve()));
qDebug()<<"new connection";
qDebug()<<"server is reading..."<<socket->bytesAvailable();
qDebug()<<socket->readAll();
//time->start(1000); //QT timer started
if(!i)
timer();
i=1;
}
void MainWindow::timer()
{
timer_t t_id;
struct sigaction sa;
struct sigaction arg;
struct sigevent s_evnt;
struct itimerspec timer;
/* Establish handler for notification signal */
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = handler;
sigemptyset(&sa.sa_mask);
s_evnt.sigev_notify = SIGEV_SIGNAL;
s_evnt.sigev_signo = SIGRTMAX;
s_evnt.sigev_value.sival_ptr = &t_id;
if (sigaction(SIGRTMAX, &sa,NULL) == -1)
{
perror("sigaction");
}
//==============timer vlaues==============
timer.it_value.tv_sec=0;
timer.it_value.tv_nsec=20000000;
timer.it_interval.tv_sec=0;
timer.it_interval.tv_nsec=20000000;
if(timer_create(CLOCK_REALTIME,&s_evnt,&t_id)==-1);
perror("timer create");
if(timer_settime(t_id,0,&timer,NULL)==-1)
perror("timer_set_time");
}
void MainWindow::config()
{
//time=new QTimer(this);
server=new QTcpServer(this);
socket=new QTcpSocket(this);
connect(server,SIGNAL(newConnection()),this,SLOT(newconnection()));
// connect(time,SIGNAL(timeout()),this,SLOT(timer_data_sending()));
if(server->listen(QHostAddress::LocalHost,600))
{
qDebug()<<"server started";
}
else
qDebug()<<"server not started";
qDebug()<<MainWindow::server->errorString();
}
static void handler(int sig, siginfo_t *si, void *uc)
{
// MainWindow w;
qDebug("in handler");
// MainWindow *s = static_cast<MainWindow*>(&w);
static char first_call=1;
static unsigned sec;
static long nsec;
struct timespec start;
struct timespec curr;
if (first_call) {
first_call = 0;
if (clock_gettime(CLOCK_MONOTONIC, &start) == -1)
perror("clock_gettime");
}
if (clock_gettime(CLOCK_MONOTONIC, &curr) == -1)
perror("clock_gettime");
sec = (curr.tv_sec - start.tv_sec);
nsec = (curr.tv_nsec - start.tv_nsec);
if (nsec < 0)
{
sec--;
nsec += 1000000000;
}
start = curr;
}
"main.cpp"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
w.config();
return a.exec();
}
here evrything is working fine about handler.
but if want to access the handler data to socket to send to client,one way is to declare socket is global.but how to decalre globally to access in mainwindow member functions and as well as in handler?
please suggest me.it is very important to me .please don't avoid it.
NOTE:qtimer is not neded here
You can use Singletone Design Pattern architecture for your TCP Socket class. You need to create class that extends QTcpSocket. So you will create only one object and access the same globally using get_instance() method, as it is public static in this design pattern. You can go through Singleton design pattern
The documentation contains a good example about how to implement a Singleton and export it from C++ to QML.

Qt two or multiple same signals calling slot only once

I'm sending two (or more) same signals, which receives one slot, but it is only called once instead of two times.. What I'm doing wrong?
main.cpp:
#include <QCoreApplication>
#include "app.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
App app;
QMetaObject::invokeMethod(&app, "run", Qt::QueuedConnection);
return a.exec();
}
app.h:
#ifndef APP_H
#define APP_H
#include <QObject>
#include "tcpserver.h"
#include "tcpsocket.h"
class App : public QObject
{
Q_OBJECT
public:
explicit App(QObject *parent = 0);
signals:
public slots:
void run()
{
qDebug() << "run()";
server.server_start(1111);
socket.connectToHost("127.0.0.1", 1111);
socket.write("hello", 5);
socket.write("olleh", 5); // should execute slot two times.
}
private:
TcpServer server;
TcpSocket socket;
};
#endif // APP_H
TcpSocket.h:
#ifndef TCPSOCKET_H
#define TCPSOCKET_H
#include <QTcpSocket>
class TcpSocket : public QTcpSocket
{
Q_OBJECT
public:
explicit TcpSocket(QObject *parent = 0);
signals:
void dataReady(QByteArray data);
public slots:
void readyRead()
{
qDebug() << "Bytes available:" << this.bytesAvailable(); // called only once.
data = this.readAll(); // just for testing.
emit dataReady(data); //
}
void disconnected();
private:
QByteArray data;
};
#endif // TCPSOCKET_H
as you can see, I'm doing two socket.write functions, which should be handled two readyRead slots, but it is called only once. I honestly don't understand what I'm doing wrong.
Regards.

Connecting signals and slots in a QTextEdit subclass?

I derived a class from QTextEdit and use it as a "logbook". I equipped it with a slot to receive log-messages.
class CLogbook : public QTextEdit
{
Q_OBJECT;
public:
void log(QString msg) {append(msg)};
public slots:
void recvLogSignal(const QString message)
{
append("hallo");
std::cout << "signal received.\n";
log(message);
}
};
another class then emits a signal like this:
// in the header
signals:
void logMessage(const QString);
// in the implementation
emit logMessage("qt is cute");
std::cout << "if you can read this the logMessage was emitted\n";
and also i connect the signal to the slot
connect(tableeditor, SIGNAL(logMessage(const QString)), logbook, SLOT(recvLogSignal(const QString)));
However the message is never shown in the "logbook". What am i missing here?
SOLVED: The connect method was called after emitting the signal :-(
It is hard to see exactly what is wrong with your implementation without a full example. Sometimes signals or slots will fail if an object goes out of scope if it isn't initialized on the heap.
Another way that it could fail is if your QApplication hasn't reached the exec() call.
I haven't experimented with using const in signal and slot calls, and I haven't seen it in any examples before, so that could be causing the problem; but it seems to work fine in the example below.
Working Example With a Derived Class of QTextEdit
Here is a simple example I put together that does some basic logging with a push button and a line edit.
Here is the header:
#ifndef WIDGET_H
#define WIDGET_H
#include <QtGui/QWidget>
//#include <QTextEdit>
#include "clogbook.h"
#include <QLineEdit>
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = 0);
~Widget() {}
public slots:
void on_pushButton();
void on_lineEditReturn();
private:
CLogBook * text_edit_log;
QLineEdit * line_edit;
};
#endif // WIDGET_H
Here is the source:
#include "widget.h"
#include <QBoxLayout>
#include <QPushButton>
#include <QTimer>
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
QBoxLayout * box_layout = new QBoxLayout(QBoxLayout::TopToBottom);
text_edit_log = new CLogBook;
line_edit = new QLineEdit("Type Here and press Enter.");
QPushButton * push_button = new QPushButton("Click to Add To Log");
text_edit_log->setText("My Log Book");
box_layout->addWidget(text_edit_log);
box_layout->addWidget(line_edit);
box_layout->addWidget(push_button);
this->setLayout(box_layout);
QObject::connect(push_button, SIGNAL(clicked()), this, SLOT(on_pushButton()));
QObject::connect(line_edit, SIGNAL(returnPressed()), this, SLOT(on_lineEditReturn()));
}
void Widget::on_pushButton()
{
// text_edit_log->append("Push Button Logging Test");
text_edit_log->recvLogSignal("Push button test.");
}
void Widget::on_lineEditReturn()
{
// text_edit_log->append(line_edit->text());
text_edit_log->recvLogSignal(QString("LineEdit: ") + line_edit->text() );
line_edit->clear();
}
And here is the main:
#include <QtGui/QApplication>
#include "widget.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
And here is the CLogBook class:
#ifndef CLOGBOOK_H
#define CLOGBOOK_H
#include <QTextEdit>
#include <iostream>
class CLogBook : public QTextEdit
{
Q_OBJECT
public:
explicit CLogBook(QWidget *parent = 0) : QTextEdit(parent) { }
void log (QString msg) { append(msg); }
public slots:
void recvLogSignal(const QString message)
{
append("hallo");
std::cout << "signal received.\n" << std::endl;
log(message);
}
};
#endif // CLOGBOOK_H

Resources