1、 实 验 报 告 课程名称 软件案例分析 实验名称 基于对话框的录入界面 班 级 学 号 姓 名 成 绩 指导教师 实验日期 1. 实验目的 (1) 了解Qt数据库访问技术(加载数据库驱动)。 (2) 掌握QSqlDatabase类和QSqlQuery类的使用。 (3) 了解熟
2、悉Qt Creator开发环境及相关控件的使用。 (4) 了解信号和槽的关联及作用。 (5) 掌握基于对话框的用户界面设计方法和数据操作方法。 (6) 掌握主窗口和子窗口之间数据访问方法。 2. 实验环境 Qt Creator + MinGW 4.9 (32-bit),Windows7,4G内存,DELL笔记本一台。 3. 实验要求 (1) 实现对人事(或其他)基本信息的增加、编辑、删除、刷新和导出功能。 (2) 参考运行界面如图所示。 (3) 运行界面友好简洁。 主界面 “增加个人基本信息”对话框 “修改个人基本
3、信息”对话框 4. 实验步骤及代码 (1)启动Qt Creator,创建基于部件框的Qt Widgets Application类型的应用程序,命名为Widget。 (2)修改对话框标题为“人事基本信息管理”。在主界面窗口中添加6个按钮控件,一个Table Widget控件,界面设计如图所示。 (3) 在主界面设置6个PushButton控件,设置text文本为“刷新”,“导出”,“增加”,“编辑”,“删除”,“退出”,编辑Table Widget的条目,分别为“序号”,“姓名”,“性别”,“出生日期”,“电话”,“最后学位”,“毕业学校”,“毕业时间”,“备注”。 (4)
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(); v
5、oid 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::Wid
6、get *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) 创建连接连接数据库,其函数代
7、码如下: 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,"警
8、告","数据库连接失败!!!");
exit(0);
return;
}
}
(7) 初始化函数代码如下(主要为查询数据库代码):
void Widget::init()
{
QSqlQuery query("select *from renshi");
while(query.next())
{
QStringList list;
list< 9、2).toString()<<
query.value(3).toString()< 10、um);
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 QTable 11、WidgetItem(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(r 12、ownum, 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,i 13、nt)),
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);
14、createConnection();
init();
r=-1;
(9) 导出函数,代码如下:
void Widget::Table2Excel(QTableWidget *table, QString title)
{
QString fileName = QFileDialog::getSaveFileName(table, "保存",
QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation),
"Excel 文件(*.xl 15、s *.xlsx)");
if (fileName!="")
{
QAxObject *excel = new QAxObject;
if (excel->setControl("Excel.Application")) //连接Excel控件
{
excel->dynamicCall("SetVisible (bool Visible)","false");//不显示窗体
excel->setProperty(" 16、DisplayAlerts", false);//不显示任何警告信息。如果为true那么在关闭是会出现类似“文件已修改,是否保存”的提示
QAxObject *workbooks = excel->querySubObject("WorkBooks");//获取工作簿集合
workbooks->dynamicCall("Add");//新建一个工作簿
QAxObject *workbook = excel->querySubObject("ActiveWorkBook");//获取当前工作簿
17、
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 18、>dynamicCall("SetValue(const QString&)", title);
cell->querySubObject("Font")->setProperty("Size", 18);
//调整行高
worksheet->querySubObject("Range(const QString&)", "1:1")->setProperty("RowHeight", 30);
//合并标题行
QStrin 19、g cellTitle;
cellTitle.append("A1:");
cellTitle.append(QChar(colcount - 1 + 'A'));
cellTitle.append(QString::number(1));
QAxObject *range = worksheet->querySubObject("Range(const QString&)", cellTitle);
range->setPr 20、operty("WrapText", true);
range->setProperty("MergeCells", true);
range->setProperty("HorizontalAlignment", -4108);//xlCenter
range->setProperty("VerticalAlignment", -4108);//xlCenter
//列标题
for(i=0;i 21、 {
QString columnName;
columnName.append(QChar(i + 'A'));
columnName.append(":");
columnName.append(QChar(i + 'A'));
col = worksheet->querySubObject("Columns(const QString&)", col 22、umnName);
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 QStri 23、ng&)", columnName);
cell->querySubObject("Font")->setProperty("Bold", true);
cell->querySubObject("Interior")->setProperty("Color",QColor(191, 191, 191));
cell->setProperty("HorizontalAlignment", -4108);//xlCenter
ce 24、ll->setProperty("VerticalAlignment", -4108);//xlCenter
}
//数据区
for(i=0;i 25、amicCall("SetValue(const QString&)", table->item(i,j)?table->item(i,j)->text():"");
}
}
//画框线
QString lrange;
lrange.append("A2:");
lrange.append(colcount - 1 + 'A');
lrange.app 26、end(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", Q 27、Color(0, 0, 0));
//调整数据区行高
QString rowsName;
rowsName.append("2:");
rowsName.append(QString::number(table->rowCount() + 2));
range = worksheet->querySubObject("Range(const QString&)", rowsName);
ran 28、ge->setProperty("RowHeight", 20);
workbook->dynamicCall("SaveAs(const QString&)",QDir::toNativeSeparators(fileName));//保存至fileName
workbook->dynamicCall("Close()");//关闭工作簿
excel->dynamicCall("Quit()");//关闭excel
delete excel;
29、 excel=NULL;
if (QMessageBox::question(NULL,"完成","文件已经导出,是否现在打开?",QMessageBox::Yes|QMessageBox::No)==QMessageBox::Yes)
{
QDesktopServices::openUrl(QUrl("file:///" + QDir::toNativeSeparators(fileName)));
}
} 30、
else
{
QMessageBox::warning(NULL,"错误","未能创建 Excel 对象,请安装 Microsoft Excel。",QMessageBox::Apply);
}
}
}
(10) 右键菜单函数,代码如下:
void Widget::contextMenuEvent(QContextMenuEvent *)
{
QMenu *menu=new QMenu(this);
QAction *action= 31、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("导出"));
action 32、2->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(a 33、ction2,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() 34、));
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();
me 35、nu->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_ 36、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-> 37、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)
{
38、 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::numbe 39、r(ui->tableWidget->rowCount()+1),"","","","","","","","",1);
add->setWindowTitle("增加个人基本信息");
}
void Widget::on_pushButton_5_clicked()
{
if(r==-1)
{
QMessageBox::warning(this,"警告","请选择要删除的行!");
return ;
}
QMessageBox msgBox;
msgBox.setText("您确定删除 40、本条信息吗?");
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->tableWi 41、dget->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_clic 42、ked();
}
break;
case QMessageBox::Cancel:
break;
default:
break;
}
}
void Widget::on_pushButton_2_clicked()
{
Table2Excel(ui->tableWidget,"人事基本信息管理");
}
5. 结果截图
初始界面如下:
“增加个人基本信息”对话框:
“修改个人基本信息”对话框:
6. 回答思考题
(1) 当打 43、开“编辑个人基本信息”对话框时需要获得当前在DataGrid控件中选中的各个字段,即在CAppendDlg类中需要访问CGUIStyleDlg类的成员变量m_DataGrid,在GetDataFromDG函数中如何实现?
答:将主界面(CGUIStyleDlg类)的成员变量m_DataGrid值传递到子对话框(CAppendDlg类),然后在子对话框界面显示即可(主要通过控件的ID来实现)。
(2) 在主对话框中,DataGrid控件的“出生日期”和“毕业时间”列数据类型为CString,而在自对话框中对应于两个Data Time Picker控件,如何实现数据类型的转换?
答:通过必要的函数将CString类型转化为对应的日期时间类型即可。






