本文将通过GUI嵌入式,将查询进行窗口化处理,便于查询,由于笔者设计的思考有欠缺,所以导致部分代码重复,这也是设计上的一大缺陷,再加上这种查询式的跳转也不太适合于实战,未来会进行修改和更正,先将代码书写出来,作为自己记录学习的历程的一种方式。
0.1Navicat for MySQL以及建立名为“stock_code”的数据库,名为“stock_codedetail”的表。
0.2Python股票量化交易到入门实战04(修改版)用于更新,维护stock_codedetail的表和代码。
0.3编程思路:通过GUI化处理,将通过sql查询方式变成一般的查询方式。
0.4编程部署:先初始化GUI框架,然后查询-匹配的模块一次,跳转反馈的模块一次,也就是说该代码分三个模块进行处理。当然美中不足的是,对于数据库的调用了两次。应该是在未来整改的时候进行修改,这就是进行封装的好处,定义一次。
1节:GUI框架初始化:
from tkinter import *
from tkinter import ttk
import pymysql
from tkinter import messagebox
import tkinter as tk#用于调用TK
import pandas as pd
import numpy as np
class basedesk():
def __init__(self,master):
self.root=master
self.root.config()
self.root.title('stock_chcek')
self.width=380
self.height=300
# 获取屏幕尺寸以计算布局参数,使窗口居屏幕中央
self.screenwidth = self.root.winfo_screenwidth() # 屏幕宽
self.screenheight = self.root.winfo_screenheight() # 屏幕高
self.alignstr = '%dx%d+%d+%d' % (
self.width, self.height, (self.screenwidth - self.width) / 2, (self.screenheight - self.height) / 2)
self.root.geometry(self.alignstr)
self.R = Register(self.root)
self.R.register(self.root)
- 这里面最难的就是理解这块代码:
self.R = Register(self.root)
self.R.register(self.root)
将初始化的__init__反过来传入后面的register类以及Register.register中,达到GUI框架与插件,查询功能实现的分离,使得整体结构更加清楚。
2节:插件布局,查询功能实现:
2.1初始化访问数据库的参数
class Register():
def __init__(self, master):
self.root = master
# 基准框架
self.localhost= 'localhost'
self.user = 'root'
self.password= '123456'
self.database='stock_code'
2.2register函数负责按键,对话框等的部署
def register(self,master):
self.initface=LabelFrame(self.root,text='stock_code',font=('微软雅黑',14))
self.initface.grid(padx=85,pady=30)
#1对话框设置
self.industry=Label(self.initface,text='industry')
self.industry.grid(row=1,column=0,padx=10,pady=10)
#1.1接受输入值
self.var1=StringVar
#1.2输入框
self.entry_industry=Entry(self.initface,textvariable=self.var1)
self.entry_industry.grid(row=1,column=1,padx=0,pady=10)
#1.3登入按键
self.button_into=Button(self.initface,text='登录',command=self.conn)
self.button_into.grid(row=3,column=0,padx=20,pady=20)
#1.4退出按键
self.button_into = Button(self.initface, text='退出', command=self.root.quit)
self.button_into.grid(row=3, column=1,padx=20, pady=20)
2.3conn函数负责匹配self.entry_industry.get()【自己传参】是否存在数据库记录之中,如果有则跳转新窗口,即self.show_result()函数,如果没有,则弹窗提示错误。
- self.data=np.ravel(self.data.values.tolist()),通过添加np.ravel函数,可以将[[a],[b],[c]]的列表嵌套列表的模式变为[a,b,c]的列表格式。之前无法调用,花了代价的,也是通过不断的print(self.data)以及print(type(self.data))等方式来查询,然后将复杂格式简单化处理。
- self.man=self.entry_industry.get()则是对self.entry_industry.get()进行取值定义,然后传参到show_result()进行查询,返回的实现。
def conn(self):
#初始化数据库
self.conn=pymysql.connect(host=self.localhost, port=3306, user=self.user,
password=self.password, db=self.database,charset='utf8')
#获取游标
self.cursor=self.conn.cursor()
#测试连接是否成功
if self.cursor:
print('连接成功')
self.data=pd.read_sql('select industry from stock_codedatail', self.conn)
self.data=np.ravel(self.data.values.tolist())
self.man=self.entry_industry.get()
2.4通过while函数,我们可以实现多次查询记录。
- 如果要实现多次查询,则# self.initface.destroy()进行注释。
- 因为我们两次调用数据库数据的定义变量均为conn,所以self.cursor.close()进行了注释,在最后的匹配进行关闭游标的处理。
while len(self.data)<40000:
if self.entry_industry.get() in self.data:
print('输入正确')
# self.initface.destroy()
self.show_result()
break
else:
self.entry_industry.delete(0,END)
messagebox.showinfo(title='note',message='查询错误,请检查')
break
#关闭游标
#self.cursor.close()
3.show_result():主要实现self.entry_industry.get()访问数据库返回查询情况,并通过treeview进行处理。
3.1其实这里我们要检讨一下,不必在show_result()函数再次定义self.conn,毕竟在conn()函数我们已经定义过一次,在同一个类里面可以再次调用。
- self.row = self.datap[self.datap[‘industry’]==’%s’%self.man],将conn函数中的self.man取值输入值进行定义,然后通过Python语句调用。获取我们想要查询的信息,并且返回一个self.row函数。
def show_result(self):
self.conn = pymysql.connect(host=self.localhost, port=3306, user=self.user,
password=self.password, db=self.database, charset='utf8')
#测试
if self.conn:
print('连接成功')
self.datap=pd.read_sql('select * from stock_codedatail', self.conn)
# print(self.datap)
self.row = self.datap[self.datap['industry']=='%s'%self.man]
self.row=self.row.reset_index(drop=True)
3.2创建新的窗口:
win=Tk()
win.geometry('500x400+100+100')
win.title('industry_stockdetail')
3.3树型菜单插件实现:
- 定义columns
- 定义column
- 定义heading
- 在这里各位不必向我一样,这么做,可以通过for…in…循环传参进去,没有必要写的这么复杂。
- self.treeview.pack(fill=BOTH,expand=YES) # 设置位置
- self.row是dataframe数据结构,5列数据结构,通过row.iloc[i,0]将每列数据传入进去。
- 最后关闭游标,数据库。
columns=['updateDate','code','code_name','industry','industryClassification']
self.treeview=ttk.Treeview(win,height=18,show='headings',columns=columns)
self.treeview.column('updateDate',width=150,anchor='center')
self.treeview.column('code', width=80, anchor='center')
self.treeview.column('code_name', width=80, anchor='center')
self.treeview.column('industry', width=90, anchor='center')
self.treeview.column('industryClassification', width=100, anchor='center')
self.treeview.heading('updateDate',text='updateDate')
self.treeview.heading('code', text='code')
self.treeview.heading('code_name', text='code_name')
self.treeview.heading('industry', text='industry')
self.treeview.heading('industryClassification',text='industryClassification')
self.treeview.pack(fill=BOTH,expand=YES) # 设置位置
for i in range(len(self.row)):
self.treeview.insert('',i,values=(self.row.iloc[i,0],self.row.iloc[i,1],self.row.iloc[i,2],
self.row.iloc[i,3],self.row.iloc[i,4]))
# 关闭游标卡尺
self.cursor.close()
# 关闭数据库
self.conn.close()
root.mainloop()
4.调用和展示:
if __name__=="__main__":
root=Tk()
basedesk(root)
mainloop()
4.1查询界面:

4.2输入查询关键字:

查询错误,提示错误,并清空原查询语句

5.总结:
- 多次调用conn却设计两次访问,这个无疑是十分冗余的
- 查询界面应当和查询结果同列,查询界面可以设置账号和密码,支持修改
- 相关的界面没有很好的优化,需要修改
- 未来将进一步进行优化,敬请期待
发布者:股市刺客,转载请注明出处:https://www.95sca.cn/archives/496093
站内所有文章皆来自网络转载或读者投稿,请勿用于商业用途。如有侵权、不妥之处,请联系站长并出示版权证明以便删除。敬请谅解!