有没有一种方法可以从QML WorkerScript运行C ++? [英] Is there a way to run C++ from a QML WorkerScript?

查看:520
本文介绍了有没有一种方法可以从QML WorkerScript运行C ++?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个很慢的I/O操作,需要从QML UI进行控制. I/O接口使用C ++.基本上,当用户按下按钮时,我需要发送消息并获得设备的响应.我希望用户能够在等待响应的同时做其他事情. WorkerScript似乎是实现此目的的最简单方法,但是由于普通的QDeclarativeContext不会传递给线程,因此如何将C ++接口添加到脚本中?有没有一种方法可以将C ++导入QML的javascript中?我什至不需要在主线程中维护C ++上下文,因为它完全驻留在worker中并且只是来回传递消息就可以了.

澄清:@dtech的答案满足了我当前的需求,但是我仍然想知道问题的答案:是否可以将C ++(即使不是有状态的)导入WorkerScript.

I have a slow I/O operation that I need to control from a QML UI. The I/O interface is in C++. Basically, when a user presses a button, I need to send a message and get a response from the device. I want the user to be able to do other things while waiting for a response. WorkerScript seems like the easiest way to make this happen, but how do I get my C++ interface into the script since the normal QDeclarativeContext doesn't pass into the thread? Is there a way to import C++ into QML's javascript? I don't even need to maintain the C++ context in the main thread, I'd be fine with it living entirely in the worker and just passing messages back and forth.

Clarifications: @dtech's answer satisfies my current need, but I would still like to know the answer to the question: is it possible to get C++ (even if not stateful) into a WorkerScript.

推荐答案

为什么可以选择将QObject放入专用线程中,在不阻塞主线程的情况下执行代码,并进行通信并传递结果,为什么要这样做?来回往返QML?

Why would you do that when you have the option to put QObjects into dedicated threads, execute code without blocking the main thread, and communicate and deliver results back and forth to QML asyncronously?

您不需要WorkerScript,这也不是其预期用途.而且由于您的代码仍然是C ++,因此您只需要QThreadQObject.

You don't need WorkerScript, nor is this its intended use. And since your code is C++ anyway, all you need is QThread and QObject.

这是一个简单的例子:

class Worker : public QObject {
    Q_OBJECT
  public slots:
    void doWork() {
      int i = 0;
      while (i < 100) {
        result(i++);
        std::this_thread::sleep_for(std::chrono::milliseconds(500));
      }
    }
  signals:
    void result(int r);
};

class Controller : public QObject {
    Q_OBJECT
  public:
    Controller() {
      w = new Worker;
      t = new QThread;
      w->moveToThread(t);
      connect(this, SIGNAL(start()), w, SLOT(doWork()));
      connect(w, SIGNAL(result(int)), this, SIGNAL(result(int)));
      t->start();
    }
  private:
    Worker * w;
    QThread * t;
  signals:
    void start();
    void result(int r);
};

// in main.cpp
  Controller cw;
  engine.rootContext()->setContextProperty("Work", &cw);
  engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); // load main qml


// QML

  Column {
    Button {
      id: start
      onClicked: Work.start()
    }
    Text {
      id: res
    }
  }

  Connections {
    target: Work
    onResult: res.text = r
  }

这是一个简单的阻塞工作程序,它将阻塞其线程约50秒钟,但是尽管如此,它仍能够发出将在QML端更新的结果,同时保持GUI线程空闲.请注意,一旦调用了工作功能,就无法以任何方式中断,暂停或控制它,如果需要的话,您将必须实现

It is a simple blocking worker that will block its thread for about 50 seconds, but nonetheless will be able to emit results that will be updated on the QML side, while keeping the GUI thread free. Note that once the work function is invoked, it is not possible to interrupt, pause, or control it in any way, if that is required, you will have to implement a non-blocking worker instead. Also not the need of a C++ controller to be present to act as a mediator between QML and the "threaded object", as it seems that QML doesn't get along with such objects directly.

这篇关于有没有一种方法可以从QML WorkerScript运行C ++?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