python 处理数据并画图

各位读者,小编来为大家解答,python excel数据处理画图 python数据画好看的图,现在让我们一起来看看吧!

大家好,给大家分享一下python做界面比较好的gui,很多人还不知道这一点Python雨点特效:技术与艺术的交融之美。下面详细解释一下。现在让我们来看看!

一、项目说明:

本次通过实现一个小的功能模块对Python GUI进行实践学习。项目来源于软件制造工程的作业python编程代码看不懂怎么办。记录在这里以复习下思路和总结编码过程。所有的源代码和文件放在这里:

链接: 密码: 4a4r

内置四个文件,分别是, , ,

二、效果预览:

主界面

新增界面(更新界面一致)

功能很简单,就是做一张表的增删改查,借此简单的熟悉下python,前几天才看了看相关的语法。

三、环境说明:

数据库采用oracle12c,使用命令行进行操作。Python版本为3.6.2,命令行+Pycharm社区版2017.1.4。Python库使用了

cx_Oracle: 连接oracle数据库

tkinter: 简单入门的GUI库

cx_Oracle库的安装我直接使用IDE自带的包管理进行下载安装的,tkinter是Python3.2以后自带的标准库,后面会讲。

四、编码过程实现:

1、数据库表实现():

conn username/pass 根据本机的用户名和密码修改,后面的数据库连接统一都用我自己密码,不再赘述。

为了简化Python代码和实践sql能力,写了两个简单的存储过程,分别是插入和更新,成功创建后只需调用存储过程和传递参数列表即可。代码详情在中。

代码折叠:

1 conn c##bai/bai1232 --建表

3 create or replace tablegroupinfo (4 no varchar(12) not null,5 name varchar(20),6 headername varchar(20),7 tel varchar(15),8 constraint pk_groupinfo primary key(no));9

10 --创建过程,直接传入参数即可插入

11 create or replace procedureinsert_groupinfo12 (no %type,13 name %type,14 headername groupinfo.headername%type,15 tel %type16 )17 is

18 begin

19 insert into groupinfo values(no,name,headername,tel);20 commit;21 end;22

23 --创建过程,直接传入参数即可完成更新,第一个字段为原纪录no。必须有。

24 create or replace procedureupdate_groupinfo25 (oldno %type,26 no %type,27 name %type,28 headername groupinfo.headername%type,29 tel %type30 )31 is

32 n_no %type;33 n_name %type;34 n_headername groupinfo.headername%type;35 n_tel %type;36 grow groupinfo%rowtype;37 ex_oldnoisnull exception;38 begin

39 select * into grow from groupinfo g where g.no=oldno;40 if oldno is null or is null then

41 raise ex_oldnoisnull;42 end if;43 if no is null then

44 n_no:=oldno;45 else

46 n_no:=no;47 end if;48 if name is null then

49 ;50 else

51 n_name:=name;52 end if;53 if headername is null then

54 n_headername:=grow.headername;55 else

56 n_headername:=headername;57 end if;58 if tel is null then

59 ;60 else

61 n_tel:=tel;62 end if;63 --dbms_output.put_line(n_no||n_name||n_headername||n_tel);

64 update groupinfo g set g.no = n_no, g.name = n_name, g.headername = n_headername, g.tel = n_tel where g.no =oldno;65 commit;66 exception67 when ex_oldnoisnull then

68 dbms_output.out_line('选择的行不存在')69 end;

2、数据库操作类():

先贴源码,折叠起来:

1 #!/usr/bin/env python

2 #encoding: utf-8

3 """

4 :author: xiaoxiaobai5

6 :contact: 865816863@qq.com7

8 :file: 9

10 :time: 2017/10/3 12:0411

12 :@Software: PyCharm Community Edition13

14 :desc: 连接oracle数据库,并封装了增删改查全部操作。15

16 """

17 importcx_Oracle18

19

20 classOracleOpr:21

22 def __init__(self, username='c##bai', passname='bai123', ip='localhost', datebasename='orcl', ipport='1521'):23 """

24 :param username: 连接数据库的用户名25 :param passname: 连接数据库的密码26 :param ip: 数据库ip27 :param datebasename:数据库名28 :param ipport: 数据库端口29 :desc: 初始化函数用于完成数据库连接,可以通过self.connStatus判断是否连接成功,成功则参数为0,不成功则返回错误详情30 """

