[QT]example3-QML+C++(2)

๐Ÿ‘‰[QT]example3-QML+C++(1)์˜ ์ถ”๊ฐ€ ์„ค๋ช…์ž…๋‹ˆ๋‹ค.
Additional explanation of [QT]example3-QML+C++(1).

1.์ฝ”๋“œ์˜ ์—ญํ•  / Role of code

โœ”๏ธMyConnector.h :

— ํด๋ž˜์Šค์˜ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜, ๋ฉ”์„œ๋“œ, ์‹œ๊ทธ๋„/์Šฌ๋กฏ ๋“ฑ์„ ์ •์˜ ํ•ฉ๋‹ˆ๋‹ค.
Defines member variables, methods, signals/slots, etc. of a class.

— ์—ฌ๊ธฐ์— ๊ธฐ๋Šฅ ๊ตฌํ˜„์€ ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.
No functionality is implemented here.

— ๋‹ค๋ฅธ ํŒŒ์ผ์—์„œ ์ด ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ์ด ํ—ค๋”๋ฅผ #include ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค
To use this class in other files, you must #include this header.

— ์ด ์ฝ”๋“œ์— ๊ธฐ์ˆ ํ•œ ๋‚ด์šฉ์„ MyConnector.cpp์™€ Screen01.qml์—์„œ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.
Implement the functionality described in this code in MyConnector.cpp and Screen01.qml.

class MyConnector : public QObject {}
-- QObject์ƒ์† :  signal/slot์‚ฌ์šฉ
QObject inheritance: using signal/slot


explicit
-- explictํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์•”์‹œ์  ํ˜•๋ณ€ํ™˜์„๋ง‰์Œ(์˜ค๋ฅ˜ ๋ฐœ์ƒ์„ ์ค„์ด๊ธฐ ์œ„ํ•ด)
Use the explicit keyword to prevent implicit type conversion (to reduce errors)
 
Q_INVOKABLE
-- ์ด ํ‚ค์›Œ๋“œ๋Š” C++ ๋ฉ”์„œ๋“œ๋ฅผ QML์—์„œ ์ง์ ‘ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ํ‚ค์›Œ๋“œ
This keyword allows you to call C++ methods directly from QML.

Q_OBJECT
-- QT์™€c++์„ ์—ฐ๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ๋งคํฌ๋กœ(์ฝ”๋“œ๋ฅผ ์ž๋™์œผ๋กœ ์น˜ํ™˜ํ•˜๊ฑฐ๋‚˜ ์‚ฝ์ž…ํ•ด์ฃผ๋Š” ์ง€์‹œ๋ฌธ
Macros for connecting QT and C++ (directives that automatically replace or insert code)
)

signals:
  void resultReady(const QString &result);
-- ์‹œ๊ทธ๋„์„ ์ •์˜ / define a signal

โœ”๏ธMyConnector.cpp

— ์—ฌ๊ธฐ์„œ ๊ธฐ๋Šฅ ๊ตฌํ˜„์„ ํ•ฉ๋‹ˆ๋‹ค. / This is where we implement the function.

 MyConnector::MyConnector(QObject *parent) : QObject(parent) {}
 
  -- ์ด ์ฝ”๋“œ๋Š” ์ƒ์„ฑ์ž ์ดˆ๊ธฐํ™” ์ฝ”๋“œ๋กœ ์•„๋ž˜ ๋ถ€๋ถ„์˜ ์ฝ”๋“œ์™€ ๊ฐ™์€ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค..
     This code is the constructor initialization code and is the same as the code below.
 

    class MyConnector {
        public:
            MyConnector(QObject *parent);
    };



 QObject(parent) :
 
 -- ๋ถ€๋ชจ ํด๋ž˜์Šค QObject์˜ ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.
    Calls the constructor of the parent class QObject.
 -- ์ƒ์† ๋ฐ›์„ ๋–„ ์ƒ์†๋ฐ›๋Š” ๋ถ€๋ชจ์˜ ์ƒ์„ฑ์ž๋„ ์ดˆ๊ธฐํ™” ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

    When inheriting, you must also initialize the constructor of the inheriting parent.
 -- ๊ทธ๋ž˜์„œ MyConnector ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ๋•Œ, QObject๋„ ์ดˆ๊ธฐํ™” ํ•ฉ๋‹ˆ๋‹ค.
    So when we create the MyConnector object, we also initialize the QObject.

emit resultReady(combined);
-- updateTextํ•จ์ˆ˜ ํ˜ธ์ถœ์‹œ(Screen01.qml์—์„œ ๋ฒ„ํŠผํด๋ฆญ ํ• ๋•Œ) ์ด resultReady(combined)์‹œ๊ทธ๋„์„ ๋ฐœ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค.
-- When the updateText function is called (when the button is clicked in Screen01.qml), this resultReady(combined) signal is generated.

โœ”๏ธqml/Screen01.qml :

Connections{ } ”

–>C++ ๊ฐ์ฒด์˜ ์‹œ๊ทธ๋„์„ QML์—์„œ ์ฒ˜๋ฆฌ
Handling signals from C++ objects in QML

target : myConnector

–>์—ฐ๊ฒฐํ•  C++ ๊ฐ์ฒด (myConnector) [myConnector.h]
C++ object to connect (myConnector) [myConnector.h]

