登录

在这个站点登录

保存我的登录记录

<<忘记密码?

还没有账号?点此注册>>

Jerry

Qt写计算机协会值班签到系统

分享到:

本文已被浏览13170

计算机协会旧版的签到系统是用Flash+PHP使用Mysql数据库来写的.但是在使用过程中发现有些同学在签到的时候容易不小心的就关掉WAMP,于是Mysql和Apache就被干掉了,只剩下一个Flash根本没有办法和Mysql通信,开学纳新后,决定重新写一下V2.0版本

这个程序没有和其他设备共用数据库的必要,选用了SQLite,SQLite和Mysql类似,只是少了一些函数方面的功能,其他方面在SQLite3版本上和Mysql基本操作一样了.

这个程序设计了五个UI界面(关于,帮助,主窗口,值班窗口,管理窗口),这里只介绍后面三个界面.每个界面都有对应的cpp文件和.h头文件.

首先上个效果图:
主窗口
主窗口

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>WorkingDialog</class>
 <widget class="QDialog" name="WorkingDialog">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>500</width>
    <height>200</height>
   </rect>
  </property>
  <property name="minimumSize">
   <size>
    <width>500</width>
    <height>200</height>
   </size>
  </property>
  <property name="maximumSize">
   <size>
    <width>500</width>
    <height>200</height>
   </size>
  </property>
  <property name="windowTitle">
   <string>计算机协会电子签到系统-正在计时</string>
  </property>
  <property name="windowIcon">
   <iconset resource="Icons.qrc">
    <normaloff>:/Icons/Working.png</normaloff>:/Icons/Working.png</iconset>
  </property>
  <property name="windowOpacity">
   <double>1.000000000000000</double>
  </property>
  <layout class="QVBoxLayout" name="verticalLayout">
   <item>
    <layout class="QHBoxLayout" name="horizontalLayout_3">
     <item>
      <widget class="QLabel" name="label">
       <property name="sizePolicy">
        <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
         <horstretch>0</horstretch>
         <verstretch>0</verstretch>
        </sizepolicy>
       </property>
       <property name="text">
        <string>当前值班人:</string>
       </property>
      </widget>
     </item>
     <item>
      <widget class="QLabel" name="CurrentMan">
       <property name="sizePolicy">
        <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
         <horstretch>0</horstretch>
         <verstretch>0</verstretch>
        </sizepolicy>
       </property>
       <property name="whatsThis">
        <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;这里应该是您的名字,如果不是,请尽快结束计时重新选择姓名后再开始计时.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
       </property>
       <property name="text">
        <string>TextLabel</string>
       </property>
      </widget>
     </item>
     <item>
      <spacer name="horizontalSpacer">
       <property name="orientation">
        <enum>Qt::Horizontal</enum>
       </property>
       <property name="sizeHint" stdset="0">
        <size>
         <width>40</width>
         <height>20</height>
        </size>
       </property>
      </spacer>
     </item>
     <item>
      <widget class="QLabel" name="label_2">
       <property name="sizePolicy">
        <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
         <horstretch>0</horstretch>
         <verstretch>0</verstretch>
        </sizepolicy>
       </property>
       <property name="text">
        <string>当前时间:</string>
       </property>
      </widget>
     </item>
     <item>
      <widget class="QLabel" name="Time">
       <property name="sizePolicy">
        <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
         <horstretch>0</horstretch>
         <verstretch>0</verstretch>
        </sizepolicy>
       </property>
       <property name="text">
        <string>TextLabel</string>
       </property>
      </widget>
     </item>
    </layout>
   </item>
   <item>
    <widget class="QGroupBox" name="horizontalGroupBox_2">
     <property name="font">
      <font>
       <family>微软雅黑 Light</family>
       <pointsize>12</pointsize>
      </font>
     </property>
     <property name="title">
      <string>已值班时间</string>
     </property>
     <layout class="QHBoxLayout" name="horizontalLayout_2">
      <item>
       <spacer name="horizontalSpacer_2">
        <property name="orientation">
         <enum>Qt::Horizontal</enum>
        </property>
        <property name="sizeHint" stdset="0">
         <size>
          <width>40</width>
          <height>20</height>
         </size>
        </property>
       </spacer>
      </item>
      <item>
       <widget class="QLabel" name="WorkingTime">
        <property name="font">
         <font>
          <family>微软雅黑 Light</family>
          <pointsize>36</pointsize>
         </font>
        </property>
        <property name="whatsThis">
         <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;这里显示您本次值班已经进行的时长.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
        </property>
        <property name="text">
         <string>X小时XX分钟XX秒</string>
        </property>
       </widget>
      </item>
      <item>
       <spacer name="horizontalSpacer_3">
        <property name="orientation">
         <enum>Qt::Horizontal</enum>
        </property>
        <property name="sizeType">
         <enum>QSizePolicy::Expanding</enum>
        </property>
        <property name="sizeHint" stdset="0">
         <size>
          <width>40</width>
          <height>20</height>
         </size>
        </property>
       </spacer>
      </item>
     </layout>
    </widget>
   </item>
   <item>
    <spacer name="verticalSpacer_2">
     <property name="orientation">
      <enum>Qt::Vertical</enum>
     </property>
     <property name="sizeHint" stdset="0">
      <size>
       <width>20</width>
       <height>40</height>
      </size>
     </property>
    </spacer>
   </item>
   <item>
    <layout class="QHBoxLayout" name="horizontalLayout">
     <item>
      <spacer name="horizontalSpacer_5">
       <property name="orientation">
        <enum>Qt::Horizontal</enum>
       </property>
       <property name="sizeHint" stdset="0">
        <size>
         <width>40</width>
         <height>20</height>
        </size>
       </property>
      </spacer>
     </item>
     <item>
      <widget class="QPushButton" name="StopTimer">
       <property name="font">
        <font>
         <family>微软雅黑 Light</family>
         <pointsize>14</pointsize>
        </font>
       </property>
       <property name="whatsThis">
        <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;点击这里将结束本次值班的计时,本次值班记录将会记录进入数据库而无法再次开始,请确保值班时间达到标准后再点击这里!&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
       </property>
       <property name="text">
        <string>结束计时(&amp;S)</string>
       </property>
       <property name="icon">
        <iconset resource="Icons.qrc">
         <normaloff>:/Icons/No.png</normaloff>:/Icons/No.png</iconset>
       </property>
       <property name="iconSize">
        <size>
         <width>25</width>
         <height>25</height>
        </size>
       </property>
      </widget>
     </item>
     <item>
      <spacer name="horizontalSpacer_4">
       <property name="orientation">
        <enum>Qt::Horizontal</enum>
       </property>
       <property name="sizeHint" stdset="0">
        <size>
         <width>40</width>
         <height>20</height>
        </size>
       </property>
      </spacer>
     </item>
     <item>
      <widget class="QPushButton" name="Exit">
       <property name="font">
        <font>
         <family>微软雅黑 Light</family>
         <pointsize>14</pointsize>
        </font>
       </property>
       <property name="whatsThis">
        <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;您可以先暂时关闭这个窗口,计时不会中止.在结束值班后请重新打开签到系统结束计时即可.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
       </property>
       <property name="text">
        <string>临时关闭(&amp;C)</string>
       </property>
       <property name="icon">
        <iconset resource="Icons.qrc">
         <normaloff>:/Icons/Exit.png</normaloff>:/Icons/Exit.png</iconset>
       </property>
       <property name="iconSize">
        <size>
         <width>25</width>
         <height>25</height>
        </size>
       </property>
      </widget>
     </item>
     <item>
      <spacer name="horizontalSpacer_6">
       <property name="orientation">
        <enum>Qt::Horizontal</enum>
       </property>
       <property name="sizeHint" stdset="0">
        <size>
         <width>40</width>
         <height>20</height>
        </size>
       </property>
      </spacer>
     </item>
    </layout>
   </item>
   <item>
    <spacer name="verticalSpacer">
     <property name="orientation">
      <enum>Qt::Vertical</enum>
     </property>
     <property name="sizeHint" stdset="0">
      <size>
       <width>20</width>
       <height>40</height>
      </size>
     </property>
    </spacer>
   </item>
  </layout>
 </widget>
 <resources>
  <include location="Icons.qrc"/>
 </resources>
 <connections/>