31 try:32 self.connStatus = '未连接' #连接状态

33 self.queryStatus = 0 #查询状态

34 self.updateStatus = 0 #更新状态

35 self.deleteStatus = 0 #删除状态

36 self.insertStatus = 0 #插入状态

37 self.__conn = ''

38 self.__conStr = username+'/'+passname+'@'+ip+':'+ipport+'/'+datebasename39 self.__conn = cx_Oracle.connect(self.__conStr)40 self.connStatus =041 exceptcx_Oracle.Error as e:42 self.connStatus =e43

44 defcloseconnection(self):45 try:46 if self.__conn:47 self.__conn.close()48 self.connStatus = '连接已断开'

49 exceptcx_Oracle.Error as e:50 self.connStatus =e51

52 def query(self, table='groupinfo', queryby=''):53 """

54 :param table: 查询表名55 :param queryby: 查询条件,支持完整where, order by, group by 字句56 :return:返回数据集,列名57 """

58 self.queryStatus =059 result = ''

60 cursor = ''

61 title = ''

62 try:63 sql = 'select * from'+table+' '+queryby64 print(sql)65 cursor = self.__conn.cursor()66 cursor.execute(sql)67 result =cursor.fetchall()68 title = [i[0] for i incursor.deion]69 cursor.close()70 cursor = ''

71 exceptcx_Oracle.Error as e:72 self.queryStatus =e73 finally:74 ifcursor:75 cursor.close()76 returnresult, title77

78 def insert(self, proc='insert_groupinfo', insertlist=[]):79 """

80 :param proc: 过程名81 :param insertlist: 参数集合,主键不能为空,参数必须与列对应,数量一致82 :desc: 此方法通过调用过程完成插入,需要在sql上完成存储过程,可以通过insertstatus的值判断是否成功83 """

84 self.insertStatus =085 cursor = ''

86 try:87 cursor = self.__conn.cursor()88 cursor.callproc(proc, insertlist)89 cursor.close()90 cursor = ''

91 exceptcx_Oracle.Error as e:92 self.insertStatus =e93 finally:94 ifcursor:95 cursor.close()96

97 def update(self, proc='update_groupinfo', updatelist=[]):98 """

99 :param proc: 存储过程名100 :param updatelist: 更新的集合,第一个为查询主键,后面的参数为对应的列,可以更新主键。101 :desc: 此方法通过调用存储过程完成更新操作,可以通过updatestatus的值判断是否成功102 """

103 self.updateStatus =0104 cursor = ''

105 try:106 cursor = self.__conn.cursor()107 cursor.callproc(proc, updatelist)108 cursor.close()109 cursor = ''

110 exceptcx_Oracle.Error as e:111 self.updateStatus =e112 finally:113 ifcursor:114 cursor.close()115

116 def delete(self, deleteby: '删除条件,where关键词后面的内容,即列名=列值(可多个组合)', table='groupinfo'):117 """

118 :param deleteby: 删除的条件,除where关键字以外的内容119 :param table: 要删除的表名120 :desc:可以通过deletestatus判断是否成功删除121 """

122 self.deleteStatus =0123 cursor = ''

124 try:125 sql = 'delete' + table + 'where' +deleteby126 cursor = self.__conn.cursor()127 cursor.execute(sql)128 cursor.close()129 cursor = ''

130 exceptcx_Oracle.Error as e:131 self.deleteStatus =e132 finally:133 ifcursor:134 cursor.close()

源码注释基本很清晰了,对关键点进行说明:数据库连接的数据全部用默认参数的形式给出了,可根据实际情况进行移植。关于调用存储过程,只需要使用connect(**).cursor.callproc(存储过程名, 参数列表)即可,方便高效。

3、GUI界面搭建(tkinter):

因为界面和逻辑我都写在中的,没有使用特别的设计模式。所以这一部分主要讲tkinter的用法,下一部分说明具体的实现。

关于安装:Python3.2后自带本库,若引用没有,很可能是安装的时候没有选。解决方案嘛找到安装文件修改安装

即可,如下图:

下一步打上勾即可,完成安装就能引用tkinter了。

使用教程简单介绍:

