如何往sqt的vs qt 新建窗口的表中输入内容

如何用Qt写Android应用_百度知道
如何用Qt写Android应用
设置qt-android开发环境第一步:创建一个Android项目我以Empty Qt Project为例.点击Choose后出现一个对话框要求填写Project的名字和选择路径,输入完成后点击Next,到下面一个比较重要的操作:选择Qt Version注意,默认是选择Destkop的,正确应该按上图设置.设置后按Next确认一下,没有错就按Finish完成Qt-Android项目的建立.只要正确建立了Qt项目,就完成了一大半了.下图是完成后的一个截图:第二步:编写程序在这步大家按照平常Qt Creator的步骤写程序就好.但是注意的是,有些模块暂时还没有移植,例如Qt网络模块,所以不能有网络相关的应用(不过我想这迟早会移植的).作为例子,我就用hello world吧:#include&QApplication#include&QLabelintmain(intargc,char**argv){QApplicationapp(argc,argv);QLabel*label=newQLabel(&&palign=centerHello,World!&/p&);label-show();returnapp.exec();}第三步:设置编译选项Projects标签 - Run 展开Package configurations,选择Android target SDK,(android7为例)展开紧跟下面的Deploy configurations,选择Deploy local qt libs然后按左边倒数第三个绿色三角按钮运行:第四步:手机上运行你写的应用会打包成apk放在你项目文件夹里的/android/bin里面.把它拷到手机上安装.但是这样手机还不能运行这个程序,毕竟Android系统没有Qt的库.这个时候你就需要Ministro,一个为Android系统Qt程序运行下载所需要的库.可以到电子市场搜索Ministro,或者到Ministro项目里下载:Ministro.安装好Ministro后再运行Qt程序,根据提示下载需要的库.
其他类似问题
为您推荐:
提问者采纳
输入完成后点击Nandroid/p&QLabel*label=newQLabel(&quot:创建一个Android项目我以Empty Qt Project为例!&lt:选择Qt Version注意,一个为Android系统Qt程序运行下载所需要的库,所以不能有网络相关的应用(不过我想这迟早会移植的):#include&lt,选择Android target SDK:Ministro.只要正确建立了Qt项目:编写程序在这步大家按照平常Qt Creator的步骤写程序就好,默认是选择Destkop的,我就用hello world吧;bin里面.点击Choose后出现一个对话框要求填写Project的名字和选择路径,argv);palign=centerHello,就完成了一大半了,正确应该按上图设置.exec();QApplication#include&lt.作为例子,毕竟Android系统没有Qt的库,一个简单的流程已经介绍完毕.设置后按Next确认一下.可以到电子市场搜索Ministro.下图是完成后的一个截图:第二步,到下面一个比较重要的操作,有些模块暂时还没有移植,选择Deploy local qt libs然后按左边倒数第三个绿色三角按钮运行,W&#47,例如Qt网络模块:设置编译选项Projects标签 - Run 展开Package configurations.这个时候你就需要M&lt,没有错就按Finish完成Qt-Android项目的建立:第四步.至此.把它拷到手机上安装,char**argv){QApplicationapp():手机上运行你写的应用会打包成apk放在你项目文件夹里的/label-show(),(android7为例)展开紧跟下面的Deploy configurations.但是注意的是,根据提示下载需要的库;}第三步;QLabelintmain(intargc设置qt-android开发环境第一步.但是这样手机还不能运行这个程序.安装好Ministro后再运行Qt程序,或者到Ministro项目里下载;returnapp
资深电脑人
android的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁会计报表公式怎么算
°花舍°1442
在UFO中,由于各种报表之间存在着密切的数据间的逻辑关系,所以报表中各种数据的采集、运算和勾稽关系的检测就用到了不同的公式,主要有计算公式、审核公式和舍位平衡公式.本节主要介绍UFO的计算公式.一、计算公式的功能计算公式是报表数据的一个重要组成部分.对于财务报表,报表中的数据可能有不同的来源:(1)有些数据需要手工输入,例如在资产负债表中直接输入各项目的数据.(2)有些数据是由其他报表项目运算得到的,例如“固定资产净值”、“所有者权益合计”、“税后利润”等项目.(3)有些数据是从其他报表中取来的,例如“期末未分配利润”项目.(4)有些数据可以从账务系统中直接提取.除了手工输入的数据,其他数据都需要通过定义计算公式来得到.通过计算公式来组织报表数据,既经济又省事,把大量重复、复杂的劳动简单化了.合理地设计计算公式能大大地节约劳动时间,提高工作效率.计算公式可以直接定义在报表单元中,这样的公式称为“单元公式”.UFO允许在报表中的每个数值型、字符型的单元内,写入代表一定运算关系的公式,用来建立表内各单元之间、报表与报表之间或报表系统与其他系统之间的运算关系.描述这些运算关系的表达式,就可称之为单元公式.二、单元公式的格式单元公式的书写规则如下:=
(1)目标区域.是用户选取的、单元公式所赋值的单元或区域.
(2)算术表达式.用来确定单元公式的数据来源和运算关系.算术表达式中可以使用单元引用、数值、字符、运算符、函数等.三、算术运算符算术运算符是在描述运算公式时采用的符号,UFO可使用的算术运算符及运算符的优先顺序如表4-2:表4-2 算术运算符顺序表顺序 金额 金额 1 ∧ 平方 2 * 、/ 乘、除 3 +、- 加、减
四、算术表达式算术表达式是由运算符、区域和单元、常数、变量、关键字、非逻辑类函数表达式的组合,其结果为一个确定值.算术表达式又分为单值和多值算术表达式.单值算术表达式的结果为一个数值,也可为一个单纯的常数,可将其赋值给一个单元.多值算术表达式的结果为多个数值,可将其运算结果赋值给多个单元.
(1)单值算术表达式.例 C1=10;C2=A1+B1.
(2)多值算术表达式.例如,C1:C10=A1:A10+B1:B10(表示 C1=A1+B1,C2=A2+B2,…,C10=A10+B10);61:C10=100(表示C1=100,C2=100,…,C10=100).五、单元公式举例(l)A1=l000.←对于所有表页,给A1单元赋值为 1000.(2)C1=A1×B1.对于所有表页,C1单元的值等于A1单元的值和B1单元的值的乘积.(3)D10=PTOTAL(D1:D9).对于所有表页,D10单元的值等于D1单元到D9单元的值的总和.(4)E10=“累计”.对于所有表页,E10单元的值为字符“累计”. 十一、函数概述按照函数的用途不同,函数又分为账务函数、其他业务系统取数函数、统计函数、数学函数、日期时间函数、本表他页取数函数等等.下面举例说明常用函数的用法.图4-13 公式列表对话框1. 账务函数账务函数通常用来采集总账中的数据,因此使用的较为频繁.常用账务取数函数见表4-3所示.函数名 中文函数名 函数定义 DFS 对方科目发生 取对方科目发生数 FS 发生 取某科目本期发生数 HL 汇率 取汇率 JE 净额 取某科目借、贷方发生净额 LFS 累计发生 取某科目累计发生额 QC 期初 取某科目期初数 QM 期末 取某科目期末数 SDFS 数量对方科目发生 取对方科目数量发生数 SFS 数量发生 取某科目本期数量发生数 SJE 数量净额 取某科目借、贷方数量发生净额 SLFS 数量累计发生 取某科目累计数量发生额 SQC 数量期初 取某科目数量期初数 SQM 数量期末 取某科目数量期末数 STFS 数量条件发生 取符合指定条件的发生数 TFS 条件发生 取符合指定条件的发生数 WDFS 外币对方科目发生 取对方科目外币发生数 WFS 外币发生 取某科目本期外币发生数 WJE 外币净额 取某科目借、贷方外币发生净额 WLFS 外币累计发生 取某科目外币累计发生额 WQC 外币期初 取某科目外币期初数 WQM 外币期末 取某科目外币期末数 QTFS 外币条件发生 取符合指定条件的外币发生数
例如:在C5单元取999账套501科目的本月贷方发生额.以单元公式形式为例,步骤为: (1) 在格式设计状态,单击C5单元.(2)输入“=”或单击“fx” 图标,出现定义公式对话框.(3)在定义公式对话框中,单击【函数向导】按钮,出现函数向导对话框.(4)在函数向导对话框中的函数分类列表框中,选择【账务函数】,在函数名列表框中,选择【发生】,单击【下一步】按钮,出现用友账务函数对话框.(5)在用友账务函数对话框中,单击【参照】按钮,出现账务函数对话框.(6)在账务函数对话框中,选择账套号:999、科目:501、期间:月、会计年度:默认、方向:贷及辅助核算项目编码,最后单击【确定】,返回用友账务函数.(7)在用友账务函数对话框中,单击【确定】返回.(8)在定义公式对话框中,最终形成公式“C5=F5(“501”,月,“贷”,999,),确定.(9)在C5单元格内显示“单元公式”字样,在公式栏中显示C5单元的公式定义.2. 统计函数统计函数一般用来做报表数据的统计工作,常用统计函数如表4-4:函数 固定区 可变区 立体方向 合计函数 PTOTAL GTOTAL TOTAL 平均值函数 PAVG GAVG AVG 计数函数 PCOUNT GCOUNT COUNT 最小值函数 PMIN GMIN MIN 最大值函数 PMAX GMAX MAX 方差函数 PVAR GVAR VAR 偏方差函数 PSTD GSTD STD0
例如:在C9单元取本表页C5到C8单元的和.以单元公式形式为例,步骤为: (1)在格式设计状态,单击C9单元.(2)输入“=”或单击“fx” 图标,出现定义公式对话框.(3)在定义公式对话框中,单击【函数向导】按钮,出现函数向导对话框.(4)在函数向导对话框中的函数分类列表框中,选择【统计函数】,在函数名列表框中,选择【PTOTAL】,单击【下一步】按钮,出现固定区统计函数对话框.(5)在固定区统计函数对话框的固定区区域文本框中输入:C5:C8,如果有筛选条件,在筛选表达式文本框中输入筛选条件,单击【确定】,返回定义公式对话框.(6)在定义公式对话框中,最终形成公式“ C9=PTOTAL(C5:C8)”,确定.(7)在C9单元格内显示“单元公式”字样,在公式栏中显示C9单元的公式定义.3.本表他页取数函数本表他页取数函数用于从同一报表文件的其他表页中采集数据.很多报表数据是从以前的历史记录中取得的,如本表其他表页.当然,这类数据可以通过查询历史资料而取得,但是,查询既不方便,又会由于抄写错误而引起数据的失真.而如果在计算公式中进行取数设定,既减少工作量,又节约时间,同时数据的准确性也得到了保障.这就需要用到表页与表页间的计算公式.(1) 取确定页号表页的数据.当所取数据所在的表页页号已知时,用以下格式可以方便地取得本表他页的数据:= @例如:下面单元公式令各页B2单元均取当前表第一页C5单元的值.其表示如下:B2= C5@1(2)按一定关键字取数.SELECT()函数常用于从本表他页取数计算.例如:在“损益表” 中,累计数 = 本月数+同年上月累计数,表示为: D=C+SELECT (D,年@=年and月@=月+1)4. 从其他报表取数计算当从他表取数时,已知条件并不是页号,而是希望按照年、月、日等关键字的对应关系来取他表数据,就必须用到关联条件.在进行报表与报表间的取数时,不仅仅要考虑取哪一个表哪一个单元的数据,还要考虑数据源在哪一页.例如,5月份的资产负债表中的利润,需要去傲利润表中5月份的利润数据,假如利润表中存在其他月份的数据,而不存在5月份的数据,那么《资产负债表》绝对不应该将其他月份的数据取出来,报表间的计算公式就是要保证这一点.报表间的计算公式与同一报表内各表页间的计算公式很相近,主要区别就是把本表表名换为他表表名.报表与报表间的计算公式分为:取他表确定页号表页的数据和用关联条件从他表取数. (1)取他表确定页号表页的数据.用以下格式可以方便地取得已知页号的他表表页数据:
]当缺省时为本表各页分别取他表各页数据.下面就该格式举一些例子.①取他表数据.令当前表页D5的值等于表“Y”第4页D5的值:D5=“Y”→D5@4;令本表各页D5的值等于表“Y”各页D5的值:D5=“Y”→D5 FOR ALL;令当前表所有表页 C5的值等于表“Y”第 1页中C10 的值与表“Y”第2页中C2的值之和:C5=“Y” →C10@1+“Y”-C2@2②取他表及本表的数据.令当前表所有表页C5的值等于表“Y”第1页中C10的值与当前表第2页中C2的值之和:C5=“Y”→C10@l+C2@2.③取其他两个表的数据.当前表 C1>0的表页 D5的值等于表“Y”第1页中 H20的值与表“X”第2页中F4的值之和:D5=“Y”→H20@l+“X”→E4@2 FOR C1>0.④可变区公式.在命令窗或批命令中,令当前可变表 C1>0的表页V_D的值等于表“Y”第1页中V_H的值与表“X” 第2页中V_L的值之和:LET V_D =“Y”→V_H@l+“X”→V_L@2 FOR C1>0.(2)用关联条件从他表取数.当从他表取数时,已知条件并不是页号,而是希望按照年、月、日等关键字的对应关系来取他表数据,就必须用到关联条件.表页关联条件的意义是建立本表与他表之间以关键字或某个单元为联系的默契关系.从他表取数的关联条件的格式为:RELATION WITH“”→具体用法我们以例子说明.例如:A1=“FYB”→A1 FOR ALL RELATION月WITH“FYB”→月,意义为取FYB表的,与当前表页月相同月的A1单元的值.如果当前表页为9月,则取FYB表9月表页A1的值;A=“LRB”→BRELATION月 WITH “LRB” →月十1,意义为令本表各页A列取表“LRB”上月各页 B列数值;A=“LRB”→A RELATION年 WITH“LRB”→年,月WITH“LRB”→月+l, 意义为令当前表各项A列取表“LRB” 同年上月A列数值;A=“LRB”→B FOR ALL RELATlON 1 WITH “LRB”→月,令当前表各页A列取表“LRB”1月B列数值;A=“LRB”→B+“ZJB”→C RELATION年 WITH“LRB”→年,月WITH“LRB”→月,年WITH“ZJB”→年,月WITH“ZJB”→月,令当前表各页A列取表“LRB” 同年上月表页B列数值及表“ZJB”上一年相同月份表页C列数值之和.十二、计算公式的编辑在UFO中,编辑计算公式有3种方式:单元公式方式、命令行方式和批处理方式.1.单元公式方式单元公式方式在格式设计状态中定义,存储在报表单元中,切换到数据处理状态时,单元公式将自动进行运算,也可以随时使用菜单【数据】中的【整表重算】命令驱动报表中所有单元公式进行重算.不需再计算时,可以点取屏幕上方的【不计算】按钮,本表页以后不再重算.要重新计算,再次点取【不计算】按钮即可.当本表单元公式中涉及到其他表或其他系统数据时,必须“整表重算”后才能更新数据.2.命令行方式在数据处理状态下,选择【文件】菜单中的【命令窗】,在报表工作区下面就会显示命令窗窗口,在命令窗中一条一条书写要执行的命令,按回车立即计算.与定义单元公式不同的是,在命令宣中书写的命令应以LET语句开头.如定义 C6单元为 C4和 C5单元之和,应键人:LET C6=C4+C5.3.批处理方式在数据处理状态下,选择【文件】菜单下的【二次开发】,选择文件类型为批处理 (SHL文件),在二次开发窗口中一次性编辑所要执行的命令,保存时,可以由用户自己定义文件名,最后选择【文件】菜单中的【执行】,即可完成批量计算.计算公式在命令窗和批命令中的格式特点是;以LET引导计算公式;一个计算公式可以为若干个筛选条件、关联条件相同的区域赋值,各赋值表达式间以逗号“,”分隔.在可变区中不能定义单元公式,要计算可变区的内容,可以在命令窗或批命令中定义可变区公式.例如:LET V-C=(V-A)×(V-B).
为您推荐:
其他类似问题
扫描下载二维码如何在新建的c++源文件中获取MFC编辑框里输入的内容_百度知道
如何在新建的c++源文件中获取MFC编辑框里输入的内容
  1、设置编辑框变量  在MFC的基本对话框中,我建立了一个编辑框控件,变量名为 m_Min ,类型为value int  [cpp] view plaincopy  CString c_  m_user.GetWindowText(c_user);  就两句代码就可以获取内容了    2、直接获取  [cpp] view plaincopy  CS  GetDlgItem(IDC_EDIT1)-&GetWindowText(str);  MessageBox(str);
