MochiuWiki : SUSE, EC, PCB
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報
We ask for
Donations
検索
個人用ツール
ログイン
Toggle dark mode
名前空間
ページ
議論
表示
閲覧
ソースを閲覧
履歴を表示
QMLの基礎 - マルチスレッドのソースを表示
提供: MochiuWiki : SUSE, EC, PCB
←
QMLの基礎 - マルチスレッド
あなたには「このページの編集」を行う権限がありません。理由は以下の通りです:
この操作は、次のグループのいずれかに属する利用者のみが実行できます:
管理者
、new-group。
このページのソースの閲覧やコピーができます。
== 概要 == QMLとC++を連携させたマルチスレッドの実装手順、および、<code>WorkerScript</code>を使用したマルチスレッドの実装手順を記載する。<br> <br><br> == WokerScriptの使用 == ==== WokerScriptでやり取りできるデータ型 ==== * <code>bool</code>型、<code>number</code>型、<code>string</code>型 * JavaScriptオブジェクトと配列 * <code>ListModel</code>(他のオブジェクトは不可) <br> また、<code>WorkerScript</code>で<code>ListModel</code>にアイテムを更新した時は、<code>sync</code>メソッドで反映できる。<br> <br> ==== 処理の手順 ==== # メインスレッドから<code>WokerScript</code>を起動する時は、<code>sendMessage(jsobject)</code>を使用する。 # <code>WokerScript</code>側のメソッドは、<code>WorkerScript.onMessage(jsobject)</code>を使用する。 # <code>WokerScript</code>からメインスレッドへ通信する時は、<code>WorkerScript.sendMessage(jsobject)</code>を使用する。 # メインスレッド側で受ける<code>onMessage</code>シグナルの引数は、<code>messageObject</code>を使用する。 <br> ==== サンプルコード ==== 以下の例では、[Click]を押下する時、1秒間隔でリストへアイテムを追加している。<br> アイテムを追加している最中でも、リストをドラッグして動かすこともできる。<br> [[ファイル:QML MultiThread 1.png|フレームなし|中央]] <syntaxhighlight lang="qml"> // main.qml import QtQuick 2.15 Rectangle { id: _root width: 200 height: 360 // ボタン Rectangle { id: _btn width: _root.width height: _lavel.paintedHeight * 2 color: "#ddddff" border.color: "#dddddd" border.width: 1 Text { id: _lavel anchors.centerIn: parent text: "Click!" } // スレッド開始処理 MouseArea { anchors.fill: parent onClicked: { console.debug("click"); // スレッド開始 _thread.sendMessage({"model":_model, "number": 20, "string": "Start!"}); } } } // スレッド用エレメント WorkerScript { id: _thread source: "scripts.js" // スレッド処理をするスクリプトファイルの指定 onMessage: { // Workerスレッドからの通信イベント console.debug("finish thread:" + messageObject.result + ", split=" + messageObject.split); } } // リスト ListView { anchors.top: _btn.bottom anchors.left: _root.left anchors.right: _root.right anchors.bottom: _root.bottom clip: true model: _model delegate: _delegate } // リストの初期アイテム ListModel { id: _model ListElement { _message: "Item" } } // リスト用レイアウト Component { id: _delegate Rectangle { width: _root.width height: _text.paintedHeight * 2 border.color: "#dddddd" border.width: 1 Text { id: _text anchors.centerIn: parent text: _message } } } } </syntaxhighlight> <br> <syntaxhighlight lang="qml"> // scripts.js WorkerScript.onMessage = function(message) { console.debug("start worker script:" + message.number + "," + message.string); var now = 0; var split = new Date(); for(var i = 0; i < message.number; i++) { delay(1000); now = new Date(); message.model.append({"_message": i + " : " + Qt.formatDateTime(now, "yyyy/MM/dd hh:mm:ss")}); message.model.sync(); } split = (new Date()) - split; // メインスレッドへの応答 WorkerScript.sendMessage({ "result": "tRue", "split": split }) } // ウエイトを入れる function delay(msec) { var start = 0; start = new Date(); do { now = new Date(); }while((now - start) < msec); } </syntaxhighlight> <br><br> == QMLとC++を連携させたマルチスレッド == QObjectクラスを継承したクラスを作成およびそのクラス内にワーカースレッドを作成して、メインスレッドをブロックせずにQML側と非同期に通信することができる。<br> <br> 以下の例では、ワーカースレッドを5秒停止かつシグナルを発信しながら、メインスレッドで画面を更新し続けている。<br> ワーカースレッドの実行中において、一時停止、中断、制御は一切できないため、それらが必要な場合はノンブロッキングワーカースレッドを実装する必要がある。 <syntaxhighlight lang="c++"> // CController.h #include <QThread> #include <QString> #include <thread> #include <memory> class CWorkerThread : public QObject { Q_OBJECT public slots: void doWork() { int i = 0; while (i < 10) { emit result(i++, tr("hoge")); std::this_thread::sleep_for(std::chrono::milliseconds(500)); } } signals: void result(int r, QString s); }; class CController : public QObject { Q_OBJECT public: Controller() { m_pWorker = std::make_unique<CWorkerThread>(); m_pThread = std::make_unique<QThread>(); m_pWorker->moveToThread(m_pThread.get()); connect(this, SIGNAL(start()), m_pWorker.get(), SLOT(doWork())); connect(m_pWorker.get(), SIGNAL(result(int,QString)), this, SIGNAL(result(int,QString))); m_pThread->start(); } private: std::unique_ptr<CWorkerThread> m_pWorker; std::unique_ptr<QThread> m_pThread; signals: void start(); void result(int r, QString s); }; </syntaxhighlight> <br> <syntaxhighlight lang="c++"> // main.cpp // ...略 qmlRegisterType<CController>("Controller", 1, 0, "CController"); QQmlApplicationEngine engine; const QUrl url(QStringLiteral("qrc:/main.qml")); // ...略 </syntaxhighlight> <br> <syntaxhighlight lang="qml"> // main.qml import QtQuick 2.15 import QtQuick.Window 2.15 import QtQuick.Controls 2.15 import Controller 1.0 ApplicationWindow { id: mainWindow // ...略 CController { id: mainController; } Column { Button { id: start onClicked: { mainController.start() } } Text { id: res } } // Result of Slot Connections { target: mainController function onResult(r, s) { res.text = r + qsTr(":") s; } } // ...略 } </syntaxhighlight> <br><br> __FORCETOC__ [[カテゴリ:Qt]]
QMLの基礎 - マルチスレッド
に戻る。
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報
We ask for
Donations
Collapse