我这次用的时候就是在网上随便搜了一下教程,发现内容都很浅显,而且不系统,当然我也没法系统的讲清楚,但官方文档可以啊,提醒自己,以后一定先看官方文档!

4、逻辑实现():

先上代码,基本注释都有:

1 #!/usr/bin/env python

2 #encoding: utf-8

3 """

4 :author: xiaoxiaobai5

6 :contact: 865816863@qq.com7

8 :file: 9

10 :time: 2017/10/3 19:4211

12 :@Software: PyCharm Community Edition13

14 :desc: 该文件完成了主要窗体设计,和数据获取,呈现等操作。调用时,运行主类MainWindow即可15

16 """

17 importtkinter as tk18 from tkinter importttk19 from dataBaseOpr import *

20 importtkinter.messagebox21

22

23 classMainWindow():24 def __init__(self):25 super().__init__()26

27 #变量定义

28 =OracleOpr()29 =self.init_data()30 self.item_selection = ''

31 =[]32

33 #定义区域,把全局分为上中下三部分

34 self.frame_top = tk.Frame(width=600, height=90)35 self.frame_center = tk.Frame(width=600, height=180)36 self.frame_bottom = tk.Frame(width=600, height=90)37

38 #定义上部分区域

39 self.lb_tip = tk.Label(self.frame_top, text="评议小组名称")40 self.string =tk.StringVar()41 ('')42 self.ent_find_name = tk.Entry(self.frame_top, textvariable=self.string)43 self.btn_query = tk.Button(self.frame_top, text="查询", command=self.query)44 (row=0, column=0, padx=15, pady=30)45 (row=0, column=1, padx=45, pady=30)46 (row=0, column=2, padx=45, pady=30)47

48 #定义下部分区域

49 self.btn_delete = tk.Button(self.frame_bottom, text="删除", command=self.delete)50 self.btn_update = tk.Button(self.frame_bottom, text="修改", command=self.update)51 self.btn_add = tk.Button(self.frame_bottom, text="添加", )52 (row=0, column=0, padx=20, pady=30)53 (row=0, column=1, padx=120, pady=30)54 (row=0, column=2, padx=30, pady=30)55

56 #定义中心列表区域

57 = ttk.Treeview(self.frame_center, show="headings", height=8, columns=("a", "b", "c", "d"))58 = ttk.Scrollbar(self.frame_center, orient=tk.VERTICAL, .yview)59 #定义树形结构与滚动条

60 .configure()61 #表格的标题

62 .column("a", width=80, anchor="center")63 .column("b", width=120, anchor="center")64 .column("c", width=120, anchor="center")65 .column("d", width=120, anchor="center")66 .heading("a", text="小组编号")67 .heading("b", text="小组名称")68 .heading("c", text="负责人")69 .heading("d", text="联系方式")70 #调用方法获取表格内容插入及树基本属性设置

71 ["selectmode"] = "browse"

72 self.get_tree()73 (row=0, column=0, , ipadx=10)74 (row=0, column=1, )75

76 #定义整体区域

77 (row=0, column=0, padx=60)78 (row=1, column=0, padx=60, ipady=1)79 (row=2, column=0, padx=60)80 _propagate(0)81 _propagate(0)82 _propagate(0)83

84 #窗体设置

85 self.center_window(600, 360)86 self.title('评议小组管理')87 self.resizable(False, False)88 self.mainloop()89

90 #窗体居中

91 defcenter_window(self, width, height):92 screenwidth =self.winfo_screenwidth()93 screenheight =self.winfo_screenheight()94 #宽高及宽高的初始点坐标

95 size = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2)96 self.geometry(size)97

98 #数据初始化获取

99 definit_data(self):100 result, _ .query()101 .queryStatus:102 return0103 else:104 returnresult105

106 #表格内容插入

107 defget_tree(self):108 if ==0:109 tkinter.messagebox.showinfo("错误提示", "数据获取失败")110 else:111 #删除原节点

112 for _ in map(.delete, .get_children("")):113 pass

114 #更新插入新节点

115 for i inrange(len()):116 group [i]117 .insert("", "end", values=(group[0],118 group[1],119 group[2],120 group[3]), text=group[0])121 #TODO 此处需解决因主程序自动刷新引起的列表项选中后重置的情况,我采用的折中方法是:把选中时的数据保存下来,作为记录