</ui>
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "WorkingDialog.h"
namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    WorkingDialog* Timer;
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    void init(WorkingDialog* Timer);

private slots:
    void on_About_triggered();
    void on_Exit_triggered();
    void on_StartTimer_clicked();
    void on_SignList_doubleClicked(const QModelIndex &index);

    void on_ExportData_triggered();

    void on_Manage_triggered();

	void on_Help_triggered();

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H
#include "MainWindow.h"
#include "ManageDialog.h"
#include "ui_mainwindow.h"
#include "WorkingDialog.h"
#include "HelpDialog.h"
#include "About.h"
#include "Person.h"
#include "SignUp.h"
#include "PreDefineFunction.h"
#include <QApplication>
#include <QDebug>
#include <QMessageBox>
#include <QList>
#include <QDateTime>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QAbstractItemView>
#include <QFileDialog>
#include <QProgressDialog>
#include <QTextStream>
#include <QInputDialog>
extern QSqlQuery *sql;
extern QSqlDatabase db;

extern QList<Person> People;
extern QList<SignUp> Signs;

extern int CurrentPerson;
extern int CurrentSign;

MainWindow::MainWindow(QWidget *parent)
    :QMainWindow(parent),
    ui(new Ui::MainWindow){
    ui->setupUi(this);
}

MainWindow::~MainWindow(){
    delete ui;
}
void MainWindow::init(WorkingDialog *Timer){
    int i;
    this->Timer=Timer;
    if(Signs.count()<=0||Signs[Signs.count()-1].IsOver){
        ui->PeoList->clear();
        ui->PeoList->addItem("请选择一个姓名");
        for(i=0;i<People.count();i++){
            ui->PeoList->addItem(People.at(i).Name);
        }
        QString Head;
        QList<QString> Content;
        if(Signs.count()>0){
            QString temp;
            int Dist;
            int Hour;
            int Min;
            int Sec;
            QDateTime Btemp,Etemp;
            Head="姓名,开始时间,结束时间,值班时长";
            for(i=0;i<Signs.count();i++){
                Btemp.setTime_t(Signs[i].Begin);
                Etemp.setTime_t(Signs[i].End);
                temp  = Signs[i].Name+",";
                temp += Btemp.toString("yyyy年MM月dd日 HH:mm:ss")+",";
                temp += Etemp.toString("yyyy年MM月dd日 HH:mm:ss")+",";
                Dist=Signs[i].End-Signs[i].Begin;
                Sec=Dist%60;
                Dist=(Dist-Sec)/60;
                Min=Dist%60;
                Hour=(Dist-Min)/60;
                if(Hour>0) temp+=(Hour<10?"0":"")+QString::number(Hour)+"小时";
                if(Min>0) temp+=(Min<10?"0":"")+QString::number(Min)+"分钟";
                temp+=(Sec<10?"0":"")+QString::number(Sec)+"秒";
                Content.append(temp);
            }
        }else{
            Head="没有签到数据!";
            Content.append("你是第一个哦~~");
        }
        fillTable(ui->SignList,Head,Content,QAbstractItemView::SingleSelection);
        ui->SignList->resizeColumnsToContents();
        this->show();
    }else{
        CurrentSign=Signs.count()-1;
        this->Timer->init(this);
    }
}

