👉기능은 버튼 클릭하면 텍스트 입력 2개에 입력된 정보를 로컬 데이터베이스에 저장하고 리스트뷰에 표시해줍니다.
The function saves the information entered in the two text inputs to a local database when the button is clicked and displays it in a list view.
👉 QML자체가 로컬 데이터베이스 연동기능이 있습니다.
QML itself has a local database connection function.
👉프로젝트생성 후 수정해야할건 Main.qml과 Screen01.qml,CMakeLists.txt입니다.
After creating the project, the files that need to be modified are Main.qml, Screen01.qml, and CMakeLists.txt.
👉CMakeLists.txt파일에서 Screen01.qml을 인식하도록 설정합니다.
Set the CMakeLists.txt file to recognize Screen01.qml.
👉Main.qml은 Screen01.qml을 불러오는 역할만 수행합니다.
Main.qml only performs the role of loading Screen01.qml.
👉모든 데이터처리와 앱디자인은 Screen01.qml에서 수행합니다.
All data processing and app design is performed in Screen01.qml.
1.CMakeLists.txt
✔️ 프로젝트 디렉토리내에 qml/Screen01.qml 파일을 만듭니다.
Create a file named qml/Screen01.qml in the project directory.
✔️ qml/Screen01.qml 이 코드만 추가하면 됩니다.
Just add this code to qml/Screen01.qml.
cmake_minimum_required(VERSION 3.16)
project(example5 VERSION 0.1 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(Qt6 REQUIRED COMPONENTS Quick)
#--
find_package(Qt6 6.5 COMPONENTS Quick REQUIRED)
qt_standard_project_setup(REQUIRES 6.8)
qt_add_executable(appexample5
main.cpp
)
qt_add_qml_module(appexample5
URI example5
VERSION 1.0
QML_FILES
Main.qml
qml/Screen01.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(appexample5 PROPERTIES
# MACOSX_BUNDLE_GUI_IDENTIFIER com.example.appexample5
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(appexample5
PRIVATE Qt6::Quick
)
include(GNUInstallDirs)
install(TARGETS appexample5
BUNDLE DESTINATION .
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
2.Main.qml
✔️ 볼드체 설정 된 부분의 코드만 입력하면 됩니다.
You only need to enter the code for the bolded part.
import QtQuick
import QtQuick.Controls
import QtQuick.Window
Window {
width: 800
height: 600
visible: true
title: qsTr("QML LocalStorage Example")
Loader {
anchors.fill: parent
source: "qml/Screen01.qml" // 로컬 QML 파일 로드 / Local QML file load
}
}
3.qml/Screen01.qml
✔️여기서 데이터 입력, 수정, 삭제를 처리합니다.
This is where you enter, edit, and delete data.
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.LocalStorage
Rectangle {
id: root
width: 800
height: 600
color: "#EAEAEA"
property var db
property int selectedId: -1 // 선택된 레코드 ID / Seclected Record ID
Component.onCompleted: {
db = LocalStorage.openDatabaseSync("ExampleLocalDB", "1.0", "Local DB Example", 1000000)
db.transaction(function(tx) {
tx.executeSql("CREATE TABLE IF NOT EXISTS records(id INTEGER PRIMARY KEY AUTOINCREMENT, text1 TEXT, text2 TEXT)")
})
loadData()
}
// DB에서 데이터 불러오기
// Retrieving data from DB
function loadData() {
db.transaction(function(tx) {
const rs = tx.executeSql("SELECT * FROM records ORDER BY id DESC")
listModel.clear()
for (let i = 0; i < rs.rows.length; i++) {
listModel.append({
id: rs.rows.item(i).id,
text1: rs.rows.item(i).text1,
text2: rs.rows.item(i).text2
})
}
selectedId = -1
})
}
// DB에 새 데이터 추가
// Add new data to DB
function insertData(t1, t2) {
if (t1.trim() === "" || t2.trim() === "") {
console.log("입력값이 비어 있습니다.")
return
}
db.transaction(function(tx) {
tx.executeSql("INSERT INTO records (text1, text2) VALUES (?, ?)", [t1, t2])
})
input1.text = ""
input2.text = ""
loadData()
}
// 선택된 레코드 삭제
// Delete selected record
function deleteSelected() {
if (selectedId === -1) return
db.transaction(function(tx) {
tx.executeSql("DELETE FROM records WHERE id = ?", [selectedId])
})
loadData()
}
// DB에 모든 데이터 삭제
// Delete all data in DB
function deleteAllData() {
db.transaction(function(tx) {
tx.executeSql("DELETE FROM records")
})
loadData()
}
ColumnLayout {
anchors.centerIn: parent
spacing: 12
width: 300
// 리스트 뷰 / List View
Rectangle {
Layout.fillWidth: true
height: 250
color: "white"
border.color: "#B0B0B0"
radius: 4
ListView {
id: listView
// 부모 Reactangle크기와 같게 설정
// Set the size to be the same as the parent Reactangle
anchors.fill: parent
// 부모 Rectangle의 경계 안쪽으로 4px 여유
// Rectangle테두리가 안보이기때문에
// 4px margin inside the parent Rectangle's border
// Because the Rectangle border is not visibl
anchors.margins: 4
clip: true
model: ListModel { id: listModel }
interactive: true
highlightFollowsCurrentItem: true
currentIndex: -1
delegate: Rectangle {
id: delegateRect
height: 36
width: listView.width
//anchors.fill: parent
//anchors.margins: 6
//anchors.left: parent.left
//anchors.right: parent.right
// 레코드색 변경 / Change record color
color: listView.currentIndex === index ? "#D0E6FF" : (index % 2 === 0 ? "#FFFFFF" : "#FFFFFF")
// -- 줄무늬 형태 적용 / Apply striped shape
//color: listView.currentIndex === index ? "#D0E6FF" : (index % 2 === 0 ? "#F9F9F9" : "#FFFFFF")
Row {
anchors.fill: parent
anchors.margins: 6
spacing: 10
Text { text: text1; font.pixelSize: 14; color: "black" }
Text { text: text2; font.pixelSize: 14; color: "gray" }
}
MouseArea {
anchors.fill: parent
onClicked: {
listView.currentIndex = index
root.selectedId = id
}
}
}
}
}
// 입력 필드 / input field
TextField { id: input1; Layout.fillWidth: true; placeholderText: "텍스트1 입력/text1 input" }
TextField { id: input2; Layout.fillWidth: true; placeholderText: "텍스트2 입력/text2 input" }
// 버튼 영역 / button area
RowLayout {
Layout.fillWidth: true
spacing: 10
Button {
text: "저장/Save"
Layout.fillWidth: true
onClicked: insertData(input1.text, input2.text)
}
Button {
text: "삭제/Delete"
Layout.fillWidth: true
enabled: selectedId !== -1
onClicked: deleteSelected()
}
Button {
text: "모두삭제/DeleteAll"
Layout.fillWidth: true
onClicked: deleteAllData()
}
}
}
}