122

123 #绑定列表项单击事件

124 ("", _item_click)125 .after(500, self.get_tree)126

127 #单击查询按钮触发的事件方法

128 defquery(self):129 query_info ()130 ('')131 #print(query_info)

132 if query_info is None or query_info == '':133 tkinter.messagebox.showinfo("警告", "查询条件不能为空!")134 self.get_tree()135 else:136 result, _ = .query(queryby="where name like '%" + query_info + "%'")137 self.get_tree()138 .queryStatus:139 tkinter.messagebox.showinfo("警告", "查询出错,请检查数据库服务是否正常")140 elif notresult:141 tkinter.messagebox.showinfo("查询结果", "该查询条件没有匹配项!")142 else:143 =result144 #TODO 此处需要解决弹框后代码列表刷新无法执行的问题

145

146 #单击删除按钮触发的事件方法

147 defdelete(self):148 if self.item_selection is None or self.item_selection == '':149 tkinter.messagebox.showinfo("删除警告", "未选中待删除值")150 else:151 #TODO: 删除提示

152 .delete(deleteby="no = '"+self.item_selection+"'")153 .deleteStatus:154 tkinter.messagebox.showinfo("删除警告", "删除异常,可能是数据库服务意外关闭了。。。")155 else:156 =self.init_data()157 self.get_tree()158

159 #为解决窗体自动刷新的问题,记录下单击项的内容

160 deftree_item_click(self, event):161 try:162 selection .selection()[0]163 = (selection, "values")164 self.item_selection [0]165 exceptIndexError:166 tkinter.messagebox.showinfo("单击警告", "单击结果范围异常,请重新选择!")167

168 #单击更新按钮触发的事件方法

169 defupdate(self):170 if self.item_selection is None or self.item_selection == '':171 tkinter.messagebox.showinfo("更新警告", "未选中待更新项")172 else:173 data =[self.item_selection]174 = self.set_info(2)175 if is None or :176 return

177 #更改参数

178 data = data +179 .update(updatelist=data)180 .insertStatus:181 tkinter.messagebox.showinfo("更新小组信息警告", "数据异常库连接异常,可能是服务关闭啦~")182 #更新界面,刷新数据

183 =self.init_data()184 self.get_tree()185

186 #单击新增按钮触发的事件方法

187 defadd(self):188 #接收弹窗的数据

189 = self.set_info(1)190 if is None or :191 return

192 #更改参数

193 .insert()194 .insertStatus:195 tkinter.messagebox.showinfo("新增小组信息警告", "数据异常库连接异常,可能是服务关闭啦~")196 #更新界面,刷新数据

197 =self.init_data()198 self.get_tree()199

200 #此方法调用弹窗传递参数,并返回弹窗的结果

201 defset_info(self, dia_type):202 """

203 :param dia_type:表示打开的是新增窗口还是更新窗口,新增则参数为1,其余参数为更新204 :return: 返回用户填写的数据内容,出现异常则为None205 """

206 dialog = MyDialog(, dia_type=dia_type)207 #self.withdraw()

208 self.wait_window(dialog) #这一句很重要!!!

209 returndialog.group_info210

211

212 #新增窗口或者更新窗口

213 classMyDialog(tk.Toplevel):214 def __init__(self, data, dia_type):215 super().__init__()216

217 #窗口初始化设置,设置大小,置顶等

218 self.center_window(600, 360)219 self.wm_attributes("-topmost", 1)220 self.resizable(False, False)221 self.protocol("WM_DELETE_WINDOW", self.donothing) #此语句用于捕获关闭窗口事件,用一个空方法禁止其窗口关闭。

222

223 #根据参数类别进行初始化

224 if dia_type == 1:225 self.title('新增小组信息')226 else:227 self.title('更新小组信息')228

229 #数据变量定义

230 =tk.StringVar()231 =tk.StringVar()232 self.pname =tk.StringVar()233 =tk.StringVar()234 if not data or dia_type == 1:235 ('')236 ('')237 ('')238 ('')239 else:240 (data[0])241 (data[1])242 (data[2])243 (data[3])244

245 #错误提示定义

