QThread wątek nie startuje.

QThread wątek nie startuje.
FQ
  • Rejestracja:ponad 10 lat
  • Ostatnio:ponad 9 lat
  • Postów:59
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

Kopiuj
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

Kopiuj
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 ?

edytowany 2x, ostatnio: FanQT
MarekR22
Moderator C/C++
  • Rejestracja:ponad 17 lat
  • Ostatnio:37 minut
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()).


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
edytowany 1x, ostatnio: MarekR22
FQ
  • Rejestracja:ponad 10 lat
  • Ostatnio:ponad 9 lat
  • Postów:59
0

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

W klasie MainWindow w jakimś slocie

Kopiuj
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ę

Kopiuj
 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

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

i na koniec bugi

Kopiuj
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ć:

Kopiuj
 qRegisterMetaType<QVector<int> >("myarray");
    qRegisterMetaType<QTextCursor> ("QTextCursor");
    qRegisterMetaType<QTextBlock> ("QTextBlock");
edytowany 3x, ostatnio: FanQT

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.