周末两天女儿反复高烧,现在还在持续中,退烧药吃了就吐,约等于每次高烧都只是通过物理降温,去了几次医院看不同的医生也没什么好办法,来来去去就是让我们硬喂、多喝水,初为人父的我看着小宝宝受苦的样子心里好难受啊。这篇文章是在宝宝睡觉的时候抽空写,没有太多高深的东西,写得不好的地方请各位见谅。另外,刚搜了一下Qt程序员的待遇,不高,原因未知,难怪Qt相关的文章阅读数寥寥。不过我非常喜欢Qt,所以我会坚持学下去。 回到正题,Spreadsheet 是一个简单的电子表格程序,相当于简化版的 Excel,日常用用还不错,用自己写的工具还挺过瘾的。 ※ 0.07版本需求: 完善Edit菜单:- 添加 Go to Cell对话框(选中指定单元格);完善Tools菜单:- 添加 Sort对话框(对选中的区域进行排序); 一、完善Edit菜单 ※ 添加 Go to Cell对话框(选中指定单元格) Go to Cell 对话框的界面是之前通过 Qt Designer设计好的,这里只是将其整合到 Spreadsheet 里,回顾一下 Go to Cell 对话框的界面: ![]() 添加 Go to Cell 的代码 先将 Go to Cell 代码拷贝到 Spreadsheet 源码目录中,然后在 Qt Creator 里点击 Add Existing Files,选择 gotocelldialog.cpp、gotocelldialog.h、gotocelldialog.ui,添加成功后,本质就是修改pro 了文件,该文件变化如下: ![]() 绑定信号槽: ![]() ![]() 代码量不多,但是包含的知识点比较重要: 1) 前面增加 Find 对话框时,通过 new 的方式创建对话框的。 为什么要这么做呢?这是因为想将 Find 对话框设计为非模态(modeless)的,即让 Find 对话框独立于应用程序的其他任何窗口,用户能够在 Spreadsheet 窗口和 Find 对话框之间进行切换。这才符合用户的使用习惯,一边查找一边编辑。 2) 想实现非模态对话框,经典的做法就是new 对话框 + show()。 new 方式会让对话框生存周期的结束时间跟整个应用的生存周期的结束时间保持一致,即 Spreadsheet 被关闭了,Find 对话框才会被删除。 show() 函数让一个窗口变为可见的,它是非阻塞的,即调用会立即返回,这样 Spreadsheet 程序才有机会继续执行。 3) Go to Cell 对话框是模态的(modal)。 Go to Cell 功能没必要和应用程序中的其他窗口相互切换,实现模态对话框的经典做法是:在栈中创建对话框 + exec()。 在 GoToCellDialog dialog(this) 里,dialog是一个局部变量,当函数返回时,dialog会自动被销毁,Go to Cell 对话框随之被关闭。而 dialog.exec() 会阻塞,直到用户在 Go to Cell 对话框中按下 OK 或者 Cacel 按钮返回返回。从而强制用户必须和 Go to Cell 对话框交互完毕后,才能继续和其他窗口交互。 运行效果: ![]() 二、完善Edit菜单 ※ 添加 Sort对话框(对选中的区域进行排序) Sort 对话框的界面也是之前通过 Qt Designer 设计好的,这里只是将其整合到 Spreadsheet 里,回顾一下 Sort 对话框的界面: ![]() 在Sort 对话框里,用户可以选择一列或者多列进行排序。More 按钮允许用户在简单外观和扩展外观之间切换。简单外观只允许用户使用单一的排序键,扩展外观则额外添加两个排序键。添加Sort 对话框代码的方式跟 Go to Cell类似,这里不再赘述。 Sort 对话框涉及到表格内容的处理,所以会分2层来实现: 第一层位于 MainWindow 类中,负责创建 Sort 对话框并和用户交互; 第二层位于 Spreadsheet 类中,负责实质的排序操作,更新表格数据; 绑定信号槽: ![]() ![]() 上面的代码负责创建 Sort 对话框并接收保存用户选中的表格区域。dialog.setColumnRange() 会根据选择的区域来设置Sort 对话框的界面,SpreadsheetCompare 类对象 compare 负责保存排序的主键、第二键、第三键,并且提供最底层的两行之间的比较大小的功能,所以需要将其传递给 spreadsheet。 Spreadsheet:sort() 的实现: ![]() 要对表格进行排序的话,思路是先要提取出选中区域的所有内容,保存在一个二维的容器中,第一维(QList)用于保存行头(QStringList),第二维 QStringList 用于保存一行内所有单元格的数据。排序时,只要将数据提交给 C++ algorithm库里的排序函数stable_sort(),它会调用 SpreadsheetCompare 类提供的比较函数来将我们的数据排好序。最后,将排好序的数据重新填回选中的区域即可。 SpreadsheetCompare的定义如下: ![]() bool operator()(...) 重载了操作符"()",该函数实现了最底层的比较两行大小的功能,具体的代码我就不粘贴了,没什么知识点。 运行效果: ![]() 到此,spreadsheet-v0.07开发完毕,参考书籍: 《C++ GUI Qt4 编程》 人只有在生病的时候才能感受到能健健康康的过日子是多幸福的一件事,人生就是一场斗争,一辈子那么长,每个人身上多多少少带有一些疾病,但是只要自己的内心和身体足够强大了,什么困难都是可以克服的,希望我的小宝贝也能早日战胜病毒,快点好起来。 你和我各有一个苹果,如果我们交换苹果的话,我们还是只有一个苹果。但当你和我各有一个想法,我们交换想法的话,我们就都有两个想法了。如果你也对嵌入式系统开发有兴趣,并且想和更多人互相交流学习的话,请关注我的公众号:ESexpert,一起来学习吧,欢迎各种收藏/转发/批评。 ---------------------------------------------------------------------------------------------------------------------- 我们尊重原创,也注重分享,文章来源于微信公众号:嵌入式系统砖家,建议关注公众号查看原文。如若侵权请联系qter@qter.org。 ---------------------------------------------------------------------------------------------------------------------- |