void MainWindow::on_About_triggered(){
	About AD;
	AD.exec();
}
void MainWindow::on_Exit_triggered(){
    int confirm=QMessageBox::question(this,"退出","确定要退出么?",QMessageBox::Yes,QMessageBox::No);
    if(confirm==QMessageBox::Yes){
        this->hide();
        exit(0);
    }
}
void MainWindow::on_StartTimer_clicked(){
    int select=ui->PeoList->currentIndex()-1;
    if(select<0){
        QMessageBox::warning(this,"警告","请选择一个姓名!");
        return;
    }
    int confirm=QMessageBox::question(this,"询问","请确认以下信息:n值班人:"+People[select].Name,QMessageBox::Ok,QMessageBox::Cancel);
    if(confirm!=QMessageBox::Ok){
        return;
    }
    CurrentPerson=select;
    CurrentSign=Signs.count();
    SignUp stemp;
    stemp.Begin=QDateTime::currentDateTime().toTime_t();
    stemp.End=0;
    stemp.IsOver=false;
    stemp.Name=People[select].Name;
    stemp.lid=CurrentSign>=1?Signs[CurrentSign-1].lid+1:0;
    Signs.append(stemp);
    sql->exec("INSERT INTO SignUp VALUES ("+QString::number(stemp.lid)+",'"+stemp.Name+"',"+QString::number(stemp.Begin)+",0,0)");
    this->hide();
    this->Timer->init(this);
}
void MainWindow::on_SignList_doubleClicked(const QModelIndex &index){
    int select=index.row();
    if(select==Signs.count()) return;
    QString Content;
    QDateTime Btemp,Etemp;
    int Dist,Sec,Min,Hour;
    Btemp.setTime_t(Signs[select].Begin);
    Etemp.setTime_t(Signs[select].End);
    Content  = "值班人:"+Signs[select].Name+"n";
    Content += "开始时间:"+Btemp.toString("yyyy年MM月dd日 HH:mm:ss")+"n";
    Content += "结束时间:"+Etemp.toString("yyyy年MM月dd日 HH:mm:ss")+"n";
    Content += "值班时长:";
    Dist=Signs[select].End-Signs[select].Begin;
    Sec=Dist%60;
    Dist=(Dist-Sec)/60;
    Min=Dist%60;
    Hour=(Dist-Min)/60;
    if(Hour>0) Content+=(Hour<10?"0":"")+QString::number(Hour)+"小时";
    if(Min>0) Content+=(Min<10?"0":"")+QString::number(Min)+"分钟";
    Content+=(Sec<10?"0":"")+QString::number(Sec)+"秒";
    QMessageBox::information(this,"值班记录",Content);
}
void MainWindow::on_ExportData_triggered(){
	if(Signs.count()<=0){
		QMessageBox::warning(this,"错误!","当前数据库中不存在任何值班记录");
		return;
	}
	QString Target;
	Target=QFileDialog::getSaveFileName(this,"导出数据至",QDir::currentPath(),"CSV 表格(*.csv)");
	if(Target.isEmpty()) return;
	QFile file(Target);
	if(!file.open(QIODevice::WriteOnly)){
		QMessageBox::critical(this,"错误","当前目录不可写,请检查后重试!");
		return;
	}
	QTextStream out(&file);
	QStringList Head;
	Head<<"#"<<"姓名"<<"值班开始时间"<<"值班结束时间"<<"值班时长";
	QProgressDialog dialog(tr("正在导出数据..."),tr("取消"),0,(Signs.count()+1)*5,this);
	int MainPrg=0;
	dialog.setWindowTitle(tr("导出进度"));
	dialog.setWindowModality(Qt::WindowModal);
	dialog.show();
	for(int i=0;i<Head.count();i++,MainPrg++){
		dialog.setValue(MainPrg);
		QCoreApplication::processEvents();
		out<<Head[i]+(Head.count()-1!=i?",":"");
		if(dialog.wasCanceled()){
			file.close();
			QFile::remove(Target);
			QMessageBox::warning(this,"提示","导出操作被中止!");
			return;
		}
	}
	out<<"n";
	for(int i=0;i<Signs.count();i++){
		QStringList temp=Signs[i].toTableUnit(i+1);
		for(int j=0;j<temp.count();j++,MainPrg++){
			dialog.setValue(MainPrg);
			QCoreApplication::processEvents();
			out<<temp[j]+(j+1!=temp.count()?",":"");
			if(dialog.wasCanceled()){
				file.close();
				QFile::remove(Target);
				QMessageBox::warning(this,"提示","导出操作被中止!");
				return;
			}
		}
		out<<"n";
	}
	dialog.setValue(MainPrg);
	QMessageBox::information(this,"成功!","成功导出"+QString::number(Signs.count())+"条记录");
}
void MainWindow::on_Manage_triggered(){
	QString Password=getMD5(QInputDialog::getText(this,"管理密码","请输入管理员密码:",QLineEdit::Password));
	sql->exec("Select 1 From options where key_name='mng_pwd' AND key_value='"+Password+"';");
	if(!sql->next()){
		QMessageBox::critical(this,"错误","管理员密码错误!");
		return;
	}
	ManageDialog MD;
	MD.init();
	this->init(this->Timer);
}

