题目:家庭财务管理系统

前言:

家庭财务管理收支管理是一个家庭日常生活中不可缺少一部分,也是财务管理的重要组成部分。

题目要求:

开发一个家庭财务管理系统,实现家庭财务信息的自动化。

系统主要功能:

1.登陆管理 :可以选一名家庭成员做管理员,普通用户只能查看自己的收支信息。

2. 家庭成员管理:成员的信息:姓名、性别、出身日期、年龄,身高,体重。

3. 收支项目管理可以设置收支项目,修改或者删除。收支项目要求分为两层,比如“车辆维护-保养费”;任意一层次都可作为收支项目记账,用户在不清楚支出是否属于“保养费”的时候,可以选择大类“车辆维护”作为支出项

5.家庭成员收支输出   显示每个成员每月的收支情况(时间、收支种类、金额、经手人)。

6.退出管理

下面是系统功能示意图:

系统的设计思路如下:

功能实现一:登录窗口实现

ui界面如下:

1.管理员登录

  1. 管理员登录功能实现:在登录窗口类loginDlg定义私有成员:管理员账号与管理员密码,通过

    #include<QSettings>    //Qt提供用于写入注册表的类

    读写注册表。

  2. 通过lineEdit行编辑输入用户名密码,在代码段中通过管理员登陆的Radio Button是否选中进行判断是否进行管理员登录。

2.管理员密码修改

  1. 通过点击左下角的管理员密码修改按钮进行密码修改(进入密码修改对话框),对话框界面如下:

密码修改对话框具体功能实现在此先不做具体介绍,

注意:此处密码修改需要用到加密算法,这里使用QT提供用于密码加密的类:

#include<QCryptographicHash>    //Qt提供用于加密的类

3.普通用户登录:读取数据库

  1. 基于QSqlite轻量级数据库,未选中管理员登录Radio Button时,默认为普通用户登录。

以下为具体代码:

logindlg.h

#ifndef LOGINDLG_H
#define LOGINDLG_H#include <QDialog>
#include<QSettings>
#include<QByteArray>
#include<QCryptographicHash>    //Qt提供用于加密的类
#include<QMessageBox>#include <QTextCodec>       //unicode编码与其他编码转换
#include <QSqlDatabase>     //提供通过连接访问数据库的接口
#include <QSqlQuery>        //sql查询中创建、导航和检索数据所涉及的功能
#include <QTime>
#include <QSqlError>
#include <QDebug>
#include <QSqlDriver>
#include <QSqlRecord>
#include <QLabel>
#include <QDataWidgetMapper>
#include <QTemporaryFile>
#include <QFile>
#include <QByteArray>#define SUB -1
#define MAIN 1namespace Ui {
class loginDlg;
}class loginDlg : public QDialog
{Q_OBJECTpublic:explicit loginDlg(QWidget *parent = nullptr);~loginDlg();void setName(QString name)  {Mng_Name = name;}void setPswd(QString pswd)  {Mng_Pswd = pswd;}bool createConnection();   //创建数据库链接bool queryAll(QString name, QString pswd);           //查找数据库void SetTabOrder();     //设置tab切换顺序int SubOrMain;          //主,从窗口切换标志QString NormalUser;                  //普通用户账号
private:Ui::loginDlg *ui;void readSettings();        //读取设置,注册表void writeSettings();       //写入设置,注册表int Mng_tryCount = 0;       //试错次数QString encrypt(const QString& str);    //字符串加密QString Mng_Name = "user";           //初始化用户名QString Mng_Pswd = "123456";         //初始化密码QSqlDatabase DB;private slots:void on_LoginPushButton_clicked();void on_SignOutPushButton_clicked();void ChangePwd();        //修改密码void on_radioButton_clicked();
};#endif // LOGINDLG_H

logindlg.cpp