246 self.text_error_no =tk.StringVar()247 self.text_error_name =tk.StringVar()248 self.text_error_pname =tk.StringVar()249 self.text_error_pnum =tk.StringVar()250 self.error_null = '该项内容不能为空!'

251 self.error_exsit = '该小组编号已存在!'

252

253 self.group_info =[]254 #弹窗界面布局

255 self.setup_ui()256

257 #窗体布局设置

258 defsetup_ui(self):259 #第一行(两列)

260 row1 =tk.Frame(self)261 (row=0, column=0, padx=160, pady=20)262 tk.Label(row1, text='小组编号:', width=8).pack()263 tk.Entry(row1, , width=20).pack()264 tk.Label(row1, textvariable=self.text_error_no, width=20, fg='red').pack()265 #第二行

266 row2 =tk.Frame(self)267 (row=1, column=0, padx=160, pady=20)268 tk.Label(row2, text='小组名称:', width=8).pack()269 tk.Entry(row2, , width=20).pack()270 tk.Label(row2, textvariable=self.text_error_name, width=20, fg='red').pack()271 #第三行

272 row3 =tk.Frame(self)273 (row=2, column=0, padx=160, pady=20)274 tk.Label(row3, text='负责人姓名:', width=10).pack()275 tk.Entry(row3, textvariable=self.pname, width=18).pack()276 tk.Label(row3, textvariable=self.text_error_pname, width=20, fg='red').pack()277 #第四行

278 row4 =tk.Frame(self)279 (row=3, column=0, padx=160, pady=20)280 tk.Label(row4, text='手机号码:', width=8).pack()281 tk.Entry(row4, , width=20).pack()282 tk.Label(row4, textvariable=self.text_error_pnum, width=20, fg='red').pack()283 #第五行

284 row5 =tk.Frame(self)285 (row=4, column=0, padx=160, pady=20)286 tk.Button(row5, text="取消", command=self.cancel).grid(row=0, column=0, padx=60)287 tk.Button(row5, text="确定", ).grid(row=0, column=1, padx=60)288

289 defcenter_window(self, width, height):290 screenwidth =self.winfo_screenwidth()291 screenheight =self.winfo_screenheight()292 size = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2)293 self.geometry(size)294

295 #点击确认按钮绑定事件方法

296 defok(self):297

298 self.group_info = [(), (), (), ()] #设置数据

299 if self.check_info() == 1: #进行数据校验,失败则不关闭窗口

300 return

301 self.destroy() #销毁窗口

302

303 #点击取消按钮绑定事件方法

304 defcancel(self):305 self.group_info = None #空!

306 self.destroy()307

308 #数据校验和用户友好性提示,校验失败返回1,成功返回0

309 defcheck_info(self):310 is_null =0311 str_tmp =self.group_info312 if str_tmp[0] == '':313 (self.error_null)314 is_null = 1

315 if str_tmp[1] == '':316 (self.error_null)317 is_null = 1

318 if str_tmp[2] == '':319 (self.error_null)320 is_null = 1

321 if str_tmp[3] == '':322 (self.error_null)323 is_null = 1

324

325 if is_null == 1:326 return 1

327 res, _ = OracleOpr().query(queryby="where no = '"+str_tmp[0]+"'")328 print(res)329 ifres:330 (self.error_exsit)331 return 1

332 return0333

334 #空函数

335 defdonothing(self):336 pass

可以看的出,窗体类继承自()可以直接通过self.x对主窗体添加控件和修改属性。然后在初始化函数中需要声明需要的成员变量,完成整体布局以及控件的事件绑定,以及数据初始化,最后self.mainloop()使窗体完成自动刷新。我们所有的逻辑处理都是在事件绑定方法中完成的,这样感觉就像是针对用户的每一个操作做出对应的逻辑处理和反应,同时需要考虑可能出现的异常以及所有的可能性,达到用户友好的设计要求。

运行此实例,可以使用test,py中的测试方法,也可以把和两个类放在同一个文件夹,在本机安装好上述两个库和完成数据库创建的情况下,直接在py解释器下导入文件下所有的包,MainWindow()即可。


原文地址1:https://blog.csdn.net/ai_lover_cat/article/details/136147206
参考资料:python中用turtle画一个圆形 https://blog.csdn.net/SXIAOYAN_/article/details/140061099

  • 16
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值