[C++,QT/Qml]12.Qml프로그래밍 cpp qml 연동1(c++에서 qml 함수 호출하기)
안녕하세요 고급 개발자가 꿈인 코린이 입니다.
오늘은 cpp와 qml의 데이터 전송하는 방법에 대해서 포스팅 하겠습니다.
qml의 gui프로그램을 만들다 보면 db에서 데이터를 받아와서 qml에서 데이터를 출력해야 한더던가.
다른앱에서 받아온 데이터들을 qml에서 출력해야 한다는지 등을 만들려고하면 qml프로그래밍 만으로는 한계가
있습니다.
그래서 이런 db에서 받아온다던가 다른앱 에서 받아오는 기능들은 c++을 이용해서 구현 하고있는데요
여기서 c++에서 받은 데이터들을 qml에 넘겨주어야하는데 이럴때 사용하는 방법에 대해 설명 드리겠습니다.
qt의 기본적인 구조로는 signal slot이라는 구조를 가지고 있습니다.
즉 signal이 발생되면 slot이라는 함수가 호출이 된다는 것이죠 그래서 특정한 signal를 만들고 이 시그널이 발생되면
어떻한 클래스나 윈도우의 slot이 발생될 것 인지 미리 등록을 한 후에 signal이 발생되면 등록된 slot이 호출되는
구조 입니다.
아래의 코드를 보겠습니다.
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
28
29
|
#ifndef CONNECTEVENT_H
#define CONNECTEVENT_
#include <QQuickView>
#include <QObject>
class ConnectEvent : public QObject//connection을 사용하기 위해 상속 받아야 하는 클래스
{
public:
Q_OBJECT//솔직히 왜 추가해야하는지는 모르겠지만 추가를 안하면 connection할때 에러 난다(추후에 알아 보도록 하겠다.)
//그리고 Q_OBJECT 추가한 후 Build->Run qmake를 해주자(중요!!)
public:
ConnectEvent();
~ConnectEvent();
void cppSignaltoQmlSlot();//cpp에서 시그널을 날리고 qml 에서 받기위해 connection을 해두는 함수
void setWindow(QQuickWindow* Window);
private:
QQuickWindow* mMainView;
signals://클래스에서 signal등록 하는 방법
void cppSignaltestData(QVariant);
};
#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
32
33
34
|
#include "ConnectEvent.h"
ConnectEvent::ConnectEvent()
{
}
ConnectEvent::~ConnectEvent()
{
}
void ConnectEvent::cppSignaltoQmlSlot()
{
QObject::connect(this, SIGNAL(cppSignaltestData(QVariant)), mMainView, SLOT(qmlSlotTestData(QVariant)));//시그널과 슬롯을 연결해주는 connection
emit cppSignaltestData(3);//cpp에서 시그널을 호출하는 부분 매개변수에 3을 넣어서 3이 qml함수에 전달됨
emit cppSignaltestData(4);
emit cppSignaltestData(5);
emit cppSignaltestData(6);
}
void ConnectEvent::setWindow(QQuickWindow* Window)
{
mMainView = Window;//connection을 해주기 위해 윈도우를 등록
cppSignaltoQmlSlot();//윈도우 등록과 동시에 connection 등록
}
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
|
import QtQuick 2.9
import QtQuick.Controls 2.0
import QtQuick.Window 2.2
import "."
Window {
property bool mbImageClicked : true
property int mCount : 0
visible: true
width: 640
height: 480
title: qsTr("Hello World")
function qmlSlotTestData(data){//slot으로 등록한 함수
console.log("qmlSlotTestData data:" + data);
}
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: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
|
위의 코드를 보면 conecctEvent.cpp 에 Qobject::connect 이라는 함수가 있다 이 함수가 signal과 slot을
연결 시켜주기위해 등록한 부분이다. signal에 conecctEvent.hpp에서 등록한 signal을 등록하고 slot에
연결하고싶은 윈도우의 함수를 선언 시켰다.
QObject::connect(this, SIGNAL(cppSignaltestData(QVariant)), mMainView, SLOT(qmlSlotTestData(QVariant)));
즉 현재 클래스의 cppSignaltestData의 signal을 호출하면 main.qml이 등록된 윈도우인 mMainView의 qmlSlotTestData
함수가 호출이 되는 것이다. 여기서 매개 변수에 QVariant로 한 이유는 qml이 자바스크립트 문법을 그대로 사용하는
언어인데 자바스크립트의 var 즉 variables를 표현하기 위한 것으로 따로 지정한 타입이 없어서 넣은 값에 따라 타입이
바뀌게 하는 것입니다. 그래서 int형을 넣으면 int형으로 보내지고 string형으로 보내면 string형식으로 보내지는 것
입니다.
그래서 위의 코드를 보시면 int형 3,4,5,6을 넣어주어서 qml쪽 코드의 로그에 3,4,5,6이 찍히는 것을 볼수 있습니다.
위 코드를 활용하면 cpp에서 qml에 데이터를 전송하면 서버에서 받아오는 값들이나 db에서 받아오는 값들을 cpp에서
저장한 후 qml에 전송해서 그 값으로 ui를 출력할 수 있는 프로그램을 만들수가 있습니다.
다음 포스팅에는 qml에서 cpp함수 연결하는 것을 포스팅 하겠습니다.
감사합니다.
'QT and QML' 카테고리의 다른 글
[C++,QT/Qml]14.Qml프로그래밍 cpp qml 연동3(qml 에서 C++ 함수 호출하기) (0) | 2019.07.14 |
---|---|
[C++,QT/Qml]13.Qml프로그래밍 cpp qml 연동2(qml 에서 C++ 함수 호출하기) (11) | 2019.06.29 |
[C++,QT/Qml]11.Qml프로그래밍 stackView 사용 하기3(이전 화면의 정보 가져오기,get previous screen data) (3) | 2019.06.16 |
[C++,QT/Qml]10.Qml프로그래밍 stackView 사용 하기3(뷰 이동시 애니메이션 변경 하기) (14) | 2019.06.15 |
[C++,QT/Qml]9.Qml프로그래밍 stackView 사용 하기2(뷰 시작시 데이터 넣기) (2) | 2019.06.12 |