「QMLの基礎 - 変数」の版間の差分
| (同じ利用者による、間の5版が非表示) | |||
| 1行目: | 1行目: | ||
== 概要 == | == 概要 == | ||
<br><br> | |||
== 値型 == | |||
==== 値型変数とは ==== | |||
QMLは、組み込みとカスタムの値型をサポートしている。<br> | |||
<br> | |||
値型とは、参照ではなく値で渡されるものであり、intやstring等の値である。<br> | |||
これは、QMLのオブジェクト型とは対照的である。オブジェクト型は参照により渡される。<br> | |||
<br> | |||
オブジェクト型のインスタンスを2つの異なるプロパティに割り当てた場合、両方のプロパティに同じ値が渡される。<br> | |||
この時、オブジェクトを変更すると、両方のプロパティに反映される。<br> | |||
<br> | |||
値型のインスタンスを2つの異なるプロパティに割り当てた場合、プロパティは別々の値を持つ。(一方を変更しても、もう一方の値は変化しない)<br> | |||
オブジェクト型とは異なり、値型はQMLオブジェクトの宣言に用いることができない。<br> | |||
例えば、int{}オブジェクトやsize{}オブジェクトを宣言することはできない。<br> | |||
<br> | |||
値型は、参照するために用いることができる。<br> | |||
* 単一の値 (例. int型は単一の数値) | |||
* プロパティとメソッドを含む値 (例. size型は、widthとheightのプロパティを持つ値) | |||
* 汎用型である<code>var</code>型は、他の任意の型の値を保持することができるが、それ自体は値型である。 | |||
<br> | |||
ある変数やプロパティが値型を保持し、それが別の変数やプロパティに代入される時、値のコピーが作成される。<br> | |||
<br> | |||
var型は、任意のデータ型を参照できる汎用的なプロパティ型である。<br> | |||
これは、通常のJavaScriptで使用される変数と同様である。<br> | |||
例えば、var型のプロパティには、数値、文字列、オブジェクト、配列、関数を格納することができる。<br> | |||
<br> | |||
==== string型 ==== | |||
===== 大文字・小文字の区別 ===== | |||
QMLでは、文字列の大文字・小文字を区別せずに比較する場合は、<code>toLowerCase</code>メソッドを使用する。<br> | |||
<syntaxhighlight lang="qml"> | |||
property string str = "Hoge" | |||
if (section.name.toLowerCase() === "hoge") { | |||
// ...略 | |||
} | |||
</syntaxhighlight> | |||
<br> | |||
<u>※注意</u><br> | |||
<u>パフォーマンスを考慮する必要がある場合、頻繁に実行される比較では<code>toLowerCase</code>メソッドの使用は避けて、初期化時に小文字変換した値を保持する。</u><br> | |||
<br> | |||
==== 配列 ==== | |||
===== 空の要素の削除 ===== | |||
* filterメソッドを使用する場合 | |||
<syntaxhighlight lang="qml"> | |||
hoge = hoge.filter(function(element) { | |||
return element !== ""; | |||
}); | |||
</syntaxhighlight> | |||
<br> | |||
* アロー関数を使用する場合 | |||
<syntaxhighlight lang="qml"> | |||
hoge = hoge.filter(element => element !== ""); | |||
</syntaxhighlight> | |||
<br> | |||
* より詳細な条件が必要な場合 (配列要素にnullおよびundefinedが存在する場合) | |||
<syntaxhighlight lang="qml"> | |||
hoge = hoge.filter(element => { | |||
return element !== "" && element !== null && element !== undefined; | |||
}); | |||
</syntaxhighlight> | |||
<br> | |||
<u>※注意</u><br> | |||
* この操作は新しい配列を生成するため、元の配列は変更されない。<br>そのため、QMLのプロパティバインディングを維持するため、新しい配列を元のプロパティに代入する必要がある。 | |||
* この操作は、プロパティが変更可能 (property var型) である場合のみ有効である。 | |||
<br> | |||
===== 空白要素の削除 ===== | |||
<code>trim</code>メソッドを使用して空白文字のみの要素を削除する。<br> | |||
<br> | |||
<syntaxhighlight lang="qml"> | |||
property var hoge: ["hoge", "piyo", " ", " "] | |||
hoge = hoge.filter(element => element.trim() !== ""); | |||
</syntaxhighlight> | |||
<br><br> | <br><br> | ||
| 58行目: | 131行目: | ||
ただし、この方法では型付けが無いため、様々なオブジェクトを代入することができる。<br> | ただし、この方法では型付けが無いため、様々なオブジェクトを代入することができる。<br> | ||
また、グローバル変数を変更した場合、それを使用しているアイテムは変更について通知されずに古い値を維持することに注意すること。<br> | また、グローバル変数を変更した場合、それを使用しているアイテムは変更について通知されずに古い値を維持することに注意すること。<br> | ||
<syntaxhighlight lang="javascript"> | <syntaxhighlight lang="javascript"> | ||
// MyGlobalVariables.js | // MyGlobalVariables.js | ||
| 70行目: | 140行目: | ||
<br> | <br> | ||
以下に、Javascriptのグローバル変数の使用手順を示す。<br> | 以下に、Javascriptのグローバル変数の使用手順を示す。<br> | ||
<u><code>as</code>を使用して別名を付ける場合、別名の頭文字は大文字にする必要がある。</u><br> | |||
<syntaxhighlight lang="qml"> | <syntaxhighlight lang="qml"> | ||
import "MyGlobalVariables.js" as Variables | import "MyGlobalVariables.js" as Variables | ||
| 105行目: | 176行目: | ||
Variables.globalVariable = 5 | Variables.globalVariable = 5 | ||
} | } | ||
} | |||
</syntaxhighlight> | |||
<br> | |||
==== QQmlEngineクラスのrootContextの使用 ==== | |||
型のチェック、バインディング、変更の通知が必要な場合は、main.qmlファイル等のルートオブジェクトに定義することにより、どこからでもアクセスできるようになる。<br> | |||
これは、ルートオブジェクトは<code>QQmlContext</code>クラスのオブジェクトに直接登録されるからである。<br> | |||
<br> | |||
<code>QQmlEngine</code>クラスの<code>rootContext</code>メソッドに<code>contextObject</code>を設定することにより、<br> | |||
その<code>QObject</code>の派生クラスが提供しているスロットや<code>Q_INVOKABLE</code>が付加されたメソッドをQMLファイルから実行することができる。<br> | |||
<syntaxhighlight lang="sh"> | |||
RESOURCES = \ | |||
qml.qrc \ | |||
main.js | |||
</syntaxhighlight> | |||
<br> | |||
<syntaxhighlight lang="c++"> | |||
// main.cppファイル | |||
#include <QCoreApplication> | |||
#include <QQmlApplicationEngine> | |||
#include <QQmlContext> | |||
#include "GlobalContext.h" | |||
int main(int argc, char *argv[]) | |||
{ | |||
QCoreApplication app(argc, argv); | |||
QQmlApplicationEngine engine; | |||
// コンテキストオブジェクト(GlobalContextクラス)の設定 | |||
engine.rootContext()->setContextObject(new GlobalContext(&app)); | |||
const QUrl url(QStringLiteral("qrc:/main.qml")); | |||
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, | |||
&app, | |||
[url](QObject *obj, const QUrl &objUrl) | |||
{ | |||
if (!obj && url == objUrl) | |||
QCoreApplication::exit(-1); | |||
}, Qt::QueuedConnection); | |||
engine.load(url); | |||
return app.exec(); | |||
} | |||
</syntaxhighlight> | |||
<br> | |||
<syntaxhighlight lang="c++"> | |||
// GlobalContext.cppファイル | |||
#include "GlobalContext.h" | |||
GlobalContext::GlobalContext(QObject *parent) : QObject(parent) | |||
{ | |||
} | |||
void GlobalContext::MyFunction(const QString &arg) | |||
{ | |||
qInfo() << Q_FUNC_INFO << arg; | |||
} | |||
</syntaxhighlight> | |||
<br> | |||
<syntaxhighlight lang="c++"> | |||
// GlobalContext.hファイル | |||
#include <QDebug> | |||
class GlobalContext : public QObject | |||
{ | |||
Q_OBJECT | |||
public: | |||
explicit GlobalContext(QObject *parent); | |||
Q_INVOKABLE void MyFunction(const QString &arg); | |||
}; | |||
</syntaxhighlight> | |||
<br> | |||
<syntaxhighlight lang="qml"> | |||
// main.qmlファイル | |||
import QtQml 2.15 | |||
import 'main.js' as Script | |||
QtObject { | |||
Component.onCompleted: { | |||
MyFunction('from QML') | |||
Script.run() | |||
Qt.quit() | |||
} | |||
} | |||
</syntaxhighlight> | |||
<br> | |||
<syntaxhighlight lang="javascript"> | |||
// main.jsファイル | |||
function run() { | |||
// Javascriptからコンテキストオブジェクト(GlobalContextクラス)のメソッドを呼ぶ | |||
MyFunction('from JavaScript') | |||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<br><br> | <br><br> | ||
{{#seo: | |||
|title={{PAGENAME}} : Exploring Electronics and SUSE Linux | MochiuWiki | |||
|keywords=MochiuWiki,Mochiu,Wiki,Mochiu Wiki,Electric Circuit,Electric,pcb,Mathematics,AVR,TI,STMicro,AVR,ATmega,MSP430,STM,Arduino,Xilinx,FPGA,Verilog,HDL,PinePhone,Pine Phone,Raspberry,Raspberry Pi,C,C++,C#,Qt,Qml,MFC,Shell,Bash,Zsh,Fish,SUSE,SLE,Suse Enterprise,Suse Linux,openSUSE,open SUSE,Leap,Linux,uCLnux,Podman,電気回路,電子回路,基板,プリント基板 | |||
|description={{PAGENAME}} - 電子回路とSUSE Linuxに関する情報 | This page is {{PAGENAME}} in our wiki about electronic circuits and SUSE Linux | |||
|image=/resources/assets/MochiuLogo_Single_Blue.png | |||
}} | |||
__FORCETOC__ | __FORCETOC__ | ||
[[カテゴリ:Qt]] | [[カテゴリ:Qt]] | ||
2024年10月30日 (水) 03:01時点における最新版
概要
値型
値型変数とは
QMLは、組み込みとカスタムの値型をサポートしている。
値型とは、参照ではなく値で渡されるものであり、intやstring等の値である。
これは、QMLのオブジェクト型とは対照的である。オブジェクト型は参照により渡される。
オブジェクト型のインスタンスを2つの異なるプロパティに割り当てた場合、両方のプロパティに同じ値が渡される。
この時、オブジェクトを変更すると、両方のプロパティに反映される。
値型のインスタンスを2つの異なるプロパティに割り当てた場合、プロパティは別々の値を持つ。(一方を変更しても、もう一方の値は変化しない)
オブジェクト型とは異なり、値型はQMLオブジェクトの宣言に用いることができない。
例えば、int{}オブジェクトやsize{}オブジェクトを宣言することはできない。
値型は、参照するために用いることができる。
- 単一の値 (例. int型は単一の数値)
- プロパティとメソッドを含む値 (例. size型は、widthとheightのプロパティを持つ値)
- 汎用型である
var型は、他の任意の型の値を保持することができるが、それ自体は値型である。
ある変数やプロパティが値型を保持し、それが別の変数やプロパティに代入される時、値のコピーが作成される。
var型は、任意のデータ型を参照できる汎用的なプロパティ型である。
これは、通常のJavaScriptで使用される変数と同様である。
例えば、var型のプロパティには、数値、文字列、オブジェクト、配列、関数を格納することができる。
string型
大文字・小文字の区別
QMLでは、文字列の大文字・小文字を区別せずに比較する場合は、toLowerCaseメソッドを使用する。
property string str = "Hoge"
if (section.name.toLowerCase() === "hoge") {
// ...略
}
※注意
パフォーマンスを考慮する必要がある場合、頻繁に実行される比較ではtoLowerCaseメソッドの使用は避けて、初期化時に小文字変換した値を保持する。
配列
空の要素の削除
- filterメソッドを使用する場合
hoge = hoge.filter(function(element) {
return element !== "";
});
- アロー関数を使用する場合
hoge = hoge.filter(element => element !== "");
- より詳細な条件が必要な場合 (配列要素にnullおよびundefinedが存在する場合)
hoge = hoge.filter(element => {
return element !== "" && element !== null && element !== undefined;
});
※注意
- この操作は新しい配列を生成するため、元の配列は変更されない。
そのため、QMLのプロパティバインディングを維持するため、新しい配列を元のプロパティに代入する必要がある。 - この操作は、プロパティが変更可能 (property var型) である場合のみ有効である。
空白要素の削除
trimメソッドを使用して空白文字のみの要素を削除する。
property var hoge: ["hoge", "piyo", " ", " "]
hoge = hoge.filter(element => element.trim() !== "");
グローバル変数
シングルトンオブジェクトの使用
シングルトンオブジェクトの使用は、Qt5.0から採用している。
まず、シングルトンオブジェクトを作成する。
以下の例では、Style.qmlファイルとしている。
// Style.qmlファイル
pragma Singleton
import QtQuick 2.15
QtObject {
property color mainbg: 'red'
}
次に、qmldirファイルを作成する。
qmldirファイルは、シングルトンのqmlファイル(上記の例では、Style.qml)と同階層のディレクトリに配置、または、相対パスで指定する必要がある。
また、qrcリソースファイルにqmldirファイルをインクルードする必要な場合もある。
// qmldirファイル
singleton Style Style.qml // singleton <定義名> <QML定義ファイル>
以下に、シングルトンオブジェクトが定義されたQML定義ファイルの使用手順を示す。
同階層のディレクトリにあるシングルトンオブジェクトを参照する場合でも、ディレクトリのimport文が必要である。
同階層のディレクトリの場合は、import "."を使用すること。
import QtQuick 2.15
import "." // 同階層のディレクトリにあるシングルトンオブジェクトを参照する場合
Rectangle {
color: Style.mainbg // シングルトンオブジェクト
width: 240
height 160
}
または、import文を使用せずに、.proファイルのRESOURCESに、QML定義ファイルとqmldirファイルを追加することでも可能である。
RESOURCES += \
qml.qrc \
Style.qml \
qmldir
Javascriptの使用
プロパティバインディングが不要な場合(値が定数で、変更時に通知する必要がない場合)は、以下のように、Javascriptの共有ライブラリで定義する。
ただし、この方法では型付けが無いため、様々なオブジェクトを代入することができる。
また、グローバル変数を変更した場合、それを使用しているアイテムは変更について通知されずに古い値を維持することに注意すること。
// MyGlobalVariables.js
.pragma library
var hoge = 100;
以下に、Javascriptのグローバル変数の使用手順を示す。
asを使用して別名を付ける場合、別名の頭文字は大文字にする必要がある。
import "MyGlobalVariables.js" as Variables
Rectangle {
width: Variables.hoge
height: Variables.hoge
}
Javascriptを使用する方法では、そのプロパティを使用する全てのファイルにインポートすることができる。
// MyGlobalVariables.jsファイル
// 注意
// 複数のqmlファイルからこの変数を変更する場合、.pragma libraryのみが必要となる
.pragma library
var globalVariable = 20;
import "MyGlobalVariables.js" as Variables
Rectangle {
id: main
width: 300
height: 400
Component.onCompleted: {
console.log(Variables.globalVariable);
// グローバル変数の値の変更
Variables.globalVariable = 5
}
}
QQmlEngineクラスのrootContextの使用
型のチェック、バインディング、変更の通知が必要な場合は、main.qmlファイル等のルートオブジェクトに定義することにより、どこからでもアクセスできるようになる。
これは、ルートオブジェクトはQQmlContextクラスのオブジェクトに直接登録されるからである。
QQmlEngineクラスのrootContextメソッドにcontextObjectを設定することにより、
そのQObjectの派生クラスが提供しているスロットやQ_INVOKABLEが付加されたメソッドをQMLファイルから実行することができる。
RESOURCES = \
qml.qrc \
main.js
// main.cppファイル
#include <QCoreApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "GlobalContext.h"
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
QQmlApplicationEngine engine;
// コンテキストオブジェクト(GlobalContextクラス)の設定
engine.rootContext()->setContextObject(new GlobalContext(&app));
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app,
[url](QObject *obj, const QUrl &objUrl)
{
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);
return app.exec();
}
// GlobalContext.cppファイル
#include "GlobalContext.h"
GlobalContext::GlobalContext(QObject *parent) : QObject(parent)
{
}
void GlobalContext::MyFunction(const QString &arg)
{
qInfo() << Q_FUNC_INFO << arg;
}
// GlobalContext.hファイル
#include <QDebug>
class GlobalContext : public QObject
{
Q_OBJECT
public:
explicit GlobalContext(QObject *parent);
Q_INVOKABLE void MyFunction(const QString &arg);
};
// main.qmlファイル
import QtQml 2.15
import 'main.js' as Script
QtObject {
Component.onCompleted: {
MyFunction('from QML')
Script.run()
Qt.quit()
}
}
// main.jsファイル
function run() {
// Javascriptからコンテキストオブジェクト(GlobalContextクラス)のメソッドを呼ぶ
MyFunction('from JavaScript')
}