QThread wątek nie startuje.

0

Witam.

Mam pewien problem, z wystartowaniem wątku w slocie od przerwania po timeout() od QTimer. Co zabawne kod na linuxie działa, a windows się wypiął na mnie. Pozwolę sobie na skróty kodu, ale mam nadzieje, że wszystko będzie zrozumiałe.

Kod z linuxa jest identyczny, jeśli chodzi o sam mechanizm slotów i sygnałów.
W konstruktorze indywidualnej klasy

thread = new QThread(this);
    timer = new QTimer();
    timer->moveToThread(thread);
    
    QObject::connect(timer , SIGNAL(timeout()) ,this ,  SLOT(SLOT_to()) , Qt::DirectConnection);
    QObject::connect(thread , SIGNAL(started()) , timer  , SLOT(start()));
    QObject::connect(thread, SIGNAL(finished()) , timer, SLOT(stop()));

wątek się uruchamia (sprawdzilem adresy przy pomocy QThread::currentthread();), ale sypie bugami

QObject::connect: Cannot queue arguments of type 'QTextBlock'
(Make sure 'QTextBlock' is registered using qRegisterMetaType().)
QObject::connect: Cannot queue arguments of type 'QTextCursor'
(Make sure 'QTextCursor' is registered using qRegisterMetaType().)
QObject::connect: Cannot queue arguments of type 'QVector<int>'
(Make sure 'QVector<int>' is registered using qRegisterMetaType().)
QObject::connect: Cannot queue arguments of type 'QVector<int>'
(Make sure 'QVector<int>' is registered using qRegisterMetaType().)
QObject::connect: Cannot queue arguments of type 'QVector<int>'
(Make sure 'QVector<int>' is registered using qRegisterMetaType().)
QObject::connect: Cannot queue arguments of type 'QVector<int>'
(Make sure 'QVector<int>' is registered using qRegisterMetaType().)
QObject::connect: Cannot queue arguments of type 'QVector<int>'
(Make sure 'QVector<int>' is registered using qRegisterMetaType().)

Dodam, że bez użycia Qt::DirectConnection, wątek się nie uruchamia, z użyciem QueuedConnection również echo. Jakieś sugestie ?

1

"QObject::connect: Cannot queue arguments of type 'QTextBlock'" znaczy, że gdzieś masz sygnał i slot które operują na QTextBlock na QTextCursor i na dodatek są przekazywane przez even loop-a (QueadConnection albo między wątkami z domyślnym połączeniem).
Po pierwsz dziwne są te sygnały i sloty, po drugie nie pokzujesz kodu z tym związanego, po trzecie by to zadziało, musisz zarejestrować te typy.

FanQT napisał(a):

Dodam, że bez użycia Qt::DirectConnection, wątek się nie uruchamia, z użyciem QueuedConnection również echo. Jakieś sugestie ?

To zależy co zrobiłęś w SLOT_to(). Nigdzie nie widzę, gdzie startujesz wątek (nawet nie widać połączenia z thread->start()).

0

Przebudowałem kod. Watek startuje, aplikacja działa jak chce.

W klasie MainWindow w jakimś slocie

comthread = new QThread(this);
    comconfigure = new COM_Configure(name);
    comconfigure->moveToThread(comthread);
    comthread->start();


    QObject::connect(this , SIGNAL(SIGNAL_to_COM()) ,comconfigure , SLOT(SLOT_SendData()) , Qt::QueuedConnection);
    QObject::connect(this , SIGNAL(SIGNAL_ReciveData()), comconfigure , SLOT(SLOT_to()), Qt::QueuedConnection);
    QObject::connect(this , SIGNAL(SIGNAL_ReciveName(QString)), comconfigure , SLOT(SLOT_ReciveName(QString)), Qt::QueuedConnection);
    QObject::connect(this , SIGNAL(SIGNAL_ReciveVoltage()) , comconfigure , SLOT(SLOT_ReciveVoltage()), Qt::QueuedConnection); 

w klasie com configure w konstruktorze oprócz szeregu funkcji które konfigurują port (baud, prędkość itd) znajduje się

 QObject::connect(this , SIGNAL(readyRead()) , this , SLOT(SLOT_ReciveData()) , Qt::DirectConnection);

void COM_Configure::SLOT_ReciveData() 
{

    receive.append(this->readLine());

}

// slot któremu zlecam przetwarzanie odebranych danych

void COM_Configure::SLOT_to()
{


    Okno_GL::ObjectMain()->MessageToLog("Odbieranie danych");
   
    if(receive.size() != 0 )
    {
        qd "Odebrano " << receive.size();
        qd" sprawdzam CRC" ;
        char intoCRC = CRC ;
        for(int i = 0 ; i < receive.size()-1 ; i ++)
        {
            qd "bajt" << i << (unsigned char)receive[i];
            intoCRC ^= receive[i];
        }
        if(intoCRC == receive[receive.size()-1])
        {
            //MessageToLog to slot w mainwindow który przekierowuje dane do slotu od QTextEdit::setText(); podejrzewam, że to to wywołuje bugi
            qd "Crc zgadza sie" ;
            Okno_GL::ObjectMain()->MessageToLog("Dane poprawnie odebrane"); // prawdopodobnie te funkcje wywoluja te bugi
            Okno_GL::ObjectMain()->MessageToLog("Transfer danych do programu"); // mainwindow typu singelton Okno_GL::ObjectMain() to funkcja zwracajaca wskaźnik do okna
            Okno_GL::ObjectMain()->SendDataToFacade(receive);
            receive.clear();
            flagReady = true;



        }
        else
        {
            qd "blad CRC" ;
            Okno_GL::ObjectMain()->MessageToLog("Blad CRC. Sprubój ponownie.");
            qd "receive" << receive;

            flagReady = true;
            receive.clear();
        }

Odbiór danych odbywa się w slocie w MainWindow

SIGNAL_to_COM();
    QThread::msleep(1000);
    SIGNAL_ReciveData();

i na koniec bugi

QObject::connect: Cannot queue arguments of type 'QTextBlock'
(Make sure 'QTextBlock' is registered using qRegisterMetaType().)
QObject::connect: Cannot queue arguments of type 'QTextCursor'
(Make sure 'QTextCursor' is registered using qRegisterMetaType().)
QObject::connect: Cannot queue arguments of type 'QVector<int>'
(Make sure 'QVector<int>' is registered using qRegisterMetaType().)
QObject::connect: Cannot queue arguments of type 'QVector<int>'
(Make sure 'QVector<int>' is registered using qRegisterMetaType().)
QObject::connect: Cannot queue arguments of type 'QVector<int>'
(Make sure 'QVector<int>' is registered using qRegisterMetaType().)
QObject::connect: Cannot queue arguments of type 'QVector<int>'
(Make sure 'QVector<int>' is registered using qRegisterMetaType().)
QObject::connect: Cannot queue arguments of type 'QVector<int>'
(Make sure 'QVector<int>' is registered using qRegisterMetaType().)

Jak rozwiązać problem z tymi bugami, czyli jak zarejestrować ? Takie komunikaty nie wyskakiwały gdy klasa pracowała w tym samym wątku co mainwindow.

Zlikwidowałem bugi, ale za Boga nie wiem o co w tym chodzi. Wystarczy dodać:

 qRegisterMetaType<QVector<int> >("myarray");
    qRegisterMetaType<QTextCursor> ("QTextCursor");
    qRegisterMetaType<QTextBlock> ("QTextBlock");

1 użytkowników online, w tym zalogowanych: 0, gości: 1