void MainWindow::on_Help_triggered(){
	HelpDialog HD;
	HD.exec();
}

值班窗口
值班界面

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>WorkingDialog</class>
 <widget class="QDialog" name="WorkingDialog">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>500</width>
    <height>200</height>
   </rect>
  </property>
  <property name="minimumSize">
   <size>
    <width>500</width>
    <height>200</height>
   </size>
  </property>
  <property name="maximumSize">
   <size>
    <width>500</width>
    <height>200</height>
   </size>
  </property>
  <property name="windowTitle">
   <string>计算机协会电子签到系统-正在计时</string>
  </property>
  <property name="windowIcon">
   <iconset resource="Icons.qrc">
    <normaloff>:/Icons/Working.png</normaloff>:/Icons/Working.png</iconset>
  </property>
  <property name="windowOpacity">
   <double>1.000000000000000</double>
  </property>
  <layout class="QVBoxLayout" name="verticalLayout">
   <item>
    <layout class="QHBoxLayout" name="horizontalLayout_3">
     <item>
      <widget class="QLabel" name="label">
       <property name="sizePolicy">
        <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
         <horstretch>0</horstretch>
         <verstretch>0</verstretch>
        </sizepolicy>
       </property>
       <property name="text">
        <string>当前值班人:</string>
       </property>
      </widget>
     </item>
     <item>
      <widget class="QLabel" name="CurrentMan">
       <property name="sizePolicy">
        <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
         <horstretch>0</horstretch>
         <verstretch>0</verstretch>
        </sizepolicy>
       </property>
       <property name="whatsThis">
        <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;这里应该是您的名字,如果不是,请尽快结束计时重新选择姓名后再开始计时.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
       </property>
       <property name="text">
        <string>TextLabel</string>
       </property>
      </widget>
     </item>
     <item>
      <spacer name="horizontalSpacer">
       <property name="orientation">
        <enum>Qt::Horizontal</enum>
       </property>
       <property name="sizeHint" stdset="0">
        <size>
         <width>40</width>
         <height>20</height>
        </size>
       </property>
      </spacer>
     </item>
     <item>
      <widget class="QLabel" name="label_2">
       <property name="sizePolicy">
        <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
         <horstretch>0</horstretch>
         <verstretch>0</verstretch>
        </sizepolicy>
       </property>
       <property name="text">
        <string>当前时间:</string>
       </property>
      </widget>
     </item>
     <item>
      <widget class="QLabel" name="Time">
       <property name="sizePolicy">
        <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
         <horstretch>0</horstretch>
         <verstretch>0</verstretch>
        </sizepolicy>
       </property>
       <property name="text">
        <string>TextLabel</string>
       </property>
      </widget>
     </item>
    </layout>
   </item>
   <item>
    <widget class="QGroupBox" name="horizontalGroupBox_2">
     <property name="font">
      <font>
       <family>微软雅黑 Light</family>
       <pointsize>12</pointsize>
      </font>
     </property>
     <property name="title">
      <string>已值班时间</string>
     </property>
     <layout class="QHBoxLayout" name="horizontalLayout_2">
      <item>
       <spacer name="horizontalSpacer_2">
        <property name="orientation">
         <enum>Qt::Horizontal</enum>
        </property>
        <property name="sizeHint" stdset="0">
         <size>
          <width>40</width>
          <height>20</height>
         </size>
        </property>
       </spacer>
      </item>
      <item>
       <widget class="QLabel" name="WorkingTime">
        <property name="font">
         <font>
          <family>微软雅黑 Light</family>
          <pointsize>36</pointsize>
         </font>
        </property>
        <property name="whatsThis">
         <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;这里显示您本次值班已经进行的时长.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
        </property>
        <property name="text">
         <string>X小时XX分钟XX秒</string>
        </property>
       </widget>
      </item>
      <item>
       <spacer name="horizontalSpacer_3">
        <property name="orientation">
         <enum>Qt::Horizontal</enum>
        </property>
        <property name="sizeType">
         <enum>QSizePolicy::Expanding</enum>
        </property>
        <property name="sizeHint" stdset="0">
         <size>
          <width>40</width>
          <height>20</height>
         </size>
        </property>
       </spacer>
      </item>
     </layout>
    </widget>
   </item>
   <item>
    <spacer name="verticalSpacer_2">
     <property name="orientation">
      <enum>Qt::Vertical</enum>
     </property>
     <property name="sizeHint" stdset="0">
      <size>
       <width>20</width>
       <height>40</height>
      </size>
     </property>
    </spacer>
   </item>
   <item>
    <layout class="QHBoxLayout" name="horizontalLayout">
     <item>
      <spacer name="horizontalSpacer_5">
       <property name="orientation">
        <enum>Qt::Horizontal</enum>
       </property>
       <property name="sizeHint" stdset="0">
        <size>
         <width>40</width>
         <height>20</height>
        </size>
       </property>
      </spacer>
     </item>
     <item>
      <widget class="QPushButton" name="StopTimer">
       <property name="font">
        <font>
         <family>微软雅黑 Light</family>
         <pointsize>14</pointsize>
        </font>
       </property>
       <property name="whatsThis">
        <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;点击这里将结束本次值班的计时,本次值班记录将会记录进入数据库而无法再次开始,请确保值班时间达到标准后再点击这里!&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
       </property>
       <property name="text">
        <string>结束计时(&amp;S)</string>
       </property>
       <property name="icon">
        <iconset resource="Icons.qrc">
         <normaloff>:/Icons/No.png</normaloff>:/Icons/No.png</iconset>
       </property>
       <property name="iconSize">
        <size>
         <width>25</width>
         <height>25</height>
        </size>
       </property>
      </widget>
     </item>
     <item>
      <spacer name="horizontalSpacer_4">
       <property name="orientation">
        <enum>Qt::Horizontal</enum>
       </property>
       <property name="sizeHint" stdset="0">
        <size>
         <width>40</width>
         <height>20</height>
        </size>
       </property>
      </spacer>
     </item>
     <item>
      <widget class="QPushButton" name="Exit">
       <property name="font">
        <font>
         <family>微软雅黑 Light</family>
         <pointsize>14</pointsize>
        </font>
       </property>
       <property name="whatsThis">
        <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;您可以先暂时关闭这个窗口,计时不会中止.在结束值班后请重新打开签到系统结束计时即可.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
       </property>
       <property name="text">
        <string>临时关闭(&amp;C)</string>
       </property>
       <property name="icon">
        <iconset resource="Icons.qrc">
         <normaloff>:/Icons/Exit.png</normaloff>:/Icons/Exit.png</iconset>
       </property>
       <property name="iconSize">
        <size>
         <width>25</width>
         <height>25</height>
        </size>
       </property>
      </widget>
     </item>
     <item>
      <spacer name="horizontalSpacer_6">
       <property name="orientation">
        <enum>Qt::Horizontal</enum>
       </property>
       <property name="sizeHint" stdset="0">
        <size>
         <width>40</width>
         <height>20</height>
        </size>
       </property>
      </spacer>
     </item>
    </layout>
   </item>
   <item>
    <spacer name="verticalSpacer">
     <property name="orientation">
      <enum>Qt::Vertical</enum>
     </property>
     <property name="sizeHint" stdset="0">
      <size>
       <width>20</width>
       <height>40</height>
      </size>
     </property>
    </spacer>
   </item>
  </layout>
 </widget>
 <resources>
  <include location="Icons.qrc"/>
 </resources>
 <connections/>