#include "logindlg.h"
#include "ui_logindlg.h"loginDlg::loginDlg(QWidget *parent) :QDialog(parent),ui(new Ui::loginDlg)
{ui->setupUi(this);this->setWindowTitle("登陆窗口");this->setAttribute(Qt::WA_DeleteOnClose);
//    Mng_Pswd = encrypt("123456");
//    writeSettings();SetTabOrder();readSettings(); //初始化注册管理员用户名和密码createConnection();connect(ui->ChangePswd_PB, SIGNAL(clicked()), this, SLOT(ChangePwd()));
}loginDlg::~loginDlg()
{delete ui;
}bool loginDlg::createConnection()
{DB = QSqlDatabase::addDatabase("QSQLITE"); //添加 SQL LITE数据库驱动DB.setDatabaseName("../familyDb.db");if (!DB.open())   //打开数据库{QMessageBox::warning(this, "错误", "打开数据库失败",QMessageBox::Ok,QMessageBox::NoButton);return false;}return true;
}bool loginDlg::queryAll(QString name, QString pswd)
{DB = QSqlDatabase::database();      //使用默认连接QSqlQuery query(DB);query.exec("select * from familyBase");while(query.next()){if(query.value(6).toString()==name&&query.value(7).toString()==pswd)return true;}return false;
}void loginDlg::SetTabOrder()
{setTabOrder(ui->IDLineEdit, ui->PassWordLineEdit);setTabOrder(ui->PassWordLineEdit, ui->LoginPushButton);setTabOrder(ui->LoginPushButton, ui->SignOutPushButton);setTabOrder(ui->SignOutPushButton, ui->radioButton);setTabOrder(ui->radioButton, ui->ChangePswd_PB);setTabOrder(ui->ChangePswd_PB, ui->radioButton);
}void loginDlg::readSettings()
{//读取存储的用户名和密码, 密码是经过加密的QString organization = "TJJ-Qt";      //用于注册表QString appName = "FIO_System";       //app名字QSettings settings(organization, appName);Mng_Name = settings.value("Username","user").toString();QString defaultPSWD = encrypt("123456");        //缺省密码“123456”加密后的数据Mng_Pswd = settings.value("PSWD", defaultPSWD).toString();  //读取PSWD
}void loginDlg::writeSettings()
{//保存用户名,密码等设置QSettings settings("TJJ-Qt", "FIO_System");      //注册表键组settings.setValue("Username",Mng_Name);          //将管理员账号存至设置settings.setValue("PSWD",Mng_Pswd);              //将管理员密码存至设置//指向的注册表目录是HKEY_CURRENT_USER/Software/TJJ-Qt/家庭收支管理系统
}QString loginDlg::encrypt(const QString &str)
{ //字符串MD5算法加密QByteArray btArray;btArray.append(str);//加入原始字符串QCryptographicHash hash(QCryptographicHash::Md5);  //Md5加密算法hash.addData(btArray);  //添加数据到加密哈希值QByteArray resultArray =hash.result();  //返回最终的哈希值QString md5 =resultArray.toHex();//转换为16进制字符串return  md5;
}void loginDlg::on_LoginPushButton_clicked()
{QString user = ui->IDLineEdit->text().trimmed();        //输入用户名QString pswd = ui->PassWordLineEdit->text().trimmed();  //输入密码QString encrptPSWD = encrypt(pswd);                     //对输入密码进行加密if(ui->radioButton->isChecked()){if ((user == Mng_Name)&&(encrptPSWD == Mng_Pswd))       //如果用户名和密码正确{writeSettings();  //保存设置SubOrMain = MAIN;this->accept();  //对话框accept(),关闭对话框}else{Mng_tryCount++; //错误次数if (Mng_tryCount>3){QMessageBox::critical(this, "提示", "已达最大试错次数,程序退出");exit(1);}else{QMessageBox::warning(this, "错误提示", "用户名或密码错误");return;}}}else{if(queryAll(user,pswd)){NormalUser = user;QFile file("../UserNameFile.txt");//        if (file.open(QIODevice::ReadWrite | QIODevice::Text))//        {//           file.write(NormalUser.toLatin1());//           file.flush();//           file.close();//        }//        QFile file("要写的文件路径");if (file.open(QIODevice::WriteOnly | QIODevice::Text)){QTextStream stream(&file);stream.seek(file.size());QString qs;for (auto& i : user){qs.append(i);}stream << qs;file.close();SubOrMain = SUB;this->accept();  //对话框accept(),关闭对话框}}//QFile::setPermissions("UserNameFile.txt", QFileDevice::ReadUser);else{Mng_tryCount++; //错误次数if (Mng_tryCount>3){QMessageBox::critical(this, "提示", "已达最大试错次数,程序退出");exit(1);}else{QMessageBox::warning(this, "错误提示", "用户名或密码错误");return;}}}
}void loginDlg::on_SignOutPushButton_clicked()
{if(QMessageBox::question(this, "提示", "确定退出程序吗")==QMessageBox::Yes){this->reject(); //退出}elsereturn;
}void loginDlg::ChangePwd()
{  //修改密码QSqlQuery query(DB);ChangePassword *dialog = new ChangePassword(this,"", &Mng_Pswd);if(dialog->exec() == QDialog::Accepted){Mng_Pswd = encrypt(*dialog->GetNewPswd_Mng());QMessageBox::information(this, "提示", "密码修改成功" , QMessageBox::Ok);}
}void loginDlg::on_radioButton_clicked()
{ui->IDLineEdit->setFocus();
}

二、管理员窗口实现

一:综述:此界面利用tabWidget实现,三个管理标签页采用同样的实现方式,即采用View和model的形式,设置手动提交操作(利用下方四个按钮实现)。第四页界面如下:

第四页功能设计思路:

  1. 使用TreeWidget实现月份与姓名的分类,通过点击TreeWidget中的Item实现右边收入项目与支出项目的TableView显示。
  2. 以下采用不可编辑的lineEdit显示计算出来的月总收入与月总支出。

主要代码如下:

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include    <QMainWindow>
#include    <QLabel>
#include    <QSqlTableModel>
#include    <QtSql>
#include    <QDataWidgetMapper>
#include    <QSqlRecord>
#include    <QSqlError>
#include    <QSqlQuery>
#include    <QDateTime>
#include    <QDate>
#include    <QDebug>
#include    <QTreeWidgetItem>
#include    <QMessageBox>
#include    "infoentry.h"
#include    "changepassword.h"namespace Ui {
class MainWindow;
}class MainWindow : public QMainWindow
{Q_OBJECTpublic:explicit MainWindow(QWidget *parent = nullptr);~MainWindow();private:Ui::MainWindow *ui;QSqlDatabase  DB;//数据库连接QSqlTableModel  *FamilyBaseTabModel;  //数据模型QSqlTableModel  *InItemTabModel;  //数据模型QSqlTableModel  *OutItemTabModel;  //数据模型QSqlTableModel  *PrintInModel;    //收入项目数据模型QSqlTableModel  *PrintOutModel;    //支出项目数据模型QItemSelectionModel *theSelection; //选择模型QDataWidgetMapper   *dataMapper; //数据映射void DBconnectAndCreateTable();     //连接数据库以及创建表void    openTable();                //打开数据表void    InitFamilyBaseView();             //初始化家庭成员基本信息视图void    InitInItemView();                 //初始化收入项目视图void    InitOutItemView();                //初始化输出项目视图void    InitPrintAllTab();                //初始化打印家庭成员信息标签页QString encrypt(const QString& str);    //字符串加密InfoEntry *InfoEntryDialog;     //信息输入窗口指针private slots:void    SignOut();              //重新登陆void    on_ActionEntry_triggered();    //对信息输入action反应void    TreeWidgetsItemChanged(QTreeWidgetItem*, int);      //切换TreeWidget槽函数void    ShowCopyRight();        //版权:谭俊杰void on_CertainDLTMem_PB_clicked();void on_CertainDLTIncome_PB_clicked();void on_AddMember_PB_clicked();void on_AddInItems_PB_clicked();void on_OUT_CertainButton_clicked();void on_OUT_CancelButton_clicked();void on_Out_AddButton_clicked();void on_CancelDLTMem_PB_clicked();void on_ConcelDLTIn_PB_clicked();void on_DeleteMember_PB_clicked();void on_DLTInItems_PB_clicked();void on_Out_DeleteButton_clicked();//    void on_pushButton_7_clicked();     //无效
//    void on_IN_CertainButton_clicked(); //无效
//    void on_pushButton_5_clicked();     //无效void on_pushButton_clicked();       //查找月份
};#endif // MAINWINDOW_H