其他类似问题
为您推荐:
提问者采纳
..这样就把编辑框中的字符传递给字符串变量c_userinput之后对c_userinput用sizeof即可.userInput..GetWindowText(c_userInput)c_useriput是输入编辑框控件变量
其他3条回答
TestDlg你可以在新建的文件前 加上#include & 头文件.h&gt,然后定义对话框类的实例
//给IDC_EDIT1~IDC_EDIT4绑定CString类型的成员变量 m_str1~m_str4//agent.cpp#include &.\TestDlg.h&void Test(){CTestDif(dlg.DoModal() == IDOK){//到到变量,长度CString s1 = dlg .m_str1;int a1 = s1.GetLength();//......}}
assWizard对话框中最重要的选项卡,主要完成创建新类、添加、删除消息处理函数等任务。
该选项卡中包含了两个下拉列表框:Project下拉列表框和Class name下拉列表框;三个列表框:Object IDs列表框、Message列表框和Member functions列表框;一个文本信息框;四个工具按钮。
★ Project下拉列表框:该下拉列表框用于选择当前操作的项目。当当前打开的工作区中包含多个项目文件时,用户可以从这个下拉列表框中选择将要操作的项目文件。对于单项目工作区来说,其默认值就是项目文件。
★ Class name下拉列表框:该下拉列表框用于选择当前要操作的类。当用户在Class name下拉列表框中选中了某个类之后,Object IDs窗口中的内容将会发生相应的变化。
★ Object IDs列表框:该列表框用于显示当前选定类中能够产生...
mfc的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁  最近从大陆来到台湾,之间杂事很多,挤不出时间来更新博客…
  这次主要是通过做一个简易的数据库管理系统,来学习在Qt中对数据库,xml,界面的各种操作,进一步熟悉Qt。一般而言数据通常存在文件,数据库,xml中,本文主要是介绍了sqlite,xml这2种存储数据的方法,实现了一个家用电器产品的销售小软件。参考资料为&&代码基本也是作者yafei的,我只是看懂一些代码然后手动敲入加稍微修改而已。反正以学习他人的代码来进一步掌握Qt编程。
  实验过程
  该实验分为3个部分,商品管理,销售统计,和修改密码。
  商品管理:
  在程序运行时,已经建立了商品销售的数据库,该数据库分为3个表,品牌表,分类表,密码表。分类表中有2个产品类别,为电视和空调。品牌表中对应的电视有4个品牌,空调有2个品牌,这2者初始化时已经有了库存信息,即商品的单价,剩余商品的数量等。密码表中设置了初始化密码,初始密码为”2012”。 与此同时也建立xml来存储数据,里面有日销售清单,还设置了销售日期,时间,品牌的信息,供后面销售完毕后来进行查询和存储。
  在商品管理页,选择对应的品牌,类型,和打算卖出的数量,则软件会自动计算卖出的总额和剩余对应产品的数量。单击售出的确认按钮后,右边的页面会显示销售的记录,其中的信息包括销售时间,日期,品牌的数量,价格等等。
  销售统计:
  销售统计这一栏用表格和饼图来显示销售产品数量的分布情况。可以在销售统计右侧的下拉列框中选择电视和空调2个类型中的一个,然后左侧的表格会显示品牌和销售数量2个量,品牌左侧有不同颜色的小方框显示。右侧显示的是其对应的饼图,饼图旁边有小方框显示不同颜色代表不同的销售商品。在左边的表格中单击表格单元格,可以看到右边饼图对应的那一个扇形的颜色更改了。销售统计中显示表格和饼图需要重写QAbstractItemView类中的很多函数,其中不少函数没有自己去敲代码,直接赋值过来的。
  密码更改:
  在密码更改页中,可以修改登录密码,新密码需要2遍确认,这些操作都与普通的更改密码操作类似。修改后的密码会被保存在sqlite数据库中。
  实验说明
  界面设计时的小技巧:
  1.如果把控件放在布局文件中,那么该控件自身的尺寸和控件之间的几何量会被自动改变,因为这些都是交给了布局文件来管理。那么怎么做到将设计好了的控件放入布局文件后不改变这些几何变量呢?首先,如果需要固定控件之间的距离量,可以加入弹簧;其实,如果需要固定控件的几何尺寸,可以在Qt Designer中控件的属性栏的minimumSize和maximumSize两个栏中都设置为同样大小。这样即使控件放入布局文件中,也不会更改它们本身的几何量了。
  2. 如果需要把各控件按照自己的习惯排布好,而这时不打算使用布局文件(因为布局文件会自动改变控件的大小),这时可以采用一个Stack Widget,让其它的控件任意形状放入其中。
  3. 分割器并不单单指的中间一条分割线,而是指的包括分割线2侧的widget,即可以理解为一个矩形,它也有长和宽。
  数据库中的一些小知识:
  数据库的一些语法中,有些地方需要加单引号,这个不能漏。
  PRIMARY KEY 约束唯一标识数据库表中的每条记录;主键必须包含唯一的值;主键列不能包含 NULL 值;每个表都应该有一个主键;并且每个表只能有一个主键。
  QSqlQuery这个类是用来查询sql数据库的类;QSqlDatabase是用来创建数据库的类;
  事务操作是用户定义的一个数据库操作序列,这些操作要么全做要么全不做,是一个不可分割的操作。在Qt中事务操作时以transaction()开始的,以commit()函数或者rollback()函数进行结束的。这两者的区别是commit()表示提交,即把事务中所有对数据库的更新写到数据库,事务是正常结束的。Rollback()表示回滚,即如果事务运行过程中发生了某些故障,事务不能继续进行,则系统将事务中对数据库的所有已完成的操作全部撤销,回滚到事务开始的状态。
  QSqlDatabase::database()返回前面成功连接的QSqlDatabase对象。
  XML使用小知识点:
  对XML文档的操作有2种方法:DOM和SAX。其中DOM是把XML文档转换成应用程序可以遍历的树形结构,这样便可以随机访问其中的节点。缺点是需要把整个XML文档读入内存,这样消耗内存会很大。
  tagName 属性返回被选元素的标签名。
  这次实验通过代码来建立一个xml文件,主要是用到了QDomDocument这个类中的很多方法,xml文件有点类似树形结构,本次实验最初始建立的xml文件内容截图如下:
  Qt使用一些小知识点:
  QString::number(num)可以将整型的num转换成string型。
  qreal 其实就是double型。
  往QListWidget加入文字可以使用其addItem()方法.
  arg()中的参数是QString型,则其对应的百分号需要用单引号括起来。
  Qt::DecorationRole是Qt::ItemDataRole中的一种, Qt::ItemDataRole表示每一个model中的Item都有自己的一个数据集,且有自己的特色。这些特点用来指定模型中的哪一种数据类型将被使用。而Qt::DecorationRole指的是说数据将以图表的形式来呈现。
  QAbstractItemView为一个抽象item视图类,里面有很多方法可以重写。
  QPaint是一个绘图类,可以设置画笔,画刷,字体。
  在设计用户名密码登陆时,如果用户名和密码都正确,则会调用调用父类的QDialog::accept()槽函数,该函数实现关闭当前对话框,设置对话框的运行结果为QDialog::Accepted,并发送QDialog::finished(int result)信号。
  增加StackWidget页面的方法,在StackWidget上鼠标右击,选择insert page,然后继续选择在本页之前或者之后加入页码。
  商品管理中的出售商品一栏:&&&&
  通过将产品的类型,品牌,价格,数量,金额等信息写入xml文件,各种信息都以一个时间为标签,做为该标签下面的各子标签。
  实验结果:
  登录界面如下:
  商品管理功能如下:
  销售统计功能如下:
  密码修改界面如下:
  实验主要部分代码及注释(附录有工程code下载链接):
