1、 实 验 报 告 课程名称 软件案例分析 实验名称 基于对话框的录入界面 班 级 学 号 姓 名 成 绩 指导教师 实验日期 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、 实现对人事(或其他)基本信息的增加、编辑、删除、刷新和导出功能。(2) 参考运行界面如图所示。(3) 运行界面友好简洁。 主界面 “增加个人基本信息”对话框“修改个人基本信息”对话框4. 实验步骤及代码(1)启动Qt Creator,创建基于部件框的Qt Widgets Application类型的应用程序,命名为Widget。(2)修改对话框标题为“人事基本信息管理”。在主界面窗口中添加6个按钮控件,一个Table Widget控件,界面设计如图所示。(3) 在主界面设置6个PushButton控件,设置text文本为“刷新”,“导出”,“增加”,“编辑”,“删除”,“退出”,编辑Tabl
3、e 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);/声明槽priva
4、te 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
5、*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:add
6、Database(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.ne
7、xt() QStringList list; listquery.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()tableWidget-rowCount(); ui-tableWidget-insertRow(rownum); ui-tableWidge
8、t-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 QTableW
9、idgetItem(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) 在构造函数中
10、添加如下代码: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()
11、;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(QSta
12、ndardPaths: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那么在关闭是会出现类似“文件已修改,是否保存”的提示 Q
13、AxObject *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; /标题行
14、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.a
15、ppend(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(Vertical
16、Alignment, -4108);/xlCenter /列标题 for(i=0;iquerySubObject(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&), colu
17、mnName); 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;irowCount();i+) for (j=0;jquerySubObject(Cells(i
18、nt,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-quer
19、ySubObject(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); ran
20、ge-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)=QM
21、essageBox: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
22、(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(t
23、r(删除); 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,
24、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(
25、); 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-clear
26、Contents(); 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)-tex
27、t() ,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:o
28、n_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
29、 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= quer
30、y.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. 结果截图初始界
31、面如下:“增加个人基本信息”对话框:“修改个人基本信息”对话框:6. 回答思考题(1) 当打开“编辑个人基本信息”对话框时需要获得当前在DataGrid控件中选中的各个字段,即在CAppendDlg类中需要访问CGUIStyleDlg类的成员变量m_DataGrid,在GetDataFromDG函数中如何实现?答:将主界面(CGUIStyleDlg类)的成员变量m_DataGrid值传递到子对话框(CAppendDlg类),然后在子对话框界面显示即可(主要通过控件的ID来实现)。(2) 在主对话框中,DataGrid控件的“出生日期”和“毕业时间”列数据类型为CString,而在自对话框中对应于两个Data Time Picker控件,如何实现数据类型的转换?答:通过必要的函数将CString类型转化为对应的日期时间类型即可。