mainwindow.cpp

void MainWindow::DBconnectAndCreateTable()
{DB = QSqlDatabase::addDatabase("QSQLITE"); //添加 SQL LITE数据库驱动DB.setDatabaseName("../familyDb.db");      //设置数据库名if (!DB.open())   //打开数据库{qDebug()<<"数据库无法打开!";return ;}else{qDebug()<<"数据库成功打开!";}QSqlQuery query;//家庭成员基本信息,包括姓名,年龄,性别,出生日期,身高,体重,以及账号,密码。query.exec("create table familyBase(name varchar(20), age int, sex varchar(4),""BirthTime varchar(40), tall int, height int, ""Username varchar(50), Password varchar(50));");//家庭收入项目,包括工资,租金,股息利息,社会福利,以及其他query.exec("create table familyIn(wage varchar(50), ""rent varchar(50), Interest varchar(50), welfare varchar(50),""others varchar(50));");//家庭支出项目,包括食品,生活用品,交通,住房,教育,医疗保健以及其他query.exec("create table familyOut(food varchar(50), ""life varchar(50), traffic varchar(50), house varchar(50),""educate varchar(50), Medical varchar(50), others varchar(50));");//家庭收支信息,包括日期,收支人姓名,收支项目,金额query.exec("create table familyIOInfo(IODate varchar(20), name varchar(20), ""Items varchar(30), MoneyAmount double);");//日期表的创建,方便根据日期加载TreeWidgetquery.exec("create table DateTable(IODate varchar(20));");
}
void MainWindow::TreeWidgetsItemChanged(QTreeWidgetItem* Item, int column)
{QSqlQuery query(DB);
//    QString sqlOp;
//    if(Item->parent() == nullptr)
//        sqlOp = QString("select Items,MoneyAmount from familyIOInfo where IODate = '%1'").arg(Item->text(column));
//    else
//        sqlOp = QString("select Items,MoneyAmount from familyIOInfo where IODate = '%1' and name = '%2'").arg(Item->parent()->text(0)).arg(Item->text(column));//    if(!query.exec(sqlOp))
//        qDebug() << query.lastError();PrintInModel = new QSqlTableModel(this);PrintOutModel = new QSqlTableModel(this);PrintInModel->setTable("familyIOInfo");PrintOutModel->setTable("familyIOInfo");if(Item->parent() == nullptr){PrintInModel->setFilter(QString("IODate = '%1' and MoneyAmount > 0").arg(Item->text(column))); //根据日期进行筛选PrintOutModel->setFilter(QString("IODate = '%1' and MoneyAmount < 0").arg(Item->text(column))); //根据日期进行筛选}else{PrintInModel->setFilter(QString("IODate = '%1' and name = '%2' and MoneyAmount > 0").arg(Item->parent()->text(column)).arg(Item->text(column))); //根据日期和姓名进行筛选PrintOutModel->setFilter(QString("IODate = '%1' and name = '%2' and MoneyAmount < 0").arg(Item->parent()->text(column)).arg(Item->text(column))); //根据日期和姓名进行筛选}PrintInModel->select(); //显示结果ui->InPrintView->setModel(PrintInModel);PrintOutModel->select();  //显示结果ui->OutPrintView->setModel(PrintOutModel);if(Item->parent() == nullptr){ui->InPrintView->setColumnHidden(0,true);    //选中日期时,表中不应隐藏姓名ui->OutPrintView->setColumnHidden(0,true);    //选中日期时,表中不应隐藏姓名}else{ui->InPrintView->setColumnHidden(0,true);ui->InPrintView->setColumnHidden(1,true);    //选中姓名时,就可以隐藏姓名ui->OutPrintView->setColumnHidden(0,true);ui->OutPrintView->setColumnHidden(1,true);    //选中姓名时,就可以隐藏姓名}PrintInModel->setHeaderData(1, Qt::Horizontal, "姓名");PrintInModel->setHeaderData(2, Qt::Horizontal, "项目");PrintInModel->setHeaderData(3, Qt::Horizontal, "金额");PrintOutModel->setHeaderData(1, Qt::Horizontal, "姓名");PrintOutModel->setHeaderData(2, Qt::Horizontal, "项目");PrintOutModel->setHeaderData(3, Qt::Horizontal, "金额");//设置收入lineEdit和支出lineEditint InRowNum = PrintInModel->rowCount();int OutRowNum = PrintOutModel->rowCount();double InValueSum = 0;double OutValueSum = 0;for(int i= 0; i < InRowNum; i++){QModelIndex InIndex = PrintInModel->index(i,3);InValueSum += PrintInModel->data(InIndex).toDouble();}for(int i= 0; i < OutRowNum; i++){QModelIndex OutIndex = PrintOutModel->index(i,3);OutValueSum += PrintOutModel->data(OutIndex).toDouble();}qDebug() << InValueSum << OutValueSum;ui->InLineEdit->setText(QString::number(InValueSum));ui->OutLineEdit->setText(QString::number(OutValueSum));
}
void MainWindow::on_pushButton_clicked()
{       //查找月份QSqlQuery query(DB);        //使用DB数据库连接query.exec("select * from DateTable");int count = 0;while(query.next()){if(ui->dateEdit->text() == query.value(0).toString()){emit ui->treeWidget->itemClicked(ui->treeWidget->topLevelItem(count), 0);ui->treeWidget->clearSelection();ui->treeWidget->topLevelItem(count)->setSelected(true);return;}count++;}QMessageBox::warning(this, "提示", "查找失败", QMessageBox::Ok);
}

