【问题标题】:Passing a QVector as arg to QRunnable将 QVector 作为 arg 传递给 QRunnable
【发布时间】:2013-09-28 01:16:13
【问题描述】:

我正在使用 Qt 构建一个 C++ 应用程序,以从以 3000Hz 运行的线扫描相机获取数据。在另一个问题 (Using C++ to interface with a line-scan camera at 3000Hz, and process / display the data) 中,我收到了很好的建议,因为我计划了我的策略来解决这个问题。我现在有一个具体的问题。我将重申我的免责声明:我是一名工程师,而不是程序员……但我正在边做边学。

我正在使用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 &lt;QMetaType&gt;。这与下面所有 cmets/answers 中的信息相结合,得到了要编译的代码。 **

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

ma​​in.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

appwidget.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);
}

acquire.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

acquire.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;
}

【问题讨论】:

  • Algorithm task;AppWidget 的成员变量,所以在构造AppWidget 时构造。 Algorithm 对象需要一个 QVector 来初始化自己,所以你必须提供一个。您需要将它包含在 AppWidget 构造函数的初始化列表中。
  • @Slavik81 在使用int 类型时,我在初始化列表中使用了task(0)QVector 应该有什么不同?我尝试了 task({0}) 等等...
  • AppWidget::AppWidget():task(QVector&lt;unsigned int&gt;()) 将修复编译错误。但是,仍然存在许多重大问题。
  • 例如,您可能不想使用指向Algorithm::arg_passed 的指针。否则你可能会发现它指向的东西在不合时宜的时候被摧毁了。直接使用 QVector:const QVector&lt;unsigned short&gt; arg_passed;
  • @Slavik81 该指针是我的“黑暗中的刺”之一。原来只是const QVector&lt;unsigned short&gt; arg_passed;我会再次更新。此外,在初始化列表中使用 task(QVector&lt;unsigned int&gt;()) 也有效。感谢那。现在,qRegisterMetaType 存在问题。我也会为此更新。我知道我对这些东西不知所措,但这就是我要学习的方式。

标签: c++ multithreading qt qthread qvector


【解决方案1】:

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

【讨论】:

  • 这绝对是我的问题之一(确实是 facepalm 问题)。我包含了QVector,但仍然无法编译。我已经编辑了我的原始问题以包含此更正。请参阅更新的错误消息。我相信这与我与AlgorithmQVector 有效负载的类构造函数的交互有关。
  • 看来你现在在main.cpp 中缺少#include &lt;QVector&gt;
猜你喜欢
  • 2018-11-27
  • 1970-01-01
  • 1970-01-01
  • 2019-12-30
  • 1970-01-01
  • 2020-02-05
  • 1970-01-01
  • 2021-04-25
  • 1970-01-01
相关资源
最近更新 更多