[QT]example4-Widget-database(SQLite)

๐Ÿ‘‰ ์•„๋ž˜๋Š” ์œ„์ ฏ ๋ฐฉ์‹์˜ ๊ฒฝ์šฐ ์ž…๋‹ˆ๋‹ค.
Below is the widget method.

1.UI๋””์ž์ธ / UI Desing

2.mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

// ์ฝ”๋“œ ์ถ”๊ฐ€ / Add code to here
#include <QStringListModel>


QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;

    // --> ์ฝ”๋“œ ์ถ”๊ฐ€ / Add cod to here

    void loadData(); // ๋ฐ์ดํ„ฐ๋กœ๋”ฉ / data loding
    void deleteSelectedRecord(); // db๋ ˆ์ฝ”๋“œ ์‚ญ์ œ / delete db record
    void deleteAllRecord(); // ๋ชจ๋“  ๋ฐ์ดํ„ฐ ์‚ญ์ œ / Delete all data
    QStringListModel *model; // ๋ฉค๋ฒ„๋กœ ๊ฐ์ฒด๋กœ ์„ ์–ธ / Declare as an object with a member

    //<-- ์—ฌ๊ธฐ๊นŒ์ง€ / up to here

};
#endif // MAINWINDOW_H

3.main.cpp

#include "mainwindow.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

4.mainwindow.cpp

#include "mainwindow.h"
#include "./ui_mainwindow.h"

// ์ฝ”๋“œ์ถ”๊ฐ€ / Add code
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QStringListModel>
#include<QMessageBox>
#include <QSqlError>


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    //-- ์—ฌ๊ธฐ์„œ๋ถ€ํ„ฐ ์ฝ”๋“œ ์ถ”๊ฐ€ / Add code from here

    // DB ์—ฐ๊ฒฐ / DB Connection
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName("localdata.db");
    db.open();

    // ํ…Œ์ด๋ธ” ์ƒ์„ฑ / Create Table
    QSqlQuery query;
    query.exec("CREATE TABLE IF NOT EXISTS records (id INTEGER PRIMARY KEY, text1 TEXT, text2 TEXT)");

    // ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ ์ €์žฅ(์‹œ๊ทธ๋„ ์Šฌ๋กฏ)
    // Save data on button click (signal slot).
    connect(ui->pushButton, &QPushButton::clicked, this, [=]() {
        QString t1 = ui->textEdit->toPlainText();
        QString t2 = ui->plainTextEdit->toPlainText();

        QSqlQuery q;
        q.prepare("INSERT INTO records (text1, text2) VALUES (?, ?)");
        q.addBindValue(t1);
        q.addBindValue(t2);
        q.exec();

        // QTextEdit์„ ๋น„์›๋‹ˆ๋‹ค.
        ui->textEdit->clear();
        ui->plainTextEdit->clear();

        loadData(); // ๋ฆฌ์ŠคํŠธ ๊ฐฑ์‹ 
    });

    // ๋ฐ์ดํ„ฐ ์‚ญ์ œ ๋ฒ„ํŠผ / Delete data button
    connect(ui->pushButton_2, &QPushButton::clicked, this, [=]() {
        deleteSelectedRecord();
    });

    // ๋ชจ๋“  ๋ฐ์ดํ„ฐ ์‚ญ์ œ ๋ฒ„ํŠผ / Delete all data button
    connect(ui->pushButton_3, &QPushButton::clicked, this, [=]() {
        deleteAllRecord();
    });

    //connect(ui->pushButton_2, &QPushButton::clicked, this, &MainWindow::deleteSelectedRecord);

    loadData(); // ์ดˆ๊ธฐ ๋กœ๋”ฉ / data loading

    //-- ์—ฌ๊ธฐ๊นŒ์ง€ / Up to here...

}


//--> ์ฝ”๋“œ ์ถ”๊ฐ€ / ์—ฌ๊ธฐ์„œ๋ถ€ํ„ฐ ์ฝ”๋“œ ์ถ”๊ฐ€ / Add code from here

// ๋ฐ์ดํ„ฐ๋กœ๋“œ / data loading
void MainWindow::loadData() {

    QStringList items;
    QSqlQuery query("SELECT text1, text2 FROM records");
    while (query.next()) {
        items << query.value(0).toString() + " | " + query.value(1).toString();
    }

    // ๋ฉค๋ฒ„๋ณ€์ˆ˜๋กœ ์‚ฌ์šฉ / Used as a member variable
    // ๋ฉค๋ฒ„ ๋ณ€์ˆ˜ ์ดˆ๊ธฐํ™” / Initialize member variables
    model = new QStringListModel(items,this);

    // ๋ฆฌ์ŠคํŠธ๋ทฐ์— ์—ฐ๊ฒฐ / Connect to list view
    ui->listView->setModel(model);

   // ์ง€์—ญ๋ณ€์ˆ˜์‚ฌ์šฉ
   // QStringListModel *model = new QStringListModel(items, this);
   // ui->listView->setModel(model);
}

