How to make signal/slot in a nude main func



  • Thank you very much! I have sloved the problem. I can create a new thread by c++11 thread but QThread. In the entrance of the new thread, QCoreApplication must be called, and a.exec() could be at the end of the entrance function.

    NUDE MAIN FUNCTION, which means there is no QApplication a, no return a.exec() in the main function.
    However, I derive a class named Client from QThread, in the Client::run(), I write this:

    void Client::run() {
        QEventLoop el;
        //something for business
        el.exec();
    }
    

    I want use the signal and slot in the new thread Client, but the console warned:
    QEventLoop: Cannot be used without QApplication
    What I can do for using singal/slot in a nude main func?


  • Lifetime Qt Champion

    Hi,

    Well, you need a QApplication or at least a QCoreApplication. You don't need to call exec from it but you still need at least one of them to have the internals of Qt setup properly.



  • @SGaist Thank you very much! But there is another question:I can't slot a function with emitting QTcpSocket::connected
    here is my code:

    class Client : public QThread {
    \\ ......
    }
    int main() {
    	qDebug() << QThread::currentThreadId() << QThread::currentThread() << __FUNCTION__ << endl;
    	int i = 1;
    	QCoreApplication a(i, nullptr);
    	Client *client = new Client;
    	client->start();
    	while (true) {
    		QThread::sleep(3600);
    	}
    }
    
    void Client::slot_connected() {
    	qDebug() << QThread::currentThreadId() << QThread::currentThread() << __FUNCTION__ << endl;
    }
    
    void Client::run() {
    	qDebug() << QThread::currentThreadId() << QThread::currentThread() << __FUNCTION__ << endl;
    	QTcpSocket *tcpsocket = new QTcpSocket;
    	connect(tcpsocket, static_cast<void(QAbstractSocket::*)(QAbstractSocket::SocketError)>(&QAbstractSocket::error), this, &Client::displayError, Qt::DirectConnection);
    	connect(tcpsocket, &QTcpSocket::connected, this, &Client::slot_connected);
    	tcpsocket->connectToHost("127.0.0.1", 7501);
    }
    

    It is cofirmed that the program server7501 was listenning and get the newConnection. But the function Client::slot_connected didn't happen


  • Lifetime Qt Champion

    Can you explain why you are using an infinite loop that makes your application sleep rather that Qt's event loop ?



  • a call to QEventLoop::exec() (or QCoreApplication::exec()) is necessary to make slots across threads working



  • @SGaist There was a mfc application, as we known, which main function is not like QCoreApplication a, return a.exec(). I want to create a shared library for that mfc application. Furthermore, the shared library need tcpsocket and singal/slot.
    Actually, the code above is a daemon for the shared library.



  • @VRonin Thank you very much! This is the code modified.

    void Client::run() {
    	qDebug() << QThread::currentThreadId() << QThread::currentThread() << __FUNCTION__ << endl;
    	QEventLoop el;
    	QTcpSocket *tcpsocket = new QTcpSocket;
    	connect(tcpsocket, static_cast<void(QAbstractSocket::*)(QAbstractSocket::SocketError)>(&QAbstractSocket::error), this, &Client::displayError, Qt::DirectConnection);
    	connect(tcpsocket, &QTcpSocket::connected, this, &Client::slot_connected);
    	tcpsocket->connectToHost("127.0.0.1", 7501);
    	el.exec();
    }
    

    But the slot function Client::slot_connected didn't happen either.
    Could you write some code for me?


  • Moderators

    @suclida said in How to make signal/slot in a nude main func:

    Could you write some code for me

    That's not how it should be.

    You should check the return value of connect() to be sure it was successful. Then check whether there was an error: you already connected error() signal.



  • @jsulm Thank you for your suggestion.

    QMetaObject::Connection connectRes = connect(tcpsocket, static_cast<void(QAbstractSocket::*)(QAbstractSocket::SocketError)>(&QAbstractSocket::error), this, &Client::displayError, Qt::DirectConnection);
    	qDebug() << connectRes << endl;
    	connectRes = connect(tcpsocket, &QTcpSocket::connected, this, &Client::slot_connected);
    	qDebug() << connectRes << endl;
    

    The QMetaObject::Connection are true, both.



  • The problem is not in Client but in your main. while (true) will prevent all signals emitted from the main thread to reach other threads.

    Both MFC and Qt require an event loop to work correctly. if you want a signal/slot system independent of the underlying event loop I suggest you take a look at Boost.Signals2



  • @VRonin Thank you!
    You mean that the problem is in the main. But the main function couldn't call the event loop, because the main fuction has its loop and we can't cost too much time in the main thread. So I have to call the event loop in a new thread.
    Further more, as you know , the tcpsokcet is born in the new thread(in the function Client::run()). Did you mean that the singal QTcpSocket::connected is emitted at the main thread although tcpsocket is born in a new thread?
    And I have create the eventloop in the Client::run(), Why was not the Client::slot_connected called?


  • Lifetime Qt Champion

    Why the QEventLoop ? QThread already has everything needed. Just call exec().

    How do you know that it's not called ?
    Do you have any explicit error ?
    Are you sure the socket gets connected ?


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.