2017-10-13 6 views
0

QML UIから制御する必要があるI/O操作が遅いです。 I/OインタフェースはC++になっています。基本的に、ユーザーがボタンを押すと、メッセージを送信してデバイスから応答を得る必要があります。私はユーザーが応答を待っている間に他のことをすることができるようにしたい。 WorkerScriptはこれを実現する最も簡単な方法のようですが、通常のQDeclarativeContextがスレッドに渡されないので、C++インターフェイスをスクリプトにどのようにして入手できますか? C++をQMLのjavascriptにインポートする方法はありますか?私はメインスレッドでC++のコンテキストを維持する必要はなく、ワーカーで完全に生きていて、メッセージを前後に渡しても問題ありません。
EDIT:
明確化:dtechの答え@は私の現在のニーズを満たし、私はまだ質問への答えを知っていただきたいと思います:それはWorkerScriptに(でも、ステートフルでない場合)++ Cを得ることが可能です。QML WorkerScriptからC++を実行する方法はありますか?

答えて

1

QObjectを専用スレッドに入れ、メインスレッドをブロックせずにコードを実行し、結果を通信してQMLに非同期的に伝達するオプションがあるのはなぜですか?

あなたはWorkerScriptを必要とせず、その使用目的もありません。とにかくあなたのコードはC++なので、必要なのはQThreadQObjectです。ここで

は簡単な例です:

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スレッドをフリーに保ちます。作業関数が呼び出されると、割り込み、一時停止、または制御することはできません。必要であれば、代わりにnon-blocking workerを実装する必要があります。また、QMLがそのようなオブジェクトに直接関係していないように見えるので、QMLと「スレッドオブジェクト」の間のメディエータとして機能するためには、C++コントローラが存在する必要はありません。

+0

一度のタスクでは、 'QtConcurrent :: run'を使う方がずっと簡単です。そして、ニックピックするには、Qt 5の接続構文を使用してください。 – GrecKo

+0

@GrecKo - 質問の最初の数単語を慎重に読んだら、それは「一度の仕事」ではないことに気付くでしょう。これはまさにスレッドオブジェクト(ioコントローラ)を必要とする状況です。 – dtech

+0

質問からはっきりと分かりません。私は代わりを提供しています。 – GrecKo

関連する問題