캐시된 SQL 테이블
'캐시된 테이블' 예제는 테이블 뷰를 사용하여 데이터베이스에 접근하고, 사용자가 푸시 버튼을 통해 명시적으로 변경 사항을 제출할 때까지 데이터 변경 사항을 캐싱하는 방법을 보여줍니다.

이 예제는 데이터베이스에 저장된 데이터를 사용자가 수정할 수 있게 해주는 사용자 정의 대화 상자 위젯인 TableEditor 이라는 단일 클래스로 구성되어 있습니다. 먼저 클래스 정의와 사용 방법을 살펴본 다음, 구현 내용을 살펴보겠습니다.
TableEditor 클래스 정의
TableEditor 클래스는 ` QWidget `를 상속받아 테이블 편집기 위젯을 최상위 대화 상자 창으로 만듭니다.
class TableEditor : public QWidget
{
Q_OBJECT
public:
explicit TableEditor(const QString &tableName, QWidget *parent = nullptr);
private slots:
void submit();
private:
QPushButton *submitButton;
QPushButton *revertButton;
QPushButton *quitButton;
QDialogButtonBox *buttonBox;
QSqlTableModel *model;
};TableEditor 생성자는 두 개의 인자를 받습니다. 첫 번째는 TableEditor 객체가 작업할 데이터베이스 테이블에 대한 참조입니다. 다른 하나는 부모 위젯에 대한 포인터로, 이 인자는 기본 클래스 생성자로 전달됩니다.
QSqlTableModel 변수 선언에 유의하십시오. 이 예제에서 보게 되겠지만, QSqlTableModel 클래스는 QTableView 과 같은 뷰 클래스에 데이터를 제공하는 데 사용될 수 있습니다. QSqlTableModel 클래스는 편집 가능한 데이터 모델을 제공하여 단일 테이블의 데이터베이스 레코드를 읽고 쓸 수 있게 해줍니다. 이 클래스는 SQL 문장을 실행하고 조작하는 기능을 제공하는 하위 수준의 QSqlQuery 클래스를 기반으로 구축되었습니다.
또한 사용자가 명시적으로 제출을 요청할 때까지 데이터 변경 사항을 캐시하기 위해 테이블 뷰를 활용하는 방법도 살펴보겠습니다. 이를 위해 모델과 편집기 버튼 외에도 ‘ submit() ’ 슬롯을 선언해야 합니다.
| 데이터베이스 연결 |
|---|
TableEditor 클래스를 사용하기 전에, 편집하려는 테이블이 포함된 데이터베이스에 대한 연결을 생성해야 합니다:
|
TableEditor 클래스 구현
이 클래스의 구현은 생성자와 ` submit() ` 슬롯, 단 두 개의 함수로만 구성됩니다. 생성자에서는 데이터 모델과 다양한 창 요소를 생성하고 사용자 정의합니다.
TableEditor::TableEditor(const QString &tableName, QWidget *parent)
: QWidget(parent)
{
model = new QSqlTableModel(this);
model->setTable(tableName);
model->setEditStrategy(QSqlTableModel::OnManualSubmit);
model->select();
model->setHeaderData(0, Qt::Horizontal, tr("ID"));
model->setHeaderData(1, Qt::Horizontal, tr("First name"));
model->setHeaderData(2, Qt::Horizontal, tr("Last name"));먼저 데이터 모델을 생성하고, 모델이 작동할 SQL 데이터베이스 테이블을 설정합니다. QSqlTableModel::setTable() 함수는 테이블에서 데이터를 선택하지 않고, 필드 정보만 가져온다는 점에 유의하십시오. 따라서 나중에 QSqlTableModel::select() 함수를 호출하여 테이블의 데이터로 모델을 채웁니다. 필터와 정렬 조건을 지정하여 선택 범위를 사용자 정의할 수 있습니다(자세한 내용은 QSqlTableModel 클래스 문서를 참조하십시오).
또한 모델의 편집 전략도 설정합니다. 편집 전략은 사용자가 뷰에서 수행한 변경 사항이 실제로 데이터베이스에 언제 적용될지를 결정합니다. 사용자가 명시적으로 변경 사항을 제출할 때까지 테이블 뷰(즉, 모델)의 변경 사항을 캐시하고 싶으므로, QSqlTableModel::OnManualSubmit 전략을 선택합니다. 다른 대안으로는 QSqlTableModel::OnFieldChange 및 QSqlTableModel::OnRowChange 가 있습니다.
마지막으로, 모델이 QSqlQueryModel 클래스에서 상속받은 setHeaderData() 함수를 사용하여 뷰 헤더에 표시될 레이블을 설정합니다.
QTableView *view = new QTableView;
view->setModel(model);
view->resizeColumnsToContents();그런 다음 테이블 뷰를 생성합니다. QTableView 클래스는 테이블 뷰의 기본 모델/뷰 구현을 제공합니다. 즉, 모델의 항목을 표시하는 테이블 뷰를 구현합니다. 또한 사용자가 항목을 편집하고 변경 사항을 모델에 저장할 수 있도록 합니다. 읽기 전용 뷰를 생성하려면, 뷰가 QAbstractItemView 클래스에서 상속받은 editTriggers 속성을 사용하여 적절한 플래그를 설정합니다.
뷰가 데이터를 표시하도록 하려면, ` setModel()` 함수를 사용하여 모델을 뷰에 전달합니다.
submitButton = new QPushButton(tr("Submit"));
submitButton->setDefault(true);
revertButton = new QPushButton(tr("&Revert"));
quitButton = new QPushButton(tr("Quit"));
buttonBox = new QDialogButtonBox(Qt::Vertical);
buttonBox->addButton(submitButton, QDialogButtonBox::ActionRole);
buttonBox->addButton(revertButton, QDialogButtonBox::ActionRole);
buttonBox->addButton(quitButton, QDialogButtonBox::RejectRole);TableEditor 의 버튼들은 일반적인 QPushButton 객체입니다. 버튼들이 현재 위젯 스타일에 적합한 레이아웃으로 표시되도록 하기 위해, 이를 버튼 박스에 추가합니다. 이는 대화 상자와 메시지 상자가 일반적으로 해당 플랫폼의 인터페이스 지침에 부합하는 레이아웃으로 버튼을 표시하기 때문입니다. 플랫폼마다 대화 상자의 레이아웃은 항상 서로 다릅니다. ` QDialogButtonBox `을 사용하면 개발자가 버튼을 추가할 수 있으며, 사용자의 데스크톱 환경에 적합한 레이아웃이 자동으로 적용됩니다.
대부분의 대화 상자 버튼은 특정 역할을 따릅니다. ` addButton() ` 함수를 사용하여 버튼 상자에 버튼을 추가할 때는 ` QDialogButtonBox::ButtonRole ` 열거형을 사용하여 버튼의 역할을 지정해야 합니다. 또는 ` QDialogButtonBox `는 ` OK`, ` Cancel`, ` Save` 등 사용할 수 있는 여러 표준 버튼을 제공합니다. 이 버튼들은 플래그 형태로 존재하므로 생성자에서 OR 연산을 통해 조합할 수 있습니다.
connect(submitButton, &QPushButton::clicked, this, &TableEditor::submit);
connect(revertButton, &QPushButton::clicked, model, &QSqlTableModel::revertAll);
connect(quitButton, &QPushButton::clicked, this, &TableEditor::close);Quit 버튼을 테이블 에디터의 close() 슬롯에 연결하고, Submit 버튼을 비공개 submit() 슬롯에 연결합니다. 후자의 슬롯은 데이터 트랜잭션을 처리합니다. 마지막으로, Revert 버튼을 모델의 revertAll() 슬롯에 연결하여 모든 보류 중인 변경 사항을 취소(즉, 원래 데이터를 복원)합니다.
QHBoxLayout *mainLayout = new QHBoxLayout;
mainLayout->addWidget(view);
mainLayout->addWidget(buttonBox);
setLayout(mainLayout);
setWindowTitle(tr("Cached Table"));
}마지막으로 버튼 박스와 테이블 뷰를 레이아웃에 추가하고, 이 레이아웃을 테이블 편집기 위젯에 적용한 뒤, 편집기의 창 제목을 설정합니다.
void TableEditor::submit()
{
model->database().transaction();
if (model->submitAll()) {
model->database().commit();
} else {
model->database().rollback();
QMessageBox::warning(this, tr("Cached Table"),
tr("The database reported an error: %1")
.arg(model->lastError().text()));
}
}사용자가 변경 사항을 저장하기 위해 ‘ Submit ’ 버튼을 누를 때마다 ` submit() ` 슬롯이 호출됩니다.
먼저, ` QSqlDatabase::transaction()` 함수를 사용하여 데이터베이스에서 트랜잭션을 시작합니다. 데이터베이스 트랜잭션이란 다른 트랜잭션과 독립적으로 일관되고 신뢰할 수 있는 방식으로 처리되는, 데이터베이스 관리 시스템 또는 유사한 시스템과의 상호작용 단위를 말합니다. 사용 중인 데이터베이스에 대한 포인터는 ` QSqlTableModel::database()` 함수를 사용하여 얻을 수 있습니다.
그런 다음, 보류 중인 모든 변경 사항, 즉 모델에서 수정된 항목들을 제출하려고 시도합니다. 오류가 발생하지 않으면 QSqlDatabase::commit() 함수를 사용하여 트랜잭션을 데이터베이스에 커밋합니다(일부 데이터베이스의 경우, 데이터베이스에 활성 상태의 QSqlQuery 가 있으면 이 함수가 작동하지 않을 수 있습니다). 오류가 발생하면 QSqlDatabase::rollback() 함수를 사용하여 트랜잭션을 롤백하고 사용자에게 경고를 표시합니다.
| 참조: Qt SQL 데이터베이스 클래스 전체 목록 및 모델/뷰 프로그래밍 문서를 참조하십시오. |
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.