</ui>
#ifndef WORKINGDIALOG_H
#define WORKINGDIALOG_H

#include <QDialog>
#include <QTimer>
namespace Ui {
class WorkingDialog;
}
class MainWindow;
class WorkingDialog : public QDialog
{
    Q_OBJECT

public:
    explicit WorkingDialog(QWidget *parent = 0);
    MainWindow* Main;
    ~WorkingDialog();
    QTimer* timer;
    void init(MainWindow* Main);

private slots:
    void on_StopTimer_clicked();
    void showTime();
    void on_Exit_clicked();

private:
    Ui::WorkingDialog *ui;

};

#endif // WORKINGDIALOG_H
#include "WorkingDialog.h"
#include "ui_workingdialog.h"
#include "MainWindow.h"
#include "SignUp.h"
#include "Person.h"
#include <QSqlError>
#include <QTimer>
#include <QDebug>
#include <QDateTime>
#include <QMessageBox>

extern QSqlQuery *sql;
extern QSqlDatabase db;

extern QList<Person> People;
extern QList<SignUp> Signs;

extern int CurrentPerson;
extern int CurrentSign;

WorkingDialog::WorkingDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::WorkingDialog){
    ui->setupUi(this);
}

WorkingDialog::~WorkingDialog(){
    delete ui;
}
void WorkingDialog::init(MainWindow* Main){
    this->Main=Main;
	ui->CurrentMan->setText(Signs[CurrentSign].Name);
    this->timer=new QTimer(this);
    QObject::connect(timer,SIGNAL(timeout()),this,SLOT(showTime()));
    timer->start(100);
    this->show();
}
void WorkingDialog::showTime(){
    unsigned CurrentTime=QDateTime::currentDateTime().toTime_t();
    int Dist=CurrentTime-Signs[CurrentSign].Begin;
    int Hour;
    int Min;
    int Sec;
    Sec=Dist%60;
    Dist=(Dist-Sec)/60;
    Min=Dist%60;
    Hour=(Dist-Min)/60;
    QString Tip;
    if(Hour>0) Tip+=(Hour<10?"0":"")+QString::number(Hour)+"小时";
    if(Min>0) Tip+=(Min<10?"0":"")+QString::number(Min)+"分钟";
    Tip+=(Sec<10?"0":"")+QString::number(Sec)+"秒";
    ui->WorkingTime->setText(Tip);
	ui->Time->setText(QDateTime::currentDateTime().toString("hh:mm:ss a"));
}
void WorkingDialog::on_StopTimer_clicked(){
    if(QMessageBox::question(this,"询问?","确定现在终止计时?",QMessageBox::Yes,QMessageBox::No)==QMessageBox::No) return;
    Signs[CurrentSign].End=QDateTime::currentDateTime().toTime_t();
    Signs[CurrentSign].IsOver=true;
    sql->exec("Update SignUp Set End="+QString::number(Signs[CurrentSign].End)+",IsOver=1 Where lid="+QString::number(Signs[CurrentSign].lid));
    this->timer->stop();
    this->hide();
    this->Main->init(this);
}
void WorkingDialog::on_Exit_clicked(){
    QMessageBox::information(this,"提示","请在离开值班室之前重新打开点击计时结束,否则将会影响下一位值班同学的签到!");
    exit(0);
}

