[C++,QT/Qml]21.Qml프로그래밍 동적 리스트 만들기7(체크박스 리스트 삭제)
아직도 내용이 많이 남았는데 ㅎㅎ 리스트구현하는게 작은게 아닌것 같아요 ㅎㅎ
암튼 오늘은 지난시간에 말씀 드렸던 리스트 삭제 후 stackview.pop을 하면 메인화면은 리스트가 업데이트 되지않아서
리스트가 그대로인데 이 메인화면의 리스트를 업데이트 하도록 시그널을 주는 내용을 다루어 보겠습니다.
일단 동영상을 먼저 보겠습니다.
지난 포스팅에서 구현한 내용에 back버튼을 추가해서 리스트 삭제후 back을 해보겠습니다.
이전에 포스팅한 코드로 돌려보시면 위처럼 첫번째 화면의 리스트가 삭제가 되지 않습니다.
그 이유는 2번째 화면의 리스트를 업데이트 했지만 첫번째 화면의 리스트가 갱신이 안되었기 때문이죠
그래서 삭제를 한 후에 1번째 화면에 리스트가 갱신이 되었다는것을 알려주어야 합니다.
그래서 아래와 같이 코드를 작성하시면 됩니다.
아래 코드를 보겠습니다.
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
import QtQuick 2.9
import QtQuick.Controls 2.0
import QtQuick.Window 2.2
import ConnectEvent 1.0//등록한 클래스 타입을 import해준다.
import "."
Window {
id:mainWindow
property bool mbImageClicked : true
property int mCount : 0
property int mListClickIndex : 0//클릭한 리스트의 index를 담는 전역 변수
signal qmlSignalListUpdate();//리스트가 업데이트되었다는 것을 알려주기 위한 시그널 등록
visible: true
width: 800
height: 600
title: qsTr("Hello World")
ConnectEvent//클래스를 qml 타입으로 지정
{
id:connectEvent
}
Component.onCompleted://view가 처음 실행될때 제일 처음으로 불려지는곳
{
for(var i = 0; i < connectEvent.getListSize(); i++){//리스트의 개수만큼 for문을 돌린다.
listView.model.append({"list_text": connectEvent.getListTitle(i),//모델에 리스트의 데이터값을 넣어준다.
"list_button_text": connectEvent.getListButtonText(i)})//listview에 선언한 임의의 모델 안에 데이터를 넣어준다.
}
}
onQmlSignalListUpdate:{//시그널이 호출되면 실행하는 함수
console.log("onQmlSignalListUpdate called")
listView.model.clear();//리스트 초기화
for(var i = 0; i < connectEvent.getListSize(); i++){//리스트 초기화 후 다시 넣어줌
listView.model.append({"list_text": connectEvent.getListTitle(i),
"list_button_text": connectEvent.getListButtonText(i)})
}
}
Component {//리스트 뷰의 틀을 만든다.
id: contactDelegate
Item {
width: 800
height: 100
Text//리스트에 텍스트를 넣어주기 위해 텍스트 객체를 만들어준다.
{
id:listView_Text
anchors.left: parent.left
anchors.leftMargin: 50
anchors.verticalCenter: parent.verticalCenter
text:list_text//모델에 매칭이될 변수 listview에 원하는 값을 넣기위해서 설정하는 값
}
Rectangle//리스트의 구분선
{
id:line
width:parent.width
anchors.bottom:parent.bottom//현재 객체의 아래 기준점을 부모객체의 아래로 잡아주어서 위치가 아래로가게 설정
height:1
color:"black"
}
MouseArea
{
id:listMouseArea
anchors.fill: parent
onClicked:
{
mListClickIndex = index;//여기에서 사용하는 index는 클릭했을때의 index를 리턴해준다
//그래서 현재 선택한 리스트를 전역변수에 담고 다음 화면에서 그에 해당하는 정보를 보여준다.
stackView.push(Qt.resolvedUrl("qrc:/deleteList.qml"))
}
}
//버튼 객체를 mouseArea아래로 옮겼다 이유는 mouseArea가 부모의 영역을 포함하고 있는데
//버튼 영역도 부모의 영역 안에 있기 때문에 버튼클릭시 버튼클릭이 아닌 리스트의 클릭이 되어 버린다.
Button//리스트에 버튼을 넣어주기 위해 버튼 객체를 만들어준다.
{
id:listView_Button
width:120
height:40
anchors.rightMargin: 30
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
text: list_button_text//모델에 매칭이될 변수 listview에 원하는 값을 넣기위해서 설정하는 값
onClicked:
{
connectEvent.deleteListItem(index);//c++ 리스트의 데이터를 삭제
listView.model.remove(index);//리스트의 모델에 삭제하는 함수(실시간 삭제)
}
}
}
}
StackView{
id:stackView
anchors.fill: parent
initialItem: Item //제일 첫화면을 설정하는 것으로 설정을 안하면 되돌아오기가 안된다.
{
ListView {
id:listView
anchors.fill: parent
model: ListModel{}//임으로 만들 모델을 넣어준다.
delegate: contactDelegate//delegate란 리스트 한개의 틀(틀을 하나 만들어서 그것들을 여러개 붙여놓은것이 리스트 뷰이다.)
highlight: Rectangle { color: "lightsteelblue"; radius: 5 }
focus: true
}
}
}
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|
deleteList.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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
import QtQuick 2.0
import QtQuick.Controls 2.0
import QtQuick.Window 2.2
import ConnectEvent 1.0//등록한 클래스 타입을 import해준다.
Item {
width: 800
height: 600
Component.onCompleted://view가 처음 실행될때 제일 처음으로 불려지는곳
{
console.log("connectEvent.getListSize():" + connectEvent.getListSize())
for(var i = 0; i < connectEvent.getListSize(); i++){//리스트의 개수만큼 for문을 돌린다.
listView.model.append({"list_text": connectEvent.getListTitle(i),//모델에 리스트의 데이터값을 넣어준다.
"list_button_text": connectEvent.getListButtonText(i),
"checkValue": false})//listview에 선언한 임의의 모델 안에 데이터를 넣어준다.
}
}
Component {//리스트 뷰의 틀을 만든다.
id: contactDelegate
Item {
width: 800
height: 100
CheckBox
{
id:checkbox
anchors.left: parent.left
anchors.leftMargin: 30
anchors.verticalCenter: parent.verticalCenter
checked: checkValue
}
Text//리스트에 텍스트를 넣어주기 위해 텍스트 객체를 만들어준다.
{
id:listView_Text
anchors.left: parent.left
anchors.leftMargin: 100
anchors.verticalCenter: parent.verticalCenter
text:list_text//모델에 매칭이될 변수 listview에 원하는 값을 넣기위해서 설정하는 값
}
Rectangle//리스트의 구분선
{
id:line
width:parent.width
anchors.bottom:parent.bottom//현재 객체의 아래 기준점을 부모객체의 아래로 잡아주어서 위치가 아래로가게 설정
height:1
color:"black"
}
MouseArea
{
id:listMouseArea
anchors.fill: parent
onClicked:
{
if(listView.model.get(index).checkValue){
listView.model.get(index).checkValue = false
}else
listView.model.get(index).checkValue = true
}
}
}
}
ListView {
id:listView
width:parent.width
height:parent.height - 100//리스트 뷰 밑에 버튼을 만들기위해 리스트뷰의 크기를 설정하는 것
clip:true//true 하면 리스트의 높이 보다 커도 리스트가 보여지는 것처럼 됨
//false 하면 리스트의 높이만 큼만 deletegate가 보여짐
model: ListModel{}//임으로 만들 모델을 넣어준다.
delegate: contactDelegate//delegate란 리스트 한개의 틀(틀을 하나 만들어서 그것들을 여러개 붙여놓은것이 리스트 뷰이다.)
highlight: Rectangle { color: "lightsteelblue"; radius: 5 }
focus: true
}
Button
{
id:deleteButton
width:200
height:50;
anchors.top: listView.bottom
anchors.topMargin: 30
anchors.horizontalCenter:parent.horizontalCenter
text:"delete"
onClicked: {
for(var i = listView.count - 1; i >= 0; i--){
if(listView.model.get(i).checkValue){
connectEvent.deleteListItem(i);
listView.model.remove(i);
}
}
mainWindow.qmlSignalListUpdate();//삭제 완료후 리스트가 업데이트 되었다는 것을 알려주기 위해 시그널을 호출 해준
}
}
Button
{
id:allSelectButton
width:200
height:50;
anchors.top: listView.bottom
anchors.topMargin: 30
anchors.left: deleteButton.right
anchors.leftMargin: 20
text:"all Select"
onClicked: {
for(var i = 0; i < listView.count; i++){
if(!listView.model.get(i).checkValue){
listView.model.get(i).checkValue = true
}
}
}
}
Button
{
id:backbutton
width:200
height:50;
anchors.top: listView.bottom
anchors.topMargin: 30
anchors.right: deleteButton.left
anchors.rightMargin: 20
text:"back"
onClicked: {
stackView.pop();
}
}
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|
먼저 메인 윈도우에 시그널 하나를 추가합니다. 이 시그널을 리스트가 삭제되었을때 삭제 되었다는것을 알려주기 위한
시그널 입니다.
1
2
|
signal qmlSignalListUpdate();//리스트가 업데이트되었다는 것을 알려주기 위한 시그널 등록
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|
그리고 시그널이 발생되었을때 실행할 함수를 작성 합니다.
이 시그널이 발생되면 메인화면의 리스트가 초기화 되고 다시 리스트를 그리게 수정 해줍니다.
1
2
3
4
5
6
7
8
|
onQmlSignalListUpdate:{//시그널이 호출되면 실행하는 함수
console.log("onQmlSignalListUpdate called")
listView.model.clear();//리스트 초기화
for(var i = 0; i < connectEvent.getListSize(); i++){//리스트 초기화 후 다시 넣어줌
listView.model.append({"list_text": connectEvent.getListTitle(i),
"list_button_text": connectEvent.getListButtonText(i)})
}
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|
여기서 onQmlSignalListUpdate 함수란 qml에서는 시그널을 등록하면 그 이름에 on을 붙혀서 시그널이 발생 되었을때의
함수를 만들어 줄수 있습니다. 그래서 onQmlSignalListUpdate 함수를 작성한 것 입니다.
여기에 리스트를 초기화 하고 리스트를 다시 넣어주는 코드를 넣어서 삭제된 리스트가 업데이트되도록 코드를 작성해
줍니다.
그리고 이 시그널을 발생시키고 싶은 위치에 시그널을 발생시키도록 코드를 작성해 줍니다.
저는 리스트 삭제요청했을때 앞의 리스트가 삭제되도록 하겠습니다.
(삭제를 시킬때마다 리스트가 업데이트 되면 쓸데없이 함수를 계속 호출할수 있으니 안좋은 방법이나 화면이 이전화면으로 갔을때 호출시키는 함수를 아직 언급하지 않아서 삭제버튼에 작성을 하였습니다. 양해해 주시면 감사하겠습니다.)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
Button
{
id:deleteButton
width:200
height:50;
anchors.top: listView.bottom
anchors.topMargin: 30
anchors.horizontalCenter:parent.horizontalCenter
text:"delete"
onClicked: {
for(var i = listView.count - 1; i >= 0; i--){
if(listView.model.get(i).checkValue){
connectEvent.deleteListItem(i);
listView.model.remove(i);
}
}
mainWindow.qmlSignalListUpdate();//삭제 완료후 리스트가 업데이트 되었다는 것을 알려주기 위해 시그널을 호출 해준
}
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none;color:white">cs |
위의 코드처럼 리스트를 삭제 요청해서 삭제할때 메인화면의 리스트가 업데이트 되도록 시그널을 호출해 줍니다.
이렇게 되면 리스트가 삭제되었을때 메인화면의 리스트가 업데이트 되는 것을 구현 할수 있습니다.
네 여기까지 체크박스 리스트에 대한 내용을 다루어 봤는데요
다음 시간에는 리스트의 스크롤 바를 만드는 것을 다루어 보겠습니다.
리스트의 스크롤바는 qt에서 지원하는 스크롤 바가 있고 프로그래머가 임의로 만드는 custom스크롤 바가 있는데
qt에서 지원하는 스크롤 바를 먼저 구현한 후 custom스크롤 바를 구현해서 포스팅 하겠습니다.
여기 까지 읽어주셔서 감사합니다!!
'QT and QML' 카테고리의 다른 글
[C++,QT/Qml]23.Qml프로그래밍 리스트 스크롤바 만들기2(custom scrollbar 만들기) (0) | 2019.09.22 |
---|---|
[C++,QT/Qml]22.Qml프로그래밍 리스트 스크롤바 만들기1(qml scrollbar 사용하기) (0) | 2019.09.08 |
[C++,QT/Qml]20.Qml프로그래밍 동적 리스트 만들기6(체크박스 리스트 삭제) (0) | 2019.09.01 |
[C++,QT/Qml]19.Qml프로그래밍 동적 리스트 만들기5(리스트 삭제기능,listview Delete) (2) | 2019.08.17 |
[C++,QT/Qml]18.Qml프로그래밍 동적 리스트 만들기4(dynamic ListView 클릭이벤트 주기) (4) | 2019.08.10 |