Calqlatr
カスタムコンポーネント、レスポンシブレイアウト、アプリケーションロジックにJavaScriptを使用した、横長と縦長のデバイス用に設計されたQt Quickアプリです。
Calqlatrは、カスタムコンポーネントの表示やレスポンシブレイアウトの使用など、様々なQMLとQt Quickの機能をデモしています。アプリケーションロジックはJavaScriptで実装され、UIはQMLで実装されています。
サンプルを実行する
Qt Creator からサンプルを実行するには、Welcome モードを開き、Examples からサンプルを選択します。詳細については、Building and Running an Example を参照してください。
カスタムコンポーネントの表示
Calqlatrアプリケーションでは、カスタム・タイプが使用されています。これらはそれぞれ別の.qmlファイルで定義されています:
- BackspaceButton.qml。
- 電卓ボタン.qml
- 表示.qml
- ナンバーパッド.qml
これらのカスタム・タイプをMain.qml
で使用するには、content
フォルダにインポート文を追加します:
import "content"
例えば、NumberPad
型は電卓の数字パッドを作成するためにMain.qml
で使用されます。これは、Qt Quick のすべてのビジュアルアイテムの基本型であるItem 型の中にネストされています:
NumberPad { id: numberPad; Layout.margins: root.margin }
カスタムコンポーネントは、どの QML ファイルでも定義できる QML タイプで、NumberPad.qml
のように、独自の .qml ファイルで定義されたコンポーネントと同じ動作をします。NumberPad.qml
ではDigitButton
コンポーネントとOperatorButton
コンポーネントが定義されています。これらのコンポーネントでは、新しいプロパティを追加したり、既存のプロパティを変更したりすることができます。ここで、onReleased
ハンドラーは、カスタム・コンポーネントの両方に対して上書きされます。
component DigitButton: CalculatorButton { onReleased: { root.digitPressed(text) updateDimmed() } } component OperatorButton: CalculatorButton { onReleased: { root.operatorPressed(text) updateDimmed() } textColor: controller.qtGreenColor implicitWidth: 48 dimmable: true }
さらに、NumberPad
のさまざまなボタンには、CalculatorButton
タイプを使用します。CalculatorButton.qml
はボタンの基本プロパティを定義しており、NumberPad.qml
で各インスタンスごとに変更します。数字ボタンと演算子ボタンには、text
、width
、dimmable
プロパティなど、いくつかの追加プロパティがあります。電卓エンジンがそのボタンからの入力を受け付けないときはいつでも、dimmable
を使用してボタンを視覚的に無効にします。
DigitButton { text: "e" dimmable: true implicitWidth: 48 }
content
ディレクトリにはBackSpaceButton.qml
という別のファイルがあります。これはCalculatorButton
の特殊なケースで、テキストではなく画像をボタンにレンダリングします。このボタンはOperatorButton
と同じですが、text
ではなくicon
を含んでいます:
icon.source: getIcon() icon.width: 38 icon.height: 38 icon.color: getIconColor() // include this text property as the calculator engine // differentiates buttons through text. The text is never drawn. text: "bs" property bool dimmable: true property bool dimmed: false readonly property color backgroundColor: "#222222" readonly property color borderColor: "#A9A9A9" readonly property color backspaceRedColor: "#DE2C2C" readonly property int buttonRadius: 8 function getBackgroundColor() { if (button.dimmable && button.dimmed) return backgroundColor if (button.pressed) return backspaceRedColor return backgroundColor
レスポンシブレイアウト
この例では、レスポンシブ・レイアウトは、さまざまなUIコンポーネントを縦向きと横向きの両方に配置します。また、この2つのモードを切り替えることもできます。このことは、Main.qml
、ポートレート・モード用のColumnLayout
、ランドスケープ用のRowLayout
を定義していることでわかります。
ColumnLayout { id: portraitMode anchors.fill: parent visible: true LayoutItemProxy { target: display Layout.minimumHeight: display.minHeight } LayoutItemProxy { target: numberPad Layout.alignment: Qt.AlignHCenter } } RowLayout { id: landscapeMode anchors.fill: parent visible: false LayoutItemProxy { target: display } LayoutItemProxy { target: numberPad Layout.alignment: Qt.AlignVCenter } }
ColumnLayout
はアプリケーションのポートレート・レイアウトを表し、RowLayout
はランドスケープ・レイアウトを表します。visible
プロパティは、ある時点でどちらのレイアウトを使用するかを処理します。NumberPad
とDisplay
コンポーネントのid
プロパティは、LayoutItemProxy
タイプのtarget
プロパティを設定するために使用されます。これにより、両方のレイアウトで同じコンテンツ・アイテムを使用することができます。さらに、LayoutItemProxy
アイテム内のプロパティをtarget
自身に転送することもできます。例えば、NumberPad
がインスタンス化されると、両方のレイアウトは異なるLayout.alignment
を必要とします。
2つのレイアウトを切り替えるには、isPortraitMode
プロパティのシグナルハンドラで、それぞれの可視性を設定します:
onIsPortraitModeChanged: { if (isPortraitMode) { portraitMode.visible = true landscapeMode.visible = false } else { portraitMode.visible = false landscapeMode.visible = true } }
これは、QMLがすべての自己宣言プロパティに対してシグナルハンドラを作成するためです。この場合、on<Property>Changed
ハンドラで、<property> はisPortraitMode
プロパティです。
レスポンシブ・レイアウトは、NumberPad.qml
、NumberPad
自体の縦長と横長のレイアウトを定義する際にも使われます。
RowLayout { spacing: controller.spacing GridLayout { id: scientificGrid columns: 3 columnSpacing: controller.spacing rowSpacing: controller.spacing visible: !isPortraitMode OperatorButton { text: "x²" } OperatorButton { text: "⅟x" } OperatorButton { text: "√" } OperatorButton { text: "x³" } OperatorButton { text: "sin" } OperatorButton { text: "|x|" } OperatorButton { text: "log" } OperatorButton { text: "cos" } DigitButton { text: "e" dimmable: true implicitWidth: 48 } OperatorButton { text: "ln" } OperatorButton { text: "tan" } DigitButton { text: "π" dimmable: true implicitWidth: 48 } } GridLayout { id: mainGrid columns: 5 columnSpacing: controller.spacing rowSpacing: controller.spacing BackspaceButton {} DigitButton { text: "7" } DigitButton { text: "8" } DigitButton { text: "9" } OperatorButton { text: "÷" implicitWidth: 38 } OperatorButton { text: "AC" textColor: controller.backspaceRedColor accentColor: controller.backspaceRedColor } DigitButton { text: "4" } DigitButton { text: "5" } DigitButton { text: "6" } OperatorButton { text: "×" implicitWidth: 38 } OperatorButton { text: "=" implicitHeight: 81 Layout.rowSpan: 2 } DigitButton { text: "1" } DigitButton { text: "2" } DigitButton { text: "3" } OperatorButton { text: "−" implicitWidth: 38 } OperatorButton { text: "±" implicitWidth: 38 } DigitButton { text: "0" } DigitButton { text: "." dimmable: true } OperatorButton { text: "+" implicitWidth: 38 } } } // RowLayout
この場合、2つのLayoutItemProxy
アイテムが作成されます。それらのtarget
プロパティは、すべての科学的ボタンを含むGrid
タイプのscientificGrid
と、すべての標準ボタンを含むGrid
タイプのmainGrid
に設定されます。
CalculatorButton.qml
では、数字パッド・ボタンの文字色もアニメーション化されている。
... color: getBackgroundColor() border.color: getBorderColor() } contentItem: Text { text: button.text font.pixelSize: button.fontSize horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter color: getTextColor() Behavior on color { ColorAnimation { duration: 120 easing.type: Easing.OutElastic }
色の変化は、color
プロパティにBehavior
を定義することでアニメーション化されます。ボタンがdimmed = true
に設定されると、ボタンは暗く表示されます。ボタンが押されると、緑色に点灯します。NumberPad
上のすべてのボタンのdimmed
プロパティを動的に変更するには、buttonPressed
シグナルがNumberPad
のupdateDimmed()
関数を呼び出します。
function updateDimmed(){ for (let i = 0; i < mainGrid.children.length; i++){ mainGrid.children[i].dimmed = root.isButtonDisabled(mainGrid.children[i].text) } for (let j = 0; j < scientificGrid.children.length; j++){ scientificGrid.children[j].dimmed = root.isButtonDisabled(scientificGrid.children[j].text) } }
計算の実行
calculator.jsファイルは電卓のエンジンを定義します。このファイルには、電卓の状態を保存する変数と、ユーザーが数字や演算子のボタンを押したときに呼び出される関数が含まれています。このエンジンを使用するには、CalcEngine
というエイリアスを使用して、Main.qml
ファイルに calculator.js をインポートします:
import "content/calculator.js" as CalcEngine
デフォルトでは、QMLからJavaScriptファイルをインポートすると、そのファイルの新しいインスタンスが作成され、そのファイルに含まれる状態はそのインスタンスに固有のものとなります。.pragma library
を使うことで、スクリプトを使うすべてのユーザ間で状態を共有することができます。
.pragma library
ユーザーが数字を押すと、その数字のテキストがディスプレイに表示されます。演算子を押すと、適切な計算が実行され、等号(=)演算子を使用して結果を表示できる。オールクリア(AC)演算子は、電卓エンジンをリセットする。
ファイル一覧
QMLアプリケーションも参照してください 。
©2024 The Qt Company Ltd. 本書に含まれる文書の著作権は、それぞれの所有者に帰属します。 ここで提供されるドキュメントは、Free Software Foundation が発行したGNU Free Documentation License version 1.3に基づいてライセンスされています。 Qtおよびそれぞれのロゴは、フィンランドおよびその他の国におけるThe Qt Company Ltd.の 商標です。その他すべての商標は、それぞれの所有者に帰属します。