📢 Webサイト閉鎖と移転のお知らせ
このWebサイトは2026年9月に閉鎖いたします。
新しい記事は移転先で追加しております。(旧サイトでは記事を追加しておりません)

ページの作成:「== 概要 == <br><br> == ウインドウのオープン / クローズ == ウィンドウの表示および非表示する等、ウィンドウ間のスイッチング…」
 
 
(同じ利用者による、間の5版が非表示)
3行目: 3行目:
<br><br>
<br><br>


== ウインドウのオープン / クローズ ==
== 子ウインドウ ==
ウィンドウの表示および非表示する等、ウィンドウ間のスイッチングを実装する手順を記載する。<br>
==== 静的宣言方式 ====
静的宣言方式は、QMLファイル内で直接ウインドウやコンポーネントを宣言する方法である。<br>
これは、直接的な実装を行う場合に適している。<br>
<br>
静的宣言方式の特徴を以下に示す。<br>
* コードが簡潔で可読性が良い。
* デザイン時にレイアウトが理解しやすい。
* アプリケーション起動時の初期化が速い。
* 宣言されたオブジェクトは常に存在するため、常にメモリを消費する。
<br>
以下の例では、静的宣言方式を使用して、ウインドウ間の表示・非表示をスイッチングしている。<br>
<br>
* メインウインドウ
*: 2つのボタンがあり、各ボタンを押下する時、メインウインドウが非表示になりサブウインドウが開く。
*: 各サブウィンドウのボタンを押下する時、サブウインドウを閉じて、メインウインドウが再度表示される。
<br>
<br>
まず、QMLにおけるシグナルの構文を以下に示す。<br>
まず、QMLにおけるシグナルの構文を以下に示す。<br>
10行目: 24行目:
シグナル(<code>signal <シグナル名></code>)を宣言して、シグナルの定義を記述する。<br>
シグナル(<code>signal <シグナル名></code>)を宣言して、シグナルの定義を記述する。<br>
シグナルの定義名は、プレフィックスに"<code>on</code>"という文字を付加して、シグナル名の先頭文字を大文字にする必要がある。<br>
シグナルの定義名は、プレフィックスに"<code>on</code>"という文字を付加して、シグナル名の先頭文字を大文字にする必要がある。<br>
<br>
  <syntaxhighlight lang="qml">
  <syntaxhighlight lang="qml">
  signal closeThisWindow
  signal closeThisWindow
   
   
  onCloseThisWindow: {
  onCloseThisWindow: {
     // Some code
     // ...略
  }
  }
  </syntaxhighlight>
  </syntaxhighlight>
<br>
<br>
以下の例では、メインウインドウの上ボタンを押下する時、メイン画面を非表示にしてサブウインドウを開く。<br>
サブウインドウを閉じる時、メイン画面を再度表示する。<br>
<br>
シグナルは、以下の例のように、サブウィンドウにおいて関数として呼び出される。<br>
<br>
なお、.proファイルとmain.cppファイルは変更していない。<br>
  <syntaxhighlight lang="qml">
  <syntaxhighlight lang="qml">
  // AnotherWindow.qml
  // AnotherWindow.qml
   
   
  import QtQuick 2.15
  import QtQuick
  import QtQuick.Controls 2.15
  import QtQuick.Controls
  import QtQuick.Window 2.15
  import QtQuick.Window
   
   
  Window {
  Window {
     id: anotherWindow
     id: anotherWindow
     width:480
     width: 480
     height:320
     height: 320
   
   
    // シグナルは、サブウインドウの関数として呼び出す
     signal signalExit  // シグナルの宣言
     signal signalExit  // シグナルの宣言
   
   
52行目: 62行目:
  </syntaxhighlight>
  </syntaxhighlight>
<br>
<br>
メインウインドウのqmlファイル(main.qmlファイル)には、ソフトウェアの主となるロジックを実装する。<br>
<br>
以下の例では、メインウィンドウには2つのボタンがあり、各ボタンを押下する時、メインウィンドウが非表示になりサブウインドウが開く。<br>
各サブウィンドウのボタンを押下する時、サブウィンドウが閉じられて、メインウインドウが再度表示される。<br>
  <syntaxhighlight lang="qml">
  <syntaxhighlight lang="qml">
  // main.qmlファイル
  // main.qmlファイル
   
   
  import QtQuick 2.15
  import QtQuick
  import QtQuick.Controls 2.15
  import QtQuick.Controls
  import QtQuick.Layouts 1.15
  import QtQuick.Layouts
   
   
  ApplicationWindow {
  ApplicationWindow {
     id: mainWindow
     id: mainWindow
     width: 640
     width: 640
     height: 480
     height: 480
     title: qsTr("Switching between windows in QML")
     title: qsTr("Switching between windows in QML")
143行目: 149行目:
           mainWindow.show()      // Shows the main window
           mainWindow.show()      // Shows the main window
       }
       }
    }
}
</syntaxhighlight>
<br>
==== 動的生成方式 ====
動的生成方式は、<code>Qt.createComponent</code>メソッドおよび<code>Component.createObject</code>メソッドを使用して、動的にコンポーネントおよびオブジェクトを生成する方法である。<br>
<br>
動的生成方式の特徴を以下に示す。<br>
* 柔軟性が高い。
* 実行時にコンポーネントを生成できる。
* メモリ使用を最適化できる。(必要な時にのみオブジェクトを生成)
* ソースコードが複雑になる可能性がある。
<br>
動的生成方法でコンポーネントに引数を渡す場合は、コンポーネントにプロパティを定義して、それらのプロパティに値を渡すことで行う。<br>
<br>
<syntaxhighlight lang="qml">
var component = Qt.createComponent("<QMLファイル名>");
var window    = component.createObject(<親コンポーネントのID>,
                                        // 各プロパティの設定
                                        { "生成するコンポーネントのプロパティ名 1":    "値",
                                          "生成するコンポーネントのプロパティ名 2":    "値",
                                          "生成するコンポーネントのプロパティ名 3":    "値"
                                        }
                                      );