// ๋ ˆ์ฝ”๋“œ ์‚ญ์ œ / delete record
void MainWindow::deleteSelectedRecord() {
    QModelIndex index = ui->listView->currentIndex();
    if (!index.isValid()) {
        QMessageBox::warning(this, "์‚ญ์ œ ์˜ค๋ฅ˜/Delete error", "์‚ญ์ œํ•  ํ•ญ๋ชฉ์„ ์„ ํƒํ•˜์„ธ์š”/Select the items you want to delete.");
        return;
    }

    QString selectedText = model->data(index, Qt::DisplayRole).toString();

    QStringList parts = selectedText.split(" | ");
    if (parts.size() != 2) {
        QMessageBox::warning(this, "์‚ญ์ œ ์˜ค๋ฅ˜/Delete error", "ํ•ญ๋ชฉ ํ˜•์‹์ด ์˜ฌ๋ฐ”๋ฅด์ง€ ์•Š์Šต๋‹ˆ๋‹ค./The item format is incorrect.");
        return;
    }

    QString text1 = parts[0].trimmed();
    QString text2 = parts[1].trimmed();

    // deburging
    //QMessageBox::warning(this, text1, text2);

    QSqlQuery query;

    // :text1,:text2๋Š” ๋ฐ”์ธ๋”ฉ ๋ณ€์ˆ˜
    // :text1,:text2 are binding variables
    query.prepare("DELETE FROM records WHERE text1 = :text1 AND text2 = :text2");
    query.bindValue(":text1", text1);
    query.bindValue(":text2", text2);

    if (!query.exec()) {
        QMessageBox::critical(this, "DB ์˜ค๋ฅ˜/DB error", query.lastError().text());
        return;
    }

    // ์‚ญ์ œ ํ›„ ๋ฆฌ์ŠคํŠธ ๊ฐฑ์‹ 
    // Update list after deletion
    loadData();

}

// ๋ชจ๋“  ๋ฐ์ดํ„ฐ ์‚ญ์ œ
// Delete all data
void MainWindow::deleteAllRecord() {
    QSqlQuery query;
    query.prepare("DELETE FROM records");

    if (!query.exec()) {
        QMessageBox::critical(this, "DB ์˜ค๋ฅ˜/DB error", query.lastError().text());
        return;
    }

    // ์‚ญ์ œ ํ›„ ๋ฆฌ์ŠคํŠธ ๊ฐฑ์‹ 
    // Update list after deletion
    loadData();

}

//<-- ์—ฌ๊ธฐ๊นŒ์ง€ / Up to here

MainWindow::~MainWindow()
{
    delete ui;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.16)

project(example4 VERSION 0.1 LANGUAGES CXX)

set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)

#-- sqlite ๋ชจ๋“ˆ ์ถ”๊ฐ€ /  Add sqlite module
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Widgets Sql)


set(PROJECT_SOURCES
        main.cpp
        mainwindow.cpp
        mainwindow.h
        mainwindow.ui
)

if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
    qt_add_executable(example4
        MANUAL_FINALIZATION
        ${PROJECT_SOURCES}
    )
# Define target properties for Android with Qt 6 as:
#    set_property(TARGET example4 APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
#                 ${CMAKE_CURRENT_SOURCE_DIR}/android)
# For more information, see https://doc.qt.io/qt-6/qt-add-executable.html#target-creation
else()
    if(ANDROID)
        add_library(example4 SHARED
            ${PROJECT_SOURCES}
        )
# Define properties for Android with Qt 5 after find_package() calls as:
#    set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android")
    else()
        add_executable(example4
            ${PROJECT_SOURCES}
        )
    endif()
endif()

# -- sqlite ๋งํฌ / sqlite linke
target_link_libraries(example4 PRIVATE
    Qt${QT_VERSION_MAJOR}::Core
    Qt${QT_VERSION_MAJOR}::Widgets
    Qt${QT_VERSION_MAJOR}::Sql
)


target_link_libraries(example4 PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)

# 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.
if(${QT_VERSION} VERSION_LESS 6.1.0)
  set(BUNDLE_ID_OPTION MACOSX_BUNDLE_GUI_IDENTIFIER com.example.example4)
endif()
set_target_properties(example4 PROPERTIES
    ${BUNDLE_ID_OPTION}
    MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
    MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
    MACOSX_BUNDLE TRUE
    WIN32_EXECUTABLE TRUE
)

include(GNUInstallDirs)
install(TARGETS example4
    BUNDLE DESTINATION .
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

if(QT_VERSION_MAJOR EQUAL 6)
    qt_finalize_executable(example4)
endif()

5.์‹คํ–‰ / run

Leave a Reply

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