管理界面
管理界面

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>ManageDialog</class>
 <widget class="QDialog" name="ManageDialog">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>600</width>
    <height>400</height>
   </rect>
  </property>
  <property name="minimumSize">
   <size>
    <width>600</width>
    <height>400</height>
   </size>
  </property>
  <property name="maximumSize">
   <size>
    <width>600</width>
    <height>400</height>
   </size>
  </property>
  <property name="windowTitle">
   <string>系统设置</string>
  </property>
  <property name="windowIcon">
   <iconset resource="Icons.qrc">
    <normaloff>:/Icons/Settings.png</normaloff>:/Icons/Settings.png</iconset>
  </property>
  <layout class="QVBoxLayout" name="verticalLayout">
   <item>
    <widget class="QGroupBox" name="horizontalGroupBox1">
     <property name="sizePolicy">
      <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
       <horstretch>0</horstretch>
       <verstretch>0</verstretch>
      </sizepolicy>
     </property>
     <property name="title">
      <string>数据库操作</string>
     </property>
     <layout class="QHBoxLayout" name="horizontalLayout">
      <item>
       <widget class="QPushButton" name="Clear">
        <property name="whatsThis">
         <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;此功能将会清除所有的值班记录,请确保所有的记录已经完全导出后再执行此项!&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
        </property>
        <property name="text">
         <string>请空已有值班记录</string>
        </property>
        <property name="icon">
         <iconset resource="Icons.qrc">
          <normaloff>:/Icons/clear.png</normaloff>:/Icons/clear.png</iconset>
        </property>
       </widget>
      </item>
      <item>
       <spacer name="horizontalSpacer">
        <property name="orientation">
         <enum>Qt::Horizontal</enum>
        </property>
        <property name="sizeType">
         <enum>QSizePolicy::Expanding</enum>
        </property>
        <property name="sizeHint" stdset="0">
         <size>
          <width>40</width>
          <height>10</height>
         </size>
        </property>
       </spacer>
      </item>
     </layout>
    </widget>
   </item>
   <item>
    <widget class="QGroupBox" name="horizontalGroupBox_2">
     <property name="sizePolicy">
      <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
       <horstretch>0</horstretch>
       <verstretch>0</verstretch>
      </sizepolicy>
     </property>
     <property name="title">
      <string>值班人员管理</string>
     </property>
     <layout class="QHBoxLayout" name="horizontalLayout_2">
      <item>
       <widget class="QListWidget" name="PeoList">
        <property name="maximumSize">
         <size>
          <width>150</width>
          <height>16777215</height>
         </size>
        </property>
        <property name="whatsThis">
         <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;当前值班人员列表.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
        </property>
       </widget>
      </item>
      <item>
       <layout class="QVBoxLayout" name="verticalLayout_2">
        <item>
         <widget class="QGroupBox" name="horizontalGroupBox">
          <property name="sizePolicy">
           <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
            <horstretch>0</horstretch>
            <verstretch>0</verstretch>
           </sizepolicy>
          </property>
          <property name="title">
           <string>添加</string>
          </property>
          <layout class="QHBoxLayout" name="horizontalLayout_4">
           <property name="leftMargin">
            <number>5</number>
           </property>
           <property name="topMargin">
            <number>5</number>
           </property>
           <property name="rightMargin">
            <number>5</number>
           </property>
           <property name="bottomMargin">
            <number>5</number>
           </property>
           <item>
            <widget class="QLabel" name="label">
             <property name="text">
              <string>姓名:</string>
             </property>
            </widget>
           </item>
           <item>
            <widget class="QLineEdit" name="PeoName">
             <property name="whatsThis">
              <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;新增人员名称,必填&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
             </property>
            </widget>
           </item>
           <item>
            <widget class="QPushButton" name="Add">
             <property name="whatsThis">
              <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;添加新的值班人员&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
             </property>
             <property name="text">
              <string>添加</string>
             </property>
             <property name="icon">
              <iconset resource="Icons.qrc">
               <normaloff>:/Icons/Add.png</normaloff>:/Icons/Add.png</iconset>
             </property>
            </widget>
           </item>
          </layout>
         </widget>
        </item>
        <item>
         <layout class="QHBoxLayout" name="horizontalLayout_5">
          <item>
           <spacer name="horizontalSpacer_2">
            <property name="orientation">
             <enum>Qt::Horizontal</enum>
            </property>
            <property name="sizeType">
             <enum>QSizePolicy::Fixed</enum>
            </property>
            <property name="sizeHint" stdset="0">
             <size>
              <width>40</width>
              <height>20</height>
             </size>
            </property>
           </spacer>
          </item>
          <item>
           <widget class="QPushButton" name="Remove">
            <property name="whatsThis">
             <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;删除左侧已经被选中的姓名.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
            </property>
            <property name="text">
             <string>删除</string>
            </property>
            <property name="icon">
             <iconset resource="Icons.qrc">
              <normaloff>:/Icons/Erase.png</normaloff>:/Icons/Erase.png</iconset>
            </property>
           </widget>
          </item>
          <item>
           <spacer name="horizontalSpacer_3">
            <property name="orientation">
             <enum>Qt::Horizontal</enum>
            </property>
            <property name="sizeType">
             <enum>QSizePolicy::Fixed</enum>
            </property>
            <property name="sizeHint" stdset="0">
             <size>
              <width>40</width>
              <height>20</height>
             </size>
            </property>
           </spacer>
          </item>
         </layout>
        </item>
        <item>
         <spacer name="verticalSpacer">
          <property name="orientation">
           <enum>Qt::Vertical</enum>
          </property>
          <property name="sizeHint" stdset="0">
           <size>
            <width>20</width>
            <height>40</height>
           </size>
          </property>
         </spacer>
        </item>
       </layout>
      </item>
     </layout>
    </widget>
   </item>
   <item>
    <widget class="QGroupBox" name="horizontalGroupBox_3">
     <property name="title">
      <string>管理员密码设置</string>
     </property>
     <layout class="QHBoxLayout" name="horizontalLayout_3">
      <item>
       <widget class="QLabel" name="label_2">
        <property name="text">
         <string>旧密码:</string>
        </property>
       </widget>
      </item>
      <item>
       <widget class="QLineEdit" name="Pwd1">
        <property name="sizePolicy">
         <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
          <horstretch>0</horstretch>
          <verstretch>0</verstretch>
         </sizepolicy>
        </property>
        <property name="whatsThis">
         <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;修改密码时输入您的旧密码.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
        </property>
        <property name="echoMode">
         <enum>QLineEdit::Password</enum>
        </property>
       </widget>
      </item>
      <item>
       <widget class="QLabel" name="label_3">
        <property name="text">
         <string>新密码:</string>
        </property>
       </widget>
      </item>
      <item>
       <widget class="QLineEdit" name="Pwd2">
        <property name="sizePolicy">
         <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
          <horstretch>0</horstretch>
          <verstretch>0</verstretch>
         </sizepolicy>
        </property>
        <property name="whatsThis">
         <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;这里输入您的新密码&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
        </property>
        <property name="echoMode">
         <enum>QLineEdit::Password</enum>
        </property>
       </widget>
      </item>
      <item>
       <widget class="QLabel" name="label_4">
        <property name="text">
         <string>重复新密码:</string>
        </property>
       </widget>
      </item>
      <item>
       <widget class="QLineEdit" name="Pwd3">
        <property name="sizePolicy">
         <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
          <horstretch>0</horstretch>
          <verstretch>0</verstretch>
         </sizepolicy>
        </property>
        <property name="whatsThis">
         <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;重复前面的密码&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
        </property>
        <property name="echoMode">
         <enum>QLineEdit::Password</enum>
        </property>
       </widget>
      </item>
      <item>
       <widget class="QPushButton" name="ChangePwd">
        <property name="toolTipDuration">
         <number>-1</number>
        </property>
        <property name="whatsThis">
         <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;执行修改密码操作&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
        </property>
        <property name="text">
         <string>修改</string>
        </property>
        <property name="icon">
         <iconset resource="Icons.qrc">
          <normaloff>:/Icons/Unlock.png</normaloff>:/Icons/Unlock.png</iconset>
        </property>
       </widget>
      </item>
     </layout>
    </widget>
   </item>
  </layout>
 </widget>
 <resources>
  <include location="Icons.qrc"/>
 </resources>
 <connections/>
