普通界面佈局:
理論解析:
QSqlRelationalTableModel 是 QSqITableModel 的子類。QSqlRelationalTableModel 可以處理關係數據表,所謂關係數據表, 是指將主表裏的某個字段存儲爲代碼型字段,而代碼的具體意義在另外一個數據表裏。
有關數據庫對應的知識點,與工程使用的db文件,在工程項目裏面,請自己查看,例子在最後有鏈接:
工程文件:
QT += sql
對應主文件的頭文件:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QLabel>
#include <QString>
#include <QtSql>
#include <QDataWidgetMapper>
//#include "qwcomboboxdelegate.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
private:
QSqlDatabase DB; //數據庫連接
QSqlRelationalTableModel *tabModel;//數據模型
QItemSelectionModel *theSelection;//選擇模型
void openTable();//打開數據表
// void getFieldNames();//獲取字段名稱
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_currentChanged(const QModelIndex ¤t, const QModelIndex &previous);
// QTableView的SelectionModel的行發生了變化,進行處理
// void on_currentRowChanged(const QModelIndex ¤t, const QModelIndex &previous);
///////////////////////
void on_actOpenDB_triggered();
void on_actRecAppend_triggered();
void on_actRecInsert_triggered();
void on_actRevert_triggered();
void on_actSubmit_triggered();
void on_actRecDelete_triggered();
void on_actFields_triggered();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
首先是主程序部分:
初始化函數:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
this->setCentralWidget(ui->tableView);
ui->tableView->setSelectionBehavior(QAbstractItemView::SelectItems);
ui->tableView->setSelectionMode(QAbstractItemView::SingleSelection);
ui->tableView->setAlternatingRowColors(true);
// ui->tableView->resizeColumnsToContents();
// ui->tableView->horizontalHeader()->setStretchLastSection(true);
}
這裏沒有什麼好說的啦,然後是常規的打開文件,就是打開數據庫了:
void MainWindow::on_actOpenDB_triggered()
{
QString aFile=QFileDialog::getOpenFileName(this,"選擇數據庫文件","",
"SQL Lite數據庫(*.db *.db3)");
if (aFile.isEmpty())
return;
//打開數據庫
DB=QSqlDatabase::addDatabase("QSQLITE"); //添加 SQL LITE數據庫驅動
DB.setDatabaseName(aFile); //設置數據庫名稱
// DB.setHostName();
// DB.setUserName();
// DB.setPassword();
if (!DB.open()) //打開數據庫
{
QMessageBox::warning(this, "錯誤", "打開數據庫失敗",
QMessageBox::Ok,QMessageBox::NoButton);
return;
}
//打開數據表
openTable();
}
打開數據表中的數據:
void MainWindow::openTable()
{//打開數據表
tabModel=new QSqlRelationalTableModel(this,DB);
tabModel->setTable("studInfo"); //設置數據表
tabModel->setEditStrategy(QSqlTableModel::OnManualSubmit); //OnManualSubmit , OnRowChange
tabModel->setSort(0,Qt::AscendingOrder);
tabModel->setHeaderData(0,Qt::Horizontal,"學號");
tabModel->setHeaderData(1,Qt::Horizontal,"姓名");
tabModel->setHeaderData(2,Qt::Horizontal,"性別");
tabModel->setHeaderData(3,Qt::Horizontal,"學院");
tabModel->setHeaderData(4,Qt::Horizontal,"專業");
//設置代碼字段的查詢關係數據表
tabModel->setRelation(3,QSqlRelation("departments","departID","department")); //學院
tabModel->setRelation(4,QSqlRelation("majors","majorID","major"));//專業
theSelection=new QItemSelectionModel(tabModel);
connect(theSelection,SIGNAL(currentChanged(QModelIndex,QModelIndex)),
this,SLOT(on_currentChanged(QModelIndex,QModelIndex)));
ui->tableView->setModel(tabModel);
ui->tableView->setSelectionModel(theSelection);
ui->tableView->setItemDelegate(new QSqlRelationalDelegate(ui->tableView)); //爲關係型字段設置缺省代理組件
tabModel->select(); //打開數據表
// ui->tableView->resizeColumnsToContents();
// ui->tableView->horizontalHeader()->setStretchLastSection(true);
ui->actOpenDB->setEnabled(false);
ui->actRecAppend->setEnabled(true);
ui->actRecInsert->setEnabled(true);
ui->actRecDelete->setEnabled(true);
ui->actFields->setEnabled(true);
}
QSqlRelationalTableModel 類的主要函數與 QSqlTableModel 相同, 有一個新的函數 setRelation() 用於設置代碼字段的關聯數據表和l關聯字段。
openTable()函數中還有關鍵的一行 :
ui->tableView->setItemDelegate(new QSqlRelationalDelegate(ui->tableView)); //爲關係型字段設置缺省代理組件
這是在 tableView 中爲代碼字段創建缺省的關係型代理組件,這樣在 tableView 中編輯代碼字段的內容時,纔會出現一個下拉列表框,列出代碼表的所有可選內容。
void MainWindow::on_currentChanged(const QModelIndex ¤t, const QModelIndex &previous)
{//更新actPost和actCancel 的狀態
Q_UNUSED(current);
Q_UNUSED(previous);
ui->actSubmit->setEnabled(tabModel->isDirty()); //有未保存修改時可用
ui->actRevert->setEnabled(tabModel->isDirty());
}
獲取字段列表:
void MainWindow::on_actFields_triggered()
{//獲取字段列表
QSqlRecord emptyRec=tabModel->record();//獲取空記錄,只有字段名
QString str;
for (int i=0;i<emptyRec.count();i++)
str=str+emptyRec.fieldName(i)+'\n';
QMessageBox::information(this, "所有字段名", str,
QMessageBox::Ok,QMessageBox::NoButton);
}
添加記錄:
void MainWindow::on_actRecAppend_triggered()
{//添加記錄
tabModel->insertRow(tabModel->rowCount(),QModelIndex()); //在末尾添加一個記錄
QModelIndex curIndex=tabModel->index(tabModel->rowCount()-1,1);//創建最後一行的ModelIndex
theSelection->clearSelection();//清空選擇項
theSelection->setCurrentIndex(curIndex,QItemSelectionModel::Select);//設置剛插入的行爲當前選擇行
// int currow=curIndex.row(); //獲得當前行
// tabModel->setData(tabModel->index(currow,0),2000+tabModel->rowCount()); //設置字段缺省值
// tabModel->setData(tabModel->index(currow,2),"男");
}
插入記錄:
void MainWindow::on_actRecInsert_triggered()
{//插入記錄
QModelIndex curIndex=ui->tableView->currentIndex();
tabModel->insertRow(curIndex.row(),QModelIndex());
theSelection->clearSelection();//清除已有選擇
theSelection->setCurrentIndex(curIndex,QItemSelectionModel::Select);
}
修改記錄:
void MainWindow::on_actRevert_triggered()
{//取消修改
tabModel->revertAll();
ui->actSubmit->setEnabled(false);
ui->actRevert->setEnabled(false);
}
保存修改:
void MainWindow::on_actSubmit_triggered()
{//保存修改
bool res=tabModel->submitAll();
if (!res)
QMessageBox::information(this, "消息", "數據保存錯誤,錯誤信息\n"+tabModel->lastError().text(),
QMessageBox::Ok,QMessageBox::NoButton);
else
{
ui->actSubmit->setEnabled(false);
ui->actRevert->setEnabled(false);
}
}
刪除當前記錄:
void MainWindow::on_actRecDelete_triggered()
{//刪除當前記錄
tabModel->removeRow(theSelection->currentIndex().row());
// QModelIndex curIndex=theSelection->currentIndex();//獲取當前選擇單元格的模型索引
// if (curIndex.row()==tabModel->rowCount()-1)//最後一行
// tabModel->removeRow(curIndex.row()); //刪除最後一行
// else
// {
// tabModel->removeRow(curIndex.row());//刪除一行,並重新設置當前選擇行
// theSelection->setCurrentIndex(curIndex,QItemSelectionModel::Select);
// }
tabModel->submitAll(); //立即更新
}
鏈接:https://pan.baidu.com/s/1QNr8dl5Ocuf4VP1m9jRQfA
提取碼:rgot