[QT]example9-QML-New Window

๐Ÿ‘‰ ๋ฒ„ํŠผ ํด๋ฆญ์‹œ ๋‹ค์ด์–ผ๋กœ๊ทธ ์ฐฝ๊ณผ ์ƒˆ๋กœ์šด ์ฐฝ์„ ์˜คํ”ˆํ•ฉ๋‹ˆ๋‹ค.
When you click the button, a dialog window and a new window open.

๐Ÿ‘‰ ์ƒˆ๋กœ์šด ์ฐฝ์—์„œ ํ…์ŠคํŠธ ์ž…๋ ฅํ•˜๊ณ  ๋ฒ„ํŠผ ํด๋ฆญ์‹œ mainwindow์˜ ๋ผ๋ฒจ์— ํ…์ŠคํŠธ๊ฐ€ ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค.
Enter text in a new window and click the button to display the text in the label of the mainwindow.

๐Ÿ‘‰ ์ƒˆ๋กœ์šด์ฐฝ๊ณผ ์ด์ „ ์ฐฝ ์‚ฌ์ด์˜ ๋ณ€์ˆ˜ ์ „๋‹ฌ์€ ์‹œ๊ทธ๋„๊ณผ ์Šฌ๋กฏ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
Passing variables between new and old windows uses signals and slots.

Project WIndow

1.CMakeLists.txt

cmake_minimum_required(VERSION 3.16)

