Russian Qt Forum
Апрель 18, 2024, 23:44 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: QThread  (Прочитано 6843 раз)
Firefox
Гость
« : Январь 10, 2017, 17:19 »

Здравствуйте. Столкнулась с проблемой следующей: хочу запихать в поток класс, в котором есть указатель на другой класс. Пихать все функции в один класс не охота. Думаю есть другое решение, которое я не знаю. Схема у меня следующая
Код:
class A: public QObject
{
Q_OBJECT
public:
explicit  A(QObject *parent,int par1, int par2)
{
cl_B=new B();
connect(cl_B,SIGNAL(...),this,SLOT(...));
};
private:
B *cl_B;
};
class B
{
Q_OBJECT
....
};
class C: public QObject
{
Q_OBJECT
public:
explicit  C(QObject *parent,int par1, int par2)
{
tr=new QThread(this);
class1=new A(this,par1,par2);
class1->moveToThred(tr);
};
private:
QThread *tr;
A *class1;
}
В вывод выдается сообщение Cannot move QObjects with a parrent. Объясните, пожалуйста, как правильно надо.
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #1 : Январь 11, 2017, 08:54 »

1. Это точно полный код? Не вижу в нем проблемы, которая привела бы к выводу такого сообщения.
2. В конструкторе класса A задавай классу B парента this, иначе он не перенесется в поток.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Firefox
Гость
« Ответ #2 : Январь 11, 2017, 11:12 »

Приведу код своих классов подробно.
Код:
#ifndef TMK_BC_H
#define TMK_BC_H

#include <QObject>
#include <QSettings>
#include <QTimer>
#include <QDebug>
#include <QTime>

#include "my_tmk/ltmk.h"

class tmk_bc: public QObject
{
    Q_OBJECT
public:
    explicit tmk_bc();
    ~tmk_bc();

};

#endif // TMK_BC_H


//.cpp
#include "tmk_bc.h"

tmk_bc::tmk_bc()

{

}

tmk_bc::~tmk_bc()
{

}

Код:
#ifndef ADAPTER_TMK_H
#define ADAPTER_TMK_H

#include <QObject>
#include "tmk_bc.h"

class adapter_tmk : public QObject
{
    Q_OBJECT
public:
    explicit adapter_tmk(QObject *parent = 0,int par=0, int nTmk=0);

public slots:
    void process();

private:
    tmk_bc *fDrv;



   
};

#endif // ADAPTER_TMK_H
//.cpp
#include "adapter_tmk.h"

adapter_tmk::adapter_tmk(QObject *parent, int par, int nTmk) :
    QObject(parent)
{

    fDrv= new tmk_bc();

}

void adapter_tmk::process()
{
    qDebug()<<__FUNCTION__<<this;

}


Код:
#ifndef GN_PP_H
#define GN_PP_H

#include <QWidget>
#include <QObject>
#include <QDebug>
#include <QDateTime>
#include <QTextStream>
#include <QThread>
#include <QTextCodec>
#include <QFrame>
#include <QKeyEvent>
#include <QTextEdit>
#include <QLineEdit>
#include <QMessageBox>

#include "tmk_bc.h"
#include "my_tmk/adapter_tmk.h"

namespace Ui {
class Widget;
}

class Widget :
               public QWidget
{
    Q_OBJECT
   
public:
    explicit Widget(QWidget *parent = 0,int par=0);
    ~Widget();
private:
    Ui::Widget *ui;

    QThread *thread_bc1;

    adapter_tmk *controller1;

};

#endif
//.cpp
#include "gn_pp.h"
Widget::Widget(QWidget *parent, int par) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);


    thread_bc1= new QThread(this);
    controller1= new adapter_tmk(this,par,0);
    controller1->moveToThread(thread_bc1);

    connect(thread_bc1,SIGNAL(started()),controller1,SLOT(process()));

    //thread_bc1->start();

}

Widget::~Widget()
{
    delete ui;
    if(thread_bc1->isRunning())
        thread_bc1->terminate();

}

Посмотрите, пожалуйста.
« Последнее редактирование: Январь 11, 2017, 12:04 от Firefox » Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #3 : Январь 11, 2017, 11:19 »

Firefox, ты можешь минимальный компилябельный пример ошибки сделать? Вот реально, в твоём коде сейчас не хочется разбираться - много лишнего. Если приложишь пример без лишнего кода, я его скомпилю, поправлю и отвечу.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Firefox
Гость
« Ответ #4 : Январь 11, 2017, 12:07 »

