crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> QSerialPort & Qthread
gvenihvivar
  опции профиля:
сообщение 12.2.2014, 15:39
Сообщение #1


Студент
*

Группа: Участник
Сообщений: 36
Регистрация: 6.11.2013
Пользователь №: 3967

Спасибо сказали: 0 раз(а)




Репутация:   0  


Пытаюсь вынести запрос по сом порту в отдельный поток. Использую для этого код из примера к библиотеке QSerialPort "master". Связь сигнал-слот и таймер в стартовом методе обрабатывает, когда доходить до инициализации порта ругается

QObject: Cannot create children for a parent that is in a different thread.
(Parent is QSerialPort(0x23fe30), parent's thread is QThread(0x35b48), current thread is QThread(0x23fe60)


В поток выношу следующим способом:
int main(int argc, char* argv[])
{
    QApplication a(argc, argv);
....
    QThread thread1;
    ComThread2 ct; // класс с сом портом

    QObject::connect(&thread1,SIGNAL(started()),&ct,SLOT(run()));
//    QObject::connect(&text1,SIGNAL(finished()),&thread1,SLOT(terminate()));

    ct.moveToThread(&thread1);
    thread1.start();
    return a.exec();
}


Вначале проверяла сам механизм переноса в другой поток, он работает. Проверяла на счетчике и таймере.

Подскажите, пожалуйста, почему он не переносит в дочерние методы в поток.
Вот код класса для другого потока:
header
Раскрывающийся текст
#ifndef COMTHREAD2_H
#define COMTHREAD2_H

#include <QObject>
#include <QCoreApplication>

#include <QTimer>
#include <QSerialPort>
#include <QVector>

#include "crc16cs.h"

class ComThread2 : public QObject
{
    Q_OBJECT
public:
    explicit ComThread2(QObject *parent = 0);
    
signals:
            void parse();
public slots:
            void sendRequest();
            void readResponse();
            void processTimeout();
            void run();
            QString formRequest();
            QString parseResponse(QString resp1);
            QVector <quint16> strToVector(QString string);
            void parseRes();
            void Init();

private:
            QSerialPort serial;
            QByteArray response;
            QTimer timer;
            //QTimer timerCOM;
            Crc16CS *crc16;
            QString fromRoc;

            void setControlsEnabled(bool enable);
            void processError(const QString &error);
  };

#endif // COMTHREAD2_H


cpp
Раскрывающийся текст
#include "comthread2.h"
#include <QtSerialPort/QSerialPortInfo>
#include <QtSql>
#include <qmath.h>
#include <QDateTime>
#include "qdatabase.h"

ComThread2::ComThread2(QObject *parent) :
    QObject(parent)
{

}
void ComThread2::sendRequest()
{
    if (serial.portName() != "COM2") {
        serial.close();
        serial.setPortName("COM2");

        if (!serial.open(QIODevice::ReadWrite)) {
            processError(tr("Can't open %1, error code %2")
                         .arg(serial.portName()).arg(serial.error()));
            return;
        }

        if (!serial.setBaudRate(QSerialPort::Baud9600)) {
            processError(tr("Can't set rate 9600 baud to port %1, error code %2")
                         .arg(serial.portName()).arg(serial.error()));
            return;
        }

        if (!serial.setDataBits(QSerialPort::Data8)) {
            processError(tr("Can't set 8 data bits to port %1, error code %2")
                         .arg(serial.portName()).arg(serial.error()));
            return;
        }

        if (!serial.setParity(QSerialPort::NoParity)) {
            processError(tr("Can't set no parity to port %1, error code %2")
                         .arg(serial.portName()).arg(serial.error()));
            return;
        }

        if (!serial.setStopBits(QSerialPort::OneStop)) {
            processError(tr("Can't set 1 stop bit to port %1, error code %2")
                         .arg(serial.portName()).arg(serial.error()));
            return;
        }

        if (!serial.setFlowControl(QSerialPort::NoFlowControl)) {
            processError(tr("Can't set no flow control to port %1, error code %2")
                         .arg(serial.portName()).arg(serial.error()));
            return;
        }
    }

    setControlsEnabled(false);
//    statusLabel->setText(tr("Status: Running, connected to port %1.")
//                         .arg(serialPortComboBox->currentText()));

//    requestLineEdit->setText(formRequest());
//    QTimer *timer = new QTimer(this);

//    timer->setSingleShot(true);

//    connect(timer, SIGNAL(timeout()),
//            this, SLOT(processTimeout()));



    QString req ("fofo");
    serial.write(req.toLocal8Bit());
    timer.start(100);

}
void ComThread2::readResponse()
{
    response.append(serial.readAll());
    emit parse();
}

void ComThread2::processTimeout()
{
    setControlsEnabled(true);
//    trafficLabel->setText(tr("Traffic, transaction #%1:"
//                             "\n\r-request: %2"
//                             "\n\r-response: %3")
//                          .arg(++transactionCount).arg(requestLineEdit->text()).arg(QString(response)));
    response.clear();
}



void ComThread2::processError(const QString &error)
{
    setControlsEnabled(true);
//    statusLabel->setText(tr("Status: Not running, %1.").arg(error));
//    trafficLabel->setText(tr("No traffic."));
}

void ComThread2::setControlsEnabled(bool enable)
{
//    runButton->setEnabled(enable);
//    serialPortComboBox->setEnabled(enable);
//    waitResponseSpinBox->setEnabled(enable);
//    requestLineEdit->setEnabled(enable);
}

QString ComThread2::formRequest()
{

    crc16 = new Crc16CS();
    QString req1 ("");
    QString roc2 ("0201");
    QString roc1 ("0101");
    QString comp ("0301");
    QString opcode ("0A");
    QString rdata ("00000B");
    if ((rdata.size()/2%2 != 0) )
    {
        req1 = roc1 + comp + opcode + "0" + QString::number(rdata.size()/2,16) + rdata;
    }
    if (rdata.size()/2%2 == 0)
    {
        req1 = roc1 + comp + opcode + QString::number(rdata.size()/2,16) + rdata;
    }

    req1 = req1 + crc16->ComputeChecksumBytes(strToVector(req1));

    return req1;
}

QString ComThread2::parseResponse(QString resp1)
{
    QVector <quint16> rqVector;


    resp1 = resp1.left(76);
    rqVector = strToVector(resp1); // str to vector

    QString cr6 = crc16->ComputeChecksumBytes(rqVector); // check ctc, if "0" it's ok


    QString ansStr ("");
    if ((cr6 == "00")&& resp1.size()>0 )
    {
    QString respFormat; // format of response
    /*
       float   4
       uint8   8
       uint16 16
       uint32 32
    */
    respFormat = "4  16  16  16  16  8  8  8  8  8  16  32";  // из базы данных
    QStringList respList = respFormat.split("  ", QString::SkipEmptyParts);
    int count(0);
    int pos (26);
    QStringList anwList;
    for (quint8 i=0; i< respList.size(); i++)
    {
        if (respList[i].toInt()!=4)
        {
            count = respList[i].toInt()/4;
            anwList.append(resp1.mid(pos,count));
            pos = pos+count;
        }
        if (respList[i].toInt()==4)
        {
            anwList.append(resp1.mid(pos,8));
            pos=pos+8;

        }
    }
bool ok;

        for( quint8 i=0; i <anwList.size(); i++)
        {
            if (respList[i].toInt()==4) // for parse float
            {
                QString resp (anwList[i]);
                QByteArray flarray;
                flarray.append(resp.at(6));
                flarray.append(resp.at(7));
                flarray.append(resp.at(4));
                flarray.append(resp.at(5));
                flarray.append(resp.at(2));
                flarray.append(resp.at(3));
                flarray.append(resp.at(0));
                flarray.append(resp.at(1));

                QString P ("");
                bool ok;
                int sign = 1;
                flarray.toLongLong(&ok,16);

                flarray = QByteArray::number(flarray.toLongLong(&ok,16),2);
                if(flarray.length()==32) {
                    if(flarray.at(0)=='1')  {sign =-1;}                       // if bit 0 is 1 number is negative
                    flarray.remove(0,1);                                     // remove sign bit
                }

                QByteArray fraction =flarray.right(23);   //get the fractional part
                double mantissa = 0;
                for(int i=0;i<fraction.length();i++)     // iterate through the array to claculate the fraction as a decimal.
                {  if(fraction.at(i)=='1')    { mantissa += 1.0/(pow(2,i+1));}}
                int exponent = flarray.left(flarray.length()-23).toLongLong(&ok,2)-127;     //claculate the exponent
                P = QString::number( sign*pow(2,exponent)*(mantissa+1.0),'f', 7 );
                ansStr = ansStr + P + "  ";
            }

            if (respList[i].toInt()==8) // for parse uint8
            {
                ansStr = ansStr + QString::number(anwList[i].toInt(&ok,16))
                        + "  ";
            }
            if (respList[i].toInt()==16) // for parse uint16
            {
                QString s =anwList[i].right(2)+anwList[i].left(2);

                ansStr = ansStr + QString::number(s.toInt(&ok,16))
                        + "  ";
            }
            if (respList[i].toInt()==32) // for parse uint32
            {
                QString s = anwList[i].mid(6,2)+anwList[i].mid(4,2)+
                        anwList[i].mid(2,2)+anwList[i].mid(0,2);

                ansStr = ansStr + QString::number(s.toInt(&ok,16))
                        + "  ";
            }
        }

    }

    return ansStr;
}

QVector<quint16> ComThread2::strToVector(QString string)
{
    bool ok;
    QVector<quint16> rqVector;
    for(int i=0; i < string.size(); i++)
    {
        QString resp2 = string.mid(i,2);
        rqVector.append(resp2.toInt(&ok,16)); // zanosim v vektor
        i++;
    }
    return rqVector;
}
void ComThread2::parseRes()
{
    QString res ("");
    res = response;
    if (res.size()!=0)
    {

        QStringList dataList = parseResponse(res).split("  ", QString::SkipEmptyParts);
        float P1 = (dataList[1].toFloat())/1000;
        float Q1 = (dataList[2].toFloat())/1000;
        float Ro1 =(dataList[3].toFloat())/10;
        float T1 = (dataList[4].toFloat())/1000;
        QDateTime dt;
        dt = QDateTime::fromMSecsSinceEpoch(dataList[11].toLongLong()*1000);

        QDataBase bb1;
        bb1.UpdateDb(dt.date(), dt.time().addSecs(2), 1, Q1, Ro1, P1, T1);
              bb1.UpdateDb(dt.date(), dt.time().addSecs(2), 2, Q1, Ro1, P1, T1);
    }
}

void ComThread2::Init()
{
    QTimer *timerCOM = new QTimer(this);
    connect(timerCOM, SIGNAL(timeout()),
            this, SLOT(sendRequest()));
    timerCOM->start(300);

    timer.setSingleShot(true);

    connect(&serial, SIGNAL(readyRead()),
            this, SLOT(readResponse()));
    connect(&timer, SIGNAL(timeout()),
            this, SLOT(processTimeout()));
    connect(this , SIGNAL(parse()),
            this, SLOT(parseRes()));
}

void ComThread2::run()
{
    Init();
}


Падает на строках
if (!serial.open(QIODevice::ReadWrite)) {
            processError(tr("Can't open %1, error code %2")
                         .arg(serial.portName()).arg(serial.error()));
            return;
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
gvenihvivar
  опции профиля:
сообщение 5.3.2014, 15:38
Сообщение #2


Студент
*

Группа: Участник
Сообщений: 36
Регистрация: 6.11.2013
Пользователь №: 3967

Спасибо сказали: 0 раз(а)




Репутация:   0  


Поработав над этим, пришла к выводу, что вопрос был глупым )

Приложение падало потому, что некоторый объекты создавались до переноса в поток и там работали не корректно. Вроде так.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 28.3.2024, 22:29