资源描述
实 验 报 告
课程名称 软件案例分析
实验名称 基于对话框的录入界面
班 级
学 号
姓 名
成 绩
指导教师
实验日期
1. 实验目的
(1) 了解Qt数据库访问技术(加载数据库驱动)。
(2) 掌握QSqlDatabase类和QSqlQuery类的使用。
(3) 了解熟悉Qt Creator开发环境及相关控件的使用。
(4) 了解信号和槽的关联及作用。
(5) 掌握基于对话框的用户界面设计方法和数据操作方法。
(6) 掌握主窗口和子窗口之间数据访问方法。
2. 实验环境
Qt Creator + MinGW 4.9 (32-bit),Windows7,4G内存,DELL笔记本一台。
3. 实验要求
(1) 实现对人事(或其他)基本信息的增加、编辑、删除、刷新和导出功能。
(2) 参考运行界面如图所示。
(3) 运行界面友好简洁。
主界面
“增加个人基本信息”对话框
“修改个人基本信息”对话框
4. 实验步骤及代码
(1)启动Qt Creator,创建基于部件框的Qt Widgets Application类型的应用程序,命名为Widget。
(2)修改对话框标题为“人事基本信息管理”。在主界面窗口中添加6个按钮控件,一个Table Widget控件,界面设计如图所示。
(3) 在主界面设置6个PushButton控件,设置text文本为“刷新”,“导出”,“增加”,“编辑”,“删除”,“退出”,编辑Table Widget的条目,分别为“序号”,“姓名”,“性别”,“出生日期”,“电话”,“最后学位”,“毕业学校”,“毕业时间”,“备注”。
(4) 向工程中添加Qt设计师界面类(模板为Widget)子对话框资源,命名为“Add”,向界面添加Label,Line Edit,Date Edit,Conbo Box等控件若干,界面设计如图。
(5) 在Widget.h添加如下代码:
//声明信号
signals:
void sendStr(QString ,QString,QString,QString,QString,QString,QString,QString,QString,int);
//声明槽
private slots:
void on_pushButton_clicked();
void on_tableWidget_cellDoubleClicked(int row, int column);
void on_pushButton_4_clicked();
void on_tableWidget_cellClicked(int row, int column);
void on_pushButton_3_clicked();
void on_pushButton_5_clicked();
void on_pushButton_2_clicked();
private:
Ui::Widget *ui;
int r;
Add *add;//增加界面对象
QSqlDatabase db;
public:
void createConnection();//创建连接
void init();
void setCW();
void Table2Excel(QTableWidget *table,QString title);//导出函数
protected:
void contextMenuEvent(QContextMenuEvent *);//增加右击菜单
(6) 创建连接连接数据库,其函数代码如下:
void Widget::createConnection()
{
db=QSqlDatabase::addDatabase("QMYSQL");
db.setHostName("localhost");
db.setPort(3306);
db.setDatabaseName("qt");
db.setUserName("root");
db.setPassword("121819");
if(!db.open())
{
QMessageBox::warning(this,"警告","数据库连接失败!!!");
exit(0);
return;
}
}
(7) 初始化函数代码如下(主要为查询数据库代码):
void Widget::init()
{
QSqlQuery query("select *from renshi");
while(query.next())
{
QStringList list;
list<<query.value(0).toString()<<query.value(1).toString()<<query.value(2).toString()<<
query.value(3).toString()<<query.value(4).toString()<<query.value(5).toString()<<
query.value(6).toString()<<query.value(7).toString()<<query.value(8).toString();
int rownum=ui->tableWidget->rowCount();
ui->tableWidget->insertRow(rownum);
ui->tableWidget->setItem(rownum, 0, new QTableWidgetItem(list.at(0)));
ui->tableWidget->setItem(rownum, 1, new QTableWidgetItem(list.at(1)));
ui->tableWidget->setItem(rownum, 2, new QTableWidgetItem(list.at(2)));
ui->tableWidget->setItem(rownum, 3, new QTableWidgetItem(list.at(3)));
ui->tableWidget->setItem(rownum, 4, new QTableWidgetItem(list.at(4)));
ui->tableWidget->setItem(rownum, 5, new QTableWidgetItem(list.at(5)));
ui->tableWidget->setItem(rownum, 6, new QTableWidgetItem(list.at(6)));
ui->tableWidget->setItem(rownum, 7, new QTableWidgetItem(list.at(7)));
ui->tableWidget->setItem(rownum, 8, new QTableWidgetItem(list.at(8)));
}
}
(8) 在构造函数中添加如下代码:
ui->setupUi(this);
add=new Add;
connect(this,SIGNAL(sendStr(QString,QString,QString,QString,QString,QString,QString,QString,QString,int)),
add,SLOT(recvStr(QString,QString,QString,QString,QString,QString,QString,QString,QString,int)));
connect(add,SIGNAL(senMsg()),this,SLOT(on_pushButton_clicked()));
setCW();
//去掉默认行号
QHeaderView* headerView = ui->tableWidget->verticalHeader();
headerView->setHidden(true);
createConnection();
init();
r=-1;
(9) 导出函数,代码如下:
void Widget::Table2Excel(QTableWidget *table, QString title)
{
QString fileName = QFileDialog::getSaveFileName(table, "保存",
QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation),
"Excel 文件(*.xls *.xlsx)");
if (fileName!="")
{
QAxObject *excel = new QAxObject;
if (excel->setControl("Excel.Application")) //连接Excel控件
{
excel->dynamicCall("SetVisible (bool Visible)","false");//不显示窗体
excel->setProperty("DisplayAlerts", false);//不显示任何警告信息。如果为true那么在关闭是会出现类似“文件已修改,是否保存”的提示
QAxObject *workbooks = excel->querySubObject("WorkBooks");//获取工作簿集合
workbooks->dynamicCall("Add");//新建一个工作簿
QAxObject *workbook = excel->querySubObject("ActiveWorkBook");//获取当前工作簿
QAxObject *worksheet = workbook->querySubObject("Worksheets(int)", 1);
int i,j,colcount=table->columnCount();
QAxObject *cell,*col;
//标题行
cell=worksheet->querySubObject("Cells(int,int)", 1, 1);
cell->dynamicCall("SetValue(const QString&)", title);
cell->querySubObject("Font")->setProperty("Size", 18);
//调整行高
worksheet->querySubObject("Range(const QString&)", "1:1")->setProperty("RowHeight", 30);
//合并标题行
QString cellTitle;
cellTitle.append("A1:");
cellTitle.append(QChar(colcount - 1 + 'A'));
cellTitle.append(QString::number(1));
QAxObject *range = worksheet->querySubObject("Range(const QString&)", cellTitle);
range->setProperty("WrapText", true);
range->setProperty("MergeCells", true);
range->setProperty("HorizontalAlignment", -4108);//xlCenter
range->setProperty("VerticalAlignment", -4108);//xlCenter
//列标题
for(i=0;i<colcount;i++)
{
QString columnName;
columnName.append(QChar(i + 'A'));
columnName.append(":");
columnName.append(QChar(i + 'A'));
col = worksheet->querySubObject("Columns(const QString&)", columnName);
col->setProperty("ColumnWidth", table->columnWidth(i)/6);
cell=worksheet->querySubObject("Cells(int,int)", 2, i+1);
columnName=table->horizontalHeaderItem(i)->text();
cell->dynamicCall("SetValue(const QString&)", columnName);
cell->querySubObject("Font")->setProperty("Bold", true);
cell->querySubObject("Interior")->setProperty("Color",QColor(191, 191, 191));
cell->setProperty("HorizontalAlignment", -4108);//xlCenter
cell->setProperty("VerticalAlignment", -4108);//xlCenter
}
//数据区
for(i=0;i<table->rowCount();i++){
for (j=0;j<colcount;j++)
{
worksheet->querySubObject("Cells(int,int)", i+3, j+1)->dynamicCall("SetValue(const QString&)", table->item(i,j)?table->item(i,j)->text():"");
}
}
//画框线
QString lrange;
lrange.append("A2:");
lrange.append(colcount - 1 + 'A');
lrange.append(QString::number(table->rowCount() + 2));
range = worksheet->querySubObject("Range(const QString&)", lrange);
range->querySubObject("Borders")->setProperty("LineStyle", QString::number(1));
range->querySubObject("Borders")->setProperty("Color", QColor(0, 0, 0));
//调整数据区行高
QString rowsName;
rowsName.append("2:");
rowsName.append(QString::number(table->rowCount() + 2));
range = worksheet->querySubObject("Range(const QString&)", rowsName);
range->setProperty("RowHeight", 20);
workbook->dynamicCall("SaveAs(const QString&)",QDir::toNativeSeparators(fileName));//保存至fileName
workbook->dynamicCall("Close()");//关闭工作簿
excel->dynamicCall("Quit()");//关闭excel
delete excel;
excel=NULL;
if (QMessageBox::question(NULL,"完成","文件已经导出,是否现在打开?",QMessageBox::Yes|QMessageBox::No)==QMessageBox::Yes)
{
QDesktopServices::openUrl(QUrl("file:///" + QDir::toNativeSeparators(fileName)));
}
}
else
{
QMessageBox::warning(NULL,"错误","未能创建 Excel 对象,请安装 Microsoft Excel。",QMessageBox::Apply);
}
}
}
(10) 右键菜单函数,代码如下:
void Widget::contextMenuEvent(QContextMenuEvent *)
{
QMenu *menu=new QMenu(this);
QAction *action=new QAction(this);
QAction *action1=new QAction(this);
QAction *action2=new QAction(this);
QAction *action3=new QAction(this);
QAction *action4=new QAction(this);
QAction *action5=new QAction(this);
action->setText(tr("刷新"));
action1->setText(tr("导出"));
action2->setText(tr("增加"));
action3->setText(tr("编辑"));
action4->setText(tr("删除"));
action5->setText(tr("退出"));
connect(action,SIGNAL(triggered(bool)),this,SLOT(on_pushButton_clicked()));
connect(action1,SIGNAL(triggered(bool)),this,SLOT(on_pushButton_2_clicked()));
connect(action2,SIGNAL(triggered(bool)),this,SLOT(on_pushButton_3_clicked()));
connect(action3,SIGNAL(triggered(bool)),this,SLOT(on_pushButton_4_clicked()));
connect(action4,SIGNAL(triggered(bool)),this,SLOT(on_pushButton_5_clicked()));
connect(action5,SIGNAL(triggered(bool)),this,SLOT(close()));
menu->addAction(action);
menu->addSeparator();
menu->addAction(action1);
menu->addSeparator();
menu->addAction(action2);
menu->addSeparator();
menu->addAction(action3);
menu->addSeparator();
menu->addAction(action4);
menu->addSeparator();
menu->addAction(action5);
menu->addSeparator();
menu->exec(QCursor::pos());
}
(11) 双击修改函数和6个PushButton添加信号对应的槽(类似消息响应函数),代码如下:
void Widget::on_pushButton_clicked()
{
ui->tableWidget->setRowCount(0);
ui->tableWidget->clearContents();
init();
}
void Widget::on_tableWidget_cellDoubleClicked(int row, int column)
{
emit sendStr(ui->tableWidget->item(row,0)->text(),ui->tableWidget->item(row,1)->text()
,ui->tableWidget->item(row,2)->text(),ui->tableWidget->item(row,3)->text()
,ui->tableWidget->item(row,4)->text(),ui->tableWidget->item(row,5)->text()
,ui->tableWidget->item(row,6)->text(),ui->tableWidget->item(row,7)->text()
,ui->tableWidget->item(row,8)->text(),2);
add->setWindowTitle("修改个人基本信息");
add->show();
}
void Widget::on_pushButton_4_clicked()
{
if(r==-1)
{
QMessageBox::warning(this,"警告","请选择要修改的行!");
return ;
}
on_tableWidget_cellDoubleClicked(r,0);
}
void Widget::on_tableWidget_cellClicked(int row, int column)
{
r=row;
}
void Widget::on_pushButton_3_clicked()
{
add->show();
emit sendStr(QString::number(ui->tableWidget->rowCount()+1),"","","","","","","","",1);
add->setWindowTitle("增加个人基本信息");
}
void Widget::on_pushButton_5_clicked()
{
if(r==-1)
{
QMessageBox::warning(this,"警告","请选择要删除的行!");
return ;
}
QMessageBox msgBox;
msgBox.setText("您确定删除本条信息吗?");
msgBox.setToolTip("提示");
msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
msgBox.setDefaultButton(QMessageBox::Ok);
int ret = msgBox.exec();
switch (ret) {
case QMessageBox::Ok:
{
QSqlQuery query;
QString num=ui->tableWidget->item(r,0)->text();
bool ok= query.exec("delete from renshi where num="+num);
if(ok)
{
QMessageBox::information(this,"提示","信息删除成功!");
}
else {
QMessageBox::warning(this,"警告","信息删除失败!");
}
on_pushButton_clicked();
}
break;
case QMessageBox::Cancel:
break;
default:
break;
}
}
void Widget::on_pushButton_2_clicked()
{
Table2Excel(ui->tableWidget,"人事基本信息管理");
}
5. 结果截图
初始界面如下:
“增加个人基本信息”对话框:
“修改个人基本信息”对话框:
6. 回答思考题
(1) 当打开“编辑个人基本信息”对话框时需要获得当前在DataGrid控件中选中的各个字段,即在CAppendDlg类中需要访问CGUIStyleDlg类的成员变量m_DataGrid,在GetDataFromDG函数中如何实现?
答:将主界面(CGUIStyleDlg类)的成员变量m_DataGrid值传递到子对话框(CAppendDlg类),然后在子对话框界面显示即可(主要通过控件的ID来实现)。
(2) 在主对话框中,DataGrid控件的“出生日期”和“毕业时间”列数据类型为CString,而在自对话框中对应于两个Data Time Picker控件,如何实现数据类型的转换?
答:通过必要的函数将CString类型转化为对应的日期时间类型即可。
展开阅读全文