Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

[Solved] QCoreApplication::sendPostedEvents: Cannot send posted events for objects in another thread ??????



  • Dear Forumers, I got unexpected message from my UI I wrote for control some third party equipment.
    Unfortunately the code has a lot of lines and it is useless to put it here and I cann't to shrink one. I think it would be better to discribe the codes briefly. I have main thread and 2 threads to read of and to write into equipment controller (these 2 threads do nothing exept sending and getting messages for main thread). In main thread I use the QInputDialog and need the QComboBox. I prepared the QStringList and issued the command:
    @dialog01 -> setComboBoxItems( this -> QComboBoxlist_dialog01 ); @

    and got the message in topic title. I only read the messages, prepared the QComboBoxlist_dialog01. The UI continues to work so as if nothing happend. How to find the cause of message ? Any hint are welcomed. Thank very much everybody in advance for help.


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    Are you trying to access your widgets from your threads ?



  • Hi, SGaist, thank you for quick reply. I read that one of the message cause could be the try to use GUI at main thread from another threads and I can say that the auxiliary thread I am using only to read from and write to interface (by normal "emit" the signals from the receiving thread about the message read and from the main thread about the message ready to send). That's all. That's why I cann't figure out the cause. And what is worse I even cann't figure out how to go further ...
    UI is working and I could tolerate this message but I don't like if something behaviour is unclear to me. The message came almost at the begining. I initiate my GUI (couple QInputDialogs, QTableWidget, menus and 3 labels) then I collect info about existing devices at interface and try to fill the QComboBox of one of dialogues and at this moment I got message. Where this event has been posted and why part of my code did it I don't know... Thank you once more for your help. Hope to get hint what I has to do futher.
    By the way I tryed to use @QCoreApplication::flush ()@ - didn't work.


  • Lifetime Qt Champion

    Can you show your thread code ?



  • No problem (exept size of codes, the limit is 6000 characters). Could you please give me a hint how to send codes in this case ?
    Here 1 piece (Getting thread cpp):
    //ObjectGetting.cpp
    @
    #include "ObjectGetting.h"
    #include <QDir>
    #include "MyThread.h"

    ObjectGetting::ObjectGetting(QObject* parent) :
    QObject( parent ),
    MessageGettingCount(0),
    socket_read(0),
    received_frame(new can_frame),
    worker(NULL),
    running(true),
    CAN_interface_name("any"),
    CAN_modl_Id(-1)

    {
    // constructor:
    // qDebug() << "constructor: start";
    // qDebug() << "constructor: end";

    }

    /=============================================================================/
    void ObjectGetting::bind_Getting_can_interface_any() {
    //do something: bind can interface for reading (B),
    #ifdef __debug_ObjectGetting
    qDebug() << "ObjectGetting::bind_Getting_can_interface_any()"
    << "^^^^^^^^^^^^^^^^^^^^^^^^" << endl;
    #endif// __debug_ObjectGetting
    openSocketCan( "any" );
    emit dispatchCanSocketOpened( socket_read );
    SleepThread::sleep(0.1);
    #ifdef __debug_ObjectGetting
    qDebug() << "ObjectGetting::bind_Getting_can_interface_any: "
    << " Start readAnyBoundCan and emit canMessageReceived " << endl;
    #endif// __debug_ObjectGetting

    while (running) {

    readAnyBoundCan();// read CAN interface "any";
    

    #ifdef __debug_ObjectGetting
    qDebug() << "ObjectGetting::do_bind_can_interface_Getting_any: "
    << " CAN_interface_name = " << CAN_interface_name
    << " CAN_modl_Id = " << CAN_modl_Id;
    #endif// __debug_ObjectGetting
    emit canMessageReceived( CAN_interface_name, received_frame );
    }
    }

    /=============================================================================/
    void ObjectGetting::InitProcessGetting() {

    worker = new QThread;
    connect(
    worker, SIGNAL( started() ),
    this, SLOT ( bind_Getting_can_interface_any() ));
    this -> moveToThread(worker);
    worker -> start();
    #ifdef __debug_ObjectGetting
    qDebug() << " ObjectGetting::InitProcessGetting(): worker starts "
    << " ^^^^^^^^^^^^^^^^^^^^^^^^^^" << endl;
    #endif// __debug_ObjectGetting

    }

    /=============================================================================/
    int ObjectGetting::openSocketCan( QString CAN ) {

    socket_read = socket(PF_CAN, SOCK_RAW, CAN_RAW);
    if( socket_read < 0 ) {
    perror( "Error while opening socket" );
    return -1;
    }
    else fprintf(stdout, "open socket -> %d\n", socket_read);

    strcpy( ifreq_read.ifr_name, CAN.toStdString().c_str() );
    ioctl(socket_read, SIOCGIFINDEX, &ifreq_read);

    sockaddr_read.can_family = AF_CAN;
    if( CAN == "any" ) {
    // When the CAN interface is bound to 'any' existing CAN interface
    // (addr.can_ifindex = 0)
    sockaddr_read.can_ifindex = 0;
    }
    else {
    sockaddr_read.can_ifindex = ifreq_read.ifr_ifindex;
    }
    /*
    // To disable the reception of CAN frames on the selected CAN_RAW socket:
    setsockopt(socket_read, SOL_CAN_RAW, CAN_RAW_FILTER, NULL, 0);

    // struct can_filter rfilter[2];
    rfilter[0].can_id = 0x280;
    rfilter[0].can_mask = CAN_SFF_MASK;
    rfilter[1].can_id = 0x280;
    rfilter[1].can_mask = 0x1F8;
    setsockopt(socket_read, SOL_CAN_RAW, CAN_RAW_FILTER,
    &rfilter, sizeof(rfilter));
    */
    bind(socket_read, (struct sockaddr *)&sockaddr_read, sizeof(sockaddr_read));
    return 1;
    }

    /=============================================================================/
    void ObjectGetting::readAnyBoundCan() {
    //The CAN interface is bound to 'any' existing CAN interface
    #ifdef __debug_ObjectGetting
    fprintf( stdout,
    "Reading the CAN interface bounded to 'any' existing CAN : socket -> %d\n",
    socket_read );
    #endif// __debug_ObjectGetting

    socklen_t len = sizeof(sockaddr_read);
    int nbytes = recvfrom(socket_read, received_frame, sizeof(struct can_frame),
    0, (struct sockaddr*)&sockaddr_read, &len);
    if (nbytes < 0) {
    perror( "can raw socket recvfrom nbytes < 0" );
    return;
    }
    /* get interface name of the received CAN frame */
    ifreq_read.ifr_ifindex = sockaddr_read.can_ifindex;
    ioctl(socket_read, SIOCGIFNAME, &ifreq_read);

    // printf("Received a CAN frame from interface %s\n", ifreq_read.ifr_name);
    CAN_interface_name = ifreq_read.ifr_name;

    /* do something with the received CAN frame */
    CAN_modl_Id = ((received_frame -> can_id - 0x200) >> 3);

    #ifdef __debug_ObjectGetting
    fprint_canframe( &received_frame ); // with eol to STDOUT
    cout << endl;
    #endif// __debug_ObjectGetting
    return;
    }

    ////////////////////////////////////////////////////////////////////////////////
    void ObjectGetting::fprint_canframe(struct can_frame cf ) {
    QDebug debugMessage(QtDebugMsg);
    qDebug() << "canId = " << hex << cf -> can_id;
    debugMessage.nospace() << "
    ** received message: can1 "" << hex
    << cf -> can_id << "#";
    qDebug() << "can_dlc = " << dec << cf -> can_dlc;
    for (int n_data = 0; n_data < cf -> can_dlc; n_data++) {
    qDebug().nospace() << "data[" << n_data << "] = " << hex
    << cf -> data[n_data];
    if(n_data < (cf -> can_dlc) -1 )
    debugMessage << hex << cf -> data[n_data] << ".";
    else
    debugMessage << hex << cf -> data[n_data] << """;
    }

    }
    ////////////////////////////////////////////////////////////////////////////////
    // QString qsname = QDir::currentPath()+"/"+ settingsFILE;
    // qDebug() << "qsname -> " << qsname;

    @



  • 2d piece:

    //ObjectGetting.h
    @
    #ifndef OBJECTGETTING_H
    #define OBJECTGETTING_H

    #include <linux/can.h>
    #include <linux/can/raw.h>
    #include <net/if.h> /* struct ifreq */
    #include <sys/ioctl.h>

    #include <QThread>
    #include <QObject>
    #include <QStringList>
    #include <QSettings>
    #include <QDebug>

    class ObjectGetting : public QObject
    {
    Q_OBJECT

    public:
    

    explicit ObjectGetting(QObject *parent = 0);

    public slots:

    void bind_Getting_can_interface_any();

    signals:

    void canMessageReceived ( QString, struct can_frame * );
    void canMessageSettings ( QString, struct can_frame * );
    void dispatchCanSocketOpened( int );

    private:

    int MessageGettingCount;
    int socket_read;
    struct can_filter rfilter[2];
    struct sockaddr_can sockaddr_read;
    struct ifreq ifreq_read;
    int openSocketCan( QString CAN );
    struct can_frame *received_frame;
    void readAnyBoundCan();
    QThread *worker;

    public:

    void InitProcessGetting();
    bool running;

    QString CAN_interface_name; // any, can0, can1
    int CAN_modl_Id; // crate position of module (0-17)

    void SendLogOnOffConfirmation( int OnOffFlag);
    void fprint_canframe ( struct can_frame * );

    };
    #endif// OBJECTGETTING_H
    @



  • 3d piece
    //ObjectSending.h
    @#ifndef OBJECTSENDING_H
    #define OBJECTSENDING_H

    #include <linux/can.h>
    #include <linux/can/raw.h>
    #include <net/if.h> /* struct ifreq */
    #include <sys/ioctl.h>

    #include <QThread>
    #include <QObject>
    #include <QDebug>

    class ObjectSending : public QObject
    {
    Q_OBJECT

    public:
    

    explicit ObjectSending( QObject *parent = 0 );

    public slots:

    void SendingThreadStarted();
    void MessageSending ( QString, struct can_frame *);
    void receiveCanSocketOpened( int socket);

    private:

    int MessageSendingCount;
    int socket_send;
    struct sockaddr_can sockaddr_send;
    struct ifreq ifreq_send;
    void writeAnyBoundCan( QString CAN, struct can_frame *frame );
    QThread *worker;

    public:

    void InitProcessSending();
    };
    #endif// OBJECTSENDING_H
    //#define MAX_CANFRAME "12345678#01.23.45.67.89.AB.CD.EF"
    @



  • 4th piece
    //ObjectSending.cpp

    @#include "myWidget.h"
    #include <ObjectSending.h>
    #include "MyThread.h"

    ObjectSending::
    ObjectSending( QObject* parent ) :
    QObject( parent ), MessageSendingCount(0), worker(NULL)
    {
    // constructor:
    }

    /=============================================================================/
    void ObjectSending::
    InitProcessSending() {
    worker = new QThread;

    connect(worker, SIGNAL(started()), this, SLOT( SendingThreadStarted() ));

    this -> moveToThread(worker);

    worker->start();
    #ifdef __debug_ObjectSending
    qDebug() << " ObjectSending::InitProcessSending(): worker starts "
    << " ^^^^^^^^^^^^^^^^^^^^^^^^^^" << endl;
    #endif// __debug_ObjectSending
    }

    void ObjectSending::SendingThreadStarted() {
    #ifdef __debug_ObjectSending
    qDebug() << "ObjectSending::SendingThreadStarted()"
    << "^^^^^^^^^^^^^^^^^^^^^^^^" << endl;
    #endif// __debug_ObjectSending
    }
    /=============================================================================/
    void ObjectSending::
    MessageSending( QString CANID, struct can_frame *frame) {
    //write CAN interface, i.e. send message to CAN
    MessageSendingCount++;
    #ifdef __debug_ObjectSending
    qDebug() << "ObjectSending::MessageSending : MessageSendingCount="
    << MessageSendingCount << "SSSSSSSSSSSSSSSSSSSSSSS" << endl;
    #endif// __debug_ObjectSending
    writeAnyBoundCan( CANID, frame );
    #ifdef __debug_ObjectSending
    qDebug()
    << "ObjectSending::MessageSending : return SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS";
    #endif// __debug_ObjectSending
    }

    /=============================================================================/
    void ObjectSending::receiveCanSocketOpened( int socket) {
    #ifdef __debug_ObjectSending
    qDebug() << "ObjectSending::receiveCanSocketOpened: socket -> " << socket;
    #endif// __debug_ObjectSending
    socket_send = socket;

    };

    /=============================================================================/
    void ObjectSending::
    writeAnyBoundCan( QString CAN, struct can_frame *frame ) {
    //The CAN interface is bound to 'any' existing CAN interface
    // To write CAN frames on sockets bound to 'any' CAN interface
    //the outgoing interface has to be defined certainly.

    #ifdef __debug_ObjectSending

    fprintf(stdout,
    "the CAN interface bounded to 'any' existing CAN : CAN -> %s\n",
    CAN.toStdString().c_str());

    fprintf(stdout,
    "Writing the CAN interface bounded to 'any' existing CAN : socket -> %d\n",
    socket_send);

    #endif// __debug_ObjectSending

    strcpy( ifreq_send.ifr_name, CAN.toStdString().c_str() );

    ioctl(socket_send, SIOCGIFINDEX, &ifreq_send);

    sockaddr_send.can_ifindex = ifreq_send.ifr_ifindex;

    sockaddr_send.can_family = AF_CAN;

    int nbytes = sendto(socket_send, frame, sizeof(struct can_frame),
    0, (struct sockaddr*)&sockaddr_send, sizeof(sockaddr_can));

    if (nbytes < 0) {
    qDebug() << "Cann't write frame to CAN interface = "
    << CAN;
    perror("can raw socket sendto nbytes < 0");
    return;
    }

    return;
    }
    @



  • Here is connection I am using:

    @void myWidget::InitThreads_GettingAndSending() {
    OSending = new ObjectSending;
    OGetting = new ObjectGetting;

    connect(
    this, SIGNAL( sendCanMessage ( QString, struct can_frame * ) ),
    OSending, SLOT ( MessageSending ( QString, struct can_frame * ) ),
    Qt::DirectConnection );

    connect(
    OGetting, SIGNAL( canMessageReceived( QString , struct can_frame * ) ),
    this, SLOT ( receivedCanMessage( QString , struct can_frame * ) ),
    Qt::DirectConnection);

    connect(
    OGetting, SIGNAL( canMessageSettings ( QString, struct can_frame * ) ),
    OSending, SLOT ( MessageSending ( QString, struct can_frame * ) ),
    Qt::DirectConnection);

    connect(
    OGetting, SIGNAL( dispatchCanSocketOpened ( int ) ),
    OSending, SLOT ( receiveCanSocketOpened ( int ) ),
    Qt::DirectConnection);

    OSending -> InitProcessSending();
    OGetting -> InitProcessGetting();

    connect( timer, SIGNAL(timeout()), this, SLOT(RequestModuleState() ));
    }
    @


  • Moderators

    Hi,

    That's a lot of code! Please remove parts that aren't related to your code. Otherwise, it's hard for others to find your issue. (And sometimes, when you work on minimizing your code, you end up finding the solution yourself).

    Anyway, why are you specifying "Qt::DirectConnection" in your connections?



  • Hi, JKSH, thank you very much. I read once more documentaion on direct and queued connection and so on and removed this parameter from connect instruction as recommended. The message I was talking about dissaoeared. Fine. Thank you and SGaits for your time and help.
    I really appreciate it. I changed topic to Solved. Best regards and wishes to all of you.


  • Moderators

    Happy coding! :)


Log in to reply