</ui>
#ifndef MANAGEDIALOG_H
#define MANAGEDIALOG_H

#include <QDialog>

namespace Ui {
class ManageDialog;
}

class ManageDialog : public QDialog
{
	Q_OBJECT

public:
	explicit ManageDialog(QWidget *parent = 0);
	~ManageDialog();
	void init();

private slots:
	void on_Clear_clicked();

	void on_Remove_clicked();

	void on_Add_clicked();

	void on_ChangePwd_clicked();

private:
	Ui::ManageDialog *ui;
};

#endif // MANAGEDIALOG_H
#include "ManageDialog.h"
#include "ui_ManageDialog.h"
#include "Person.h"
#include "SignUp.h"
#include "PreDefineFunction.h"
#include <QApplication>
#include <QMessageBox>
#include <QDebug>
#include <QSqlError>
extern QSqlQuery *sql;
extern QSqlDatabase db;

extern QList<Person> People;
extern QList<SignUp> Signs;

extern int CurrentPerson;
extern int CurrentSign;

ManageDialog::ManageDialog(QWidget *parent) :
	QDialog(parent),
	ui(new Ui::ManageDialog)
{
	ui->setupUi(this);
}
void ManageDialog::init(){
	if(People.count()<=0){
		ui->PeoList->addItem("目前列表为空!");
	}else{
		for(int i=0;i<People.count();i++){
			ui->PeoList->addItem(People[i].Name);
		}
	}
	this->exec();
}

ManageDialog::~ManageDialog()
{
	delete ui;
}

void ManageDialog::on_Clear_clicked(){
	if(QMessageBox::warning(this,"询问","确定要清除所有值班记录?n请在导出数据后再执行此项!",QMessageBox::Yes,QMessageBox::No)==QMessageBox::No) return;
	sql->exec("Delete From SignUp");
	Signs.clear();
	QMessageBox::information(this,"提示","清除成功!");
}

void ManageDialog::on_Remove_clicked(){
	int selected=ui->PeoList->currentRow();
	if(selected<0){
		QMessageBox::warning(this,"错误","请选择要删除的项目!");
		return;
	}
	if(QMessageBox::question(this,"删除","确定要删除"+People[selected].Name+"吗?",QMessageBox::Yes,QMessageBox::No)==QMessageBox::No) return;
	ui->PeoList->takeItem(selected);
	sql->exec("Delete from Person where pid="+QString::number(People[selected].pid));
	People.removeAt(selected);
	QMessageBox::information(this,"提示","删除成功!");
}

