筆者按:
本文將通過GUI嵌入式,將查詢進行窗口化處理,便于查詢,由于筆者設計的思考有欠缺,所以導致部分代碼重復,這也是設計上的一大缺陷,再加上這種查詢式的跳轉也不太適合于實戰,未來會進行修改和更正,先將代碼書寫出來,作為自己記錄學習的歷程的一種方式。
0節:前期準備
0.1Navicat for MySQL以及建立名為“stock_code”的數據庫,名為“stock_codedetail”的表。
0.2用于更新,維護stock_codedetail的表和代碼。
0.3編程思路:通過GUI化處理,將通過sql查詢方式變成一般的查詢方式。
0.4編程部署:先初始化GUI框架,然后查詢-匹配的模塊一次,跳轉反饋的模塊一次,也就是說該代碼分三個模塊進行處理。當然美中不足的是,對于數據庫的調用了兩次。應該是在未來整改的時候進行修改,這就是進行封裝的好處,定義一次。
1節:GUI框架初始化:
from tkinter import *from tkinter import ttkimport pymysqlfrom tkinter import messageboximport tkinter as tk#用于調用TKimport pandas as pdimport numpy as npclass 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卻設計兩次訪問,這個無疑是十分冗余的查詢界面應當和查詢結果同列,查詢界面可以設置賬號和密碼,支持修改相關的界面沒有很好的優化,需要修改未來將進一步進行優化,敬請期待
評論前必須登錄!
立即登錄 注冊