用PySimpleGui做户籍资料查询工具

前言

最近手里有一张几千人的户籍信息表格,突发奇想,想用python做一个小工具,可以按照人名搜索,获取该人所在户的所有人信息,然后显示图片,个人详情页,方便查询
以前用tkinter做过一个从xls表格获取行信息填入doc,并批量打印的小工具,tkinter是比较好用,可是想做好看真心不容易,搜索之下发现了PySimpleGui,这个更加简单
学习python属于个人兴趣,没有接受系统学习,风格也是野路子,写下这篇心得纯粹是记录学习内容,毕竟功能实现都是自己一点点想的,没有参考别人的案例。同为初学者的可以看看,抛砖引玉。大神也请赐教。

逻辑部分

数据源

我手里有一份整村的村民户籍表,不是很完整,错误也比较多,没有身份证号,所以没有泄密嫌疑。表格是xls的,为了更好操作,先手动转成csv格式,当数据库用了。表格内容较多,我们主要用到的是姓名、性别、户主关系、电话号码,几项

需求分析

我想要实现的一个主要功能是,输入一个人名,在数据表中搜索到所有这个名字的人(当然有重名的),然后根据他的户主关系,找到他整户的人,并打印出来。这样有几个技术问题需要解决。。。(我本人纯属爱好,没有接触过算法,都是用最笨的方法解决)

思路及方法

获取csv所有行的内容

这是csv基础操作了,上代码

def open_csv():with open('sunzhuang.csv', 'r') as csvfile:reader = csv.DictReader(csvfile)return reader

根据每行里“户主关系”内容,找到一共有多少户主,并将所有户主的序号记录

这个就是突发奇想了,我找到所有的户主,并把它们的序号单独存一个list,这样确定了被搜索的人的序号,就可以通过序号,确定他在哪两位“户主”之间,从而找到所有的家庭成员。ok,上代码

# 获取所有属性是户主的村民序号 存到huzhu_list列表并返回
def get_huzhu_list():with open('sunzhuang.csv', 'r') as csvfile:reader = csv.DictReader(csvfile)for row in reader:if row['与户主关系'] == '户主':# print(row)huzhu_list.append(row['序号'])return huzhu_list

找到被搜索人在csv中的序号

# 根据姓名 获取她的序号
# 考虑到会有重名的情况,所以用一个列表name_id保存了所有了该名字的序号
def get_name_id(name):name_id = []with open('sunzhuang.csv', 'r') as csvfile:reader = csv.DictReader(csvfile)for row in reader:if row['姓名'] == name:name_id.append(row['序号'])# print('序号是:' + name_id)return name_id

接下来,就是找到被搜索人全家了

# 这是核心了,通过用户序号 找到该户的户主和下一户的户主序号,从而计算出该户所有人的序号
def get_hole_family_id(huzhu_list, name_id):first = 0last = 0for i in huzhu_list:# 首先,huzhu_list里边是所有户主的id# 如果搜索的人就是户主,那么他的id就是该户的第一个人,# 先用huzhu_list.index(i)找到他在户主列表里的位置,+1 找到下一个户主的id# 然后在通过这个位置,找到下一个户主的id 说起来有点绕# 这里只是定位到下一个户主的位置,而不用-1 因为下边用到的# range(first,last)函数构建列表时正好是 first到last-1if int(i) == int(name_id):first = int(i)last = int(huzhu_list[huzhu_list.index(i) + 1])break# 如果要搜索的人不是户主,那么先找他的下一个户主的位置,再通过-1找到本户主的位置elif int(i) > int(name_id):last = int(huzhu_list[huzhu_list.index(i)])first = int(huzhu_list[huzhu_list.index(i) - 1])breakfamily_id_list = [i for i in range(first, last)]return family_id_list

这样,我们得到了被搜索人全家的人员序号

再用两个方法,根据序号,获取csv文件里的整行信息