исправила предыдущий код. Все собирается, только в дебаг валится сообщение на функции moveToThread()
QObject:moveToThread: Cannot move objects with a parent
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #5 : Январь 11, 2017, 12:12 »

    controller1= new adapter_tmk(nullptr,par,0);
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Firefox
Гость
« Ответ #6 : Январь 11, 2017, 12:28 »

Спасибо. Без парента работает я это поняла, немогли бы вы мне объяснить для понимания. У меня была еще одна программа и там класс с конструктором, в котором QWidget *parent, помещается в поток и проблем нет. А QObject *parent приводит к таким проблемам?
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #7 : Январь 11, 2017, 12:38 »

QWidget вообще должен быть подальше от потоков. Просто запомни - если хочешь мувать в поток, забудь про парентов.
« Последнее редактирование: Январь 11, 2017, 13:09 от Пантер » Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Firefox
Гость
« Ответ #8 : Январь 11, 2017, 12:40 »

Спасибо  Веселый
Записан
Firefox
Гость
« Ответ #9 : Январь 16, 2017, 16:00 »

Возник еще один вопрос. При старте потока в функции я инициализирую некоторые данные, а далее по нажатию на кнопку стартует функция, которая работает циклически. Но по отжатию кнопки функцию надо прервать. Я создала сигнал, который иметируется при нажатии на кнопку и при отжатии. В слоте из потока при нажатии на кнопку выводится флаг и запускается функция. Если же кнопку отжали то в этом же слоте флаг устанавливается в 0. Внутри функции проверяется флаг и если он не 1 то делается return. Но проблема в том, что если функция уже запущено и крутится непрерывно то сигнала обработки нет, Тоесть в слот не попадает. Что можно сделать?   думала что-то типа processEvents (), но не в
могу понять как его в потоке использовать. EventFilter попробовала тоже самое.
« Последнее редактирование: Январь 16, 2017, 16:20 от Firefox » Записан
Firefox
Гость
« Ответ #10 : Январь 16, 2017, 17:13 »

Основной класс
Код:
Widget::Widget(QWidget *parent, int par) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    thread_bc1= new QThread(this);
    controller1= new adapter_tmk(0,par,0);

    controller1->moveToThread(thread_bc1);
    connect(thread_bc1,SIGNAL(started()),controller1,SLOT(process()));
    connect(controller1,SIGNAL(finished()),thread_bc1,SLOT(quit()));
    connect(controller1,SIGNAL(finished()),controller1,SLOT(deleteLater()));
    connect(thread_bc1,SIGNAL(finished()),thread_bc1,SLOT(deleteLater()));

    connect(ui->send_pb,SIGNAL(clicked(bool)),controller1,SLOT(startObmen(bool)),Qt::AutoConnection);

    thread_bc1->start();

}

Widget::~Widget()
{
    delete ui;
    if(thread_bc1->isRunning())
        thread_bc1->terminate();

}
поток
Код:
#include "adapter_tmk.h"

adapter_tmk::adapter_tmk(QObject *parent, int par, int nTmk) :
    QObject()
{   
    tmk_N=nTmk;
    flag_send=false;
    flag_conf=false;
   Subaddress1=2;
   Subaddress1=3;
    connect(this, SIGNAL(sendSinhr_commandW(int,int,int,int,int,short)), this, SLOT(sendCommand_OU_10Format(int,int,int,int,int,short)));
    connect(this,SIGNAL(endSendFormat10(int,int)),this,SLOT(Slot_endSendFormat10(int,int)));
    connect(this, SIGNAL(sendData_7Format(int,int,QByteArray,int,int,int)), this, SLOT(sendData_OU_7Format(int,int,QByteArray,int,int,int)));
    connect(this,SIGNAL(endSendFormat7(int,int,int)),this,SLOT(Slot_endSendFormat7(int,int, int)));
    connect(this, SIGNAL(sendSinhr_command(int,int,int,int,bool,int)), this, SLOT(sendCommand_OU_9Format(int,int,int,int,bool,int)));

    nTmk=0;

    this->installEventFilter(this);

}
adapter_tmk::~adapter_tmk()
{
   
}

