python GUI实战项目——tkinter库的简单实例
一、项目说明:
本次通过实现一个小的功能模块对Python GUI进行实践学习。项目来源于软件制造工程的作业。记录在这里以复习下思路和总结编码过程。所有的源代码和文件放在这里:
链接: https://pan.baidu.com/s/1qXGVRB2 密码: 4a4r
内置四个文件,分别是ora.sql, dataBaseOpr.py, guiPy.py, test.py
二、效果预览:
主界面
新增界面(更新界面一致)
功能很简单,就是做一张表的增删改查,借此简单的熟悉下python,前几天才看了看相关的语法。
三、环境说明:
数据库采用oracle12c,使用命令行进行操作。Python版本为3.6.2,命令行+Pycharm社区版2017.1.4。Python库使用了
cx_Oracle: 连接oracle数据库
tkinter: 简单入门的GUI库
cx_Oracle库的安装我直接使用IDE自带的包管理进行下载安装的,tkinter是Python3.2以后自带的标准库,后面会讲。
四、编码过程实现:
1、数据库表实现(ora.sql):
conn username/pass 根据本机的用户名和密码修改,后面的数据库连接统一都用我自己密码,不再赘述。
为了简化Python代码和实践sql能力,写了两个简单的存储过程,分别是插入和更新,成功创建后只需调用存储过程和传递参数列表即可。代码详情在ora.sql中。
代码折叠:
- conn c##bai/bai123
- --建表
- create or replace table groupinfo (
- no varchar(12) not null,
- name varchar(20),
- headername varchar(20),
- tel varchar(15),
- constraint pk_groupinfo primary key(no));
- --创建过程,直接传入参数即可插入
- create or replace procedure insert_groupinfo
- (no groupinfo.no%type,
- name groupinfo.name%type,
- headername groupinfo.headername%type,
- tel groupinfo.tel%type
- )
- is
- begin
- insert into groupinfo values(no,name,headername,tel);
- commit;
- end;
- --创建过程,直接传入参数即可完成更新,第一个字段为原纪录no。必须有。
- create or replace procedure update_groupinfo
- (oldno groupinfo.no%type,
- no groupinfo.no%type,
- name groupinfo.name%type,
- headername groupinfo.headername%type,
- tel groupinfo.tel%type
- )
- is
- n_no groupinfo.no%type;
- n_name groupinfo.name%type;
- n_headername groupinfo.headername%type;
- n_tel groupinfo.tel%type;
- grow groupinfo%rowtype;
- ex_oldnoisnull exception;
- begin
- select * into grow from groupinfo g where g.no=oldno;
- if oldno is null or grow.no is null then
- raise ex_oldnoisnull;
- end if;
- if no is null then
- n_no:= oldno;
- else
- n_no:= no;
- end if;
- if name is null then
- n_name:= grow.name;
- else
- n_name:= name;
- end if;
- if headername is null then
- n_headername:= grow.headername;
- else
- n_headername:= headername;
- end if;
- if tel is null then
- n_tel:= grow.tel;
- else
- n_tel:= tel;
- end if;
- --dbms_output.put_line(n_no||n_name||n_headername||n_tel);
- update groupinfo g set g.no = n_no, g.name = n_name, g.headername = n_headername, g.tel = n_tel where g.no = oldno;
- commit;
- exception
- when ex_oldnoisnull then
- dbms_output.out_line('选择的行不存在')
- end;
ora.sql
2、数据库操作类(dataBaseOpr.py):
先贴源码,折叠起来:
- #!/usr/bin/env python
- # encoding: utf-8
- """
- :author: xiaoxiaobai
- :contact: 865816863@qq.com
- :file: dataBaseOpr.py
- :time: 2017/10/3 12:04
- :@Software: PyCharm Community Edition
- :desc: 连接oracle数据库,并封装了增删改查全部操作。
- """
- import cx_Oracle
- class OracleOpr:
- def __init__(self, username='c##bai', passname='bai123', ip='localhost', datebasename='orcl', ipport=''):
- """
- :param username: 连接数据库的用户名
- :param passname: 连接数据库的密码
- :param ip: 数据库ip
- :param datebasename:数据库名
- :param ipport: 数据库端口
- :desc: 初始化函数用于完成数据库连接,可以通过self.connStatus判断是否连接成功,成功则参数为0,不成功则返回错误详情
- """
- try:
- self.connStatus = '未连接' # 连接状态
- self.queryStatus = 0 # 查询状态
- self.updateStatus = 0 # 更新状态
- self.deleteStatus = 0 # 删除状态
- self.insertStatus = 0 # 插入状态
- self.__conn = ''
- self.__conStr = username+'/'+passname+'@'+ip+':'+ipport+'/'+datebasename
- self.__conn = cx_Oracle.connect(self.__conStr)
- self.connStatus = 0
- except cx_Oracle.Error as e:
- self.connStatus = e
- def closeconnection(self):
- try:
- if self.__conn:
- self.__conn.close()
- self.connStatus = '连接已断开'
- except cx_Oracle.Error as e:
- self.connStatus = e
- def query(self, table='groupinfo', queryby=''):
- """
- :param table: 查询表名
- :param queryby: 查询条件,支持完整where, order by, group by 字句
- :return:返回数据集,列名
- """
- self.queryStatus = 0
- result = ''
- cursor = ''
- title = ''
- try:
- sql = 'select * from '+table+' '+queryby
- print(sql)
- cursor = self.__conn.cursor()
- cursor.execute(sql)
- result = cursor.fetchall()
- title = [i[0] for i in cursor.description]
- cursor.close()
- cursor = ''
- except cx_Oracle.Error as e:
- self.queryStatus = e
- finally:
- if cursor:
- cursor.close()
- return result, title
- def insert(self, proc='insert_groupinfo', insertlist=[]):
- """
- :param proc: 过程名
- :param insertlist: 参数集合,主键不能为空,参数必须与列对应,数量一致
- :desc: 此方法通过调用过程完成插入,需要在sql上完成存储过程,可以通过insertstatus的值判断是否成功
- """
- self.insertStatus = 0
- cursor = ''
- try:
- cursor = self.__conn.cursor()
- cursor.callproc(proc, insertlist)
- cursor.close()
- cursor = ''
- except cx_Oracle.Error as e:
- self.insertStatus = e
- finally:
- if cursor:
- cursor.close()
- def update(self, proc='update_groupinfo', updatelist=[]):
- """
- :param proc: 存储过程名
- :param updatelist: 更新的集合,第一个为查询主键,后面的参数为对应的列,可以更新主键。
- :desc: 此方法通过调用存储过程完成更新操作,可以通过updatestatus的值判断是否成功
- """
- self.updateStatus = 0
- cursor = ''
- try:
- cursor = self.__conn.cursor()
- cursor.callproc(proc, updatelist)
- cursor.close()
- cursor = ''
- except cx_Oracle.Error as e:
- self.updateStatus = e
- finally:
- if cursor:
- cursor.close()
- def delete(self, deleteby: '删除条件,where关键词后面的内容,即列名=列值(可多个组合)', table='groupinfo'):
- """
- :param deleteby: 删除的条件,除where关键字以外的内容
- :param table: 要删除的表名
- :desc:可以通过deletestatus判断是否成功删除
- """
- self.deleteStatus = 0
- cursor = ''
- try:
- sql = 'delete ' + table + ' where ' + deleteby
- cursor = self.__conn.cursor()
- cursor.execute(sql)
- cursor.close()
- cursor = ''
- except cx_Oracle.Error as e:
- self.deleteStatus = e
- finally:
- if cursor:
- cursor.close()
dataBaseOpr.py
源码注释基本很清晰了,对关键点进行说明:数据库连接的数据全部用默认参数的形式给出了,可根据实际情况进行移植。关于调用存储过程,只需要使用connect(**).cursor.callproc(存储过程名, 参数列表)即可,方便高效。
3、GUI界面搭建(tkinter):
因为界面和逻辑我都写在guiPy.py中的,没有使用特别的设计模式。所以这一部分主要讲tkinter的用法,下一部分说明具体的实现。
关于安装:Python3.2后自带本库,若引用没有,很可能是安装的时候没有选。解决方案嘛找到安装文件修改安装即可,如下图:
下一步打上勾即可,完成安装就能引用tkinter了。
使用教程简单介绍:
我这次用的时候就是在网上随便搜了一下教程,发现内容都很浅显,而且不系统,当然我也没法系统的讲清楚,但官方文档可以啊,提醒自己,以后一定先看官方文档!
http://effbot.org/tkinterbook/tkinter-index.htm
4、逻辑实现(guiPy.py):
先上代码,基本注释都有:
- #!/usr/bin/env python
- # encoding: utf-8
- """
- :author: xiaoxiaobai
- :contact: 865816863@qq.com
- :file: guiPy.py
- :time: 2017/10/3 19:42
- :@Software: PyCharm Community Edition
- :desc: 该文件完成了主要窗体设计,和数据获取,呈现等操作。调用时,运行主类MainWindow即可
- """
- import tkinter as tk
- from tkinter import ttk
- from dataBaseOpr import *
- import tkinter.messagebox
- class MainWindow(tk.Tk):
- def __init__(self):
- super().__init__()
- # 变量定义
- self.opr = OracleOpr()
- self.list = self.init_data()
- self.item_selection = ''
- self.data = []
- # 定义区域,把全局分为上中下三部分
- self.frame_top = tk.Frame(width=600, height=90)
- self.frame_center = tk.Frame(width=600, height=180)
- self.frame_bottom = tk.Frame(width=600, height=90)
- # 定义上部分区域
- self.lb_tip = tk.Label(self.frame_top, text="评议小组名称")
- self.string = tk.StringVar()
- self.string.set('')
- self.ent_find_name = tk.Entry(self.frame_top, textvariable=self.string)
- self.btn_query = tk.Button(self.frame_top, text="查询", command=self.query)
- self.lb_tip.grid(row=0, column=0, padx=15, pady=30)
- self.ent_find_name.grid(row=0, column=1, padx=45, pady=30)
- self.btn_query.grid(row=0, column=2, padx=45, pady=30)
- # 定义下部分区域
- self.btn_delete = tk.Button(self.frame_bottom, text="删除", command=self.delete)
- self.btn_update = tk.Button(self.frame_bottom, text="修改", command=self.update)
- self.btn_add = tk.Button(self.frame_bottom, text="添加", command=self.add)
- self.btn_delete.grid(row=0, column=0, padx=20, pady=30)
- self.btn_update.grid(row=0, column=1, padx=120, pady=30)
- self.btn_add.grid(row=0, column=2, padx=30, pady=30)
- # 定义中心列表区域
- self.tree = ttk.Treeview(self.frame_center, show="headings", height=8, columns=("a", "b", "c", "d"))
- self.vbar = ttk.Scrollbar(self.frame_center, orient=tk.VERTICAL, command=self.tree.yview)
- # 定义树形结构与滚动条
- self.tree.configure(yscrollcommand=self.vbar.set)
- # 表格的标题
- self.tree.column("a", width=80, anchor="center")
- self.tree.column("b", width=120, anchor="center")
- self.tree.column("c", width=120, anchor="center")
- self.tree.column("d", width=120, anchor="center")
- self.tree.heading("a", text="小组编号")
- self.tree.heading("b", text="小组名称")
- self.tree.heading("c", text="负责人")
- self.tree.heading("d", text="联系方式")
- # 调用方法获取表格内容插入及树基本属性设置
- self.tree["selectmode"] = "browse"
- self.get_tree()
- self.tree.grid(row=0, column=0, sticky=tk.NSEW, ipadx=10)
- self.vbar.grid(row=0, column=1, sticky=tk.NS)
- # 定义整体区域
- self.frame_top.grid(row=0, column=0, padx=60)
- self.frame_center.grid(row=1, column=0, padx=60, ipady=1)
- self.frame_bottom.grid(row=2, column=0, padx=60)
- self.frame_top.grid_propagate(0)
- self.frame_center.grid_propagate(0)
- self.frame_bottom.grid_propagate(0)
- # 窗体设置
- self.center_window(600, 360)
- self.title('评议小组管理')
- self.resizable(False, False)
- self.mainloop()
- # 窗体居中
- def center_window(self, width, height):
- screenwidth = self.winfo_screenwidth()
- screenheight = self.winfo_screenheight()
- # 宽高及宽高的初始点坐标
- size = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2)
- self.geometry(size)
- # 数据初始化获取
- def init_data(self):
- result, _ = self.opr.query()
- if self.opr.queryStatus:
- return 0
- else:
- return result
- # 表格内容插入
- def get_tree(self):
- if self.list == 0:
- tkinter.messagebox.showinfo("错误提示", "数据获取失败")
- else:
- # 删除原节点
- for _ in map(self.tree.delete, self.tree.get_children("")):
- pass
- # 更新插入新节点
- for i in range(len(self.list)):
- group = self.list[i]
- self.tree.insert("", "end", values=(group[0],
- group[1],
- group[2],
- group[3]), text=group[0])
- # TODO 此处需解决因主程序自动刷新引起的列表项选中后重置的情况,我采用的折中方法是:把选中时的数据保存下来,作为记录
- # 绑定列表项单击事件
- self.tree.bind("<ButtonRelease-1>", self.tree_item_click)
- self.tree.after(500, self.get_tree)
- # 单击查询按钮触发的事件方法
- def query(self):
- query_info = self.ent_find_name.get()
- self.string.set('')
- # print(query_info)
- if query_info is None or query_info == '':
- tkinter.messagebox.showinfo("警告", "查询条件不能为空!")
- self.get_tree()
- else:
- result, _ = self.opr.query(queryby="where name like '%" + query_info + "%'")
- self.get_tree()
- if self.opr.queryStatus:
- tkinter.messagebox.showinfo("警告", "查询出错,请检查数据库服务是否正常")
- elif not result:
- tkinter.messagebox.showinfo("查询结果", "该查询条件没有匹配项!")
- else:
- self.list = result
- # TODO 此处需要解决弹框后代码列表刷新无法执行的问题
- # 单击删除按钮触发的事件方法
- def delete(self):
- if self.item_selection is None or self.item_selection == '':
- tkinter.messagebox.showinfo("删除警告", "未选中待删除值")
- else:
- # TODO: 删除提示
- self.opr.delete(deleteby="no = '"+self.item_selection+"'")
- if self.opr.deleteStatus:
- tkinter.messagebox.showinfo("删除警告", "删除异常,可能是数据库服务意外关闭了。。。")
- else:
- self.list = self.init_data()
- self.get_tree()
- # 为解决窗体自动刷新的问题,记录下单击项的内容
- def tree_item_click(self, event):
- try:
- selection = self.tree.selection()[0]
- self.data = self.tree.item(selection, "values")
- self.item_selection = self.data[0]
- except IndexError:
- tkinter.messagebox.showinfo("单击警告", "单击结果范围异常,请重新选择!")
- # 单击更新按钮触发的事件方法
- def update(self):
- if self.item_selection is None or self.item_selection == '':
- tkinter.messagebox.showinfo("更新警告", "未选中待更新项")
- else:
- data = [self.item_selection]
- self.data = self.set_info(2)
- if self.data is None or not self.data:
- return
- # 更改参数
- data = data + self.data
- self.opr.update(updatelist=data)
- if self.opr.insertStatus:
- tkinter.messagebox.showinfo("更新小组信息警告", "数据异常库连接异常,可能是服务关闭啦~")
- # 更新界面,刷新数据
- self.list = self.init_data()
- self.get_tree()
- # 单击新增按钮触发的事件方法
- def add(self):
- # 接收弹窗的数据
- self.data = self.set_info(1)
- if self.data is None or not self.data:
- return
- # 更改参数
- self.opr.insert(insertlist=self.data)
- if self.opr.insertStatus:
- tkinter.messagebox.showinfo("新增小组信息警告", "数据异常库连接异常,可能是服务关闭啦~")
- # 更新界面,刷新数据
- self.list = self.init_data()
- self.get_tree()
- # 此方法调用弹窗传递参数,并返回弹窗的结果
- def set_info(self, dia_type):
- """
- :param dia_type:表示打开的是新增窗口还是更新窗口,新增则参数为1,其余参数为更新
- :return: 返回用户填写的数据内容,出现异常则为None
- """
- dialog = MyDialog(data=self.data, dia_type=dia_type)
- # self.withdraw()
- self.wait_window(dialog) # 这一句很重要!!!
- return dialog.group_info
- # 新增窗口或者更新窗口
- class MyDialog(tk.Toplevel):
- def __init__(self, data, dia_type):
- super().__init__()
- # 窗口初始化设置,设置大小,置顶等
- self.center_window(600, 360)
- self.wm_attributes("-topmost", 1)
- self.resizable(False, False)
- self.protocol("WM_DELETE_WINDOW", self.donothing) # 此语句用于捕获关闭窗口事件,用一个空方法禁止其窗口关闭。
- # 根据参数类别进行初始化
- if dia_type == 1:
- self.title('新增小组信息')
- else:
- self.title('更新小组信息')
- # 数据变量定义
- self.no = tk.StringVar()
- self.name = tk.StringVar()
- self.pname = tk.StringVar()
- self.pnum = tk.StringVar()
- if not data or dia_type == 1:
- self.no.set('')
- self.name.set('')
- self.pname.set('')
- self.pnum.set('')
- else:
- self.no.set(data[0])
- self.name.set(data[1])
- self.pname.set(data[2])
- self.pnum.set(data[3])
- # 错误提示定义
- self.text_error_no = tk.StringVar()
- self.text_error_name = tk.StringVar()
- self.text_error_pname = tk.StringVar()
- self.text_error_pnum = tk.StringVar()
- self.error_null = '该项内容不能为空!'
- self.error_exsit = '该小组编号已存在!'
- self.group_info = []
- # 弹窗界面布局
- self.setup_ui()
- # 窗体布局设置
- def setup_ui(self):
- # 第一行(两列)
- row1 = tk.Frame(self)
- row1.grid(row=0, column=0, padx=160, pady=20)
- tk.Label(row1, text='小组编号:', width=8).pack(side=tk.LEFT)
- tk.Entry(row1, textvariable=self.no, width=20).pack(side=tk.LEFT)
- tk.Label(row1, textvariable=self.text_error_no, width=20, fg='red').pack(side=tk.LEFT)
- # 第二行
- row2 = tk.Frame(self)
- row2.grid(row=1, column=0, padx=160, pady=20)
- tk.Label(row2, text='小组名称:', width=8).pack(side=tk.LEFT)
- tk.Entry(row2, textvariable=self.name, width=20).pack(side=tk.LEFT)
- tk.Label(row2, textvariable=self.text_error_name, width=20, fg='red').pack(side=tk.LEFT)
- # 第三行
- row3 = tk.Frame(self)
- row3.grid(row=2, column=0, padx=160, pady=20)
- tk.Label(row3, text='负责人姓名:', width=10).pack(side=tk.LEFT)
- tk.Entry(row3, textvariable=self.pname, width=18).pack(side=tk.LEFT)
- tk.Label(row3, textvariable=self.text_error_pname, width=20, fg='red').pack(side=tk.LEFT)
- # 第四行
- row4 = tk.Frame(self)
- row4.grid(row=3, column=0, padx=160, pady=20)
- tk.Label(row4, text='手机号码:', width=8).pack(side=tk.LEFT)
- tk.Entry(row4, textvariable=self.pnum, width=20).pack(side=tk.LEFT)
- tk.Label(row4, textvariable=self.text_error_pnum, width=20, fg='red').pack(side=tk.LEFT)
- # 第五行
- row5 = tk.Frame(self)
- row5.grid(row=4, column=0, padx=160, pady=20)
- tk.Button(row5, text="取消", command=self.cancel).grid(row=0, column=0, padx=60)
- tk.Button(row5, text="确定", command=self.ok).grid(row=0, column=1, padx=60)
- def center_window(self, width, height):
- screenwidth = self.winfo_screenwidth()
- screenheight = self.winfo_screenheight()
- size = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2)
- self.geometry(size)
- # 点击确认按钮绑定事件方法
- def ok(self):
- self.group_info = [self.no.get(), self.name.get(), self.pname.get(), self.pnum.get()] # 设置数据
- if self.check_info() == 1: # 进行数据校验,失败则不关闭窗口
- return
- self.destroy() # 销毁窗口
- # 点击取消按钮绑定事件方法
- def cancel(self):
- self.group_info = None # 空!
- self.destroy()
- # 数据校验和用户友好性提示,校验失败返回1,成功返回0
- def check_info(self):
- is_null = 0
- str_tmp = self.group_info
- if str_tmp[0] == '':
- self.text_error_no.set(self.error_null)
- is_null = 1
- if str_tmp[1] == '':
- self.text_error_name.set(self.error_null)
- is_null = 1
- if str_tmp[2] == '':
- self.text_error_pname.set(self.error_null)
- is_null = 1
- if str_tmp[3] == '':
- self.text_error_pnum.set(self.error_null)
- is_null = 1
- if is_null == 1:
- return 1
- res, _ = OracleOpr().query(queryby="where no = '"+str_tmp[0]+"'")
- print(res)
- if res:
- self.text_error_no.set(self.error_exsit)
- return 1
- return 0
- # 空函数
- def donothing(self):
- pass
guiPy.py
可以看的出,窗体类继承自tkinter.TK()可以直接通过self.x对主窗体添加控件和修改属性。然后在初始化函数中需要声明需要的成员变量,完成整体布局以及控件的事件绑定,以及数据初始化,最后self.mainloop()使窗体完成自动刷新。我们所有的逻辑处理都是在事件绑定方法中完成的,这样感觉就像是针对用户的每一个操作做出对应的逻辑处理和反应,同时需要考虑可能出现的异常以及所有的可能性,达到用户友好的设计要求。
运行此实例,可以使用test,py中的测试方法,也可以把guiPy.py和dataBaseOpr.py两个类放在同一个文件夹,在本机安装好上述两个库和完成数据库创建的情况下,直接在py解释器下导入guiPy.py文件下所有的包,MainWindow()即可。
python GUI实战项目——tkinter库的简单实例的更多相关文章
- 如何美观地打印 Python 对象?这个标准库可以简单实现
前不久,我写了一篇文章回顾 Python 中 print 的发展历史 ,提到了两条发展线索: 明线:早期的 print 语句带有 C 和 Shell 的影子,是个应用程序级的 statement,在最 ...
- [python]近日 用3种库 实现简单的窗口 的回顾~
最近任务:利用python 实现以下4个窗口弹窗. 信息提示框 文本输入框(需在窗口消失后,返回 用户输入的值) 文件选择(需在窗口消失后, 返回 用户选择的文件名的全路径) 文件夹选择(需在窗口消失 ...
- python fastApi实战项目 - 爱投票管理系统(一)
一.闲来无事,在工作之余自己研究了一下python的异步框架 - fastapi,并写包括 1.部门管理 2.角色管理 3.用户管理 4.菜单管理 5.登录日志 6.操作日志 六个基础功能模块,演示链 ...
- 32个Python爬虫实战项目,满足你的项目慌
爬虫项目名称及简介 一些项目名称涉及企业名词,小编用拼写代替 1.[WechatSogou]- weixin公众号爬虫.基于weixin公众号爬虫接口,可以扩展成其他搜索引擎的爬虫,返回结果是列表,每 ...
- Python GUI编程(TKinter)(简易计算器)
搞课设搞得心累,现在看到人脸这两个字就烦躁,无聊搞搞tkinter,实现一个计算器的功能,能够简单的加减乘除. 简单的页面如下: 简单的代码如下: # encoding:utf-8 import tk ...
- Python -- Gui编程 -- Tkinter的使用 -- 基本控件
1.按钮 tkBtton.py import tkinter root = tkinter.Tk() btn1 = tkinter.Button(root, anchor=tkinter.E,\ te ...
- Python GUI之tkinter窗口视窗教程大集合(看这篇就够了) JAVA日志的前世今生 .NET MVC采用SignalR更新在线用户数 C#多线程编程系列(五)- 使用任务并行库 C#多线程编程系列(三)- 线程同步 C#多线程编程系列(二)- 线程基础 C#多线程编程系列(一)- 简介
Python GUI之tkinter窗口视窗教程大集合(看这篇就够了) 一.前言 由于本篇文章较长,所以下面给出内容目录方便跳转阅读,当然也可以用博客页面最右侧的文章目录导航栏进行跳转查阅. 一.前言 ...
- 再一波Python实战项目列表
前言: 近几年Python可谓是大热啊,很多人都纷纷投入Python的学习中,以前我们实验楼总结过多篇Python实战项目列表,不但有用还有趣,最主要的是咱们实验楼不但有详细的开发教程,更有在线开发环 ...
- Python GUI - tkinter
目录: Tkinter 组件 标准属性 几何管理 代码实例: 1. Label & Button 2. Entry & Text 3.Listbox列表 4.Radiobutton单选 ...
随机推荐
- maven 随笔
<build> <plugins> <!--打包源代码--> <plugin> <artifactId>maven-source-plugi ...
- wireshark 随笔
在进行通信开发的过程中,我们往往会把本机既作为客户端又作为服务器端来调试代码,使得本机自己和自己通信.但是wireshark此时是无法抓取到数据包的,需要通过简单的设置才可以. 具体方法如下: ①:以 ...
- Java基础精选,你答对了几道?
没有技术深度是大多程序员的一种常态. 但是当你成为一个资深的工程师的时候,很多公司并不希望你还是那样平庸,没有深度.虽然你会纳闷,我就算有深度你们也不一定用得上呀?然而到了这个级别的人需求量并不像初中 ...
- 后台方庄List razor 循环
后台: //1.查询所有年卡类型 StringBuilder sqlStr = new StringBuilder(); sqlStr.Ap ...
- JSONP的实现流程
在进行AJAX的时候会经常产生这样一个报错: 看红字,这是浏览器的同源策略,使跨域进行的AJAX无效.注意,不是不发送AJAX请求(其实就是HTTP请求),而是请求了,也返回了,但浏览器‘咔擦’一声, ...
- 如何解决xshell中无法输入中文的问题
自从安上了xshell以后,用着那叫一个顺手,美中不足的就是一直无法输入中文.不过,既然学习IT,就要习惯英文嘛~直到--我遇到了脚本,写好一个脚本,必要的注释是少不了的,但是作为一个英文渣渣,我真的 ...
- 201521123091 《Java程序设计》第12周学习总结
Java 第十一周总结 第十一周的作业. 目录 1.本章学习总结 2.Java Q&A 3.码云上代码提交记录及PTA实验总结 4.课后阅读 1.本章学习总结 1.1 以你喜欢的方式(思维导图 ...
- 姑娘你大胆地往前走——答大二学生XCL之八问
姑娘你大胆地往前走--答大二学生XCL之八问 以下问题的答案写给我家正在读大二的XCL. 写于 2017-9-13 晚 请问您是为什么选择了IT行业的? 与其说是我选择了行业,不如说是行业选择了我. ...
- 团队作业8——第二次项目冲刺(Beta阶段)(冲刺计划)
Beta阶段冲刺计划 Alpha冲刺暂时告一段落,项目现在也有个了大体框架,当然还是有很多漏洞,在接下来的Beta冲刺中尽量完善,希望最后能有一个好的结果. 新成员介绍 何跃斌:掌握java.c的基本 ...
- 201521123042 《java程序设计》 第八周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容. ①泛型定义:泛型(Generic type 或者 generics)是对 Java 语言的类型系统的一种扩展, ...