— QML UI์—์„œ C++ ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
Use C++ objects in QML UI.

— ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ updateText() ํ˜ธ์ถœ, ์‹œ๊ทธ๋„ ๋ฐœ์ƒ ์‹œ onResultReady()๋กœ ๋ฐ˜์‘ํ•ฉ๋‹ˆ๋‹ค.
When the button is clicked, updateText() is called, and when a signal is generated, onResultReady() is responded to.

        Button {
            id: button
            text: qsTr("Button")
            // === ์ฝ”๋“œ์ถ”๊ฐ€:ํด๋ฆญ ์ด๋ฒคํŠธ ===
            // === Add code:Click Event ===
            onClicked: myConnector.updateText(textEdit.text, textEdit2.text)

        }
        // === ์ฝ”๋“œ์ถ”๊ฐ€:์—ฐ๊ฒฐ ===
        // === Add code:connection ===
        Connections {
            target: myConnector

            // Qt QML์—์„œ๋Š” ์‹œ๊ทธ๋„ ์ด๋ฆ„์ด resultReady์ด๋ฉด,
            // QML์—์„œ ๊ทธ ์‹œ๊ทธ๋„์— ๋ฐ˜์‘ํ•˜๋Š” ํ•จ์ˆ˜ ์ด๋ฆ„์€ **์ž๋™์œผ๋กœ onResultReady๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.
            // ํŒŒ๋ผ๋ฉ”ํ„ฐ ํƒ€์ž…๊ณผ ์ˆซ์ž๊ฐ€ ์ผ์น˜ํ•ด์•ผํ•จ.
            // In Qt QML, if the signal name is resultReady,
            // the function that responds to that signal in QML is automatically named onResultReady.
            // The parameter types and numbers must match.
            
            function onResultReady(result) {
                text1.text = result
            }
        }

โœ”๏ธmain.cpp :

— C++ํŒŒ์ผ๊ณผ QMLํŒŒ์ผ์„ ์—ฐ๊ฒฐํ•˜๋Š” ๋ธŒ๋ฆฟ์ง€ ์—ญํ• .
Acts as a bridge connecting C++ files and QML files.

— MyConnector.cpp์™€ Screen01.qmlํŒŒ์ผ์„ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค.
Connect the MyConnector.cpp and Screen01.qml files.

โœ”๏ธMain.qml :

— ์ด qmlํŒŒ์ผ์—์„œ qml/Screen01.qmlํŒŒ์ผ ๋กœ๋”ฉํ•ฉ๋‹ˆ๋‹ค.
Load the qml/Screen01.qml file from this qml file.

2.ํ๋ฆ„ ์ •๋ฆฌ / flow summary

1) ํ—ค๋”์—์„œ ์‹œ๊ทธ๋„ ์ •์˜ ํ•ฉ๋‹ˆ๋‹ค.
Define the signal in the header.

2) MyConnector.cpp์—์„œ ๋ฉ”์„œ๋“œ์™€ ํ•จ๊ป˜ ๊ตฌํ˜„ ํ•ฉ๋‹ˆ๋‹ค.
Implement it with methods in MyConnector.cpp.

3)๋ฉ”์„œ๋“œ ํ˜ธ์ถœ์‹œ ์‹œ๊ทธ๋„์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
Executes a signal when a method is called.

4)main.cpp์—์„œ QML(Screen01.qml)ํŒŒ์ผ๊ณผ MyConnector.cpp์—ฐ๊ฒฐ์„ค์ •
Setting up the connection between the QML (Screen01.qml) file and MyConnector.cpp in main.cpp

5)๋ฒ„ํŠผ ํด๋ฆญ์œผ๋กœ ๊ฐ’์€ MyConnector.cpp์˜ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด์„œ ๊ฐ’์„ ๋„˜๊ฒจ์ฃผ๊ณ 
ํ•จ์ˆ˜๋‚ด์—์„œ ์‹œ๊ทธ๋„ ์‹คํ–‰ํ•œ๋‹ค.
When a button is clicked, the value is passed to a function in MyConnector.cpp, which then executes a signal within the function.

6)์‹œ๊ทธ๋„ ์ด๋ฆ„์— on<์‹œ๊ทธ๋„>์ด๋ฆ„์ด ๋™์ผํ•œ ํ•จ์ˆ˜๋ฅผ Screen02.qml์˜ Connection๋ธ”๋Ÿญ์—์„œ ์ฐพ์•„ ๊ฐ’์„ ๋„˜๊ฒจ๋‘”๋‹ค.
Find the function with the same name as on in the Connection block of Screen02.qml and pass the value to it.

7)๊ฒฐ๊ตญ์€ ์‹œ๊ทธ๋„์„ emit์„ ์‹คํ–‰ํ•˜๋ฉด on<์‹œ๊ทธ๋„์ด๋ฆ„>๊ณผ ๊ฐ™์€ ํ•จ์ˆ˜์— ๊ฐ’์„ ๋„˜๊ฒจ์ฃผ๋Š”๊ฒŒ ํ•ต์‹ฌ ํฌ์ธํŠธ์ž…๋‹ˆ๋‹ค.
Ultimately, the key point is that when you emit a signal, you pass a value to a function like on.

Leave a Reply

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