.pro

    1. QT += core gui sql xml

    domxml.h

    1. #ifndef DOMXML_H
    2. #define DOMXML_H
    3. #include <QString>
    4. #include <QStringList>
    5. #include <QDomDocument>
    6. #include <QDomElement>
    7. class DomXML
    8. {
    9. public:
    10. DomXML();
    11. static void createXML(QString filePath); // 创建xml空文件
    12. static void appendXML(QString filePath, QStringList list); // 追加节点
    13. static void writeXML(QDomDocument &doc, QDomElement &root, QStringList &list); // 写子节点
    14. static void readXML(QString filePath,
    15. QStringList &fList,
    16. QStringList &bList,
    17. QStringList &pList,
    18. QStringList &nList,
    19. QStringList &tList
    20. ); // 读内容
    21. };
    22. #endif // DOMXML_H

    domxml.cpp

    1. #include "domxml.h"
    2. #include <QFile>
    3. #include <QDomDocument> // 文件指针
    4. #include <QDomProcessingInstruction> // 格式头部
    5. #include <QDomElement> // 元素
    6. #include <QDebug>
    7. #include <QTextStream> // 文本流
    8. #include <QDateTime>
    9. // #include <QXmlParseException>
    10. #define cout qDebug() << "[" << __FILE__ << ":" << __LINE__ << "]"
    11. DomXML::DomXML()
    12. {
    13. }
    14. // 创建xml空文件
    15. void DomXML::createXML(QString filePath)
    16. {
    17. QFile file(filePath); // 关联文件名字
    18. // 如果存在就不创建
    19. if( file.exists() )
    20. {
    21. cout << "文件已存在";
    22. return;
    23. }else
    24. { // 不存在才创建
    25. // 只写方式打开文件
    26. bool isOk = file.open(QIODevice::WriteOnly);
    27. if(isOk)
    28. {
    29. // 创建xml文档对象
    30. QDomDocument doc;
    31. QDomProcessingInstruction ins;
    32. ins = doc.createProcessingInstruction("xml", "version=\'1.0\' encoding=\'UTF-8\' ");
    33. // 追加元素
    34. doc.appendChild(ins);
    35. // 根节点元素
    36. QDomElement root = doc.createElement("日销售清单");
    37. // 追加元素
    38. doc.appendChild(root);
    39. // 保存文件
    40. QTextStream stream(&file); // 文本流关联文件
    41. doc.save(stream, 4); // 4代表缩进
    42. file.close(); // 关闭文件
    43. }else
    44. {
    45. cout << "WriteOnly error";
    46. return;
    47. }
    48. }
    49. }
    50. // 追加节点
    51. void DomXML::appendXML(QString filePath, QStringList list)
    52. {
    53. QFile file(filePath);
    54. bool isOk = file.open(QIODevice::ReadOnly);
    55. if( isOk == true ) // 打开成功
    56. {
    57. // file和xml文档对象关联
    58. QDomDocument doc;
    59. QString error;
    60. isOk = doc.setContent(&file, false, &error);
    61. if( isOk )
    62. {
    63. cout << "关联成功";
    64. file.close(); // 关闭文件
    65. // 获取根节点元素
    66. QDomElement root = doc.documentElement();
    67. // 获取当前时间
    68. QDateTime date = QDateTime::currentDateTime();
    69. QString dateStr = date.toString("yyyy-MM-dd");
    70. // 判断根节点下有没有子节点
    71. if(root.hasChildNodes())
    72. { // 有子节点
    73. cout << "有子节点";
    74. // 查找最后一个子节点
    75. QDomElement lastEmt = root.lastChildElement();
    76. if(lastEmt.attribute("date") == dateStr)
    77. {
    78. // 有当天日期
    79. // 写有效数据
    80. writeXML(doc, lastEmt, list);
    81. }else
    82. {
    83. // 没有当天日期
    84. // 创建日期子节点元素
    85. QDomElement dateEmt = doc.createElement("日期");
    86. // 创建date属性
    87. QDomAttr dateAttr = doc.createAttribute("date");
    88. // 设置属性的值
    89. dateAttr.setNodeValue(dateStr);
    90. // 节点和属性关联
    91. dateEmt.setAttributeNode(dateAttr);
    92. // 把日期节点追加的根节点上
    93. root.appendChild(dateEmt);
    94. // 写有效数据
    95. writeXML(doc, dateEmt, list);
    96. }
    97. }else
    98. { // 无子节点
    99. // 创建日期子节点元素
    100. QDomElement dateEmt = doc.createElement("日期");
    101. // 创建date属性
    102. QDomAttr dateAttr = doc.createAttribute("date");
    103. // 设置属性的值
    104. dateAttr.setNodeValue(dateStr);
    105. // 节点和属性关联
    106. dateEmt.setAttributeNode(dateAttr);
    107. // 把日期节点追加的根节点上
    108. root.appendChild(dateEmt);
    109. // 写有效数据
    110. writeXML(doc, dateEmt, list);
    111. }
    112. // 保存文件
    113. isOk = file.open(QIODevice::WriteOnly);
    114. if(isOk)
    115. {
    116. QTextStream stream( &file );
    117. doc.save(stream, 4);
    118. file.close();
    119. cout << "追加了";
    120. }
    121. }else {
    122. cout << "关联失败";
    123. qDebug() << error;
    124. return;
    125. }
    126. }else
    127. {
    128. cout << "ReadOnly error";
    129. }
    130. }
    131. void DomXML::writeXML(QDomDocument &doc, QDomElement &root, QStringList &list)
    132. {
    133. // 获取当前时间
    134. QDateTime tiem = QDateTime::currentDateTime();
    135. QString tiemStr = tiem.toString("hh-mm-ss");
    136. // 创建时间节点元素
    137. QDomElement timeEmt = doc.createElement("时间");
    138. // 创建属性
    139. QDomAttr timeAttr = doc.createAttribute("time");
    140. // 给属性设置值
    141. timeAttr.setNodeValue(tiemStr);
    142. // 时间节点元素和属性关联
    143. timeEmt.setAttributeNode(timeAttr);
    144. // 把时间节点追加到日期节点后面
    145. root.appendChild(timeEmt);
    146. // 创建子节点
    147. QDomElement factory = doc.createElement("厂家");
    148. QDomElement brand = doc.createElement("品牌");
    149. QDomElement price = doc.createElement("报价");
    150. QDomElement num = doc.createElement("数量");
    151. QDomElement total = doc.createElement("金额");
    152. QDomText text = doc.createTextNode(list.at(0));
    153. factory.appendChild(text);
    154. text = doc.createTextNode(list.at(1));
    155. brand.appendChild(text);
    156. text = doc.createTextNode(list.at(2));
    157. price.appendChild(text);
    158. text = doc.createTextNode(list.at(3));
    159. num.appendChild(text);
    160. text = doc.createTextNode(list.at(4));
    161. total.appendChild(text);
    162. timeEmt.appendChild(factory);
    163. timeEmt.appendChild(brand);
    164. timeEmt.appendChild(price);
    165. timeEmt.appendChild(num);
    166. timeEmt.appendChild(total);
    167. }
    168. void DomXML::readXML(QString filePath, QStringList &fList, QStringList &bList, QStringList &pList, QStringList &nList, QStringList &tList )
    169. {
    170. QFile file(filePath);
    171. bool isOk = file.open(QIODevice::ReadOnly);
    172. if( isOk == true ) // 打开成功
    173. {
    174. cout << "打开成功";
    175. // file和xml文档对象关联
    176. QDomDocument doc;
    177. QString error;
    178. isOk = doc.setContent(&file, false, &error);
    179. file.close();
    180. QDateTime date = QDateTime::currentDateTime();
    181. QString dateStr = date.toString("yyyy-MM-dd");
    182. if( isOk )
    183. {
    184. // 获取根节点
    185. QDomElement root = doc.documentElement();
    186. if(root.hasChildNodes())
    187. {
    188. // 找最后一个节点元素
    189. QDomElement lastEmt = root.lastChildElement();
    190. // 判断最后一个节点是否和当天日期相同
    191. if(lastEmt.attribute("date") == dateStr)
    192. {
    193. // 找出当前日期下所有时间子节点
    194. QDomNodeList list = lastEmt.childNodes();
    195. for(int i = 0; i < list.size(); i++)
    196. {
    197. // list.at(0).toElement();
    198. // 转换为元素,找到时间节点下的所有子节点
    199. QDomNodeList subList = list.at(i).toElement().childNodes();
    200. // 厂家
    201. QString factory = subList.at(0).toElement().text();
    202. fList.append(factory);
    203. // 品牌
    204. QString brand = subList.at(1).toElement().text();
    205. bList.append(brand);
    206. // 价格
    207. QString price = subList.at(2).toElement().text();
    208. pList.append(price);
    209. // 销量
    210. QString num = subList.at(3).toElement().text();
    211. nList.append(num);
    212. // 金额
    213. QString total = subList.at(4).toElement().text();
    214. tList.append(total);
    215. }
    216. }else
    217. {
    218. cout << "无当天日期";
    219. return;
    220. }
    221. }else
    222. {
    223. cout << "没有子节点";
    224. }
    225. }else
    226. {
    227. cout << "关联失败";
    228. }
    229. }else
    230. {
    231. cout << "打开失败";
    232. return;
    233. }
    234. }

    mainwindow.h

    1. #ifndef MAINWINDOW_H
    2. #define MAINWINDOW_H
    3. #include <QMainWindow>
    4. namespace Ui {
    5. class MainWindow;
    6. }
    7. class MainWindow : public QMainWindow
    8. {
    9. Q_OBJECT
    10. public:
    11. explicit MainWindow(QWidget *parent = nullptr);
    12. ~MainWindow();
    13. void connectDB(); // 连接数据库函数
    14. void initData(); // 初始化
    15. private slots:
    16. void on_actionCar_triggered();
    17. void on_actionCalc_triggered();
    18. void on_comboBoxFactory_currentIndexChanged(const QString &arg1);
    19. void on_comboBoxBrand_currentIndexChanged(const QString &arg1);
    20. void on_spinBox_valueChanged(int arg1);
    21. void on_buttonCancel_clicked();
    22. void on_buttonSure_clicked();
    23. private:
    24. Ui::MainWindow *ui;
    25. };
    26. #endif // MAINWINDOW_H

    mainwindow.cpp

    1. #include "mainwindow.h"
    2. #include "ui_mainwindow.h"
    3. #include <QSqlDatabase>
    4. #include <QSqlError>
    5. #include <QMessageBox>
    6. #include <QSqlQueryModel> // 数据库模型
    7. #include <QSqlQuery>
    8. #include "domxml.h"
    9. MainWindow::MainWindow(QWidget *parent) :
    10. QMainWindow(parent),
    11. ui(new Ui::MainWindow)
    12. {
    13. ui->setupUi(this);
    14. // 初始化时显示的界面
    15. on_actionCar_triggered();
    16. // 打开数据库
    17. connectDB();
    18. // 初始化数据
    19. initData();
    20. DomXML::createXML("../demo.xml"); // 创建空的xml文件
    21. // QStringList list;
    22. // list << "二汽神龙" << "毕加索" << "39" << "1" << "39";
    23. // DomXML::appendXML("../demo1.xml", list);
    24. // QStringList fList;
    25. // QStringList bList;
    26. // QStringList pList;
    27. // QStringList nList;
    28. // QStringList tList;
    29. // DomXML::readXML("../demo1.xml", fList, bList, pList, nList, tList);
    30. // for(int i = 0; i < fList.size(); i++)
    31. // {
    32. // QString str = QString("%1:%2:卖出了%3, 单价:%4, 总价:%5")
    33. // .arg(fList.at(i))
    34. // .arg(bList.at(i))
    35. // .arg(pList.at(i))
    36. // .arg(nList.at(i))
    37. // .arg(tList.at(i));
    38. // ui->textEdit->append(str);
    39. // }
    40. }
    41. MainWindow::~MainWindow()
    42. {
    43. delete ui;
    44. }
    45. // 车辆管理菜单
    46. void MainWindow::on_actionCar_triggered()
    47. {
    48. // 切换到车辆管理页面
    49. ui->stackedWidget->setCurrentWidget(ui->car);
    50. ui->label->setText("车辆管理");
    51. }
    52. // 销售统计菜单
    53. void MainWindow::on_actionCalc_triggered()
    54. {
    55. // 切换到销售统计页面
    56. ui->stackedWidget->setCurrentWidget(ui->calc);
    57. ui->label->setText("销售统计");
    58. }
    59. // 连接数据库
    60. void MainWindow::connectDB()
    61. {
    62. // 添加数据库
    63. QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
    64. db.setHostName("127.0.0.1");
    65. db.setUserName("root");
    66. db.setPassword("123456");
    67. db.setDatabaseName("car");
    68. if (!db.open())
    69. {
    70. QMessageBox::warning(this, "数据库打开失败", db.lastError().text());
    71. return;
    72. }
    73. }
    74. // 初始化数据
    75. void MainWindow::initData()
    76. {
    77. QSqlQueryModel *queryModel = new QSqlQueryModel(this); // 新建模型
    78. queryModel->setQuery("select name from factory"); // sql语句
    79. // 设置值
    80. ui->comboBoxFactory->setModel(queryModel);
    81. ui->last->setText("0"); // 剩余数量初始化
    82. ui->lineEditTotal->setEnabled(false); // 金额初始化
    83. }
    84. // 厂家下拉框槽函数
    85. void MainWindow::on_comboBoxFactory_currentIndexChanged(const QString &arg1)
    86. {
    87. if (arg1 == "请选择厂家")
    88. {
    89. // 内容清空
    90. ui->comboBoxBrand->clear(); // 品牌下拉框清空
    91. ui->lineEditPrice->clear(); // 报价清空
    92. ui->last->setText("0");
    93. ui->lineEditTotal->clear(); // 金额清空
    94. ui->spinBox->setValue(0); // 数量选择清空
    95. ui->spinBox->setEnabled(false);
    96. ui->buttonSure->setEnabled(false);
    97. }else
    98. {
    99. ui->comboBoxBrand->clear(); // 先清空
    100. QSqlQuery query;
    101. QString sql = QString("select name from brand where factory = '%1'").arg(arg1);
    102. // 执行sql语句
    103. query.exec(sql);
    104. // 获取内容
    105. while(query.next())
    106. {
    107. QString name = query.value(0).toString();
    108. ui->comboBoxBrand->addItem(name);
    109. }
    110. ui->spinBox->setEnabled(true);
    111. }
    112. }
    113. // 品牌下拉框槽函数
    114. void MainWindow::on_comboBoxBrand_currentIndexChanged(const QString &arg1)
    115. {
    116. QSqlQuery query;
    117. QString sql = QString("select price, last from brand where factory = '%1' and name = '%2'")
    118. .arg(ui->comboBoxFactory->currentText()) // 厂家下拉框当前选中内容
    119. .arg(arg1); // 选中的品牌
    120. // 执行sql语句
    121. query.exec(sql);
    122. // 获取内容
    123. while(query.next())
    124. {
    125. // 报价
    126. int price = query.value("price").toInt();
    127. // 剩余数
    128. int last = query.value("last").toInt();
    129. // 更新到对应的空间
    130. ui->lineEditPrice->setText(QString::number(price));
    131. ui->last->setText(QString::number(last));
    132. ui->spinBox->setMaximum(last);
    133. }
    134. ui->spinBox->setValue(0);
    135. }
    136. // 数据选择槽函数
    137. void MainWindow::on_spinBox_valueChanged(int arg1)
    138. {
    139. // 更新剩余数量
    140. // 厂家
    141. QString factoryStr = ui->comboBoxFactory->currentText();
    142. // 品牌
    143. QString brandStr = ui->comboBoxBrand->currentText();
    144. // 获取数据库剩余值
    145. QSqlQuery query;
    146. QString sql = QString("select sum, last from brand where factory = '%1' and name = '%2'")
    147. .arg(factoryStr)
    148. .arg(brandStr);
    149. // 执行数据库
    150. query.exec(sql);
    151. int last;
    152. while (query.next()) {
    153. last = query.value("last").toInt(); // 剩余
    154. }
    155. int tgempNum = last - arg1;
    156. ui->last->setText(QString::number(tgempNum));
    157. // 金额
    158. int price = ui->lineEditPrice->text().toInt(); // 报价
    159. int sum = price * arg1;
    160. ui->lineEditTotal->setText(QString::number(sum));
    161. // 判断确定按钮状态
    162. if (arg1)
    163. {
    164. ui->buttonSure->setEnabled(true);
    165. } else
    166. {
    167. ui->buttonSure->setEnabled(false);
    168. }
    169. }
    170. // 取消槽
    171. void MainWindow::on_buttonCancel_clicked()
    172. {
    173. on_comboBoxFactory_currentIndexChanged("请选择厂家");
    174. ui->comboBoxFactory->setCurrentIndex(0);
    175. }
    176. // 确定槽
    177. void MainWindow::on_buttonSure_clicked()
    178. {
    179. // 获取信息
    180. int num = ui->spinBox->value(); // 销售数据
    181. int last = ui->last->text().toInt(); // 剩余数据
    182. // 获取数据库的销量
    183. QSqlQuery query;
    184. QString sql = QString("select sell from brand where factory = '%1' and name = '%2'")
    185. .arg( ui->comboBoxFactory->currentText() )
    186. .arg( ui->comboBoxBrand->currentText() );
    187. // 执行数据库
    188. query.exec(sql);
    189. int sell;
    190. while (query.next()) {
    191. sell = query.value("sell").toInt();
    192. }
    193. // 更新数据库,剩余数量,销售总量
    194. sell += num;
    195. sql = QString("update brand set sell = %1, last = %2 where factory = '%3' and name = '%4'")
    196. .arg( sell )
    197. .arg( last )
    198. .arg( ui->comboBoxFactory->currentText() )
    199. .arg( ui->comboBoxBrand->currentText() );
    200. query.exec(sql);
    201. // 把确认后的数据更新到xml中
    202. QStringList list;
    203. list << ui->comboBoxFactory->currentText()
    204. << ui->comboBoxBrand->currentText()
    205. << ui->lineEditPrice->text()
    206. << QString::number(num)
    207. << ui->lineEditTotal->text();
    208. DomXML::appendXML("../demo.xml", list);
    209. QStringList fList;
    210. QStringList bList;
    211. QStringList pList;
    212. QStringList nList;
    213. QStringList tList;
    214. DomXML::readXML("../demo.xml", fList, bList, pList, nList, tList);
    215. ui->textEdit->clear(); // 先清除框内的数据
    216. for(int i = 0; i < fList.size(); i++)
    217. {
    218. QString str = QString("%1:%2:卖出了%3, 单价:%4, 总价:%5")
    219. .arg(fList.at(i))
    220. .arg(bList.at(i))
    221. .arg(pList.at(i))
    222. .arg(nList.at(i))
    223. .arg(tList.at(i));
    224. ui->textEdit->append(str);
    225. }
    226. ui->spinBox->setValue(0);
    227. }

    ui界面
    image.png

    数据库:
    image.png

    文件:CarManage.zip