startwindow.h
#ifndef STARTWINDOW_H
#define STARTWINDOW_H
#include <QMainWindow>
#include <QDesktopServices>
#include <QApplication>
#include <QFileDialog>
#include <QAxObject>
#include <QMouseEvent>
#include <QPaintEvent>
#include <QBrush>
#include <QPainterPath>
#include <QRect>
#include <QBitmap>
#include <QPainter>
#include <QPoint>
#include <QDebug>
#include <QString>
#include <QFileInfo>
#include <ctime>
#include <QFile>
#include <QDir>
#include<Qt>
#include <windows.h>
#include <ctime>
namespace Ui {
class StartWindow;
}
class StartWindow : public QMainWindow
{
Q_OBJECT
public:
explicit StartWindow(QWidget *parent = 0);
~StartWindow();
private:
Ui::StartWindow *ui;
};
#endif // STARTWINDOW_H
startwindow.cpp
#include "startwindow.h"
#include "ui_startwindow.h"
StartWindow::StartWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::StartWindow)
{
ui->setupUi(this);
setWindowFlags(Qt::FramelessWindowHint);
//设置关于窗体为圆角
QBitmap bmp(this->size());
bmp.fill();
QPainter p(&bmp);
p.setPen(Qt::NoPen);
p.setBrush(Qt::black);
p.drawRoundedRect(bmp.rect(),30,30);
setMask(bmp);
//880 523
//this->resize(400,300);
ui->progressBar->setMinimum(0);
ui->progressBar->setMaximum(100);
this->show();
srand(time(0));
//(rand() % (b-a+1))+ a
int tim=rand()%(12-1+1)+1;
for(int i=0;i<100;i++)
{
ui->progressBar->setValue(i);
Sleep(tim);
}
this->close();
}
StartWindow::~StartWindow()
{
delete ui;
}
yikewindow.h
#ifndef YIKEWINDOW_H
#define YIKEWINDOW_H
#include <QMainWindow>
#include <QDesktopServices>
#include <QApplication>
#include <QFileDialog>
#include <QAxObject>
#include <QMouseEvent>
#include <QPaintEvent>
#include <QBrush>
#include <QPainterPath>
#include <QRect>
#include <QBitmap>
#include <QPainter>
#include <QPoint>
#include <QDebug>
#include <QString>
#include <QFileInfo>
#include <ctime>
#include <QFile>
#include <QDir>
#include<Qt>
#include <windows.h>
namespace Ui {
class YIKEWindow;
}
class YIKEWindow : public QMainWindow
{
Q_OBJECT
public:
QPoint StartPos;
void mouseMoveEvent(QMouseEvent *event);
void mousePressEvent(QMouseEvent *event);
explicit YIKEWindow(QWidget *parent = 0);
~YIKEWindow();
private slots:
void on_fun_daoru_clicked();
void on_mode_paiban_clicked();
void on_mode_xuanren_clicked();
void on_fun_shengcheng_clicked();
void on_Quit_clicked();
void on_mode_suijishu_clicked();
void on_commandLinkButton_clicked();
void on_toolButton_clicked();
private:
Ui::YIKEWindow *ui;
};
#endif // YIKEWINDOW_H
yikewindow.cpp
#include "yikewindow.h"
#include "ui_yikewindow.h"
#include <stdio.h>
#include <ctime>
#include <iostream>
using namespace std;
#define SMAX 1024 //数组最大值
#define CENTER -4108 //CENTER
#define RANGE_MAX 10000 //数组最大值
QString file_path; //打开文件的文件路径
QString stu_str; //学生名单的字符串
QString Student[SMAX]; //学生名单的数组
QString temp_Student[SMAX][SMAX]; //excel表格页面内容
QString read_stu[SMAX][SMAX]; //excel表格页面内容,同temp_Student[][]
int Stu_Max=0; //学生数目
int minRow; //最小的开始单元格序号
int minCol;
int maxRow; //最大的单元格序号
int maxCol;
YIKEWindow::YIKEWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::YIKEWindow)
{
ui->setupUi(this);
setWindowFlags(Qt::FramelessWindowHint); //窗口圆角
setWindowOpacity(0.88); //设置窗口背景透明度0.88
/*设置关于窗体为圆角*/
QBitmap bmp(this->size());
bmp.fill();
QPainter p(&bmp);
p.setPen(Qt::NoPen);
p.setBrush(Qt::black);
p.drawRoundedRect(bmp.rect(),30,30);
setMask(bmp);
//设置父对象,防止某一些控件的属性无效
ui->mode_paiban->setParent(this);
ui->mode_xuanren->setParent(this);
ui->mode_suijishu->setParent(this);
ui->fun_daoru->setParent(this);
ui->fun_shengcheng->setParent(this);
ui->Quit->setParent(this);
ui->tip1->setParent(this);
ui->lihui->setParent(this);
ui->notime_student->setParent(this);
ui->commandLinkButton->setParent(this);
//开始默认关闭的部件
ui->label_6->close();
ui->textBrowser_2_mode2->close();
ui->houxuanren->close();
ui->MIN->close();
ui->MAX->close();
ui->tip2->close();
ui->tip3->close();
ui->random_tip->close();
}
//主窗口的析构函数
YIKEWindow::~YIKEWindow()
{
delete ui;
}
//导入功能键
void YIKEWindow::on_fun_daoru_clicked()
{
if(!(ui->MAX->isHidden())&&!(ui->MIN->isHidden())) //判断是否为随机数模式
{
ui->zhuangtai->setText("当前模式不需要导入文档..."); //如果是随机数模式,又点击导入按键,提示不需要导入
}
else //开始导入的工作
{
ui->zhuangtai->setText("读取中..."); //向状态栏输出信息
QFileDialog* open_file =new QFileDialog(this); //创建一个导入文件对话框
open_file->setAcceptMode(QFileDialog::AcceptOpen); //设置为打开模式
file_path=open_file->getOpenFileName(open_file); //打开文件选择窗口选择文件,然后返回文件路径
if(file_path!=NULL) //判断打开文件路径是否为空
{
ui->zhuangtai->setText("已打开:"+file_path); //将成功打开的信息输出到状态栏
QAxObject Application("Excel.Application"); //创建一个软件对象,对象为excel
Application.setProperty("Visible", false); //设置软件运行为不可见
Application.setProperty("DisplayAlerts", false);
QAxObject* WorkBooks = Application.querySubObject("WorkBooks"); //创建一个工作簿集合
WorkBooks->querySubObject("Open(const QString&)", QDir::toNativeSeparators(file_path)); //从导入的excel文件中读取信息
//WorkBooks->dynamicCall("Add");
QAxObject* WorkBook = Application.querySubObject("ActiveWorkBook"); //创建一个工作表
QAxObject* WorkSheets = WorkBook->querySubObject("Sheets");
QAxObject* WorkSheet = WorkSheets->querySubObject("Item(int)", 1); //得到第一页
QAxObject* usedrange = WorkSheet->querySubObject("UsedRange"); //获取已经使用的sheet
minRow = usedrange->property("Row").toInt(); //最小的开始单元格序号
minCol = usedrange->property("Column").toInt();
maxRow = usedrange->querySubObject("Rows")->property("Count").toInt(); //最大的单元格序号
maxCol = usedrange->querySubObject("Columns")->property("Count").toInt();
// 查看已经使用的最大行数和最大列数
Stu_Max=0; //将最大人数清空
stu_str.clear(); //将字符串清空
QString notime_stu_str; //创建没有时间同学名单
QAxObject * Range=new QAxObject; //创建一个单元格范围
QString _week[9]={" ","周一","周二","周三","周四","周五","周六","周日"}; //定义一个字符串数组,打印到excel表格中
for(int i=minRow;i<=maxRow;i++) //遍历所有已经使用的excel单元格
{
for(int j=minCol;j<=maxCol;j++)
{
Range = WorkSheet->querySubObject("Cells(int,int)", i, j); //访问单个单元格
read_stu[i][j]=Range->property("Value").toString(); //读取导入的excel表格信息
if(j%2==0&&i>1&&j>1&&read_stu[i][j]!=NULL) //从[2,2]开始判断学生那一天没有时间
{
notime_stu_str+=read_stu[i][1]; //将学生的姓名保存到没有时间的名单中,read_stu[x][1]表示x名学生的姓名
notime_stu_str+=_week[(int)j/2]; //加上具体是星期几没空
notime_stu_str+=" 下午 没空!\n"; //加上是星期几的下午没有空
}
else if(j%2==1&&i>1&&j>1&&read_stu[i][j]!=NULL) //同上一个if判断
{
notime_stu_str+=read_stu[i][1];
notime_stu_str+=_week[(int)j/2];
notime_stu_str+=" 晚上 没空!\n";
}
}
if((read_stu[i][1]!=" ")&&(read_stu[i][1]!="姓名")) //判断read_stu[][]中是否为“ ” 或者“姓名”,是则不处理
{
Student[Stu_Max++]=read_stu[i][1]; //净学生名单数组
stu_str+=read_stu[i][1]; //净学生名单
stu_str+='\n'; //换行
}
ui->lcdNumber->display(Stu_Max); //在LCD显示器显示最大同学数量
}
ui->notime_student->setText(notime_stu_str); //在没有时间页面显示没有时间同学的信息
ui->textBrowser_2_mode2->setText(stu_str); //选人模式下的显示名单
ui->textBrowser->setText(stu_str); //模式一下显示名单
WorkBooks->dynamicCall("Close()"); //关闭所有工作表
Application.dynamicCall ("Quit()"); //关闭excel程序
}
}
}
/*排班模式按键*/
void YIKEWindow::on_mode_paiban_clicked()
{
/*和排班模式相关的控件显示*/
ui->notime_student->show();
ui->lihui->show();
ui->textBrowser->show();
ui->tip1->show();
/*其他控件关闭*/
ui->houxuanren->close();
ui->textBrowser->resize(350,400);
ui->random_tip->close();
ui->MIN->close();
ui->MAX->close();
ui->textBrowser_2_mode2->close();
ui->tip2->close();
ui->tip3->close();
/*模式一显示为空,在没有导入名单以前*/
ui->textBrowser->setText(" ");
if(file_path==NULL) //判断打开的路径是否为空,如果是提示先导入文档
{
ui->zhuangtai->setText("排班模式,请先导入名单");
}
else //否则,显示导入最大学生数
{
ui->lcdNumber->display(Stu_Max); //显示最大学生数
ui->zhuangtai->setText("排班模式:已导入:"+file_path); //显示导入的名单路径
ui->textBrowser->setText(stu_str); //并且显示但如的同学的名单
}
}
/*选人模式按键*/
void YIKEWindow::on_mode_xuanren_clicked()
{
/*和选人模式相关的控件显示*/
ui->tip2->show();
ui->houxuanren->show();
ui->textBrowser_2_mode2->show();
/*其他控件关闭*/
ui->notime_student->close();
ui->label_6->close();
ui->lihui->close();
ui->textBrowser->close();
ui->MIN->close();
ui->MAX->close();
ui->tip1->close();
ui->tip3->close();
ui->random_tip->close();
ui->zhuangtai->setText("选人模式,请先导入名单");
if(file_path==NULL) //判断打开的路径是否为空,如果是提示先导入文档
{
ui->zhuangtai->setText("选人模式:请先导入名单");
}
else
{
ui->textBrowser_2_mode2->setText(stu_str); //显示名单
ui->zhuangtai->setText("选人模式:已导入"+file_path); //显示导入的名单路径
ui->lcdNumber->display(Stu_Max); //显示最大学生数
}
}
//随机数模式
void YIKEWindow::on_mode_suijishu_clicked()
{
/*和随机数模式相关的控件显示*/
ui->label_6->show();
ui->MIN->show();
ui->MAX->show();
ui->tip3->show();
ui->random_tip->show();
ui->random_tip->show();
ui->random_tip->show();
/*其他控件关闭*/
ui->tip1->close();
ui->tip2->close();
ui->notime_student->close();
ui->lihui->close();
ui->houxuanren->close();
ui->zhuangtai->setText("随机数模式");
ui->textBrowser_2_mode2->close();
ui->textBrowser->close();
}
//开始生成
void YIKEWindow::on_fun_shengcheng_clicked()
{
ui->zhuangtai->setText("开始抽取随机数"); //点击生成随机数按钮后提示信息
if(!(ui->MIN->isHidden())&&!(ui->MAX->isHidden())) //判断是否选择了随机数模式
{
int random_min=ui->MIN->text().toInt(); //读取用户置于控件中的数的范围
int random_max=ui->MAX->text().toInt(); //最大值和最小值
if((random_min>random_max)||(random_min==random_max)) //判断选择的随机数区间是否合法
{
ui->zhuangtai->setText("请选择合适的区间"); //不合法提示
}
else
{
srand(time(0)); //随机数初始化
int number = rand() % random_max + random_min; //生成随机数
ui->lcdNumber->display(number); //LCD显示生成的随机数
ui->random_tip->setText(QString::number(number)); //在随机数提示框中显示随机数的结果
ui->zhuangtai->setText("抽取随机数为:"+QString::number(number)); //同样状态栏中显示随机数
}
}
else if(!(ui->textBrowser->isHidden())) //判断是否选择了排班处理
{
if(file_path!=NULL) //如果导入的文件名不为空,生成文档
{
ui->zhuangtai->setText("正在生成excel文档..."); //提示生成文档
/*获取保存路径*/
QString savefilepath = QFileDialog::getSaveFileName(this, QString::fromLocal8Bit("导出"), "志愿者值班表", tr("Microsoft Office(*.xlsx)"));
if (!savefilepath.isEmpty()) //如果保存路径不为空
{
/*新建excel对象,生成一个新的excel文件,就是最终要导出的文件*/
QAxObject *save_excel = new QAxObject(this);
save_excel->setControl("Excel.Application"); //连接Excel控件
save_excel->dynamicCall("SetVisible (bool Visible)", "false"); //不显示窗体
save_excel->setProperty("DisplayAlerts", false); //不显示任何警告信息。如果为true那么在关闭是会出现类似“文件已修改,是否保存”的提示
QAxObject *save_workbooks = save_excel->querySubObject("WorkBooks"); //获取工作簿集合
save_workbooks->dynamicCall("Add"); //新建一个工作簿
QAxObject *save_workbook = save_excel->querySubObject("ActiveWorkBook"); //获取当前工作簿
QAxObject *save_worksheets = save_workbook->querySubObject("Sheets"); //获取工作表集合
QAxObject *save_worksheet = save_worksheets->querySubObject("Item(int)", 1);//获取工作表集合的工作表1,即sheet1
QAxObject * Save_Range=new QAxObject(this); //创建保存的excel范围
QAxObject* border=new QAxObject(this); //创建新的excel边框对象,用来上边框
QAxObject* interior=new QAxObject(this); //用来设置单元格的背景颜色
/**********/
int lihui_day=ui->lihui->text().toInt(); //用来选择例会是那一天
QString week[5]={"周一","周二","周三","周四","周五"};
for(int i=0;i<5;i++) //打印第一栏周末信息,及其一些设定
{
Save_Range = save_worksheet->querySubObject("Cells(int,int)", 1, i+2); //访问单个单元格
Save_Range->setProperty("Value",week[i]); //向单元格写入数据
interior = Save_Range->querySubObject("Interior"); //填充背景颜色
interior->setProperty("Color", QColor(0, 0, 255)); //设置单元格背景色(blue色)
Save_Range->setProperty("HorizontalAlignment", CENTER); //-4131 居中
}
Save_Range = save_worksheet->querySubObject("Cells(int,int)", 8, 1); //访问单个单元格
Save_Range->setProperty("Value","20:00-22:30"); //向单元格写入数据
Save_Range = save_worksheet->querySubObject("Cells(int,int)", 2, 1); //访问单个单元格
Save_Range->setProperty("Value","16:00-18:00"); //向单元格写入数据
int student_cou_max=Stu_Max+1; //(7+(int)(Stu_Max/8),重新定义学生的最大值
for(int i=minRow;i<=maxRow;i++)
for(int j=minCol;j<=maxCol;j++)
temp_Student[i][j]=read_stu[i][j]; //重新定义excel的页面,这里是为了不改动原有的名单
/*分析,开始排班*/
for(int i=1;i<=(7+(int)((Stu_Max+1)/8));i++) //将所有人的名字填入表中
{
int xiawu_k=2,wanshang_k=3; //这东西用来约束星期几,懂得就懂
for(int j=1;j<7;j++) //周一到周五,分为奇数偶数来排
{
Save_Range = save_worksheet->querySubObject("Cells(int,int)", i, j);
border = Save_Range->querySubObject("Borders");
border->setProperty("Color", QColor(0, 0, 0));
if(i%2==0&&i>1&&j>1) //偶数,偶数即是下午
{
Save_Range = save_worksheet->querySubObject("Cells(int,int)", (i/2)+1, j); //访问单个单元格
// (rand() % (b-a+1))+ a;生成[a,b]的随机数,保证每一个随机数都再[2,student_cou_max]以内
int out_num; //定义随机数
do
{
if(student_cou_max<=2) //判断学生最大的人数是否小于2,是立刻结束循环,一面出现死循环
break;
srand(time(0)); //种下随机数的种子
out_num= rand() % (student_cou_max-2+1)+2; //产生[2,student_cou_max]里面的随机数,每一个随机数代表一个人
}while(temp_Student[out_num][xiawu_k]!=NULL); //这里定义NULL为有空,反之忙,直到产生一个有空的同学跳出循环
if(student_cou_max>=2) //跳出循环后也要保证student_cou_max>=2
Save_Range->setProperty("Value",temp_Student[out_num][1]); //条件都成立则向单元格写入数据
for(int v=minCol;v<=maxCol;v++) //将最后一个同学及其他的信息移到该同学的位置
temp_Student[out_num][v]=temp_Student[student_cou_max][v];
student_cou_max--; //并且最大值减一,这样就保证了下次如果选的随机数与这次一样,但是人已经不一样了
xiawu_k+=2;
Save_Range->setProperty("HorizontalAlignment", CENTER); //居中(xlCenter):-4108
}
else if(i%2==1&&i>1&&j>1) //奇数表示晚上,与上面一样
{
if((5==j-1)||(lihui_day==j-1))
{}
else
{
Save_Range = save_worksheet->querySubObject("Cells(int,int)", (i+13)/2, j); //访问单个单元格
int out_num;
do
{
if(student_cou_max<=2)
break;
srand(time(0));
out_num= rand() % (student_cou_max-2+1)+2;
}while(temp_Student[out_num][wanshang_k]!=NULL); //[2-32]
if(student_cou_max>=2)
Save_Range->setProperty("Value",temp_Student[out_num][1]);
for(int v=minCol;v<=maxCol;v++)
temp_Student[out_num][v]=temp_Student[student_cou_max][v];
student_cou_max--;
wanshang_k+=2;
Save_Range->setProperty("HorizontalAlignment", CENTER); //居中(xlCenter):-4108
}
}
}
}
ui->zhuangtai->setText("可能还差:"+temp_Student[2][1]+"同学");
//qDebug()<<"还差:"<<temp_Student[2]<<"-"<<temp_Student[3];
save_workbook->dynamicCall("SaveAs(const QString&)", QDir::toNativeSeparators(savefilepath));//保存至filepath,注意一定要用QDir::toNativeSeparators将路径中的"/"转换为"\",不然一定保存不了。
save_workbook->dynamicCall("Close()");//关闭工作簿
save_excel->dynamicCall("Quit()");//关闭excel
delete save_excel;
save_excel = NULL;
if(temp_Student==NULL)
ui->zhuangtai->setText("已完成!到"+savefilepath+"查看!");
else
ui->zhuangtai->setText("已完成!可能还差"+temp_Student[2][1]+"、"+temp_Student[3][1]+"等同学!");
}
}
else
{
ui->zhuangtai->setText("请先导入文档...");
}
}
/*随机选人模式*/
else if(!(ui->houxuanren->isHidden())) //随机选人
{
if(file_path!=NULL)
{
ui->zhuangtai->setText("正在选人...");
srand(time(0));
int stu_number = rand() % Stu_Max + 0;
ui->houxuanren->setText(Student[stu_number]);
ui->zhuangtai->setText("选出:"+Student[stu_number]);
}
else
{
ui->zhuangtai->setText("请先导入文档...");
}
}
else
{
ui->zhuangtai->setText("请先选择模式...");
}
}
//显示提示信息
void YIKEWindow::on_commandLinkButton_clicked()
{
ui->lihui->close();
ui->notime_student->close();
ui->houxuanren->close();
ui->random_tip->close();
ui->textBrowser_2_mode2->close();
ui->textBrowser->resize(700,400);
ui->textBrowser->show();
ui->textBrowser->setText("温馨提示\n"
"1、界面前三为三种模式[排班、选人、随机数]\n"
" A、排班模式:首次进入界面,默认模式为排班模式,该模式下你应该首先选择周几是例会,"
"即:再例会当天晚上将不进行排班,默认为1,即周一。选择好例会日期后,你必须先导入"
"excel名单,格式要求详见益科,导入名单后,在界面的LCD显示屏上会显示出读取的人数,"
"在TEXT显示区会显示读取同学的姓名及其他情况。最后点击生成选择合适的储存位置即可!\n"
" B、选人模式:该模式下不需要的控件会相应关闭,如果已经导入名单,在显示区的左侧会"
"显示已导入的同学姓名,点击生成,在最右侧会显示,选出人的姓名。如果未导入名单请先导入名单!\n"
" C、随机数模式:在该模式下,两个绿框中输入最大值和最小值,默认1-31,点击生成随机数在"
"显示区显示。注意:点击生成之前一定保证最小值小于最大值,否则可能导致程序崩溃!\n"
"4、点击益科图标你将了解我们\n"
"5、相关的处理状态可以在下方[OUT\]查看\n"
"6、任何模式都是点击生成以获取计算结果\n"
"7、频繁不合法操作可能会导致程序崩溃,善待程序\n"
"8、随机数的区间是[a,b],请选择合适的区间,请确定第一次选择区间时a<b\n"
"9、更多:1043886331@qq.com\n"
"\n\n"
"\t\t\t\t\t\t供“益科”使用\n"
"\t\t\t\t\t\t团结、高效、务实、创新\n"
);
}
//
void YIKEWindow::on_toolButton_clicked()
{
QString url = "https://baike.baidu.com/item/%E7%9B%8A%E7%A7%91%E6%8A%80%E6%9C%AF%E6%9C%8D%E5%8A%A1%E9%98%9F/55558492";
QDesktopServices::openUrl(QUrl(url, QUrl::TolerantMode));
}
//退出程序
void YIKEWindow::on_Quit_clicked()
{
YIKEWindow::close();
}
/*********************窗口处理**************************/
//实现窗口移动
void YIKEWindow::mouseMoveEvent(QMouseEvent *event)
{
//去表格虚框
QPoint EndPos;
if(event->buttons()==Qt::LeftButton)
{
EndPos = event->globalPos()- StartPos;
this->move(EndPos);
}
}
void YIKEWindow::mousePressEvent(QMouseEvent *event)
{
if(event->buttons() == Qt::LeftButton)
{
//记录窗口此时的坐标
StartPos = event->globalPos() - this->frameGeometry().topLeft();
}
}