[C++,QT/Qml]14.Qml프로그래밍 cpp qml 연동3(qml 에서 C++ 함수 호출하기)
오늘 포스팅할 내용은 qml에서 c++함수를 호출하는 2번째 방법 입니다.
기존에는 signal과 slot을 사용해서 함수를 호출을 했다면 이번에는 qml에서 제가 만든 클래스를 등록을 해서
그 클래스의 함수를 직접 호출하는 방법에 대해서 설명 드리겠습니다.
qml에서 클래스를 등록하기 위해서는 클래스를 qml에 맞게 타입을 지정해야하고
그 타입을 사용하기 위해서 import를 시켜 주어야 합니다.
아래의 코드를 보겠습니다.
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <ConnectEvent.h>
#include <QQuickView>
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
ConnectEvent *event = new ConnectEvent();
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
QObject *root = engine.rootObjects()[0];//qrc:/main.qml를 등록한 엔진의 object값을 가져옴
event->setWindow(qobject_cast<QQuickWindow *>(root));//qrc:/main.qml를 등록한 엔진의 object값을 window타입으로 변경해준다.
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4f; text-decoration:none">Colored by Color Scripter
|
ConnectEvent.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
#ifndef CONNECTEVENT_H
#define CONNECTEVENT_
#include <QQuickView>
#include <QObject>
#include <iostream>
using namespace std;
class ConnectEvent : public QObject//connection을 사용하기 위해 상속 받아야 하는 클래스
{
public:
Q_OBJECT
public:
ConnectEvent();
~ConnectEvent();
void setWindow(QQuickWindow* Window);
Q_INVOKABLE void cppStringTestMethod(QString stringData);//함수앞에 Q_INVOKABLE를 선언해서 qml에서 직접 호출이 가능한 함수를 만들어 준다.
private:
QQuickWindow* mMainView;
};
#endif // CONNECTEVENT_H
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4f; text-decoration:none">Colored by Color Scripter
|
ConnectEvent.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
#include "ConnectEvent.h"
ConnectEvent::ConnectEvent()
{
cout << "ConnectEvent" << endl;
qmlRegisterType<ConnectEvent>("ConnectEvent", 1, 0, "ConnectEvent");//class를 qml에서 사용하기 위해서 등록해주는 부분
}
ConnectEvent::~ConnectEvent()
{
}
void ConnectEvent::setWindow(QQuickWindow* Window)
{
mMainView = Window;//connection을 해주기 위해 윈도우를 등록
}
void ConnectEvent::cppStringTestMethod(QString stringData)//qml 소스코드에서 클래스를 등록해서 클래스의 함수를 직접 호출하는 함수
{
cout << "cppStringTestMethod call" << endl;
std::string data_str = stringData.toStdString();//QVariant를 std::string으로 변환
cout << "cppStringTestMethod data_str: " << data_str << endl;
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4f; text-decoration:none">Colored by Color Scripter
|
main.qml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
import QtQuick 2.9
import QtQuick.Controls 2.0
import QtQuick.Window 2.2
import ConnectEvent 1.0//등록한 클래스 타입을 import해준다.
import "."
Window {
property bool mbImageClicked : true
property int mCount : 0
visible: true
width: 640
height: 480
title: qsTr("Hello World")
signal qmlSignalStringData(var stringData); //qml에서 signal을 선언해주는 부분
signal qmlSignalintData(var intData); //qml에서 signal을 선언해주는 부분
function qmlSlotTestData(data){//slot으로 등록한 함수
console.log("qmlSlotTestData data:" + data);
}
ConnectEvent//qml에 클래스를 선언해 주는 곳
{
id:connectEvent;//클래스를 선언해주고 id를 등록
}
StackView
{
id:stackView
anchors.fill: parent
initialItem: Item //제일 첫화면을 설정하는 것으로 설정을 안하면 되돌아오기가 안된다.
{
objectName: "mainscreen"//이전화면에 대한 정보를 얻기위해 설정하는 값
Rectangle//배경 색을 지정하는 부분
{
anchors.fill: parent
color:"red"
}
Text
{
id:testData
anchors.horizontalCenter: parent.horizontalCenter
text:"main screen testData"
font.pixelSize: 30
font.bold: true
}
Text
{
id:testText
anchors.centerIn: parent
text:"main screen"
font.pixelSize: 50
font.bold: true
}
Button
{
id:strButton //string형 데이터를 매개변수에 넣어서 cpp함수를 호출하는 버튼
anchors.right:nextButton.left
anchors.top:nextButton.top
anchors.rightMargin: 30
text:"String Data"
onClicked:
{
console.log("qml signal strButton click")
connectEvent.cppStringTestMethod("qml register class method"); //등록한 클래스의 함수를 호출 하는 방법
}
}
Button
{
id:nextButton
anchors.top:testText.bottom
anchors.horizontalCenter: parent.horizontalCenter
text:"go screen1"
onClicked:
{
console.log("push screen1")
stackView.push(Qt.resolvedUrl("qrc:/screen1.qml"))//다음 화면을 출력하기 위해 stack에 화면을 쌓는 코드
}
}
Button
{
anchors.top:testText.bottom
anchors.left:nextButton.right
anchors.leftMargin: 30
text:"go screen2"
onClicked:
{
console.log("push screen2")
stackView.push(Qt.resolvedUrl("qrc:/screen2.qml"))//다음 화면을 출력하기 위해 stack에 화면을 쌓는 코드
}
}
}
}
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4f; text-decoration:none">Colored by Color Scripter
|
위의 코드를 보겠습니다.
connectEvent.cpp 파일을 보시면 아래와 같이 코딩이 되어 있습니다. 이부분이 qml에서 class를 등록해서 사용할수
있도록 qml타입으로 등록해주는 코드입니다.
1
|
qmlRegisterType<ConnectEvent>("ConnectEvent", 1, 0, "ConnectEvent");//class를 qml에서 사용하기 위해서 등록해주는 부분
|
그리고 위의 등록된 클래스를 사용할 qml에서 등록된 클래스를 import시켜주는데 이부분은 import ConnectEvent 1.0
입니다. 왜 1.0으로 import시켰냐 라고 말씀하신다면 1.0은 자신이 클래스를 어떻게 등록했냐에 따라서
다르게 적어주시면 됩니다. 위의 클래스를 등록하는 부분이 1,0 으로 등록하였기 때문에 import시에도 1.0으로
클래스틑 불러올수 있습니다.
그리고 qml에서 클래스를 사용할수 있도록 qml형식으로 선언해줍니다. 선언하는 방식은 아래와 같습니다.
1
2
3
4
5
|
ConnectEvent//qml에 클래스를 선언해 주는 곳
{
id:connectEvent;//클래스를 선언해주고 id를 등록
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|
그리고 cpp파일에서는 qml에서 직접 함수를 사용 할수 있게 함수를 Q_INVOKABLE 형식으로 선언을 해주어야 합니다.
Q_INVOKABLE 형식으로 선언을 안해주면 qml에서 함수를 가져올수가 업습니다. Q_INVOKABLE 형식으로 선언하는
방법은 아래와 같습니다.
1
|
Q_INVOKABLE void cppStringTestMethod(QString stringData);//함수앞에 Q_INVOKABLE를 선언해서 qml에서 직접 호출이 가능한 함수를 만들어 준다
|
그리고 이 함수를 qml에서 호출하면 호출이 잘되는 것을 확인할수 있습니다.
qml에서 클래스의 함수를 호출하는 방법은 위에서 클래스를 qml형식으로 선언하고 등록한 id를 사용해서 호출해 주면
됩니다. 호출하는 방법은 아래와 같습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
Button
{
id:strButton //string형 데이터를 매개변수에 넣어서 cpp함수를 호출하는 버튼
anchors.right:nextButton.left
anchors.top:nextButton.top
anchors.rightMargin: 30
text:"String Data"
onClicked:
{
console.log("qml signal strButton click")
connectEvent.cppStringTestMethod("qml register class method"); //등록한 클래스의 함수를 호출 하는 방법
}
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|
여기까지 qml에서 cpp함수를 호출하는 두번째 방법에 대해서 설명 드렸습니다.
여기 까지 설명드린 qml에서 cpp함수를 호출하거나 cpp에서 qml함수를 호출한다면 기본적으로
데이터들을 다루고 앱까지는 구현을 할수 있습니다.
그래서 다음 시간에는 qml에서 listview를 다루고 listview의 데이터들을 cpp에서 저장하고 다루는 방법을 포스팅
하겠습니다. 감사합니다.!!
'QT and QML' 카테고리의 다른 글
[C++,QT/Qml]16.Qml프로그래밍 동적 리스트 만들기2(dynamic ListView) (0) | 2019.08.01 |
---|---|
[C++,QT/Qml]15.Qml프로그래밍 리스트 만들기1(ListView) (0) | 2019.07.22 |
[C++,QT/Qml]13.Qml프로그래밍 cpp qml 연동2(qml 에서 C++ 함수 호출하기) (11) | 2019.06.29 |
[C++,QT/Qml]12.Qml프로그래밍 cpp qml 연동1(c++에서 qml 함수 호출하기) (8) | 2019.06.23 |
[C++,QT/Qml]11.Qml프로그래밍 stackView 사용 하기3(이전 화면의 정보 가져오기,get previous screen data) (3) | 2019.06.16 |