視頻項目:7----汽車銷售管理系統(登錄,品牌車管理,新車入庫,銷售統計圖表)-----項目視頻沒有,代碼也不全,更改項目練習:學生信息管理系統。
學生信息管理系統:簡介:兩個頁面:主頁面+學生信息添加頁面(下面的例子僅舉例學號和姓名)
1.點擊添加按鈕彈出添加對話框
添加一個繼承自QDialog的QT界面類AddDialog(注意如果AddDialog是繼承QWidget的話在主頁面new 一個AddDialog的時候AddDialog頁面會直接顯示在主頁面上)
主頁面:
#include "adddialog.h"
...
AddDialog *m_addDialog; //添加學生信息窗口//構造函數:
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);m_addDialog = new AddDialog(this);
}
void Widget::on_pushButton_add_clicked()
{//點擊按鈕彈出新增窗口qDebug()<<"on_pushButton_add_clicked";m_addDialog->show();
}
2.添加按鈕點擊取消則關閉對話框
void AddDialog::on_btnCancel_clicked()
{qDebug()<<"on_btnCancel_clicked";this->close();
}
3.添加一個數據類定義需要存儲數據類型(子界面存入,傳遞給主界面顯示)
添加Q_DECLARE_METATYPE(type)宏,能使type類型讓所有基于模板的函數識別
#ifndef CSTUDENTINFO_H
#define CSTUDENTINFO_H#include <QString>
#include <QMetaType>class CStudentInfo
{
public:CStudentInfo();bool setData(int id,QString name);int id() const;void setId(int id);QString name() const;void setName(const QString &name);private://此處舉例僅用兩個數據信息類int m_id; //學生id 四位數字QString m_name; //學生名稱};Q_DECLARE_METATYPE(CStudentInfo)// 該宏放在類或結構體聲明的最后面
#endif // CSTUDENTINFO_H
#include "cstudentinfo.h"CStudentInfo::CStudentInfo()
{}bool CStudentInfo::setData(int id, QString name)
{m_id = id;m_name = name;return true;
}int CStudentInfo::id() const
{return m_id;
}void CStudentInfo::setId(int id)
{m_id = id;
}QString CStudentInfo::name() const
{return m_name;
}void CStudentInfo::setName(const QString &name)
{m_name = name;
}
在子界面上按這個數據類存進入:
void AddDialog::on_btnConfirm_clicked()
{qDebug()<<"on_btnConfirm_clicked";//......//把檢測合格的數據添加進入int id = ui->edtId->text().toInt();QString name = ui->edtName->text();//數據類型CStudentInfo stuInfo;stuInfo.setData(id,name);//僅進行數據的修改到主頁面,對話框不關閉emit sig_addStuInfo(stuInfo);
}
通過信號槽把數據類接收,并顯示在主頁面:
信號槽傳遞:
//關聯槽函數connect(m_addDialog,&AddDialog::sig_addStuInfo,this,&Widget::slot_addStuInfo);bool Widget::slot_addStuInfo(CStudentInfo &stuInfo)
{//收到添加對話框發出的信號,把添加的內容顯示到UI上appendToModel(stuInfo); //此處可以收到信號傳來的return true;
}
主頁面model模型顯示:
構造函數中:
//實例化modelm_standardModel = new QStandardItemModel(this);//設置tableView 菜單策略 customContextMenuRequested(const QPoint &pos)ui->tableView_StudentInfo->setContextMenuPolicy(Qt::CustomContextMenu);//添加表頭QStringList headerList;headerList<<"學號"<<"姓名";m_standardModel->setHorizontalHeaderLabels(headerList);ui->tableView_StudentInfo->setModel(m_standardModel);
bool Widget::appendToModel(CStudentInfo &stuInfo)
{QStandardItem *itemId = new QStandardItem(QString("%1").arg(stuInfo.id(),4,10,QLatin1Char('0')));itemId->setCheckable(true); //添加復選框itemId->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);QStandardItem *itemName = new QStandardItem(stuInfo.name());itemName->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);QList<QStandardItem*> rowItem;rowItem.append(itemId);rowItem.append(itemName);m_standardModel->appendRow(rowItem);return true;}
效果:(后續需要添加學號是否存在驗證等需另外再加入判斷)
4.加入數據庫進行數據的長期存儲,主頁面顯示,子頁面寫入,以及刪除功能
先創建一個數據庫的類CDataSQLite:
#ifndef CDATASQLITE_H
#define CDATASQLITE_H#include "cstudentinfo.h"
#include <QSqlDatabase>class CDataSQLite
{
public:CDataSQLite();/*** @brief 查詢所有信息* @param stuInfos* @return*///用來遍歷virtual bool selectStuInfos(QList<CStudentInfo> &stuInfoList) ; //用來新增virtual bool addStuInfo(CStudentInfo &stuInfo) ; virtual bool updateStuInfo(CStudentInfo &stuInfo) ;//用來刪除virtual bool deleteStuInfo(int id) ;
private:QSqlDatabase m_db; //數據庫連接
};#endif // CDATASQLITE_H
CDataSQLite的構造函數:
//打開數據庫m_db = QSqlDatabase::addDatabase("QSQLITE"); //QMYSQLm_db.setDatabaseName("./stuInfoDB_demo.db"); // 相對路徑是相對于.exe所在的文件夾下(即bin文件夾下)if(!m_db.open()){qDebug() << "Failed to Open database";return;}qDebug() << "success Open ";//如果沒有這個表則會創建QSqlQuery query;QString sql = QString("create table if not exists tb_stuInfo""(id int primary key not null,""name varchar(50),""overallScore real);");if(!query.exec(sql)){qDebug() << "Failed to create table";qDebug() << query.lastQuery();return;}//關閉數據庫m_db.close();
bool CDataSQLite::addStuInfo(CStudentInfo &stuInfo)
{//新增if(!m_db.open()){qDebug() << "Failed to Open Database : addStuInfo";return false;}QSqlQuery query;query.prepare("insert into tb_stuInfo (id,name)""values(:id,:name)");query.bindValue(":id",stuInfo.id());query.bindValue(":name",stuInfo.name());if(!query.exec()){qDebug() << query.lastQuery();m_db.close();return false;}m_db.close();return true;}bool CDataSQLite::selectStuInfos(QList<CStudentInfo> &stuInfoList)
{//查詢if(!m_db.open()){qDebug() << "Failed to Open Database : selectStuInfos";return false;}QSqlQuery query;QString sql = "Select * from tb_stuInfo;";if(!query.exec(sql)){qDebug() << "Failed to selcet tb_stuInfo;";return false;}while(query.next()){CStudentInfo stuInfo;int id = query.value("id").toInt();QString name = query.value("name").toString();stuInfo.setData(id,name);stuInfoList.append(stuInfo);}m_db.close();return true;
}bool CDataSQLite::deleteStuInfo(int id)
{if(!m_db.open()){qDebug() << "Failed to Open Database : deleteStuInfo";return false;}QSqlQuery query;QString sql = QString("delete from tb_stuInfo where id = %1").arg(id);if(!query.exec(sql)){qDebug() << "Failed to delete stuInfo!!!";m_db.close();return false;}m_db.close();return true;
}
使用CDataSQLite數據庫類:
在主頁面中,構造函數中會先實例化數據庫類,然后進行遍歷查詢進行顯示。
//在.h文件中
CDataSQLite *m_dataSource; //數據源//.cpp構造函數中
//實例化數據源m_dataSource = new CDataSQLite();//查詢數據QList<CStudentInfo> stuInfoList;bool res = m_dataSource->selectStuInfos(stuInfoList);if(!res){QMessageBox::information(this,"提示","查詢學生信息失敗");return;}qDebug() << stuInfoList.size();for(int i=0;i<stuInfoList.size();++i){appendToModel(stuInfoList[i]);}
在新增頁面點擊確認發送信號之后,主頁面接收到信號在槽函數中進行數據庫類新增
//接收到子頁面的確認添加按鈕發出的處理信號的槽函數
bool Widget::slot_addStuInfo(CStudentInfo &stuInfo)
{//把數據添加到數據庫中bool res = m_dataSource->addStuInfo(stuInfo);if(!res){QMessageBox::information(this,"提示","插入失敗!!!");return false;}//收到添加對話框發出的信號,把添加的內容添加appendToModel(stuInfo);return true;
}
刪除:主頁面的刪除按鈕點擊之后槽函數:on_pushButton_delate_clicked,會把勾選的數據從數據庫中以及主頁面中刪除
void Widget::on_pushButton_delate_clicked()
{QMap<int,QStandardItem*> delRowsMap; //待刪除的行for(int row = 0;row<m_standardModel->rowCount();++row){QStandardItem *item = m_standardModel->item(row);if(item->checkState() == Qt::Checked){delRowsMap.insert(row,item);}}if(delRowsMap.size()<1)return;//彈出刪除提示int res = QMessageBox::information(this,"提示","是否真的要刪除",QMessageBox::Yes|QMessageBox::No);if(res == QMessageBox::No) return;QList<int> keyList = delRowsMap.keys();//1.刪除數據庫中的數據for(int key=keyList.size()-1;key>=0;--key){if(m_dataSource->deleteStuInfo(delRowsMap.value(keyList[key])->text().toInt())){//2.刪除窗口中的數據m_standardModel->removeRow(keyList[key]);}}}
(存著自己看看)
項目原例子源碼:鏈接
項目練習源碼(跟博客相同,但是功能相比原例子不全):鏈接