void adapter_tmk::startSend(int Par_send,int lpi, int subaddr)
{

    if(flag_send==false)
        return;

    switch(Par_send)
    {
        case 0:
        {

            emit sendSinhr_commandW(Adress_ALL,BUS_A,CMD_SYNCHRONIZE_WITH_DATA_WORD,tmk_N,20,5);

        }break;
        case 1:
        {
           
            QByteArray arr_send;
            arr_send.resize(32);
            emit sendData_7Format(Adress_ALL,subaddr,arr_send,lpi,tmk_N,20);///???


        }break;
        case 2:
        {
             usleep(100*1000);

            QByteArray arr_send;
            arr_send.resize(32);
            emit sendData_7Format(Adress_ALL,subaddr,arr_send,lpi,tmk_N,20);///???
            count_line1++;
            if(count_line1==10 || count_line2==10)
            {
                emit sendSinhr_command(Adress_ALL,lpi,CMD_TRANSMIT_STATUS_WORD,tmk_N,false,20);

            }

        }break;
        //ERRORS
        case 1007:
        {
               startSend(0,BUS_A,Subaddress1);

        }break;
        case 1010:
        {
               startSend(1,BUS_A,Subaddress2);

        }break;
    }
}
void adapter_tmk::Slot_endSendFormat10(int rezult,int Lpi)
{
    if(rezult==0)
    {
       startSend(1,BUS_A,Subaddress1);
    }
    else
    {
        startSend(1010,Lpi,Subaddress2);
    }
}
void adapter_tmk::Slot_endSendFormat7(int rezult, int Lpi, int wSubaddress)
{
    if(rezult==0)
    {
        if(wSubaddress==Subaddress1)
            startSend(2,BUS_A,Subaddress2);
        else
            startSend(0,BUS_A,Subaddress1);
    }
    else
    {
        startSend(1007,Lpi,wSubaddress);
    }
}


void adapter_tmk::startObmen(bool mean)
{
   //СЮДА 2-ой РАЗ НЕ ЗАХОДИТ(Обработка события не работает)
    if(!flag_conf)
        return;
     if(mean)
     {
         flag_send=true;
         startSend(0,BUS_A, Subaddress1);
     }
     else
     {
         flag_send=false;
     }

}
void adapter_tmk::process()
{
    if(!tmk_configure(tmk_N))
    {
        flag_conf=false;

    }
    else
    {
        flag_conf=true;
    }
}


bool adapter_tmk::tmk_configure(int tmkNumber)
{
    return true;
}


void adapter_tmk::sendData_OU_7Format(int tmkAddress,int wxSubaddress, QByteArray send_data, int busNumber, int tmkNumb,int time_wait)
{
    emit endSendFormat7(0,lpi,wxSubaddress);
}
void adapter_tmk::sendCommand_OU_9Format(int tmkAddress,int busNumber, int command, int tmkNumb, bool rej_rab,int time_wait)
{
      emit endSendFormat9(0, command,lpi,rej_rab);
}

void adapter_tmk::sendCommand_OU_10Format(int tmkAddress,int busNumber, int command, int tmkNumb,int time_wait,short sd)
{
    emit endSendFormat10(0,lpi);
}

Записан
Firefox
Гость
« Ответ #11 : Январь 18, 2017, 09:03 »

Проблема решилась заменой в connect (...,Qt:DirrctConnection)
Записан
Firefox
Гость
« Ответ #12 : Январь 18, 2017, 13:07 »

Есть еще одна проблема. По кнопке стартует и завершается мой поток. Но внутри потока много раз в секунду с помощью сигналов /слотов и функций вызываемых внутри происходит обработка и завершение terminate () wait ()  потока происходит где-то в течение минуты что очень долго, потому как пока не завершится заново  не запустить. Как то можно ускорить завершение?
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3258


Просмотр профиля
« Ответ #13 : Январь 18, 2017, 13:19 »

Для начала, не спать.
Долги операции периодически проверять флаг завершения.
И да, возможно конкарент тут будет лучше.
И да, терминейтить тред не стоит.
Записан
Firefox
Гость
« Ответ #14 : Январь 18, 2017, 15:03 »

Оказалась проблема в том, что внутри класса который помещается в поток были вызовы функции, заменила на сигналы ( внутри одного потока)  и все хорошо и быстро стало завершаться. Убрала терминэйт, как Вы и советуете. Спасибо
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.055 секунд. Запросов: 22.