# 根据序号 定位到csv文件中的行
def get_content(name_id):with open('sunzhuang.csv', 'r') as csvfile:reader = csv.DictReader(csvfile)for row in reader:if row['序号'] == name_id:print(row)
# 通过全家人的序号,获取全家人的信息,并全部添加到列表all_familly_list中
def get_hole_family_cont(family_id_list):all_familly_list = []with open('sunzhuang.csv', 'r') as csvfile:reader = csv.DictReader(csvfile)for row in reader:for id in family_id_list:if row['序号'] == str(id):# row 是一个字典格式,需要用dict.values()将键值转化为列表list3 = list(row.values())# 从列表中找出我们需要的信息,从新创建一个列表,就得到了该人的信息family_list = [list3[3], list3[4], list3[7], list3[6]]all_familly_list.append(family_list)return all_familly_list

至此,通过一个人名,我们得到了他家所有人的信息,并全部装入一个列表里。下面就是做一个页面,把他们显示出来

界面部分

PySimpleGui介绍

网上介绍很多,我摘抄了一点过来,实现很简单,布局采用layout行式布局,很直观
1.import 库
2.layout UI布局
3.window 窗口显示
4.Event loop 事件循环,用户持续交互
5.close 关闭窗口

# 1 - The import
import PySimpleGUI as sg
# 2 - Layout definition
layout = [[sg.Text('My layout')],[sg.Input(key='-INPUT-')],[sg.Button('OK'), sg.Button('Cancel')] ]
# 3 - Create window
window = sg.Window('Design Pattern 3 - Persistent Window', layout)
# 4 - Event Loop
while True:event, values = window.read()if event in (None, 'Cancel'):break# 5 - Close window
window.close()

效果是

基本很容易实现我想要的,其他不再累述,需要的可以去csdn找,很多很多

界面布局

通过修改一个案例,一番折腾,得到了我想要的布局如下


代码如下:

