先上效果圖吧:
本例子連接:
鏈接:https://pan.baidu.com/s/17JmeJGvoj7oJROcNsBX6Kg 提取碼:b051
有關數據庫的操作部分,可以學習下sqlite編程,如果你還不會數據庫編程的話,那要加油去看看基本的東西了。本例子是基於
sqlite3 的編程,下面我們一起來看看吧。
首先是工程文件中一定要加:
QT += sql
主界面的頭文件:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QLabel>
#include <QString>
#include <QtSql>
#include <QDataWidgetMapper>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
private:
QSqlDatabase DB; //數據庫
QSqlQueryModel *qryModel; //數據庫模型
QItemSelectionModel *theSelection; //選擇模型
private:
void openTable();//打開數據表
void updateRecord(int recNo); //更新記錄
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_actOpenDB_triggered();
void on_actRecInsert_triggered();
void on_actRecDelete_triggered();
void on_actRecEdit_triggered();
void on_actScan_triggered();
void on_tableView_doubleClicked(const QModelIndex &index);
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
主頁面佈局:
設置界面的佈局:
這個類是WDialogData 繼承爲 QDialog
來看:
#ifndef WDIALOGDATA_H
#define WDIALOGDATA_H
#include <QDialog>
#include <QSqlRecord>
namespace Ui {
class WDialogData;
}
class WDialogData : public QDialog
{
Q_OBJECT
private:
QSqlRecord mRecord; //保存一條記錄的數據
public:
explicit WDialogData(QWidget *parent = nullptr);
~WDialogData();
void setUpdateRecord(QSqlRecord &recData); //更新記錄
void setInsertRecord(QSqlRecord &recData); //插入記錄
QSqlRecord getRecordData();//獲取錄入的數據
private slots:
void on_btnSetPhoto_clicked();
void on_btnClearPhoto_clicked();
private:
Ui::WDialogData *ui;
};
#endif // WDIALOGDATA_H
這裏確定與取消要設定爲:
這樣目的可以與主頁面進行頁面的交互。
對應的cpp文件:
#include "wdialogdata.h"
#include "ui_wdialogdata.h"
#include <QFileDialog>
WDialogData::WDialogData(QWidget *parent) :
QDialog(parent),
ui(new Ui::WDialogData)
{
ui->setupUi(this);
}
WDialogData::~WDialogData()
{
delete ui;
}
void WDialogData::setUpdateRecord(QSqlRecord &recData)
{
//編輯記錄,更新記錄數據到界面
mRecord = recData;
ui->spinEmpNo->setEnabled(false); //員工編號不許編程
setWindowTitle("跟新記錄");
//根據recData的數據更新界面顯示
ui->spinEmpNo->setValue(recData.value("empNo").toInt());
ui->editName->setText(recData.value("Name").toString());
ui->comboSex->setCurrentText(recData.value("Gender").toString());
ui->spinHeight->setValue(recData.value("Height").toFloat());
ui->editBirth->setDate(recData.value("Birthday").toDate());
ui->editMobile->setText(recData.value("Mobile").toString());
ui->comboProvince->setCurrentText(recData.value("Province").toString());
ui->editCity->setText(recData.value("City").toString());
ui->comboDep->setCurrentText(recData.value("Department").toString());
ui->comboEdu->setCurrentText(recData.value("Education").toString());
ui->spinSalary->setValue(recData.value("Salary").toInt());
ui->editMemo->setPlainText(recData.value("Memo").toString());
QVariant va=recData.value("Photo");//
if (!va.isValid()) //圖片字段內容爲空
ui->LabPhoto->clear();
else {
QByteArray data=va.toByteArray();
QPixmap pic;
pic.loadFromData(data);
ui->LabPhoto->setPixmap(pic.scaledToWidth(ui->LabPhoto->size().width()));
}
}
void WDialogData::setInsertRecord(QSqlRecord &recData)
{
//插入記錄,無需更新界面顯示,但是要存儲recData的字段結構
mRecord=recData; //保存recData到內部變量
ui->spinEmpNo->setEnabled(true); //插入的記錄,員工編號允許編輯
setWindowTitle("插入新記錄");
ui->spinEmpNo->setValue(recData.value("empNo").toInt());
}
QSqlRecord WDialogData::getRecordData()
{
//"確定"按鈕後,界面數據保存到記錄mRecord
mRecord.setValue("empNo",ui->spinEmpNo->value());
mRecord.setValue("Name",ui->editName->text());
mRecord.setValue("Gender",ui->comboSex->currentText());
mRecord.setValue("Height",ui->spinHeight->value());
mRecord.setValue("Birthday",ui->editBirth->date());
mRecord.setValue("Mobile",ui->editMobile->text());
mRecord.setValue("Province",ui->comboProvince->currentText());
mRecord.setValue("City",ui->editCity->text());
mRecord.setValue("Department",ui->comboDep->currentText());
mRecord.setValue("Education",ui->comboEdu->currentText());
mRecord.setValue("Salary",ui->spinSalary->value());
mRecord.setValue("Memo",ui->editMemo->toPlainText());
//照片編輯時已經修改了mRecord的photo字段的值
return mRecord; //以記錄作爲返回值
}
void WDialogData::on_btnSetPhoto_clicked()
{
QString aFile = QFileDialog::getOpenFileName(this,"選擇圖片文件","",
"照片(*.jpg)");
if(aFile.isEmpty())
return;
QByteArray data;
QFile * file = new QFile(aFile);
file->open(QIODevice::ReadOnly); //只讀
data = file->readAll();
file->close();
mRecord.setValue("photo",data); //圖片保存到Photo字段
QPixmap pic;
pic.loadFromData(data);
ui->LabPhoto->setPixmap(pic.scaledToWidth(ui->LabPhoto->size().width()));
}
void WDialogData::on_btnClearPhoto_clicked()
{
//清除照片
ui->LabPhoto->clear();
mRecord.setNull("Photo"); //Photo字段清空
}
下面是主頁面中的程序部分:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFileDialog>
#include <QMessageBox>
#include "wdialogdata.h"
void MainWindow::openTable()
{
//打開數據表
qryModel = new QSqlQueryModel(this);
theSelection = new QItemSelectionModel(qryModel);
qryModel->setQuery("SELECT empNo,name,Gender,Height,Birthday,Mobile,"
"Province, City,Department,Education,Salary FROM employee order by empNo");
//數據查詢
if(qryModel->lastError().isValid())
{
QMessageBox::information(this, "錯誤", "數據表查詢錯誤,錯誤信息\n"+qryModel->lastError().text(),
QMessageBox::Ok,QMessageBox::NoButton);
return;
}
qryModel->setHeaderData(0,Qt::Horizontal,"工號");
qryModel->setHeaderData(1,Qt::Horizontal,"姓名");
qryModel->setHeaderData(2,Qt::Horizontal,"性別");
qryModel->setHeaderData(3,Qt::Horizontal,"身高");
qryModel->setHeaderData(4,Qt::Horizontal,"出生日期");
qryModel->setHeaderData(5,Qt::Horizontal,"手機");
qryModel->setHeaderData(6,Qt::Horizontal,"省份");
qryModel->setHeaderData(7,Qt::Horizontal,"城市");
qryModel->setHeaderData(8,Qt::Horizontal,"部門");
qryModel->setHeaderData(9,Qt::Horizontal,"學歷");
qryModel->setHeaderData(10,Qt::Horizontal,"工資");
ui->tableView->setModel(qryModel);
ui->tableView->setSelectionModel(theSelection);
ui->actOpenDB->setEnabled(false);
ui->actRecInsert->setEnabled(true);
ui->actRecDelete->setEnabled(true);
ui->actRecEdit->setEnabled(true);
ui->actScan->setEnabled(true);
}
void MainWindow::updateRecord(int recNo)
{
//更新一條記錄
QSqlRecord curRec=qryModel->record(recNo); //獲取當前記錄
int empNo = curRec.value("EmpNo").toInt(); //獲取EmpNo
QSqlQuery query; //查詢出當前記錄的所有字段
query.prepare("select * from employee where EmpNo = :ID"); //設置準備執行的 SQL 語句,一般用於帶參數的 SQL 語句
query.bindValue(":ID",empNo); //設置 SQL 語句中參數的俏,以佔位符表示參數
query.exec();//執行由 prepare()和 bindValue()設置的 SQL 語句
query.first();
if(!query.isValid()) //判斷是否無效
{
return; //無效返回函數
}
curRec = query.record();//返回當前記錄
//另一個界面
WDialogData * dataDialog = new WDialogData(this);
Qt::WindowFlags flags=dataDialog->windowFlags();
dataDialog->setWindowFlags(flags | Qt::MSWindowsFixedSizeDialogHint); //設置對話框固定大小
dataDialog->setUpdateRecord(curRec);//調用對話框函數更新數據和界面
int ret=dataDialog->exec();// 以模態方式顯示對話框
if(ret == QDialog::Accepted) //OK鍵被按下
{
QSqlRecord recData = dataDialog->getRecordData();//獲取返回的數據
query.prepare("update employee set Name = :Name, Gender = :Gender,Height=:Height,"
" Birthday=:Birthday, Mobile=:Mobile, Province=:Province,"
" City=:City, Department=:Department, Education=:Education,"
" Salary=:Salary, Memo=:Memo, Photo=:Photo "
" where EmpNo = :ID");
query.bindValue(":Name",recData.value("Name"));
query.bindValue(":Gender",recData.value("Gender"));
query.bindValue(":Height",recData.value("Height"));
query.bindValue(":Birthday",recData.value("Birthday"));
query.bindValue(":Mobile",recData.value("Mobile"));
query.bindValue(":Province",recData.value("Province"));
query.bindValue(":City",recData.value("City"));
query.bindValue(":Department",recData.value("Department"));
query.bindValue(":Education",recData.value("Education"));
query.bindValue(":Salary",recData.value("Salary"));
query.bindValue(":Memo",recData.value("Memo"));
query.bindValue(":Photo",recData.value("Photo"));
query.bindValue(":ID",empNo);
if(!query.exec())
{
QMessageBox::critical(this, "錯誤", "記錄更新錯誤\n"+query.lastError().text(),
QMessageBox::Ok,QMessageBox::NoButton);
}
else {
qryModel->query().exec();//數據模型重新查詢數據,更新tableView顯示
// qryModel->setQuery("SELECT empNo,name,Gender,Height,Birthday,Mobile,"
// "Province, City,Department,Education,Salary FROM employee order by empNo");
qryModel->layoutChanged();
}
}
}
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
this->setCentralWidget(ui->tableView); //設置爲中間
ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
ui->tableView->setSelectionMode(QAbstractItemView::SingleSelection);
ui->tableView->setAlternatingRowColors(true);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_actOpenDB_triggered()
{
QString aFile = QFileDialog::getOpenFileName(this,"選擇數據庫文件","",
"SQL Lite數據庫(*.db *.db3)");
if(aFile.isEmpty())
{
QMessageBox::warning(this, "錯誤", "打開數據庫失敗",
QMessageBox::Ok,QMessageBox::NoButton);
return;
}
//打開數據庫
DB = QSqlDatabase::addDatabase("QSQLITE"); //添加 SQL LITE數據庫驅動
DB.setDatabaseName(aFile);
if(!DB.open())
{
QMessageBox::warning(this, "錯誤", "打開數據庫失敗",
QMessageBox::Ok,QMessageBox::NoButton);
return;
}
//打開數據表
openTable();
}
void MainWindow::on_actRecInsert_triggered()
{
//插入記錄
QSqlQuery query;
query.exec("select * from employee where EmpNo =-1"); //實際不查詢出記錄,只查詢字段信息
QSqlRecord curRec = query.record(); //獲取當前記錄,實際爲空記錄
curRec.setValue("EmpNo",qryModel->rowCount()+3000);
WDialogData *dataDialog=new WDialogData(this);
Qt::WindowFlags flags=dataDialog->windowFlags();
dataDialog->setWindowFlags(flags | Qt::MSWindowsFixedSizeDialogHint); //設置對話框固定大小
dataDialog->setInsertRecord(curRec);
int ret=dataDialog->exec();// 以模態方式顯示對話框
if(ret == QDialog::Accepted) //OK鍵按下去後
{
QSqlRecord recData = dataDialog->getRecordData();
query.prepare("INSERT INTO employee (EmpNo,Name,Gender,Height,Birthday,Mobile,Province,"
" City,Department,Education,Salary,Memo,Photo) "
" VALUES(:EmpNo,:Name, :Gender,:Height,:Birthday,:Mobile,:Province,"
" :City,:Department,:Education,:Salary,:Memo,:Photo)");
query.bindValue(":EmpNo",recData.value("EmpNo"));
query.bindValue(":Name",recData.value("Name"));
query.bindValue(":Gender",recData.value("Gender"));
query.bindValue(":Height",recData.value("Height"));
query.bindValue(":Birthday",recData.value("Birthday"));
query.bindValue(":Mobile",recData.value("Mobile"));
query.bindValue(":Province",recData.value("Province"));
query.bindValue(":City",recData.value("City"));
query.bindValue(":Department",recData.value("Department"));
query.bindValue(":Education",recData.value("Education"));
query.bindValue(":Salary",recData.value("Salary"));
query.bindValue(":Memo",recData.value("Memo"));
query.bindValue(":Photo",recData.value("Photo"));
if(!query.exec())
{
QMessageBox::critical(this, "錯誤", "插入記錄錯誤\n"+query.lastError().text(),
QMessageBox::Ok,QMessageBox::NoButton);
}
else {
// qryModel->query().exec();//數據模型重新查詢數據,更新tableView顯示
qryModel->setQuery("SELECT empNo,name,Gender,Height,Birthday,Mobile,"
"Province, City,Department,Education,Salary FROM employee order by empNo");
}
}
delete dataDialog;
}
void MainWindow::on_actRecDelete_triggered()
{
//刪除當前記錄
int curRecNo = theSelection->currentIndex().row();
QSqlRecord curRec = qryModel->record(curRecNo);
if (curRec.isEmpty()) //當前爲空記錄
return;
int empNo=curRec.value("EmpNo").toInt();//獲取員工編號
QSqlQuery query;
query.prepare("delete from employee where EmpNo = :ID");
query.bindValue(":ID",empNo);
if (!query.exec())
QMessageBox::critical(this, "錯誤", "刪除記錄出現錯誤\n"+query.lastError().text(),
QMessageBox::Ok,QMessageBox::NoButton);
else //插入,刪除記錄後需要重新設置SQL語句查詢
{
qryModel->query().exec();
// qryModel->setQuery("SELECT empNo,name,Gender,Height,Birthday,Mobile,"
// "Province, City,Department,Education,Salary FROM employee order by empNo");
qryModel->layoutChanged();
}
// ui->tableView->update();
}
void MainWindow::on_actRecEdit_triggered()
{
int curRecNo=theSelection->currentIndex().row();
updateRecord(curRecNo);
}
void MainWindow::on_actScan_triggered()
{
//漲工資,記錄遍歷
QSqlQuery qryEmpList; //員工工資信息列表
qryEmpList.exec("SELECT empNo,Salary FROM employee ORDER BY empNo");
qryEmpList.first();
QSqlQuery qryUpdate; //臨時 QSqlQuery
qryUpdate.prepare("UPDATE employee SET Salary=:Salary WHERE EmpNo = :ID");
while(qryEmpList.isValid()) //當前記錄有效
{
int empID=qryEmpList.value("empNo").toInt(); //獲取empNo
float salary=qryEmpList.value("Salary").toFloat(); //獲取Salary
salary=salary+1000; //漲工資
qryUpdate.bindValue(":ID",empID);
qryUpdate.bindValue(":Salary",salary); //設置SQL語句參數
qryUpdate.exec(); //執行UPDATE
if (!qryEmpList.next()) //移動到下一條記錄,並判斷是否到末尾了
break;
}
qryModel->query().exec();//數據模型重新查詢數據,更新tableView的顯示
QMessageBox::information(this, "提示", "漲工資計算完畢",
QMessageBox::Ok,QMessageBox::NoButton);
}
void MainWindow::on_tableView_doubleClicked(const QModelIndex &index)
{
//雙擊編輯
int curRecNo=index.row();
updateRecord(curRecNo);
}
這裏大部分代碼都是qt5.9開發實例書上的代碼,其中的知識點可以看這本書,需要資源也可以私信我,這裏只是簡單記錄這個例子,希望大家能夠喜歡。