void ManageDialog::on_Add_clicked(){
	if(ui->PeoName->text().isEmpty()){
		QMessageBox::warning(this,"错误","请输入要添加的姓名!");
		return;
	}
	Person temp(NULL);
	temp.Name=ui->PeoName->text();
	temp.pid=People[People.count()-1].pid+1;
	sql->exec("Insert into Person values(NULL,'"+temp.Name+"')");
	People.append(temp);
	ui->PeoList->addItem(temp.Name);
	ui->PeoName->setText("");
}

void ManageDialog::on_ChangePwd_clicked(){
	QString Pwd1=ui->Pwd1->text();
	QString Pwd2=ui->Pwd2->text();
	QString Pwd3=ui->Pwd3->text();
	if(Pwd1.isEmpty()){
		QMessageBox::warning(this,"错误","请输入旧密码!");
		return;
	}else if(Pwd2.isEmpty()){
		QMessageBox::warning(this,"错误","请输入新密码!");
		return;
	}else if(Pwd2!=Pwd3){
		QMessageBox::warning(this,"错误","两次输入的新密码不同!");
		return;
	}
	Pwd1=getMD5(Pwd1);
	Pwd2=getMD5(Pwd2);
	sql->exec("Select 1 From options where key_name='mng_pwd' AND key_value='"+Pwd1+"'");
	if(!sql->next()){
		QMessageBox::warning(this,"错误","旧密码错误!");
		return;
	}
	sql->exec("Update options set key_value='"+Pwd2+"' Where key_name='mng_pwd'");
	QMessageBox::information(this,"提示","修改成功!");
}

另外还有两个文件,用于定义了一下一些预定义的函数和类

#include <QApplication>
#include <QTableView>
#include <QStandardItemModel>
#include <QHeaderView>
#include <QCryptographicHash>
void fillTable(QTableView *Target,QString Title,QStringList Content,QAbstractItemView::SelectionMode mode){
    QStandardItemModel *Table_model = new QStandardItemModel();
    QStringList SplitTitle=Title.split(",");
    QStringList SplitRow;
    int i;
    for(i=0;i<SplitTitle.count();i++){
        Table_model->setHorizontalHeaderItem(i, new QStandardItem(SplitTitle[i]));
    }
    int rowid=0;
    foreach(QString SingleRow,Content){
        SplitRow=SingleRow.split(",");
        for(i=0;i<SplitRow.count();i++){
            Table_model->setItem(rowid, i, new QStandardItem(SplitRow[i]));
        }
        rowid++;
    }
    //利用setModel()方法将数据模型与QTableView绑定
    Target->setModel(Table_model);
    Target->horizontalHeader()->setStretchLastSection(true);
    Target->setSelectionMode(mode);
    Target->setEditTriggers(QAbstractItemView::NoEditTriggers);
    Target->setSelectionBehavior(QAbstractItemView::SelectRows);
}
QList<int> getTableViewSelected(QTableView *Target){
     QModelIndexList Selected=Target->selectionModel()->selectedRows();
     QList<int> Select;
     foreach(QModelIndex single,Selected){
         Select.append(single.row());
     }
     return Select;
}
QString getMD5(QString Password){
	QString md5;
	QByteArray ba,bb;
	QCryptographicHash md(QCryptographicHash::Md5);
	ba.append(Password);
	md.addData(ba);
	bb = md.result();
	md5.append(bb.toHex());
	return md5;
}
class Person{
    public:
    QString Name;
    int pid;
    Person(QSqlQuery *sql);

};
class SignUp{
public:
    int lid;
    QString Name;
    unsigned Begin;
    unsigned End;
    bool IsOver;
    SignUp();
    void Prepare(QSqlQuery *sql);
    QStringList toTableUnit(int index);
};
Person::Person(QSqlQuery *sql){
	if(sql==NULL) return;
    this->Name=sql->value("Name").toString();
    this->pid=sql->value("pid").toInt();
}
SignUp::SignUp(){

}
void SignUp::Prepare(QSqlQuery *sql){
    this->lid=sql->value("lid").toInt();
    this->Name=sql->value("name").toString();
    this->Begin=sql->value("Begin").toUInt();
    this->End=sql->value("End").toUInt();
    this->IsOver=sql->value("IsOver").toBool();
}
QStringList SignUp::toTableUnit(int index){
    QStringList temp;
    QDateTime B,E;
    B.setTime_t(this->Begin);
	E.setTime_t(this->End);
	temp<<QString::number(index);
	temp<<this->Name;
	temp<<B.toString("yyyy年MM月dd日 HH:mm:ss");
	temp<<E.toString("yyyy年MM月dd日 HH:mm:ss");
    int Dist,Sec,Min,Hour;
    QString Time;
    Dist=this->End-this->Begin;
    Sec=Dist%60;
    Dist=(Dist-Sec)/60;
    Min=Dist%60;
    Hour=(Dist-Min)/60;
    if(Hour>0) Time+=(Hour<10?"0":"")+QString::number(Hour)+"小时";
    if(Min>0) Time+=(Min<10?"0":"")+QString::number(Min)+"分钟";
    Time+=(Sec<10?"0":"")+QString::number(Sec)+"秒";
	temp<<Time;
    return temp;
}

最后,本程序开源,可以做任何研究,其中算法可以直接移作他用,如非计算机协会需要使用此签到系统,请联系站长,谢谢!

 手机扫描左边的二维码,立刻将文章收入手机!
 微信扫描左边二维码,点击右上角即可分享到朋友圈!
严禁任何非授权的采集与转载,转载须经站长同意并在文章显著位置标注本文连接,站长保留追究法律责任的权利.

评论

 您需要 先登录 才可以回复.