как передать структуру в поток QT - PullRequest
0 голосов
/ 10 января 2020

Я пытаюсь передать структуру данных в поток QT, но безуспешно.

вот что я делаю и сделал.

Я готовлю данные для потока, как это, и затем попытался передать подготовленные данные в поток перед запуском.

void mytable::prepare_data(){
   // get table row count 
   int rowCount = ui->my_table_view->rowCount();    

  // create structure array  based on rowCount
  pnp_com_info pnp_data[rowCount];

  /* pnp_com_info structure defined it top of file below includes to make it global
    struct pnp_com_info{
      QString com_name = "";
      int x = 0;
      int y = 0;
      int angle = 0;
      bool status = false;
    };
  */

  // loop on table rows columns and load pnp_data with data of columns


// PROBLEM : how to pass pnp_data structure to thread side ?

 // can pass basic vars like
 RunJobThread->mynum = 10; 


// start QT thread 
RunJobThread->start();

 // std:: thread experiment
 // std::stdthreadtest(pnp_data,rowCount);

}

run_job_thread.h исходный код

#ifndef RUN_JOB_THREAD_H
#define RUN_JOB_THREAD_H

#include <QObject>
#include <QThread>

class run_job_thread : public QThread
{
    Q_OBJECT
public:
    run_job_thread();

    void run();

    int mynum;

        struct pnp_com_info_thread{
          QString com_name = "";
          int x = 0;
          int y = 0;
          int angle = 0;
          bool status = false;
        };
    bool Stop;  // bool to stop the job
signals:
    void select_row_of_table_signal(int);
public slots:

};
#endif // RUN_JOB_THREAD_H

run_job_thread. cpp исходный код

#include "run_job_thread.h"
#include <QtCore>

run_job_thread::run_job_thread()
{

}

// run the thread
void run_job_thread::run(){

  qDebug() << "my num passed value is : "<<this->mynum;  // output : 10

    // Goal : loop on pnp_data structure and emit signal to table rows

    emit select_row_of_table_signal(5);
}

вещи, которые я пробовал

вместо struct я попытался использовать другие контейнеры данных, такие как map, multimap, vector, но они дают ошибку, так как я инициализирую структуру pnp_com_info внутри функции mytable :: prepare_data () на основе rowCount, который делает ее локальной и ограниченный функцией prepare_data (), но с map, multimap, vector я планировал, что они будут глобальными, и я смогу получить к ним доступ из потока, однако это не сработало.

std::map<std::string, int,int,int> pnp_com_info;  // error: too many template arguments for class template 'map'
std::multimap<std::string, int,int,int,bool> pnp_com_info; // error: too many template arguments for class template 'multimap'
std::vector<std::string, int,int,int,bool> pnp_com_info; // error: too many template arguments for class template 'vector'

я также попробовал std :: thread, который был частичным успехом, я имею в виду, что он работал нормально, но похоже, что std :: thread не работает с потоком QT GUI, как при запуске приложения GUI go freez, хотя std :: thread делал свою работу

Ответы [ 2 ]

2 голосов
/ 10 января 2020

Я бы предложил сделать следующее, потому что объявление

pnp_com_info pnp_data [rowCount];

находится в контексте, и я думаю, что их жизненный цикл будет потерян, как только вы покинете его, Другая проблема заключается в том, что было бы действительно «небезопасно» создавать такие массивы и затем передавать их из одной стороны в другую. Поэтому я бы создал QList и затем передал бы либо копию, либо ссылку на рабочий поток. Итак,

1) Создайте QList pnp_data в publi c части mytable

2) Заполните все данные, используя для l oop, следующим образом.

3) Создайте еще один QList pnp_data или QList * pnp_data (если вы хотите использовать копию или указатель)

4) Затем просто передайте копию или ссылку на рабочий поток .

Тогда это должно выглядеть так:

mytable.h исходный код

public: QList<pnp_com_info> pnp_data;

mytable. cpp исходный код

void mytable::prepare_data(){
   // get table row count 
   int rowCount = ui->my_table_view->rowCount();    



// HERE YOU LOAD ALL THE VALUES TO THE LIST
for(int i = 0; i<rowCount; i++){
pnp_com_info itemToInsert;
//FILL HERE THE itemToInsert
//Insert the item inside the list.
 pnp_data.append(itemToInsert);
}


// PROBLEM : how to pass pnp_data structure to thread side ?

 // Either pass it as a copy
 RunJobThread->pnp_data = pnp_data; 
//or as a reference
QList<pnp_com_info> *pnpDataPointer = &pnp_data;
RunJobThread->pnp_data_reference = pnpDataPointer;


// start QT thread 
RunJobThread->start();

 // std:: thread experiment
 // std::stdthreadtest(pnp_data,rowCount);

}

run_job_thread.h исходный код

#ifndef RUN_JOB_THREAD_H
#define RUN_JOB_THREAD_H

#include <QObject>
#include <QThread>

class run_job_thread : public QThread
{
    Q_OBJECT
public:
    run_job_thread();

    void run();

            struct pnp_com_info_thread{
          QString com_name = "";
          int x = 0;
          int y = 0;
          int angle = 0;
          bool status = false;
        };

    QList<pnp_com_info> pnp_data; //This one if you create a copy
    QList<pnp_com_info> *pnp_data_reference; //This if you want a pointer



    bool Stop;  // bool to stop the job
signals:
    void select_row_of_table_signal(int);
public slots:

};
#endif // RUN_JOB_THREAD_H

Надеюсь, это поможет.

1 голос
/ 10 января 2020

Во-первых, не создавайте подкласс QThread для создания работника - перечитайте Как на самом деле, действительно использовать QThreads; Полное объяснение Майя Пош. Вы обнаружите, что намного проще управлять созданием рабочего объекта и подключением потоков started() к основному методу вашего рабочего, а сигналы рабочего к потокам quit() и deleteLater().

. Затем следует гораздо проще передать ваши данные работнику, прежде чем они будут перемещены в поток, или использовать сигнальное соединение, если его необходимо передать во время работы работника (для этого не забудьте зарегистрировать вашу структуру в мета-объектной системе) .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...