connection.h:
#ifndef CONNECTION_H
#define CONNECTION_H
#include &QtSql&
#include &QDebug&
#include &QtXml&
//该头文件就一个函数,即创建关联表的函数
static bool createConnection()
//SqlDatabase为实现数据库连接的类
QSqlDatabase db = QSqlDatabase::addDatabase(&QSQLITE&);//创建一个数据库,添加数据库驱动
db.setHostName(&tornadomeet&);
db.setDatabaseName(&data.db&);//设置数据库的名字
db.setUserName(&tornadomeet1&);//设置数据库的用户名
db.setPassword(&2012&);//设置数据库的密码
if(!db.open())
return false;
QSqlQ//新建一个查询库
//创建一个类型表,表名为varchar是用来保存可变长度的字符串
query.exec(&create table type(id varchar primary key, name varchar)&);
query.exec(QString(&insert into type values('00', '请选择类型')&));//表中的第一个项
query.exec(QString(&insert into type values('01', '电视')&));//加入第二项
query.exec(QString(&insert into type values('02', '空调')&));//第三项
//创建一个品牌表,表名为brand
query.exec(&create table brand(id varchar primary key, name varchar, &
&type varchar, price int, sum int, sell int, last int)&);
query.exec(QString(&insert into brand values('01', '海信', '电视', '3699', '50', '10', '40')&));
query.exec(QString(&insert into brand values('02', '创维', '电视', '3499', '20', '5', '15')&));
query.exec(QString(&insert into brand values('03', '海尔', '电视', '4199', '80', '40', '40')&));
query.exec(QString(&insert into brand values('04', '王牌', '电视', '3999', '40', '10', '30')&));
query.exec(QString(&insert into brand values('05', '海尔', '空调', '2699', '60', '10', '50')&));
query.exec(QString(&insert into brand values('06', '格力', '空调', '2799', '70', '20', '50')&));
query.exec(&insert into type brand('05', '海尔', '空调', '2699', '60', '10', '50')&);
query.exec(&insert into type brand('06', '格力', '空调', '2799', '70', '20', '50')&);
query.exec(&create table password(pwd varchar primary key)&);
query.exec(&insert into password values('2012')&);
return true;
static bool createXml()
QFile file(&data.xml&);//创建一个xml文件
if(file.exists())
return true;
if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate))//以只写方式打开,且清零以前的信息
return false;
QDomD//新建一个QDomDocument类对象,它代表一个xml文件
QDomProcessingIns//添加处理指令
instruction = doc.createProcessingInstruction(&xml&, &version=\&1.0\& encoding=\&UTF-8\&&);
doc.appendChild(instruction);//xml文件版本等信息
QDomElement root = doc.createElement(QString(&目录销售清单&));
doc.appendChild(root);//增加根目录
QTextStream out(&file);//指定文本流
doc.save(out, 4);//将xml文档保存到文件data.xml文件中,4表示子元素缩进字符数
file.close();
return true;
#endif // CONNECTION_H
datamanager.h:
#ifndef DATAMANAGER_H
#define DATAMANAGER_H
#include &QMainWindow&
#include &QDomDocument&
namespace Ui {
class DataM
class QStandardItemM//这个类为Qt中提供了存储定制数据的通用模型
class DataManager : public QMainWindow
explicit DataManager(QWidget *parent = 0);
~DataManager();
enum DataTimeType{Time, Date, DateTime};//定义时间的枚举类型
QString getDataTime(DataTimeType type);
private slots:
void on_sellTypeComboBox_currentIndexChanged(const QString &arg1);
void on_sellBrandComboBox_currentIndexChanged(const QString &arg1);
void on_sellNumSpinBox_valueChanged(int arg1);
void on_sellCancelButton_clicked();
void on_sellOkButton_clicked();
void on_typeComboBox_currentIndexChanged(const QString &arg1);
void on_updateButton_clicked();
void on_manageButton_clicked();
void on_chartButton_clicked();
void on_passwordButton_clicked();
void on_okButton_clicked();
void on_cancelButton_clicked();
Ui::DataManager *
QStandardItemModel *chartM
bool docRead();
bool docWrite();
void writeXml();
void createNodes(QDomElement &data);
void showDailyList();
void createChartModelView();
void showChart();
#endif // DATAMANAGER_H
datamanager.cpp:
#include &datamanager.h&
#include &ui_datamanager.h&
#include &connection.h&
#include &pieview.h&
#include &QtSql&
#include &QtXml&
#include &QtGui&
DataManager::DataManager(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::DataManager)
ui-&setupUi(this);
ui-&stackedWidget-&setCurrentIndex(0);
QSqlQueryModel *typeModel = new QSqlQueryModel(this);//新建一个Sql查询模块
typeModel-&setQuery(QString(&select name from type&));//执行改句相当于执行查询语句,其结果可以设置在组合框中
ui-&sellTypeComboBox-&setModel(typeModel);
QSplitter *splitter = new QSplitter(ui-&managePage);//增加一个分隔符
splitter-&resize(680, 400);
splitter-&move(10, 40);
splitter-&addWidget(ui-&toolBox);
splitter-&addWidget(ui-&dailyList);
splitter-&setStretchFactor(0, 1);//第一个widget的分割器中所占面积大小之比为1
splitter-&setStretchFactor(1, 1);
on_sellCancelButton_clicked();//初始化各控件的状态
showDailyList();
ui-&typeComboBox-&setModel(typeModel);
createChartModelView();
DataManager::~DataManager()
void DataManager::on_sellTypeComboBox_currentIndexChanged(const QString &arg1)
if(arg1 == &请选择类型&)
ui-&sellBrandComboBox-&setEnabled(true);
QSqlQueryModel *model = new QSqlQueryModel(this);
model-&setQuery(QString(&select name from brand where type = '%1'&).arg(arg1));//注意单引号是英文状态下的
ui-&sellBrandComboBox-&setModel(model);
ui-&sellCancelButton-&setEnabled(true);//取消按钮可用
void DataManager::on_sellBrandComboBox_currentIndexChanged(const QString &arg1)
ui-&sellNumSpinBox-&setValue(0);//将数量值设置为0
ui-&sellNumSpinBox-&setEnabled(false);//数量值那一栏不可更改
ui-&sellSumLineEdit-&clear();//金额数清0
ui-&sellSumLineEdit-&setEnabled(false);//金额一栏不可用
ui-&sellOkButton-&setEnabled(false);//确定按钮也不可用
query.exec(QString(&select price from brand where name ='%1' and type ='%2'&).
arg(arg1).arg(ui-&sellTypeComboBox-&currentText()));
query.next();//查询记录指向相邻的下一条记录
ui-&sellPriceLineEdit-&setEnabled(true);//单价输入框
ui-&sellPriceLineEdit-&setReadOnly(true);
ui-&sellPriceLineEdit-&setText(query.value(0).toString());//value(0)为获得第0个属性的值,这里指的是price
query.exec(QString(&select last from brand where name ='%1' and type = '%2'&).
arg(arg1).arg(ui-&sellTypeComboBox-&currentText()));
query.next();//移向第一个记录
int num = query.value(0).toInt();//取出来
if(0 == num)
QMessageBox::information(this, tr(&提示&), tr(&该商品已经销售完了!&), QMessageBox::Ok);
ui-&sellNumSpinBox-&setEnabled(true);//可用使用
ui-&sellNumSpinBox-&setMaximum(num);//设置最大值为剩余数量的值
ui-&sellLastNumLabel-&setText(tr(&剩余数量: %1&).arg(num));
ui-&sellLastNumLabel-&setVisible(true);//其实默认情况下就是可见的
void DataManager::on_sellNumSpinBox_valueChanged(int arg1)
if(arg1 == 0)
ui-&sellSumLineEdit-&clear();//清零且不可用
ui-&sellSumLineEdit-&setEnabled(false);
ui-&sellOkButton-&setEnabled(false);
ui-&sellSumLineEdit-&setEnabled(true);
ui-&sellSumLineEdit-&setReadOnly(true);
//qreal其实就是一个double型
qreal sum = arg1*(ui-&sellPriceLineEdit-&text().toInt());//卖出的数量*单价等于总额
ui-&sellSumLineEdit-&setText(QString::number(sum));//显示总额
ui-&sellOkButton-&setEnabled(true);
void DataManager::on_sellCancelButton_clicked()
ui-&sellTypeComboBox-&setCurrentIndex(0);
ui-&sellBrandComboBox-&clear();//品牌框不可用,且清零
ui-&sellBrandComboBox-&setEnabled(false);
ui-&sellPriceLineEdit-&clear();
ui-&sellPriceLineEdit-&setEnabled(false);//单价栏不可用
ui-&sellNumSpinBox-&setValue(0);//数量栏清零且不可用
ui-&sellNumSpinBox-&setEnabled(false);
ui-&sellSumLineEdit-&clear();
ui-&sellSumLineEdit-&setEnabled(false);//总额栏不可用
ui-&sellOkButton-&setEnabled(false);
ui-&sellCancelButton-&setEnabled(false);//按钮不可用
ui-&sellLastNumLabel-&setVisible(false);//剩余数不可见
void DataManager::on_sellOkButton_clicked()
//QSqlDatabase::database()返回前面成功连接的QSqlDatabase对象。
QString type = ui-&sellTypeComboBox-&currentText();
QString name = ui-&sellBrandComboBox-&currentText();
int value = ui-&sellNumSpinBox-&value();//当前打算卖出的量
int last = ui-&sellNumSpinBox-&maximum()-//当前还剩余的量
query.exec(QString(&select sell from brand where name=%1 and type=2%&).arg(name).arg(type));
query.next();//指向结果集的第一条记录
int sell = query.value(0).toInt()+//总共售出量
QSqlDatabase::database().transaction();//事务操作开始
bool rtn = query.exec(QString(&update brand set sell=%1, last=%2 where name='%3' and type='%4'&).arg(sell).
arg(last).arg(name).arg(type));
QSqlDatabase::database().commit();//上面查询操作成功时,则提交事务操作
QMessageBox::information(this, tr(&提示&), tr(&购买成功!&), QMessageBox::Ok);
writeXml();
showDailyList();
on_sellCancelButton_clicked();
qDebug() && &It's OK!&;
QSqlDatabase::database().rollback();//如果上述查询操作失败,则执行事务回滚
QString DataManager::getDataTime(DataManager::DataTimeType type)
QDateTime datetime = QDateTime::currentDateTime();
QString date = datetime.toString(&yyyy-MM-dd&);
QString time = datetime.toString(&hh:mm&);
QString date_time = datetime.toString(&yyyy-MM-dd dddd hh:mm&);
if(type == Date)
else if(type == Time)
else return date_
//将xml文件中的内容读取到QDomDocument类对象中去
bool DataManager::docRead()
QFile file(&data.xml&);
if(!file.open(QIODevice::ReadOnly))//打开文件
return false;
if(!doc.setContent(&file))//读取文件
file.close();
return false;
file.close();
return true;
//将QDomDocument类对象的内容写到xml文档中去
bool DataManager::docWrite()
QFile file(&data.xml&);
if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
return false;
QTextStream out(&file);
doc.save(out, 4);//将doc内容存入到file中
file.close();
return true;
void DataManager::writeXml()
if(docRead())
QString currentDate = getDataTime(Date);//获得当前日期
QDomElement root = doc.documentElement();//获得当前文档根节点
if(!root.hasChildNodes())
QDomElement date = doc.createElement(QString(&日期&));//增加一个标签
QDomAttr curDate = doc.createAttribute(&date&);//增加一个属性
curDate.setValue(currentDate);//给属性赋值
date.setAttributeNode(curDate);//给新增加的标签附上该属性
root.appendChild(date);//往根节点上添加标签
createNodes(date);//创建标签节点
QDomElement date = root.lastChild().toElement();
//已经有了今天的节点信息
if(date.attribute(&date&) == currentDate)
createNodes(date);
QDomElement date = doc.createElement(QString(&日期&));
QDomAttr curDate = doc.createAttribute(&date&);
curDate.setValue(currentDate);
date.setAttributeNode(curDate);
root.appendChild(date);
createNodes(date);
docWrite();//写入到xml文件中
//创建销售商品的信息的节点
void DataManager::createNodes(QDomElement &date)
//创建标签time,并为其设置属性值
QDomElement time = doc.createElement(QString(&时间&));
QDomAttr curTime = doc.createAttribute(&time&);
curTime.setValue(getDataTime(Time));
time.setAttributeNode(curTime);
//将新建的time标签加载到date标签上
date.appendChild(time);
QDomElement type = doc.createElement(QString(&类型&));
QDomElement brand = doc.createElement(QString(&品牌&));
QDomElement price = doc.createElement(QString(&单价&));
QDomElement num = doc.createElement(QString(&数量&));
QDomElement sum = doc.createElement(QString(&金额&));
QDomT//用来存放文本值对象
text = doc.createTextNode(QString(&%1&).arg(ui-&sellTypeComboBox-&currentText()));
type.appendChild(text);//type标签中的文本内容
//brand标签
text = doc.createTextNode(QString(&%1&).arg(ui-&sellBrandComboBox-&currentText()));
brand.appendChild(text);
//price标签
text = doc.createTextNode(QString(&%1&).arg(ui-&sellPriceLineEdit-&text()));
price.appendChild(text);
text = doc.createTextNode(QString(&%1&).arg(ui-&sellNumSpinBox-&value()));
num.appendChild(text);
text = doc.createTextNode(QString(&%1&).arg(ui-&sellSumLineEdit-&text()));
sum.appendChild(text);
time.appendChild(type);//将新建的标签都贴在time标签上
time.appendChild(brand);
time.appendChild(price);
time.appendChild(num);
time.appendChild(sum);
void DataManager::showDailyList()
ui-&dailyList-&clear();
if(docRead())
QDomElement root = doc.documentElement();//获取根标签
QString title = root.tagName();//获得根标签的名字
QListWidgetItem *listItem = new QListWidgetI//建立一个listWidget
listItem-&setText(QString(&......%1......&).arg(title));//设置显示的标题
listItem-&setTextAlignment(Qt::AlignCenter);//标题设置为中心对齐
ui-&dailyList-&addItem(listItem);//将该listItem添加到QListWidgetItem中
if(root.hasChildNodes())
QString currentDate = getDataTime(Date);//得到当前的日期
QDomElement dateElement = root.lastChild().toElement();//得到最后一个标签
QString date = dateElement.attribute(&date&);//得到该标签的的时间属性
if(date == currentDate)
ui-&dailyList-&addItem(&&);//这里是空格一行
ui-&dailyList-&addItem(QString(&日期: %1&).arg(date));
ui-&dailyList-&addItem(&&);
QDomNodeList children = dateElement.childNodes();//获得该标签的所有子元素列表
qDebug() && children.count();
for(int i = 0; i & children.count(); i++)
QDomNode node = children.at(i);//得到第i个子元素的节点
QString time = node.toElement().attribute(&time&);//需先将node转换成element
QDomNodeList list = node.childNodes();
//分别获取节点中元素的内容
QString type = list.at(0).toElement().text();
QString brand = list.at(1).toElement().text();
QString price = list.at(2).toElement().text();
QString num = list.at(3).toElement().text();
QString sum = list.at(4).toElement().text();
QString str = time + & 出售 & + brand + type
+ & & + num + &台, & + &单价:& + price
+ &元, 共& + sum + &元&;
QListWidgetItem *tempItem =
new QListWidgetI
tempItem-&setText(&*************************&);
tempItem-&setTextAlignment(Qt::AlignCenter);
ui-&dailyList-&addItem(tempItem);
ui-&dailyList-&addItem(str);//显示该卖出产品的信息
void DataManager::createChartModelView()
chartModel = new QStandardItemModel(this);
chartModel-&setColumnCount(2);//设置为2列显示
chartModel-&setHeaderData(0, Qt::Horizontal, QString(&品牌&));
chartModel-&setHeaderData(1, Qt::Horizontal, QString(&销售数量&));//模型的字段名
QSplitter *splitter = new QSplitter(ui-&chartPage);//新建分隔器
splitter-&resize(680, 400);
splitter-&move(10, 40);
QTableView *table = new QTableV
PieView *pieChart = new PieV
splitter-&addWidget(table);//为分隔符2侧添加widget
splitter-&addWidget(pieChart);
splitter-&setStretchFactor(0, 1);//设置比例
splitter-&setStretchFactor(1, 2);
table-&setModel(chartModel);//设置模型??
pieChart-&setModel(chartModel);
QItemSelectionModel *selectionModel = new QItemSelectionModel(chartModel);
table-&setSelectionModel(selectionModel);//设置共用选择模型
pieChart-&setSelectionModel(selectionModel);
void DataManager::showChart()
query.exec(QString(&select name, sell from brand where type='%1'&).arg(ui-&typeComboBox-&currentText()));
//全部删除表中的内容
//rowCount()为返回参数索引中的行数,QModelIndex()为一个不可用的模型索引,该模型索引通常被用来在顶级项目时被父索引使用
//removeRows()为删除参数1开始的参数2行个行
chartModel-&removeRows(0, chartModel-&rowCount(QModelIndex()), QModelIndex());
int row = 0;
while(query.next())
int r = qrand()%256;
int g = qrand()%256;
int b = qrand()%256;
chartModel-&insertRows(row, 1, QModelIndex());//增加一行
chartModel-&setData(chartModel-&index(row, 0, QModelIndex()), query.value(0).toString());//第一行第一列设置查询结果值
chartModel-&setData(chartModel-&index(row, 1, QModelIndex()), query.value(1).toInt());
//Qt::DecorationRole是Qt::ItemDataRole中的一种, Qt::ItemDataRole表示每一个model中的Item都有自己的一个数据集,
//且有自己的特色。这些特点用来指定模型中的哪一种数据类型将被使用。而Qt::DecorationRole指的是说数据将以图表的形式来呈现。
chartModel-&setData(chartModel-&index(row, 0, QModelIndex()), QColor(r, g, b), Qt::DecorationRole);
chartModel-&setData(chartModel-&index(row, 1, QModelIndex()), query.value(1).toInt());
chartModel-&setData(chartModel-&index(row, 0, QModelIndex()), QColor(r, g, b), Qt::DecorationRole);
row ++;
void DataManager::on_typeComboBox_currentIndexChanged(const QString &arg1)
if(arg1 != &请选择类型&)
showChart();
void DataManager::on_updateButton_clicked()
if(ui-&typeComboBox-&currentText() != &请选择类型&)
showChart();//其实是更新品牌的随机颜色
void DataManager::on_manageButton_clicked()
ui-&stackedWidget-&setCurrentIndex(0);//显示stackWidget的第一页
void DataManager::on_chartButton_clicked()
ui-&stackedWidget-&setCurrentIndex(1);//显示stackWidget的第二页
void DataManager::on_passwordButton_clicked()
ui-&stackedWidget-&setCurrentIndex(2);//进入密码管理页
void DataManager::on_okButton_clicked()
query.exec(&select pwd from password&);
query.next();
if(ui-&oldPasswordLineEdit-&text().isEmpty())
QMessageBox::warning(this, tr(&请输入密码&), tr(&请输入旧密码和新密码&), QMessageBox::Ok);
else if(ui-&oldPasswordLineEdit-&text() != query.value(0).toString())
QMessageBox::warning(this, &密码错误&, tr(&输入的旧密码错误&), QMessageBox::Ok);
ui-&oldPasswordLineEdit-&setFocus();
if(ui-&newPasswordLineEdit-&text() == ui-&surePasswordlineEdit-&text())
QString newPassword = ui-&newPasswordLineEdit-&text();
query.exec(QString(&update password set pwd=%1&).arg(newPassword));//更新密码
QMessageBox::information(this, tr(&修改密码&), tr(&修改密码成功!&), QMessageBox::Ok);
QMessageBox::warning(this, tr(&修改密码失败&), tr(&新密码两次输入不一致!&), QMessageBox::Ok);
void DataManager::on_cancelButton_clicked()
ui-&oldPasswordLineEdit-&clear();
ui-&oldPasswordLineEdit-&setFocus();//把输入焦点放在旧密码处,方便重新输入
ui-&newPasswordLineEdit-&clear();
ui-&surePasswordlineEdit-&clear();
logindialog.h:
#ifndef LOGINDIALOG_H
#define LOGINDIALOG_H
#include &QDialog&
namespace Ui {
class LoginD
class LoginDialog : public QDialog
explicit LoginDialog(QWidget *parent = 0);
~LoginDialog();
private slots:
void on_loginButton_clicked();
void on_quitButton_clicked();
Ui::LoginDialog *
#endif // LOGINDIALOG_H
logindialog.cpp:
#include &logindialog.h&
#include &ui_logindialog.h&
#include &QMessageBox&
#include &QSqlQuery&
#include &QDebug&
LoginDialog::LoginDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::LoginDialog)
ui-&setupUi(this);
ui-&passwordEdit-&setFocus();
ui-&loginButton-&setDefault(true);
LoginDialog::~LoginDialog()
void LoginDialog::on_loginButton_clicked()
if(ui-&passwordEdit-&text().isEmpty())
QMessageBox::information(this, tr(&请输入密码&), tr(&请输入密码再登录&), QMessageBox::Ok);
ui-&passwordEdit-&setFocus();
query.exec(&select pwd from password&);
query.next();
if(query.value(0).toString() == ui-&passwordEdit-&text())
QDialog::accept();
QMessageBox::warning(this, tr(&密码错误&), tr(&请输入正确密码后再登录&),QMessageBox::Ok);
ui-&passwordEdit-&clear();
ui-&passwordEdit-&setFocus();//给一个输入焦点
void LoginDialog::on_quitButton_clicked()
QDialog::reject();//隐藏对话框,发送拒绝信号
preview.h:
#ifndef PIEVIEW_H
#define PIEVIEW_H
#include &QAbstractItemView&
class PieView : public QAbstractItemView
explicit PieView(QWidget *parent = 0);
QModelIndex indexAt(const QPoint &point) const;
void scrollTo(const QModelIndex &index, ScrollHint hint = EnsureVisible);
QRect visualRect(const QModelIndex &index) const;
public slots:
protected slots:
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
void rowsInserted(const QModelIndex &parent, int start, int end);
void rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end);
protected:
void paintEvent(QPaintEvent *event);
void resizeEvent(QResizeEvent * /* event */);
bool isIndexHidden(const QModelIndex &index) const;
QRegion itemRegion(const QModelIndex &index) const;
int horizontalOffset() const;
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
QModelIndex moveCursor(QAbstractItemView::CursorAction cursorAction,
Qt::KeyboardModifiers /*modifiers*/);
bool PieView::edit(const QModelIndex &index, EditTrigger trigger, QEvent *event);
void setSelection(const QRect&, QItemSelectionModel::SelectionFlags command);
void scrollContentsBy(int dx, int dy);
int verticalOffset() const;
QRegion visualRegionForSelection(const QItemSelection &selection) const;
int margin, totalSize, pieS
int validI
double totalV
QRubberBand *rubberB
QRect itemRect(const QModelIndex &item) const;
int rows(const QModelIndex &index = QModelIndex()) const;
void updateGeometries();
#endif // PIEVIEW_H
preview.cpp:
#include &pieview.h&
#include &QtGui&
#include &QtCore&
#ifndef M_PI
#define M_PI 3.1415927
PieView::PieView(QWidget *parent) :
QAbstractItemView(parent)
horizontalScrollBar()-&setRange(0 ,0);//设置水平拖动条范围
verticalScrollBar()-&setRange(0, 0);//设置垂直拖动条范围
margin = 8;
totalSize= 230;
pieSize = totalSize - 2*
validItems = 0;
totalValue = 0.0;
//这是个槽函数,当视图数据改变时调用
void PieView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
QAbstractItemView::dataChanged(topLeft, bottomRight);//当数据被改变时改变这个槽函数
validItems = 0;//有效的item数目
totalValue = 0.0;//总销售量
for (int row = 0; row & model()-&rowCount(rootIndex()); ++row)
QModelIndex index = model()-&index(row, 1, rootIndex());//按顺序进行索引
double value = model()-&data(index).toDouble();//对应索引的销售量
if(value & 0.0)
totalValue +=//即统计总销售量和有效条目
validItems ++;
viewport()-&update(); //视图更新
//该函数是当当前所选的item处于可编辑状态时对应的编辑操作
bool PieView::edit(const QModelIndex &index, EditTrigger trigger, QEvent *event)
if( index.column() == 0)
return QAbstractItemView::edit(index, trigger, event);
return false;
QModelIndex PieView::indexAt(const QPoint &point) const
if( validItems == 0)
return QModelIndex();
int wx = point.x() + horizontalScrollBar()-&value();
int wy = point.y() + verticalScrollBar()-&value();
if(wx & totalSize)
double cx = wx - totalSize/2;
double cy = totalSize/2 -
double d = pow(pow(cx, 2) + pow(cy, 2), 0.5);//求2点之间的欧式距离
if(d == 0 || d & pieSize/2)
return QModelIndex();
double angle = (180/ M_PI)* acos(cx/d);//角度
if(cy & 0)
angle = 360 -
double startAngle = 0;//起始角度
for(int row = 0; row & model()-&rowCount(rootIndex()); ++row)
QModelIndex index = model()-&index(row, 1, rootIndex());
double value = model()-&data(index).toDouble();
if(value & 0.0)
double sliceAngle = 360*value/totalV
if(angle & startAngle && angle & (sliceAngle + startAngle))
return model()-&index(row, 1, rootIndex());
startAngle += sliceA
double itemHeight = QFontMetrics(viewOptions().font).height();
int listItem = int((wy - margin) / itemHeight);
int validRow = 0;
for (int row = 0; row & model()-&rowCount(rootIndex()); ++row) {
QModelIndex index = model()-&index(row, 1, rootIndex());
if (model()-&data(index).toDouble() & 0.0) {
if (listItem == validRow)
return model()-&index(row, 0, rootIndex());
validRow++;
return QModelIndex();
//判断索引是否隐藏
bool PieView::isIndexHidden(const QModelIndex &index) const
return false;
QRect PieView::itemRect(const QModelIndex &index) const
if(!index.isValid())
return QRect();
QModelIndex valueI
if(index.column() != 1)
valueIndex = model()-&index(index.row(), 1, rootIndex());
valueIndex =
if(model()-&data(valueIndex).toDouble()& 0.0)
int listItem = 0;
for(int row = index.row()-1; row&-0; --row)
if(model()-&data(model()-&index(row, 1, rootIndex())).toDouble()&0.0)
listItem++;
double itemH
switch(index.column())
itemHeight = QFontMetrics(viewOptions().font).height();//获取字体的高度
return QRect(totalSize, int(margin + listItem*itemHeight),
totalSize - margin, int(itemHeight));
return viewport()-&rect();
return QRect();
QRegion PieView::itemRegion(const QModelIndex &index) const
if (!index.isValid())
return QRegion();
if (index.column() != 1)
return itemRect(index);
if (model()-&data(index).toDouble() &= 0.0)
return QRegion();
double startAngle = 0.0;
for (int row = 0; row & model()-&rowCount(rootIndex()); ++row) {
QModelIndex sliceIndex = model()-&index(row, 1, rootIndex());
double value = model()-&data(sliceIndex).toDouble();
if (value & 0.0) {
double angle = 360*value/totalV
if (sliceIndex == index) {
QPainterPath sliceP
slicePath.moveTo(totalSize/2, totalSize/2);
slicePath.arcTo(margin, margin, margin+pieSize, margin+pieSize,
startAngle, angle);
slicePath.closeSubpath();
return QRegion(slicePath.toFillPolygon().toPolygon());
startAngle +=
return QRegion();
int PieView::horizontalOffset() const
return horizontalScrollBar()-&value();
//鼠标按下时的反应处理
void PieView::mousePressEvent(QMouseEvent *event)
QAbstractItemView::mousePressEvent(event);
origin = event-&pos();
if (!rubberBand)
//QRubberBand为设置橡皮筋框
rubberBand = new QRubberBand(QRubberBand::Rectangle, viewport());
rubberBand-&setGeometry(QRect(origin, QSize()));
rubberBand-&show();
//鼠标移动时的处理
void PieView::mouseMoveEvent(QMouseEvent *event)
if (rubberBand)
rubberBand-&setGeometry(QRect(origin, event-&pos()).normalized());
QAbstractItemView::mouseMoveEvent(event);
//鼠标释放时的处理
void PieView::mouseReleaseEvent(QMouseEvent *event)
QAbstractItemView::mouseReleaseEvent(event);
if (rubberBand)
rubberBand-&hide();
viewport()-&update();
//光标移动时的处理
QModelIndex PieView::moveCursor(QAbstractItemView::CursorAction cursorAction,
Qt::KeyboardModifiers /*modifiers*/)
QModelIndex current = currentIndex();
switch (cursorAction) {
case MoveLeft:
case MoveUp://向左和向上处理效果一样
if (current.row() & 0)
current = model()-&index(current.row() - 1, current.column(),
rootIndex());
current = model()-&index(0, current.column(), rootIndex());
case MoveRight:
case MoveDown://向下和向右处理效果一样
if (current.row() & rows(current) - 1)
current = model()-&index(current.row() + 1, current.column(),
rootIndex());
current = model()-&index(rows(current) - 1, current.column(),
rootIndex());
viewport()-&update();
void PieView::paintEvent(QPaintEvent *event)
QItemSelectionModel *selections = selectionModel();//selectionModel()为返回当前的选择模型
QStyleOptionViewItem option = viewOptions();//返回一个带有填充视图的调试版,字体,对齐方式等熟悉的QStyleOptionViewItem结构
QBrush background = option.palette.base();//获得调色版的背景色
QPen foreground(option.palette.color(QPalette::WindowText));//定义一个用于前景色的画笔
QPainter painter(viewport());//设置绘图类
painter.setRenderHint(QPainter::Antialiasing);//设置渲染属性,这里设置为使用抗锯齿效果绘图
painter.fillRect(event-&rect(), background);//用背景色填充矩形
painter.setPen(foreground);//设置画笔的前景色
QRect pieRect = QRect(margin, margin, pieSize, pieSize);//该矩形用来画饼状图和饼状图旁边的图示的
//开始绘制饼图
if(validItems & 0)
painter.save();//保存绘图类
//translate()为将坐标系移动
//如果滑动条向右移,那么坐标系需向左移动
painter.translate(pieRect.x()-horizontalScrollBar()-&value(), pieRect.y()-verticalScrollBar()-&value());
painter.drawEllipse(0, 0, pieSize, pieSize);//在指定的矩形中画椭圆,两者的中心重合,椭圆长短轴和矩形的长宽对应起来
double startAngle = 0.0;
//model()为返回当前视图的model
for(row = 0; row & model()-&rowCount(rootIndex()); ++row)
//rootIndex()为model的根索引
QModelIndex index = model()-&index(row, 1, rootIndex());//销量索引,即后面单击销售数量那一列能用到
double value = model()-&data(index).toDouble();//通过索引获取销售量
if(value & 0)
double angle = 360*value/totalV
QModelIndex colorIndex = model()-&index(row, 0, rootIndex());//颜色栏索引号
QColor color = QColor(model()-&data(colorIndex, Qt::DecorationRole).toString());//获取表中的颜色
if(currentIndex() == index)//currentIndex为当前模型的item
painter.setBrush(QBrush(color, Qt::Dense4Pattern));//为画图类设置画刷,其中Qt::Dense4Pattern为画笔的样式
else if(selections-&isSelected(index))
painter.setBrush(QBrush(color, Qt::Dense3Pattern));//所选的行用另一种样式表示
painter.setBrush(QBrush(color));//其它的没选中的用它原来的颜色显示
painter.drawPie(0, 0, pieSize, pieSize, int(startAngle*16), int(angle*16));//绘制饼图
startAngle +=
painter.restore();//保存绘画设置
//绘制饼图旁边的图示
int keyNumber = 0;
for(row = 0; row & model()-&rowCount(rootIndex()); ++row)
QModelIndex index = model()-&index(row, 1, rootIndex());
double value = model()-&data(index).toDouble();//取出销售数量值
if(value & 0.0)
QModelIndex labelIndex = model()-&index(row, 0, rootIndex());//以第0列为索引
QStyleOptionViewItem option = viewOptions();
option.rect = visualRect(labelIndex);//返回虚拟的矩形,即被占住的矩形也能显示
if(selections-&isSelected(labelIndex))
option.state |= QStyle::State_S//用于指定该widget是否被选中
if(currentIndex() == labelIndex)
option.state |= QStyle::State_HasF//用于指定该widget是否有焦点
itemDelegate()-&paint(&painter, option, labelIndex);//itemDelegate()类为Qt中的代理类
keyNumber ++;
//改变几何形状
void PieView::resizeEvent(QResizeEvent * /* event */)
updateGeometries();
//返回父级index的行数
int PieView::rows(const QModelIndex &index) const
return model()-&rowCount(model()-&parent(index));
void PieView::rowsInserted(const QModelIndex &parent, int start, int end)
for (int row = row &= ++row) {
QModelIndex index = model()-&index(row, 1, rootIndex());
double value = model()-&data(index).toDouble();
if (value & 0.0) {
totalValue +=
validItems++;
QAbstractItemView::rowsInserted(parent, start, end);//调用父类的方法
void PieView::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
for (int row = row &= ++row) {
QModelIndex index = model()-&index(row, 1, rootIndex());
double value = model()-&data(index).toDouble();
if (value & 0.0) {
totalValue -=
validItems--;
QAbstractItemView::rowsAboutToBeRemoved(parent, start, end);//调用父类的方法
//滑动条移动
void PieView::scrollContentsBy(int dx, int dy)
viewport()-&scroll(dx, dy);
void PieView::scrollTo(const QModelIndex &index, ScrollHint)
QRect area = viewport()-&rect();
QRect rect = visualRect(index);
if (rect.left() & area.left())
horizontalScrollBar()-&setValue(
horizontalScrollBar()-&value() + rect.left() - area.left());
else if (rect.right() & area.right())
horizontalScrollBar()-&setValue(
horizontalScrollBar()-&value() + qMin(
rect.right() - area.right(), rect.left() - area.left()));
if (rect.top() & area.top())
verticalScrollBar()-&setValue(
verticalScrollBar()-&value() + rect.top() - area.top());
else if (rect.bottom() & area.bottom())
verticalScrollBar()-&setValue(
verticalScrollBar()-&value() + qMin(
rect.bottom() - area.bottom(), rect.top() - area.top()));
void PieView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags command)
QRect contentsRect = rect.translated(
horizontalScrollBar()-&value(),
verticalScrollBar()-&value()).normalized();
int rows = model()-&rowCount(rootIndex());
int columns = model()-&columnCount(rootIndex());
QModelIndexL
for (int row = 0; row & ++row) {
for (int column = 0; column & ++column) {
QModelIndex index = model()-&index(row, column, rootIndex());
QRegion region = itemRegion(index);
if (!region.intersect(contentsRect).isEmpty())
indexes.append(index);
if (indexes.size() & 0) {
int firstRow = indexes[0].row();
int lastRow = indexes[0].row();
int firstColumn = indexes[0].column();
int lastColumn = indexes[0].column();
for (int i = 1; i & indexes.size(); ++i) {
firstRow = qMin(firstRow, indexes[i].row());
lastRow = qMax(lastRow, indexes[i].row());
firstColumn = qMin(firstColumn, indexes[i].column());
lastColumn = qMax(lastColumn, indexes[i].column());
QItemSelection selection(
model()-&index(firstRow, firstColumn, rootIndex()),
model()-&index(lastRow, lastColumn, rootIndex()));
selectionModel()-&select(selection, command);
QModelIndex noI
QItemSelection selection(noIndex, noIndex);
selectionModel()-&select(selection, command);
void PieView::updateGeometries()
horizontalScrollBar()-&setPageStep(viewport()-&width());
horizontalScrollBar()-&setRange(0, qMax(0, 2*totalSize - viewport()-&width()));
verticalScrollBar()-&setPageStep(viewport()-&height());
verticalScrollBar()-&setRange(0, qMax(0, totalSize - viewport()-&height()));
int PieView::verticalOffset() const
return verticalScrollBar()-&value();
QRect PieView::visualRect(const QModelIndex &index) const
QRect rect = itemRect(index);
if (rect.isValid())
return QRect(rect.left() - horizontalScrollBar()-&value(),
rect.top() - verticalScrollBar()-&value(),
rect.width(), rect.height());
QRegion PieView::visualRegionForSelection(const QItemSelection &selection) const
int ranges = selection.count();
if (ranges == 0)
return QRect();
for (int i = 0; i & ++i) {
QItemSelectionRange range = selection.at(i);
for (int row = range.top(); row &= range.bottom(); ++row) {
for (int col = range.left(); col &= range.right(); ++col) {
QModelIndex index = model()-&index(row, col, rootIndex());
region += visualRect(index);
#include &QApplication&
#include &datamanager.h&
#include &connection.h&
#include &logindialog.h&
#include &QTextCodec&
int main(int argc, char *argv[])
QApplication a(argc, argv);
QTextCodec::setCodecForTr(QTextCodec::codecForLocale());
QTextCodec::setCodecForCStrings(QTextCodec::codecForLocale());
if(!createConnection() || !createXml())//可以直接调用头文件中的函数
DataM//两个界面类都要定义
//当在LoginDialog中运行QDialog::accept()函数时,会发送QDialog::Accepted信号,当接收到时,再调用DataManager界面
if (dlg.exec() == QDialog::Accepted)
return a.exec();
  实验总结:
  本次实验主要是学习在Qt中对数据库,xml文件的建立,查询,删除,查找等操作,并且与Qt界面设计,图像绘制自定义视图等功能综合起来,是一个很不错的Qt学习sample。
  参考资料:
  附录:
作者:tornadomeet 出处:/tornadomeet 欢迎转载或分享,但请务必声明文章出处。 (新浪微博:tornadomeet,欢迎交流!)
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:8332次
排名:千里之外
原创:13篇
转载:22篇
(1)(15)(17)(1)(24)(1)

我要回帖

更多关于 vs qt 新建窗口 的文章

 

随机推荐