</syntaxhighlight>
<br>
以下の例では、メインウインドウのボタンを押下する時、各プロパティに初期値を渡して別のウインドウを開いている。<br>
<syntaxhighlight lang="qml">
// SecondWindow.qml
import QtQuick
import QtQuick.Window
import QtQuick.Controls
ApplicationWindow {
    id:      secondWindow
    width:  400
    height:  300
    visible: true
    property string windowTitle:    "Default Title"
    property color  backgroundColor: "white"
    property string message:        "Default message"
    title: windowTitle
    color: backgroundColor
    Column {
      anchors.centerIn: parent
      spacing: 20
      Label {
          text: message
          font.pixelSize: 16
      }
      Button {
          text: "Debug Button"
          onClicked: {
            console.log("Debug button clicked in Second Window")
            console.log("Window Title:", windowTitle)
            console.log("Background Color:", backgroundColor)
            console.log("Message:", message)
          }
      }
    }
}
</syntaxhighlight>
<br>
<syntaxhighlight lang="qml">
// MainWindow.qml
import QtQuick
import QtQuick.Window
import QtQuick.Controls
ApplicationWindow {
    id:      mainWindow
    width:  640
    height:  480
    visible: true
    title:  qsTr("Main Window")
    Button {
      anchors.centerIn: parent
      text: "Open Second Window"
      onClicked: {
          var component = Qt.createComponent("SecondWindow.qml");
          var window = component.createObject(mainWindow, {
            "windowTitle":    "Custom Title",
            "backgroundColor": "lightblue",
            "message":        "Hello from Main Window!"
          });
          window.show();
      }
    }
}
</syntaxhighlight>
<br>
===== シグナル / シグナルハンドラの定義 =====
動的生成方式において、コンポーネントを生成して、そのコンポーネントにシグナルを定義して、シグナルハンドラで受信することもできる。<br>
<br>
以下の例では、子ウインドウでwindowClosedシグナルを定義して、親ウインドウで動的に生成した子ウインドウのシグナルを接続・受信している。<br>
<br>
親ウインドウのボタンを押下する時、子ウインドウが開く。<br>
子ウインドウのボタンを押下する時、子ウインドウを閉じてシグナルが親ウインドウに送信される。<br>
<br>
<syntaxhighlight lang="qml">
// DynamicWindow.qml
import QtQuick
import QtQuick.Window
import QtQuick.Controls
Window {
    id:      dynamicWindow
    width:  400
    height:  300
    visible: true
    title: windowTitle
    property string windowTitle: "Dynamic Window"
    signal windowClosed(string message)
    Column {
      anchors.centerIn: parent
      spacing: 20
      Button {
          text: "Close Window"
          onClicked: {
            dynamicWindow.windowClosed("Window is closing")
            dynamicWindow.close()
          }
      }
    }
}
</syntaxhighlight>
<br>
<syntaxhighlight lang="qml">
// MainWindow.qml
import QtQuick
import QtQuick.Window
import QtQuick.Controls
Window {
    id:      mainWindow
    width:  640
    height:  480
    visible: true
    title:  qsTr("Main Window")
    Column {
      anchors.centerIn: parent
      spacing: 20
      Button {
          text: "Create Dynamic Window"
          onClicked: {
            var component = Qt.createComponent("DynamicWindow.qml");
            if (component.status === Component.Ready) {
                var dynamicWindow = component.createObject(mainWindow, {"windowTitle": "New Dynamic Window"});
                // シグナルの接続
                dynamicWindow.windowClosed.connect(function(message) {
                  console.log("Received signal:", message);
                  statusText.text = "Last signal: " + message;
                });
            }
          }
      }
      Text {
          id:  statusText
          text: "No signal received yet"
      }
    }
}
</syntaxhighlight>
<br>
===== メソッドの定義 / 戻り値の受け取り =====
動的生成方式において、コンポーネントを生成して、そのコンポーネントに定義したメソッドの戻り値を受け取ることもできる。<br>
<br>
以下の例では、子ウインドウにメソッドを定義して、親ウインドウで動的に生成した子ウインドウのメソッドを実行して戻り値を取得している。<br>
<br>
親ウインドウのボタンを押下する時、子ウインドウが開く。<br>
子ウインドウのボタンを押下する時、子ウインドウを閉じてシグナルが親ウインドウに送信される。<br>
<br>
この方法では、親ウインドウから子ウィンドウの関数を直接呼び出し、あるいは、子ウィンドウから親ウィンドウの関数を呼び出すことで通信を行う。<br>
シグナル / シグナルハンドラを使用しないため、コードの流れが直接的になる。<br>
<br>
<u>ただし、オブジェクト間の結合度が高くなるため、複雑なアプリケーションでは管理が難しくなる可能性があることに注意すること。</u><br>
<br>
<syntaxhighlight lang="qml">
// DynamicWindow.qml
import QtQuick
import QtQuick.Window
import QtQuick.Controls
Window {
    id:      dynamicWindow
    width:  400
    height:  300
    visible: true
    title:  windowTitle
    property var    parentWindow: null
    property string windowTitle:  "Dynamic Window"
    function closeWindow() {
      if (parentWindow) parentWindow.onChildWindowClosed("Window is closing")
      dynamicWindow.close()
    }
    function getWindowInfo() {
      return {
          title: windowTitle,
          width: width,
          height: height
      }
    }
    Column {
      anchors.centerIn: parent
      spacing: 20
      Button {
          text: "Close Window"
          onClicked: {
            closeWindow()
          }
      }
      Button {
          text: "Change Title"
          onClicked: {
            windowTitle = "Updated Title"
            if (parentWindow) parentWindow.updateChildWindowInfo()
          }
      }
    }
}
</syntaxhighlight>
<br>
<syntaxhighlight lang="qml">
// MainWindow.qml
import QtQuick
import QtQuick.Window
import QtQuick.Controls
Window {
    id:      mainWindow
    width:  640
    height:  480
    visible: true
    title:  qsTr("Main Window")
    property var dynamicWindow: null
    Column {
      anchors.centerIn: parent
      spacing: 20
      Button {
          text: "Create Dynamic Window"
          onClicked: {
            var component = Qt.createComponent("DynamicWindow.qml");
            if (component.status === Component.Ready) {
                dynamicWindow = component.createObject(mainWindow, {
                  "windowTitle":  "New Dynamic Window",
                  "parentWindow": mainWindow
                });
                updateChildWindowInfo()
            }
          }
      }
      Button {
          text: "Update Window Info"
          enabled: dynamicWindow !== null
          onClicked: updateChildWindowInfo()
      }
      Text {
          id: statusText
          text: "No window closed yet"
      }
      Text {
          id: infoText
          text: "No window info yet"
      }
    }
    function updateChildWindowInfo() {
      if (dynamicWindow) {
          var windowInfo = dynamicWindow.getWindowInfo()
          console.log("Updated Window Info:", JSON.stringify(windowInfo))
          infoText.text  = "Window Info: " + JSON.stringify(windowInfo)
      }
    }
    function onChildWindowClosed(message) {
      console.log("Child window closed:", message)
      statusText.text = "Last closed: " + message
      dynamicWindow  = null
     }
     }
  }
  }
  </syntaxhighlight>
  </syntaxhighlight>
<br><br>
<br><br>


__FORCETOC__
__FORCETOC__
[[カテゴリ:Qt]]
[[カテゴリ:Qt]]