project(example9 VERSION 0.1 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(Qt6 REQUIRED COMPONENTS Quick)

qt_standard_project_setup(REQUIRES 6.8)

qt_add_executable(appexample9
    main.cpp
)
#-- qml ํŒŒ์ผ ์ถ”๊ฐ€ / Add qml files --
qt_add_qml_module(appexample9
    URI example9
    VERSION 1.0
    QML_FILES
        Main.qml
        qml/mainwindow.qml
        qml/dialog.qml
        qml/newwindow.qml
)

# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1.
# If you are developing for iOS or macOS you should consider setting an
# explicit, fixed bundle identifier manually though.
set_target_properties(appexample9 PROPERTIES
#    MACOSX_BUNDLE_GUI_IDENTIFIER com.example.appexample9
    MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
    MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
    MACOSX_BUNDLE TRUE
    WIN32_EXECUTABLE TRUE
)

target_link_libraries(appexample9
    PRIVATE Qt6::Quick
)

include(GNUInstallDirs)
install(TARGETS appexample9
    BUNDLE DESTINATION .
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

2.qml/dialog.qml


// dialog.qml
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15

Window {
    id: dialogWindow
    width: 400
    height: 300
    title: "Dialog Window"
    visible: false
    modality: Qt.ApplicationModal // ๋ชจ๋‹ฌ์ฒ˜๋Ÿผ ๋™์ž‘ / behaves like a modal
    Rectangle {
        anchors.fill: parent
        color: "#f0f0f0" // ๋ฐฐ๊ฒฝ ์ƒ‰์ƒ / background color


        ColumnLayout {
            anchors.fill: parent
            spacing: 20
            //padding: 20

            Label {
                text: "์ด๊ฒƒ์€ ์ƒˆ ์ฐฝ์ž…๋‹ˆ๋‹ค / This is a new window"
                horizontalAlignment: Text.AlignHCenter
                Layout.alignment: Qt.AlignHCenter
            }
            RowLayout {
                Layout.alignment: Qt.AlignHCenter
                spacing: 20

                Button {
                    text: "ํ™•์ธ/Confirm"
                    Layout.preferredWidth: 80
                    onClicked: dialogWindow.close()
                }

                Button {
                    text: "์ทจ์†Œ/Cancle"
                    Layout.preferredWidth: 80
                    onClicked: dialogWindow.close()
                }
            }

        }
    }
}

3.qml/mainwindow.qml

import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15


    // ์ค‘์•™ ์œ„์ ฏ / Central Widget
    Rectangle {
        anchors.fill: parent
        color: "#f0f0f0"

        // ํ…์ŠคํŠธ ๋ผ๋ฒจ / Text Label
        Label {
            id: label
            text: "TextLabel"
            width: 221
            height: 20
            anchors.horizontalCenter: parent.horizontalCenter
            anchors.top: parent.top
            anchors.topMargin: 270
            horizontalAlignment: Text.AlignHCenter
            verticalAlignment: Text.AlignVCenter
        }

        // ์ฒซ ๋ฒˆ์งธ ๋ฒ„ํŠผ / First Button
        Button {
            id: pushButton
            text: "PushButton"
            width: 75
            height: 24
            anchors.horizontalCenter: parent.horizontalCenter
            anchors.top: label.bottom
            anchors.topMargin: 30

            onClicked: {
                var component = Qt.createComponent("newwindow.qml")
                if (component.status === Component.Ready) {

                    //== ์Šฌ๋กฏ/Slot ==
                    var newWindowInstance = component.createObject(pushButton)
                    newWindowInstance.textSubmitted.connect(function(text) {
                        label.text = text
                        console.log = "Slot"
                    })
                    //====

                    newWindowInstance.visible = true
                } else {
                    console.error("์ƒˆ ์ฐฝ์„ ๋กœ๋“œํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค./The new window cannot be loaded.")
                }
            }

        }

        // ๋‘ ๋ฒˆ์งธ ๋ฒ„ํŠผ / Second Button
        Button {
            id: pushButton2
            text: "Dialogue Button2"
            width: 131
            height: 21
            anchors.horizontalCenter: parent.horizontalCenter
            anchors.top: pushButton.bottom
            anchors.topMargin: 16

            onClicked: {
                var component = Qt.createComponent("dialog.qml")
                if (component.status === Component.Ready) {
                    var dialogInstance = component.createObject(pushButton2) 
                    dialogInstance.visible = true


                } else {
                    console.error("Dialog component failed to load")
                }
            }

        }

        // ์ƒํƒœ๋ฐ” (QML์—์„œ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์ œ๊ณต๋˜์ง€๋Š” ์•Š์ง€๋งŒ, ์•„๋ž˜์ฒ˜๋Ÿผ ๊ตฌํ˜„ ๊ฐ€๋Šฅ)
        // Status bar (not provided by default in QML, but can be implemented as shown below)
        ToolBar {
            height: 22
            width: parent.width
            anchors.bottom: parent.bottom

            RowLayout {
                anchors.fill: parent
                Label {
                    text: "StatusBar"
                    Layout.alignment: Qt.AlignLeft
                }
            }
        }
    }

4.qml/newwindow.qml

import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15

Window {
    id: newWindow
    width: 400
    height: 300
    visible: true
    title: "new window"

    // ๋ผ๋ฒจ์— ์ถœ๋ ฅํ•˜๊ธฐ ์œ„ํ•œ ์‹œ๊ทธ๋„ ์ •์˜
    // Define a signal to output to the label
    signal textSubmitted(string text)
    Rectangle {
        anchors.fill: parent
        color: "#f0f0f0" // ๋ฐฐ๊ฒฝ์ปฌ๋Ÿฌ / Background Color

        ColumnLayout {
            anchors.centerIn: parent
            spacing: 10

            TextField {
                id: inputField
                placeholderText: "ํ…์ŠคํŠธ๋ฅผ ์ž…๋ ฅํ•˜์„ธ์š” / Enter text"
                Layout.fillWidth: true
            }

            Button {
                id: confirmButton
                text: "ํ™•์ธ / Confirm"
                Layout.alignment: Qt.AlignHCenter

                onClicked: {

                    // ์ฝ˜์†”์— ์ถœ๋ ฅ
                    // output to console
                    console.log("์ž…๋ ฅ๋œ ํ…์ŠคํŠธ / Entered Text:", inputField.text)

                    //์‹œ๊ทธ๋„ ๋ฐœ์ƒ
                    //Signal generation
                    textSubmitted(inputField.text)

                    // ์ฐฝ ๋‹ซ๊ธฐ ์›ํ•  ๊ฒฝ์šฐ / If you want to close the window : newWindow.close()

                }
            }
        }
    }
}

5.main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    QObject::connect(
        &engine,
        &QQmlApplicationEngine::objectCreationFailed,
        &app,
        []() { QCoreApplication::exit(-1); },
        Qt::QueuedConnection);
    engine.loadFromModule("example9", "Main");

    return app.exec();
}

6.Main.qml

import QtQuick

Window {
    width: 850
    height: 650
    visible: true
    title: qsTr("Main Window")

    // ๋กœ์ปฌ QML ํŒŒ์ผ ๋กœ๋“œ / Local QML file load
    Loader {
        anchors.fill: parent
        source: "qml/mainwindow.qml"
    }
}

7.์‹คํ–‰ / Run

Leave a Reply

Your email address will not be published. Required fields are marked *