import PySimpleGUI as sg
from PySimpleGUI import InputCombo, Combo, Multiline, ML, MLine, Checkbox, CB, Check, Button, B, Btn, ButtonMenu, \Canvas, Column, Col, Combo, Frame, Graph, Image, InputText, Input, In, Listbox, LBox, Menu, Multiline, ML, MLine, \OptionMenu, Output, Pane, ProgressBar, Radio, Slider, Spin, StatusBar, Tab, TabGroup, Table, Text, Txt, T, Tree, \TreeData, VerticalSeparator, Window, Sizersg.theme('GreenTan')
list = [['    ','  ','户主','      ']]col3 = Column([[Frame('Information:', [[Text(), Column([[Text('户      数:  ')],[Text('人      数:  ')],[Text('低保人数:  ')],[Text('五保人数:  ')],],size=(210, 120), pad=(0, 0))]])]], pad=(0, 0))col2 = Column([[Frame('Accounts:', [[Column([[Table(values=list,headings=['  姓  名  ',' 性  别 ',' 属  性 ','   电     话   '],max_col_width=300,auto_size_columns=True,#自动调整列宽(根据上面第一次的values默认值为准,update时不会调整)display_row_numbers=True,#序号justification='center',#字符排列 left right centernum_rows=12,#行数row_height=30,#行高key='_table_',font=('微软雅黑', 12),text_color='black',background_color='white',enable_events=True,bind_return_key=True,tooltip='This is a table')], ], size=(450, 400),pad=(0, 0))]])]],pad=(0, 0))col1 = Column([# Information frame[Frame('Search:', [[Text(), Column([[Text('输入姓名:')],[Input(key='-USERID-IN-', size=(16, 1)),Button('Search', key='-SEAR-')],], size=(195, 120), pad=(0, 0))]])], ], pad=(0, 0))layout = [[col1,col3], [col2]]window = Window('人员信息查询', layout)while True:event, values = window.read()print(event, values)if event == sg.WIN_CLOSED:breakelif event == '-SEAR-':#print(values['-LIST-'][0])sg.popup('This is {}'.format(values['_table_'][0]))window.close()

现在逻辑部分和界面都有了,把他们融合

这一点颇费脑筋,无奈基础太差,暂时不用面向对象了
基本方法是通过按钮事件的触发,调用逻辑代码,实现功能,并通过更新窗口,使结果显示出来

小技巧

不算技巧吧,是PySimpleGui一个比较方便的地方,每个窗口组件都有一个key属性和一个value属性(text没有),key是组件的名字,value是他要显示的内容,通过window[‘key’],可以定位该组件,通过window[‘key’].update(‘value’),可以直接将value更新到组件的value属性

最终界面

完整代码


import csv
import PySimpleGUI as sg
from PySimpleGUI import InputCombo, Combo, Multiline, ML, MLine, Checkbox, CB, Check, Button, B, Btn, ButtonMenu, \Canvas, Column, Col, Combo, Frame, Graph, Image, InputText, Input, In, Listbox, LBox, Menu, Multiline, ML, MLine, \OptionMenu, Output, Pane, ProgressBar, Radio, Slider, Spin, StatusBar, Tab, TabGroup, Table, Text, Txt, T, Tree, \TreeData, VerticalSeparator, Window, Sizernum = 0
# 搜索所有的户主 并将他们的序号填入列表 用来调取整户信息
huzhu_list = []# 通过DictReader方法打开csv文件,可以做到搜索功能
def open_csv():with open('sunzhuang.csv', 'r') as csvfile:reader = csv.DictReader(csvfile)return reader# 获得总户数
def get_familly_num():familly_num = 0with open('sunzhuang.csv', 'r') as csvfile:reader = csv.DictReader(csvfile)for row in reader:if row['与户主关系'] == '户主':familly_num += 1# print(row)return familly_num# 获得总人数
def get_people_num():people_num = 0with open('sunzhuang.csv', 'r') as csvfile:reader = csv.DictReader(csvfile)for row in reader:people_num += 1# print(row)return people_num# 获取所有属性是户主的村民序号 存到huzhu_list列表并返回
def get_huzhu_list():with open('sunzhuang.csv', 'r') as csvfile:reader = csv.DictReader(csvfile)for row in reader:if row['与户主关系'] == '户主':# print(row)huzhu_list.append(row['序号'])return huzhu_list# 根据姓名 获取她的序号
# 考虑到会有重名的情况,所以用一个列表name_id保存了所有了该名字的序号
def get_name_id(name):name_id = []with open('sunzhuang.csv', 'r') as csvfile:reader = csv.DictReader(csvfile)for row in reader:if row['姓名'] == name:name_id.append(row['序号'])# print('序号是:' + name_id)return name_id# 根据序号 定位到csv文件中的行
def get_content(name_id):with open('sunzhuang.csv', 'r') as csvfile:reader = csv.DictReader(csvfile)for row in reader:if row['序号'] == name_id:print(row)# 这是核心了,通过用户序号 找到该户的户主和下一户的户主序号,从而计算出该户所有人的序号
def get_hole_family_id(huzhu_list, name_id):first = 0last = 0for i in huzhu_list:# 首先,huzhu_list里边是所有户主的id# 如果搜索的人就是户主,那么他的id就是该户的第一个人,# 先用huzhu_list.index(i)找到他在户主列表里的位置,+1 找到下一个户主的id# 然后在通过这个位置,找到下一个户主的id 说起来有点绕# 这里只是定位到下一个户主的位置,而不用-1 因为下边用到的# range(first,last)函数构建列表时正好是 first到last-1if int(i) == int(name_id):first = int(i)last = int(huzhu_list[huzhu_list.index(i) + 1])break# 如果要搜索的人不是户主,那么先找他的下一个户主的位置,再通过-1找到本户主的位置elif int(i) > int(name_id):last = int(huzhu_list[huzhu_list.index(i)])first = int(huzhu_list[huzhu_list.index(i) - 1])breakfamily_id_list = [i for i in range(first, last)]return family_id_list# 通过全家人的序号,获取全家人的信息,并全部添加到列表all_familly_list中
def get_hole_family_cont(family_id_list):all_familly_list = []with open('sunzhuang.csv', 'r') as csvfile:reader = csv.DictReader(csvfile)for row in reader:for id in family_id_list:if row['序号'] == str(id):# row 是一个字典格式,需要用dict.values()将键值转化为列表list3 = list(row.values())# 从列表中找出我们需要的信息,从新创建一个列表,就得到了该人的信息family_list = [list3[3], list3[4], list3[7], list3[6]]all_familly_list.append(family_list)return all_familly_list# print(first)# print(huzhu_list)sg.theme('GreenTan')col3 = Column([[Frame('Information:', [[Text(), Column([[Text('户      数:  '), Input(key='-hushu-', size=(10, 1))],[Text('人      数:  '), Input(key='-renshu-', size=(10, 1))],[Text('低保人数:  '), Input(key='-dibao-', size=(10, 1))],[Text('五保人数:  '), Input(key='-wubao-', size=(10, 1))], ],size=(210, 120), pad=(0, 0))]])]], pad=(0, 0))col2 = Column([[Frame('Accounts:', [[Column([[Table(values=[['', '', '', '']],headings=['  姓  名  ', ' 性  别 ', ' 属  性 ', '     身 份 证 号     '],max_col_width=300,auto_size_columns=True,  # 自动调整列宽(根据上面第一次的values默认值为准,update时不会调整)display_row_numbers=True,  # 序号justification='center',  # 字符排列 left right centernum_rows=12,  # 行数row_height=30,  # 行高key='_table_',font=('微软雅黑', 12),text_color='black',background_color='white',enable_events=True,bind_return_key=True,tooltip='This is a table')], ], size=(450, 400), pad=(0, 0))]])]], pad=(0, 0))col1 = Column([# Information frame[Frame('Search:', [[Text(), Column([[Text('输入姓名:')],[Input(key='-USERID-IN-', size=(15, 1)),Button('Search', key='-SEAR-')],], size=(195, 120), pad=(0, 0))]])], ], pad=(0, 0))layout = [[col1, col3], [col2]]window = Window('人员信息查询', layout)while True:event, values = window.read()print(event, values)familly_num = get_familly_num()people_num = get_people_num()window['-hushu-'].update(familly_num)window['-renshu-'].update(people_num)if event == sg.WIN_CLOSED:breakelif event == '-SEAR-':# print(values['-LIST-']])if values['-USERID-IN-'] != '':name = values['-USERID-IN-']else:sg.popup('输入一个人名,比如:张三')name = '张三'id_list = get_name_id(name)list1 = get_huzhu_list()all_list = []num = 0for id in id_list:family_id_list = get_hole_family_id(list1, id)familly_list = get_hole_family_cont(family_id_list)num += 1for i in familly_list:all_list.append(i)window['_table_'].Update(all_list)sg.popup('一共找到{}户'.format(num))window.close()

总结

写这个小东西,从构思,查资料,写代码,查bug,用了一整天的时间,对我一个小白爱好者来说还是挺有成就感的。后续将会继续添加照片显示,家庭成员详细信息页面,和添加、删除、修改功能,实现了再分享。

用PySimpleGui做户籍资料查询工具相关推荐

  1. 自助查询工具需求分析

    平时工作临时需求查询比较多,领导让做一个自助查询工具,这样可以给工程师省下很可观的时间,也减少了各部门扯皮的碰撞. 客户端 php + mysql server1 服务器端 shell,python, ...

  2. 12小时上线“新冠肺炎同程查询工具”,开发者这样狙击疫情

    阿里妹导读:2020开年极为复杂.面对新型肺炎的疫情,我们每一个人都与国家命运紧密相连.全社会的力量都凝聚在一起,众志成城,共克时艰.有这么一群热爱代码的人,用自己的方式提升效率,保卫家园. &quo ...

  3. 安卓 spinner下拉框 做模糊查询_SEO数据查询工具

    SEO数据查询工具是SEO工作中使用最频繁的工作,最常用的是站长之家(http://tool.chinaz.com/)以及爱站(http://www.aizhan.com/)的查询.这里主要介绍站长之 ...

  4. 网站排名查询软件alexa_想要SEO优化做得好,网站排名查询工具少不了

    在如今这个互联网时代,很多企业都在做网站,尤其是那些有业务和产品销售的网站,能够在搜索引擎上排名靠前,是最希望看到的事,而这就需要用到SEO优化这份工作了. 当然,做SEO优化并不是那么容易的事,不仅 ...

  5. Python制作吃鸡各数据资料查询助手,带你做理论王者~

    前言 大家早好.午好.晚好吖 ❤ ~ 吃鸡想必大家都玩过了 今天来教大家制作一个资料查询助手 1.我们是不是要去获取这些数据 武器配件 首先:对于 武器一个详情页url地址发送请求, 获取 每个武器的 ...

  6. 资料管理工具VSGoogle?

    最近看到自己从工作到现在收集的各种工具.文档.编码等好生烦恼呀!这些可都是我的积累.财富,但是我总感觉没有好好利用,真是浪费中浪费.为此,我思索着是不是做个资料管理器呢?原始的文档可以通过目录来划分, ...

  7. JavaEE全套资料+视频+工具

    JavaEE全套资料+视频+工具[点击链接原文] Java学习路线图引言: 一.Java学习路线图-流程篇: 二.Java学习路线图-视频篇: 1.第一阶段-Java基础入门 Java视频篇第一阶段- ...

  8. 站长SEO常用查询工具

    一.网站管理员工具 网站管理员工具需要对网站域名所有权进行验证,通常是通过上传指定文件.增加META或者修改网站DNS来验证管理员身份,通过验证后,网站管理员可以查询到自己网站的各类统计信息. 1.  ...

  9. 如何开发一个简单的智能对话查询工具

    我们经常在电影中看到机器和人对答如流,随着越来越多自然语言开放平台的出现, IT 爱好者制作一个自己的 APP 或者小玩具等逐渐可以变为现实.自然语言对话即你的 APP 或者你制作的工具.机器人等能够 ...

  10. 基于 Python 的 tkinter 模块制作的名人名言查询工具

    简介:本文主要介绍如何用 Python 内置的 tkinter 写一个查询工具. 很多人学习python,不知道从何学起. 很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手. 很多 ...

最新文章

  1. FPGA的设计艺术(5)STA实战之时钟偏斜对建立保持时间的影响以及时序报告分析
  2. windows7 ORA-12514 TNS 监听程序当前无法识别连接描述符中请求服务 的解决方法
  3. 强化学习(十四) Actor-Critic
  4. SpringIOCAOP
  5. maven项目打包插件:将maven项目打包成一个可执行的jar(瘦jar)
  6. Linux内核中container_of宏的理解
  7. Spring EL中的类操作符
  8. Linux下 <用户名> 不在 sudoers 文件中。此事将被报告。
  9. Java6开发WebService进阶
  10. Java word转pdf方法
  11. java ajax是什么东东_Ajax是什么意思,它是在做什么用的?
  12. 能够在乱世中_乱世中
  13. yigo 第一阶段 异常处理 解决方案
  14. 揭秘:古代五大美男的悲惨结局
  15. 报错:实体名称必须紧跟在 '' 后面
  16. iPhone SE 3将定档3月8日:外观照旧 价格或成新惊喜
  17. 与i7性能相当的服务器cpu,i7 8550 U相当于七代什么水平?i7 8550 U性能评测分析
  18. jstree的简单使用例子
  19. matlab体素化,教程|如何使用Matlab制造GrabCAD体素打印切片
  20. jquery选择器连续选择_jQuery选择器简介

热门文章

  1. camera内存优化
  2. 教育问题案例研究(张奎明)
  3. 【高通】【QPST】QCN导入
  4. 126邮箱国外服务器,网易邮箱海外服务器大升级
  5. (原创)如何将Nios II硬件和软件合成一个文件(NIOS II)(硬件)(软件)(合并)...
  6. 哪个软件可以玩java游戏_安卓java模拟器?安卓手机如何玩JAVA游戏以及JAVA软件的方法...
  7. CM311-1a_YST代工_安卓9_S905L3A_没无线版Emotn UI桌面线刷固件包
  8. 2个方式快速解决:Word背景图片怎么设置
  9. Epicor 完成和关闭工单
  10. C/C++遍历文件夹指定文件