将 QVector 作为参数传递给 QRunnable

Passing a QVector as arg to QRunnable

本文关键字:QRunnable 参数传递 QVector      更新时间:2023-10-16

我正在使用Qt构建一个C++应用程序,以从运行在3000Hz的线扫描相机中获取数据。 在另一个问题中(使用C++与3000Hz的线扫描相机接口,并处理/显示数据(,当我计划解决这个问题的策略时,我收到了很好的建议。 我现在有一个特定的问题。 我将重申我的免责声明:我是一名工程师,而不是程序员......但我边走边学。

我正在使用QThread不断将数据获取到QVector中。 我将QVector发送到主 GUI 线程,该线程创建一个QRunnable并将其传递给QThreadPool以处理数据块。 通过这种方式,我计划获取数据块并创建任务来"实时"处理和响应这些块。 为了简单地让所有部分发挥作用和编译,我最初使用单个整数值作为有效负载。 我可以在QThread中不断生成一个随机 int,发出到 GUI 线程,创建一个QRunnable并对线程池中的 int 进行操作。 我为此感到自豪。 但是,我无法让它与QVector一起工作. 我遇到了几个编译错误,包括:

main.cpp:12:5: error: use of undeclared identifier 'qRegisterMetaType'
    qRegisterMetaType<QVector<unsigned short> >("QVector<unsigned short>");
main.cpp:12:47: error: expected '(' for function-style cast or type construction
    qRegisterMetaType<QVector<unsigned short> >("QVector<unsigned short>")

**编辑:上述错误显然是由于main.cpp中缺少#include <QMetaType>。 这与下面所有评论/答案中的信息相结合,获得了要编译的代码。**

由于我真的在这里游弋,我现在只是盲目地摆弄代码,试图破译错误消息并尝试不同的事情。 以下是构成该项目的所有单个文件。 请注意,最重要的是我尝试实现 QVector 有效负载的代码,我注释掉了适用于int类型的代码位。 查找"//适用于 int 类型! 我知道这是一篇很长的帖子,但我不知道如何进一步简化 MWE 并仍然说明我的问题,因为我不知道 QVector 的问题从哪里开始......因此,所有文件。 我希望它强调我真的试图让它工作。

主.cpp

#include <QApplication>
#include <QMetaType> // Added based on comments provided on SO
#include "appwidget.h"
int main(int argc, char* argv[]) {
    QApplication app(argc, argv);
    AppWidget gui;
    gui.show();
    qRegisterMetaType<QVector<unsigned short> >("QVector<unsigned short>");
    return app.exec();
}

appwidget.h

#ifndef APPWIDGET_H
#define APPWIDGET_H
#include <QWidget>
#include <QThreadPool>
#include "acquire.h"
#include "algorithm.h"
class AppWidget : public QWidget
{ Q_OBJECT
 public:
  AppWidget(QWidget *parent = 0);
 protected:
  Acquire thread;
  Algorithm task;
 private slots:
  //void processBlock(int);  // works with type int!
  void processBlock(const QVector<unsigned short>);
};
#endif

应用小部件.cpp

#include <QtGui>
#include <iostream>
#include "appwidget.h"
AppWidget::AppWidget(QWidget *parent)
    : QWidget(parent), task({0}) //task(0)
{
    thread.liftoff();
    //connect(&thread, SIGNAL(blockAcquired(int)), this, SLOT(processBlock(int)));  // works with type int!
    connect(&thread, SIGNAL(blockAcquired(const QVector<unsigned short>)), this, SLOT(processBlock(const QVector<unsigned short>)));
    setWindowTitle(tr("TestApp"));
    resize(550, 400);
}
//void AppWidget::processBlock(int slot_arg)  // works with type int!
void AppWidget::processBlock(const QVector<unsigned short> slot_arg)
{
    std::cout << "GUI: received signal: " << &slot_arg << std::endl;
    Algorithm *task = new Algorithm(slot_arg);
    QThreadPool::globalInstance()->start(task);
}

获取.h

#ifndef ACQUIRE_H
#define ACQUIRE_H
#include <QVector>
#include <QMutex>
#include <QThread>
#include <QWaitCondition>
class Acquire : public QThread {
  Q_OBJECT
 public:
    Acquire(QObject *parent = 0);
    ~Acquire();
    void liftoff();
 signals:
    //void blockAcquired(int);  // works with type int!
    void blockAcquired(const QVector<unsigned short>);
 protected:
    void run();
 private:
    QVector<unsigned short> image_buffer;
    QMutex mutex;
    QWaitCondition condition;
};
#endif

收购.cpp

#include <iostream>
#include <time.h>
#include <stdlib.h>
#include "acquire.h"
Acquire::Acquire(QObject *parent)
     : QThread(parent)
{
}
Acquire::~Acquire()
{
    std::cout << "Acquire thread: dying." << std::endl;
    wait();
}
void Acquire::liftoff()
{
    std::cout << "Acquire thread: init." << std::endl;
    start();
}
void Acquire::run()
{
    //int image_buffer; // works with type int!
    QVector<unsigned short> image_buffer(384 * sizeof(unsigned short) * 192);
    forever {
    /* // works with type int!
    image_buffer = rand() % (int)(65535 - 0 + 1);
    nanosleep((struct timespec[]){{0, 800000*192}}, NULL);
    */
    int k=0;
    for (int i=0; i<384; i++) {
        for (int j=0; j<192; j++) {
        image_buffer[k] = 0 + (rand() % (int)(65535 - 0 + 1));
        k++;
        }
        nanosleep((struct timespec[]){{0, 800000}}, NULL);
    }
    //std::cout << "Acquire thread: block acquired: " << image_buffer << std::endl;  // works with type int!
    std::cout << "Acquire thread: block acquired: " << &image_buffer << std::endl;  
    //emit blockAcquired(image_buffer);  // works with type int!
    emit blockAcquired(image_buffer);
    }
}

算法.h

#ifndef ALGORITHM_H
#define ALGORITHM_H
#include <QRunnable>
#include <QThread>
#include <QVector>
class Algorithm : public QObject, public QRunnable
{
  Q_OBJECT
 public:
  //Algorithm(int);  // works with type int!
  Algorithm(const QVector<unsigned short>);
  ~Algorithm();
  //int arg_passed;  // works with type int!
  const QVector<unsigned short> arg_passed;
 protected:
  void run();
};
#endif

算法.cpp

#include <iostream>
#include "algorithm.h"
//Algorithm::Algorithm(int i) // works with type int!
Algorithm::Algorithm(const QVector<unsigned short> arg_passed)
{
    // arg_passed = i;  // works with type int!
    std::cout << "Algorithm: init." << std::endl;
}
Algorithm::~Algorithm()
{
    std::cout << "Algorithm: dying." << std::endl;
}
void Algorithm::run()
{
    std::cout << "Algorithm: running, " << QThread::currentThread() << std::endl;
    std::cout << "Arg: " << arg_passed << std::endl;
}

错误消息表示您正在尝试使用不完整的类型。您需要将#include <QVector>添加到algorithm.h的顶部。