信息录入窗口实现:

ui界面如下:

  1. 通过Combox下拉框显示收支项目,右边double spinbox输入金额,如果用户切换到其他项目,则已更改的项目的字体会切换为橙色,表示已经更改。
  2. 通过上方的成员姓名下拉框加载需要录入信息的成员姓名,同时,通过更改输入格式的DateEdit输入录入的月份。
  3. 以上全部信息录入到数据库。

具体代码如下:

infoentry.h

#ifndef INFOENTRY_H
#define INFOENTRY_H#include <QDialog>
#include    <QtSql>
#include    <QDataWidgetMapper>
#include    <QSqlRecord>
#include    <QSqlError>
#include    <QSqlQuery>
#include    <QMessageBox>
#include    <QCompleter>
#include    <QStringList>
#include    <QDateTime>
#include    <QPalette>
#include    <QStandardItemModel>
#include    <QDebug>
#include    <QVariantList>struct FamilyIOInfo
{QString Name;         //姓名字段储存QStringList *InItemStringList; //收入项目列表QVariantList *InValuesList;     //收入项目值QStringList *OutItemStringList;//支出项目列表QVariantList *OutValuesList;    //支出项目值FamilyIOInfo(QString &name, QStringList* &InStrings, QVariantList* &InValue, QStringList* &OutStrings, QVariantList* &OutValue){Name = name;InItemStringList = InStrings;InValuesList = InValue;OutItemStringList = OutStrings;OutValuesList = OutValue;}
};namespace Ui {
class InfoEntry;
}class InfoEntry : public QDialog
{Q_OBJECTpublic:explicit InfoEntry(QWidget *parent = nullptr);~InfoEntry();bool createConnection();   //创建数据库链接void setCombox();          //设置下拉框字段void updateFamilyDb();     //根据输入金额更新数据库void InitialFamily();      //初始化家庭成员收支信息储存结构体family
private:Ui::InfoEntry *ui;QStringList *InItemstrings; //收入项目列表QVariantList *InValues;     //收入项目值QStringList *OutItemstrings;//支出项目列表QVariantList *OutValues;    //支出项目值int InCurrentIndex[5] = {0, 0, 0, 0, 0};    //保存收入下拉框目前indexint OutCurrentIndex[7] = {0, 0, 0, 0, 0, 0, 0}; //保存支出下拉框目前indexbool InSpinBoxIsChange[5] = {false, false, false, false, false};    //设置输入项目Spinbox更改标志bool OutSpinBoxIsChange[7] = {false, false, false, false, false, false, false}; //设置输出项目SpinBox更改标志QSqlDatabase DB;                    //数据库连接QStandardItemModel *pItemModel;     //通过model设置下拉框文本颜色
private slots:void on_SureButton_clicked();           //确定按钮槽函数void on_CancelButton_clicked();         //取消按钮槽函数void on_WageComboBox_currentIndexChanged(const QString &arg1);  //工资下拉框字段改变反应void on_RentComboBox_currentIndexChanged(int index);            //租金下拉框字段改变反应void on_InterestComboBox_currentIndexChanged(int index);        //股息利息下拉框字段改变反应void on_WelfareComboBox_currentIndexChanged(int index);         //社会福利下拉框字段改变反应void on_InOtherComboBox_currentIndexChanged(int index);         //收入其他项下拉框字段改变反应void on_FoodComboBox_currentIndexChanged(int index);            //食品下拉框字段改变反应void on_LifeUseComboBox_currentIndexChanged(int index);         //生活用品下拉框字段改变反应void on_TrafficComboBox_currentIndexChanged(int index);         //交通下拉框字段改变反应void on_HouseComboBox_currentIndexChanged(int index);           //住房下拉框字段改变反应void on_EducateComboBox_currentIndexChanged(int index);         //教育下拉框字段改变反应void on_MedicalComboBox_currentIndexChanged(int index);         //医疗保健下拉框字段改变反应void on_OutOtherComboBox_currentIndexChanged(int index);        //支出其他项目下拉框字段改变反应void on_WageSpinBox_valueChanged(double arg1);void on_RentSpinBox_valueChanged(double arg1);void on_InterestSpinBox_valueChanged(double arg1);void on_WelfareSpinBox_valueChanged(double arg1);void on_InOtherSpinBox_valueChanged(double arg1);void on_FoodSpinBox_valueChanged(double arg1);void on_LifeUseSpinBox_valueChanged(double arg1);void on_TrafficSpinBox_valueChanged(double arg1);void on_HouseSpinBox_valueChanged(double arg1);void on_EducateSpinBox_valueChanged(double arg1);void on_MedicalSpinBox_valueChanged(double arg1);void on_OutOtherSpinBox_valueChanged(double arg1);};#endif // INFOENTRY_H

infoentry.cpp

void InfoEntry::setCombox()
{   //设置下拉框字段//设置收入项目字段QSqlQuery InQuery(DB);InQuery.exec("select * from familyIn");QSqlRecord InRecord = InQuery.record();InItemstrings = new QStringList[InRecord.count()];InValues = new QVariantList[InRecord.count()];while(InQuery.next()){for(int i = 0; i < InRecord.count(); i++){if(InQuery.value(i).toString() != ""){InItemstrings[i] << InQuery.value(i).toString();InValues[i].append(0.0);}}}ui->WageComboBox->clear();ui->WageComboBox->addItems(InItemstrings[0]);ui->WageComboBox->setCurrentIndex(0);ui->RentComboBox->clear();ui->RentComboBox->addItems(InItemstrings[1]);ui->RentComboBox->setCurrentIndex(0);ui->InterestComboBox->clear();ui->InterestComboBox->addItems(InItemstrings[2]);ui->InterestComboBox->setCurrentIndex(0);ui->WelfareComboBox->clear();ui->WelfareComboBox->addItems(InItemstrings[3]);ui->WelfareComboBox->setCurrentIndex(0);ui->InOtherComboBox->clear();ui->InOtherComboBox->addItems(InItemstrings[4]);ui->InOtherComboBox->setCurrentIndex(0);//设置支出项目字段QSqlQuery queryOut(DB);queryOut.exec("select * from familyOut");QSqlRecord OutRecord = queryOut.record();OutItemstrings = new QStringList[OutRecord.count()];OutValues = new QVariantList[OutRecord.count()];while(queryOut.next()){for(int i = 0; i < OutRecord.count(); i++){if(queryOut.value(i).toString() != ""){OutItemstrings[i] << queryOut.value(i).toString();OutValues[i].append(0.0);}}}ui->FoodComboBox->clear();ui->FoodComboBox->addItems(OutItemstrings[0]);ui->FoodComboBox->setCurrentIndex(0);ui->LifeUseComboBox->clear();ui->LifeUseComboBox->addItems(OutItemstrings[1]);ui->LifeUseComboBox->setCurrentIndex(0);ui->TrafficComboBox->clear();ui->TrafficComboBox->addItems(OutItemstrings[2]);ui->TrafficComboBox->setCurrentIndex(0);ui->HouseComboBox->clear();ui->HouseComboBox->addItems(OutItemstrings[3]);ui->HouseComboBox->setCurrentIndex(0);ui->EducateComboBox->clear();ui->EducateComboBox->addItems(OutItemstrings[4]);ui->EducateComboBox->setCurrentIndex(0);ui->MedicalComboBox->clear();ui->MedicalComboBox->addItems(OutItemstrings[5]);ui->MedicalComboBox->setCurrentIndex(0);ui->OutOtherComboBox->clear();ui->OutOtherComboBox->addItems(OutItemstrings[6]);ui->OutOtherComboBox->setCurrentIndex(0);//设置姓名字段QSqlQuery query(DB);query.exec("select * from familyBase");QSqlRecord record = query.record();QStringList stringList;while(query.next()){if(query.value(0).toString() != "")stringList << query.value(0).toString();}ui->NameComboBox->addItems(stringList);}
void InfoEntry::on_SureButton_clicked()
{       //确定按钮槽函数if(QMessageBox::question(this, "提问" , "确定更改吗") == QMessageBox::Yes){//保存目前收入项目的值InValues[0].replace(InCurrentIndex[0], ui->WageSpinBox->value());      //储存该值InValues[1].replace(InCurrentIndex[1], ui->RentSpinBox->value());      //储存该值InValues[2].replace(InCurrentIndex[2], ui->InterestSpinBox->value());      //储存该值InValues[3].replace(InCurrentIndex[3], ui->WelfareSpinBox->value());      //储存该值InValues[4].replace(InCurrentIndex[4], ui->InOtherSpinBox->value());      //储存该值//保存目前支出项目的值OutValues[0].replace(OutCurrentIndex[0], ui->FoodSpinBox->value());      //储存该值OutValues[1].replace(OutCurrentIndex[1], ui->LifeUseSpinBox->value());      //储存该值OutValues[2].replace(OutCurrentIndex[2], ui->InterestSpinBox->value());      //储存该值OutValues[3].replace(OutCurrentIndex[3], ui->HouseSpinBox->value());      //储存该值OutValues[4].replace(OutCurrentIndex[4], ui->EducateSpinBox->value());      //储存该值OutValues[5].replace(OutCurrentIndex[5], ui->MedicalSpinBox->value());      //储存该值OutValues[6].replace(OutCurrentIndex[6], ui->OutOtherSpinBox->value());      //储存该值//保存即将存入数据库中的数据,他们包括//Items:收支项目//Values:对应金额//FamilyName:收支人姓名//DateString:收支日期QStringList Items;          //收支项目QVariantList Values;         //对应金额QStringList DateString;     //储存日期QStringList FamilyName;     //姓名字段储存for(int i = 0; i < 5; i++){for(int j = 0; j < InValues[i].length(); j++){if(InValues[i][j] != 0){FamilyName << ui->NameComboBox->currentText();DateString << ui->dateEdit->text();Items << InItemstrings[i][j];Values << InValues[i][j].toDouble();}}}for(int i = 0; i < 7; i++){for(int j = 0; j < OutValues[i].length(); j++){if(OutValues[i][j] != 0){FamilyName <<ui->NameComboBox->currentText();DateString << ui->dateEdit->text();Items << OutItemstrings[i][j];Values << -OutValues[i][j].toDouble();  //支出项目变成支出形式(即负数)}}}//判断空否,若空则未做修改,给出提示框if(Items.isEmpty()){if(QMessageBox::warning(this, "警告", "您并未进行修改,请问是否继续修改?", QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes)return;elsethis->close();}//将数据写入数据库QSqlQuery query(DB);//写入到日期表query.exec("select * from DateTable");//QSqlRecord Record = query.record();//qDebug() << Record.count();//将日期存入日期表QStringList NewDateList;query.next();if(query.value(0).toString() == "")     //表空则直接插入{qDebug() << "这个表是空的";NewDateList << ui->dateEdit->text();query.prepare("insert into DateTable(IODate) values(:IODate)");query.bindValue(0, NewDateList);if(!query.exec())qDebug() << query.lastError();}else{   //不空则按顺序插入qDebug() << "进来了";query.previous();int tableLength = 0;while(query.next()){tableLength++;NewDateList.insert(tableLength - 1, query.value(0).toString());}for(int i = 0; i < tableLength; i++){if(NewDateList[i].compare(ui->dateEdit->text()) < 0){NewDateList.insert(i,ui->dateEdit->text());break;}}qDebug() << NewDateList;query.prepare("delete from DateTable");if(!query.exec())qDebug() << query.lastError();query.prepare("insert into DateTable(IODate) values(:IODate)");query.addBindValue(NewDateList);if(!query.execBatch())qDebug() << query.lastError();}//写入到家庭收支信息表query.prepare("insert into familyIOInfo(IODate, name, Items, MoneyAmount) values(:IODate, :name, :Items, :MoneyAmount)");query.addBindValue(DateString); //写入日期query.addBindValue(FamilyName); //写入姓名query.addBindValue(Items);      //写入项目query.addBindValue(Values);     //写入对应金额if(!query.execBatch())qDebug() << query.lastError();this->close();}elsereturn;
}
void InfoEntry::on_WageComboBox_currentIndexChanged(const QString &arg1)
{       //工资下拉框字段改变反应if(InSpinBoxIsChange[0] == true){int OldIndex = InCurrentIndex[0];pItemModel = qobject_cast<QStandardItemModel*>(ui->WageComboBox->model());pItemModel->item(OldIndex)->setForeground(QColor(255, 97, 0));     //修改文本颜色InValues[0].replace(OldIndex, ui->WageSpinBox->value());      //储存该值InCurrentIndex[0] = ui->WageComboBox->findText(arg1);ui->WageSpinBox->setValue(InValues[0][ui->WageComboBox->findText(arg1)].toDouble());InSpinBoxIsChange[0] = false;return;}else{ui->WageSpinBox->setValue(InValues[0][ui->WageComboBox->findText(arg1)].toDouble());InSpinBoxIsChange[0] = false;return;}
}
void InfoEntry::on_WageSpinBox_valueChanged(double arg1)
{InSpinBoxIsChange[0] = true;
}

普通用户窗口

  1. 该窗口类似于管理员窗口,只需要根据登录窗口获取用户账号,显示用户信息。并将View设置为不可编辑。

界面如下:

具体代码如下:

subwindow.h

#ifndef SUBWINDOW_H
#define SUBWINDOW_H#include <QMainWindow>
#include <QSqlDatabase>
#include <QTreeWidgetItem>
#include <QSqlTableModel>
#include <QDate>
#include <QMessageBox>
#include <QProcess>
#include <QDir>
#include <QSqlError>
#include <QDialog>
#include "changepassword.h"namespace Ui {
class SubWindow;
}class SubWindow : public QMainWindow
{Q_OBJECTpublic:explicit SubWindow(QWidget *parent = nullptr);~SubWindow();void setUserName(QString user){userName = user;}
public slots:void CheckMonth();          //月份查找响应槽函数void TreeWidgetsItemChanged(QTreeWidgetItem*, int);     //点击treewidget
private slots:void on_dateEdit_userDateChanged(const QDate &date);void SignOut();             //登出void ChangePwd();      //修改密码void on_pushButton_clicked();void ShowCopyRight();   //版权:谭俊杰private:Ui::SubWindow *ui;QSqlDatabase  DB;//数据库连接QString name;    //用户姓名(非账号)QString userName;           //用户账号QDate CheckDate;          //查找月份QSqlTableModel *PrintInModel;  //收入项目模型QSqlTableModel *PrintOutModel;  //支出项目模型double InValueSum;              //收入项目总值double OutValueSum;             //支出项目总值void  InitUI();             //初始化界面void InitialNameAndTitle(); //初始化用户名与窗口标题
};#endif // SUBWINDOW_H

subwindow.cpp

void SubWindow::TreeWidgetsItemChanged(QTreeWidgetItem *Item, int column)
{PrintInModel->setTable("familyIOInfo");PrintInModel->setFilter(QString("IODate = '%1' and name = '%2' and MoneyAmount > 0").arg(Item->text(column)).arg(name)); //根据日期和姓名进行筛选PrintInModel->select(); //读取数据库//PrintInModel->removeColumn(0);  //隐藏日期列//PrintInModel->removeColumn(1);  //隐藏姓名列ui->PrintInItemsView->setModel(PrintInModel);ui->PrintInItemsView->setColumnHidden(0,true);ui->PrintInItemsView->setColumnHidden(1,true);PrintOutModel->setTable("familyIOInfo");PrintOutModel->setFilter(QString("IODate = '%1' and name = '%2' and MoneyAmount < 0").arg(Item->text(column)).arg(name)); //根据日期和姓名进行筛选PrintOutModel->select(); //显示结果//PrintOutModel->removeColumn(0); //隐藏日期列//PrintOutModel->removeColumn(1); //隐藏姓名列ui->PrintOutItemsView->setModel(PrintOutModel);ui->PrintOutItemsView->setColumnHidden(0,true);ui->PrintOutItemsView->setColumnHidden(1,true);//更改modelPrintInModel->setHeaderData(2, Qt::Horizontal, "收入项目");PrintInModel->setHeaderData(3, Qt::Horizontal, "金额");PrintOutModel->setHeaderData(2, Qt::Horizontal, "支出项目");PrintOutModel->setHeaderData(3, Qt::Horizontal, "金额");int InRowNum = PrintInModel->rowCount();int OutRowNum = PrintOutModel->rowCount();InValueSum = 0;OutValueSum = 0;for(int i= 0; i < InRowNum; i++){QModelIndex InIndex = PrintInModel->index(i,3);InValueSum += PrintInModel->data(InIndex).toDouble();}for(int i= 0; i < OutRowNum; i++){QModelIndex OutIndex = PrintOutModel->index(i,3);OutValueSum += PrintOutModel->data(OutIndex).toDouble();}qDebug() << InValueSum << OutValueSum;ui->InlineEdit->setText(QString::number(InValueSum));ui->OutlineEdit->setText(QString::number(OutValueSum));
}
void SubWindow::InitialNameAndTitle()
{QString userName;//指定文件QFile file( "../UserNameFile.txt" );//指定为GBKQTextCodec *codec = QTextCodec::codecForName("GBK");//如果打开文件失败,直接退出if(!file.open(QIODevice::ReadOnly|QIODevice::Text))return;//当未到达文件结束位置while(!file.atEnd()){//读取一行文本数据QByteArray line = file.readLine();//将读取到的行数据转换为UnicodeuserName = codec->toUnicode(line);}file.close();if(QFile::remove("../UserNameFile.txt"))    //删除用于信息传递的文件qDebug() << "你已删除文件!";elseqDebug() << "文件未删除";DB = QSqlDatabase::addDatabase("QSQLITE"); //添加 SQL LITE数据库驱动DB.setDatabaseName("../familyDb.db");      //设置数据库名if (!DB.open())   //打开数据库{qDebug()<<"数据库无法打开!";return ;}else{qDebug()<<"数据库成功打开!";}QSqlQuery query(DB);QString sqlOp = QString("select * from familyBase where Username = '%1'").arg(userName);query.exec(sqlOp);while (query.next()){qDebug() << query.value(0).toString();if(query.value(6).toString() == userName){name = query.value(0).toString();this->setWindowTitle("用户:"+name);break;}}
}

系统测试情况:

  1. 经测试,系统运行无强制退出错误,且实现基本功能,未发现bug。

系统的优点与改进:

  1. 优点:通过TreeWidget将成员信息显示,更加清晰明了。
  2. 优点:添加了退出登录计算金额总量功能,方便用户查看信息。
  3. 改进:界面设计不足:单调切无图标,背景等,可以在这方面进行优化
  4. 改进:在对话框信息返回时由于初始思路匮乏以及Qt传递QString信息错误,使用了临时文件储存信息的方法,其实可以使用指针。

感想:

通过这样一个程序,真正初步认识带有图形界面的windows应用程序开发。明白了qt的信号和槽机制,以及qt的控件和储存结构的相关知识,让我更加产生进行更强大系统功能实现的兴趣。

基于QT(c++)的家庭财务管理系统相关推荐

  1. 基于Springboot开发的家庭财务管理系统

    项目编号:BS-XX-025 本系统基于springboot+mybatis+springmvc开发实现,前端采用layui+jquery开发实现,图形报表采用echarts开发实现,开发工具为IDE ...

  2. [附源码]Python计算机毕业设计SSM基于Java家庭财务管理系统(程序+LW)

    项目运行 环境配置: Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclis ...

  3. 基于Android的家庭财务管理流程图,SYL_Android_FamilyFinaceSystem 双鱼林基于安卓Android家庭财务管理系统毕业课程设计源码 - 下载 - 搜珍网...

    464双鱼林基于安卓Android家庭财务管理系统\安卓客户端\.classpath ........................................\..........\.ic_l ...

  4. 基于java的家庭财务管理系统_基于JAVA的家庭财务管理系统的设计与实现.doc

    基于JAVA的家庭财务管理系统的设计与实现 码农毕业设计下载网: PAGE \* MERGEFORMAT PAGE \* MERGEFORMAT 1 毕业论文(设计) 论文题目 家庭理财管理系统 学 ...

  5. 基于javaweb的家庭财务管理系统

    随着互联网技术的快速发展和计算机的大量普及,通过电脑并利用互联网技术实现家庭财务信息的归集管理成为很多家庭使用的财务管理手段.原有的手工管理财务方式不仅效率低,而且财务信息记录分散混乱不容易统计分析. ...

  6. java实现家庭财务管理_基于jsp的家庭财务管理系统-JavaEE实现家庭财务管理系统 - java项目源码...

    基于jsp+servlet+pojo+mysql实现一个javaee/javaweb的家庭财务管理系统, 该项目可用各类java课程设计大作业中, 家庭财务管理系统的系统架构分为前后台两部分, 最终实 ...

  7. 基于Android的家庭财务管理系统

    一.项目简介 该项目共有5个表(收入.支出.转账.用户.账户).用户登录后可进行转账和收支的操作.通过对表中信息的增加.删除.修改.查看来实现家庭财务管理系统的实现. 1.用户 可以通过注册信息,来插 ...

  8. 家庭账务管理系统html,基于WEB的家庭财务管理系统(46页)-原创力文档

    摘要 在21世纪的今天,随着我国主要的居民收入的提升和消费实力的提高,理财的项目是家庭居家过日子的研究对象.有关学者通过调查发现,当下人们的的规划财产比之计划经济年代,已经有着显著的改善.现在的大多数 ...

  9. 计算机毕设(附源码)JAVA-SSM基于Java家庭财务管理系统

    项目运行 环境配置: Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclis ...

最新文章

  1. 系统的环境变量path的作用是什么
  2. strcpy与面试官
  3. HDU 4864 Task(2014多校--贪心)
  4. 虚拟机中RedHat Linux系统安装
  5. Android local.properties 文件读取
  6. JavaScript常用单词整理总结
  7. 【渝粤教育】广东开放大学 商务英语听说 形成性考核 (37)
  8. [转载] 大型网站的 HTTPS 实践(一)—— HTTPS 协议和原理
  9. Inside ASP.NET 2.0-即时编译系统
  10. 详细记录基于vue+nodejs+mongodb构建的商城学习(四)基于项目的node.js开发后端的学习与梳理总结...
  11. python中的缩进是长度统一吗_python缩进长度是否统一
  12. 产品需求分析流程图怎么做?软件我都帮你找了
  13. xp系统如何更改计算机用户名,windows xp电脑如何设置、修改开机密码
  14. GVRP基础配置【eNSP实现】
  15. Excel中数字、数值和文本的区别
  16. Golang-Flag包文档翻译
  17. Linux之父-林纳斯 配置命令基操
  18. 5G时代下的物联网发展前景,物联网人才的发展机遇有哪些?
  19. 吸血鬼 hrbust 1160 并查集
  20. 地图导航开启蓝牙后无导航语音

热门文章

  1. 华为大搞5G光通信,火星人快步紧跟
  2. CC00028.CloudKubernetes——|KuberNetes二进制部署.V06|5台Server|——|etcd配置|
  3. 新浪微博开发平台基于php的sdk包(包含demo程序),新浪微博API开发教程(一)-体验篇...
  4. 计算机网络——路由器和交换机
  5. NR-PRACH:prach格式以及时频域情况
  6. Oracle -PL/SQL Developer错误解决方案(ORA-02291)
  7. java独步寻花,江畔独步寻花
  8. 用python画小猪佩奇代码_用python画个小猪佩奇(turtle示例源码)
  9. 科技爱好者周刊:第 90 期
  10. 以太坊Ropsten测试网合并意味着什么?