問題描述:時間過得真快,In the blink of an eye, another month has passed,2022And in the past half,7月的尾巴,Finally made it a little bit 東西,I am not a developer,Also a novice who is constantly learning.這次使用tkinter制作了一個mysqlinspection tool,使用圖形化操作,邊學邊操作,一路踩坑,寫的不好,But I can give you something,Deepen the learning processclass的理解,學習了tkinter布局,How to connect to the database etc..
python:Python 3.8.1
數據庫對象:MySQL
過程中遇到的問題
1.Because it is a database inspection system,Therefore, the logged-in account is often a more privileged account, such asroot,Then how to checkroot賬號,Unlike normal management system,Not create a good user and password table,然後去比對.rootis stored in the database system,no way to checkroot的用戶和密碼.這裡的root是作為參數傳進來的,So how to compare users with more privileges??
2.How does the display page load the query results in the database??It should be simple,Get the return value of a database query,then load in the page.But the final result is not very good
3.How to return when the database is logged inmysqlThe error value given by the connection,It is very simple if you only set up to determine whether the login is successful or not,但是在返回mysqlHow to return to the front desk when an error value is reported?
登錄類
class Application(Frame):
username = ''
password = ''
ip = ''
port = '' def __init__(self,master=None):
super().__init__(master)
self.master = master
self.pack()
self.createWidget() def createWidget(self): #創建組件容器 page = Frame(self)
page.pack() self.usernameGet = StringVar()
self.usernameGet.set('root')
self.passwordGet = StringVar()
self.passwordGet.set('zabbix.9.31')
self.ipGet = StringVar()
self.ipGet.set('192.168.163.21')
self.portGet = StringVar() #這裡如果設置IntVar,GUI上會顯示0,Integer can be0,不能是空
self.portGet.set('33306') Label(page).grid(row=0,column=0)
Label(page,text='賬戶:').grid(row=1,column=1)
Entry(page,textvariable=self.usernameGet).grid(row=1,column=2)
Label(page,text='密碼:').grid(row=2,column=1)
Entry(page,textvariable=self.passwordGet,show='*').grid(row=2,column=2)
Label(page,text='IP地址:').grid(row=3,column=1)
Entry(page,textvariable=self.ipGet).grid(row=3,column=2)
Label(page,text='端口:').grid(row=4,column=1)
Entry(page,textvariable=self.portGet).grid(row=4,column=2) Button(page,text='登錄',command=self.login_check).grid(row=5,column=1,pady=10)
Button(page,text='退出',command=page.quit).grid(row=5,column=2)
def login_check(self): #Set up login exit button
i = self.ipGet.get()
p = int(self.portGet.get())
u = self.usernameGet.get()
pa = self.passwordGet.get()
db_name = 'mysql' #實例化Mysql類
mysqlLogin = Mysql(i,p,u,pa,db_name) #這裡不能用mysqlloginObject to do boolean judgment,只要輸入正確,His boolean value has always beentrue
results = mysqlLogin.select('select @@version')
print(bool(mysqlLogin));print(bool(results))
if results:
messagebox.showinfo('提示', '連接成功,Generating inspection report for you')
# print(type(i),type(p),type(u),type(pa))
self.destroy()
MainPage(root)
mysqlLogin.show()
數據庫連接類
class Mysql(object):
# mysql 端口號,注意:必須是int類型
def __init__(self, host, port, user, passwd, db_name):
self.host = host
self.user = user
self.passwd = passwd
self.port = port
self.db_name = db_name def select(self, sql):
"""
執行sql命令
:param sql: sql語句
:return: 元祖
"""
try:
conn = pymysql.connect(
host=self.host,
user=self.user,
passwd=self.passwd,
port=self.port,
database=self.db_name,
charset='utf8',
#cursorclass=pymysql.cursors.DictCursor
)
cur = conn.cursor() # 創建游標
# conn.cursor()
cur.execute(sql) # 執行sql命令
#print(type(cur.execute(sql)))
res = cur.fetchall() # 獲取執行的返回結果
#print(type(res))
cur.close()
conn.close()
# print(res)
return res
except Exception as e:
messagebox.showerror('提示',e)
return False def show(self):
sql1 = "show global variables"
# sql2 = "show master status;"
# sql3 = "SELECT table_schema,SUM((AVG_ROW_LENGTH*TABLE_ROWS+INDEX_LENGTH))/1024 AS total_KB FROM information_schema.TABLES GROUP BY table_schema ORDER BY total_KB DESC ;" res1 = dict(self.select(sql1))
# res2 = self.select(sql2)
# res3 = self.select(sql3)
filename = r"D:\{}".format('mysql_check.txt')
with open(filename, mode='w', encoding='utf-8') as f:
# 檢查MySQL版本
#print("\033[1;32m當前數據庫的版本是:\033[0m" + res1['version'])
f.write("當前數據庫的版本是:" + res1['version'] + "\n") f.write("當前數據庫的version_comment是:" + res1['version_comment'] + "\n")
f.write("當前數據庫的version_compile_machine是:" + res1['version_compile_machine'] + "\n")
f.write("當前數據庫的version_compile_os是:" + res1['version_compile_os'] + "\n")
f.write("當前數據庫的version_compile_zlib是:" + res1['version_compile_zlib'] + "\n")
f.write("當前數據庫的sql_mode是:" + res1['sql_mode'] + "\n") # 檢查MySQL端口
#print("\033[1;35mThe port of the current database is:\033[0m" + res1['port'])
f.write("The port of the current database is:" + res1['port'] + "\n")
# 檢查server_id
#print("\033[1;32m當前數據庫的server_id是:\033[0m" + res1['server_id'])
f.write("當前數據庫的server_id是:" + res1['server_id'] + "\n")
# 檢查basedir目錄
#print("\033[1;32m當前數據庫的basedir在:\033[0m" + res1['basedir'])
f.write("當前數據庫的basedir在:" + res1['basedir'] + "\n")
# 檢查datadir目錄
#print("\033[1;35m當前數據庫的datadir在:\033[0m" + res1['datadir'])
f.write("當前數據庫的datadir在:" + res1['datadir'] + "\n")
# 檢查tmpdir目錄
#print("\033[1;32m當前數據庫的tmpdir在:\033[0m" + res1['tmpdir'])
f.write("當前數據庫的tmpdir在:" + res1['tmpdir'] + "\n") #pid_file
f.write("當前數據庫的pid_file在:" + res1['pid_file'] + "\n")
#optimizer_switch
f.write("當前數據庫的optimizer_switch:" + res1['optimizer_switch'] + "\n")
#mysqlx_socket
f.write("mysqlx_socket:" + res1['mysqlx_socket'] + "\n")
#log_bin_basename
f.write("當前數據庫的log_bin_basename在:" + res1['log_bin_basename'] + "\n")
#log_error
f.write("當前數據庫的log_error在:" + res1['log_error'] + "\n")
#slow_query_log_file
f.write("當前數據庫的slow_query_log_file在:" + res1['slow_query_log_file'] + "\n")
class MainPage:
def __init__(self,master: tk.Tk):
self.root = master
self.root.title('Database inspection system')
self.root.geometry('600x400')
self.create_page()
def create_page(self):
self.about_frame = AboutFrame(self.root) #調用views中的aboutframe類,Show information about
# tk.Label(self.about_frame,text = '關於作品:Database inspection system').pack()
# tk.Label(self.about_frame,text = '關於作者:i love water lilies').pack()
# tk.Label(self.about_frame,text = '版權所有:https://www.cnblogs.com/houzhiheng/').pack() self.check_frame = CheckFrame(self.root) menubar = tk.Menu(self.root)
menubar.add_command(label='巡檢結果',command=self.show_check)
menubar.add_command(label='關於',command=self.show_about)
self.root['menu'] = menubar def show_check(self):
self.check_frame.pack()
self.about_frame.pack_forget() #Selectively forget other loaded pages,Otherwise, it will be loaded in the page def show_about(self):
self.about_frame.pack()
self.check_frame.pack_forget()
Show About Sections
class AboutFrame(tk.Frame):
def __init__(self,root):
super().__init__(root)
tk.Label(self, text='Production:Database inspection system').pack()
tk.Label(self, text='Author:i love water lilies').pack()
tk.Label(self, text='Version:1.0').pack()
tk.Label(self, text='@Copyright:https://www.cnblogs.com/houzhiheng/').pack()
Display database inspection result class
class CheckFrame(tk.Frame):
def __init__(self,root):
super().__init__(root)
# tk.Label(self, text='巡檢結果').pack()
self.table_view = tk.Frame()
self.table_view.pack() self.create_page() tk.Button(self,text='保存文件',command=self.save_data_frame).pack(anchor=tk.E,pady=5) def create_page(self):
# self.tree_view = ttk.Treeview(self,show='headings')
# columns = ("check_results")
# columns_values = ("數據庫巡檢報告")
# top = Tk() # 設置窗口
# sb = Scrollbar(top) # set window scroll bar
# sb.pack(side=RIGHT, fill=) # Set the window scroll bar position
# self.sb = Scrollbar()
# self.sb.pack(side=RIGHT,fill= Y)
# self.tree_view = ttk.Treeview(self,show='headings',columns=columns)
# self.tree_view.column('check_results',width=500,anchor='center')
# self.tree_view.heading('check_results',text=columns_values)
# self.tree_view.pack(fill=tk.BOTH,expand=True)
# self.show_data_frame() with open(r'D:\mysql_check.txt', 'r', encoding='utf-8') as f:
lines2 = [l.split() for l in f.readlines() if l.strip()]
# 滾動條初始化(scrollBar為垂直滾動條,scrollBarx為水平滾動條)
scrollBar = Scrollbar(self)
scrollBarx = Scrollbar(self, orient=HORIZONTAL)
# 靠右,充滿Y軸
scrollBar.pack(side=RIGHT, fill=Y)
# 靠下,充滿X軸
scrollBarx.pack(side=BOTTOM, fill=X)
lb = Text(self, width=100, height=25,)
lb.pack()
# db = Mysql('192.168.163.21', 33306, 'root', 'zabbix.9.31', 'mysql')
# res = db.show() textvar = "1:{} \n2:{}\n3:{}\n4:{}\n5:{}\n6:{}\n7:{}\n8:{}\n9:{}\n10:{}\n11:{}\n12:{}\n13:{}\n14:{}\n15:{}"\
.format(lines2[0],lines2[1],lines2[2],lines2[3],lines2[4],lines2[5],lines2[6],lines2[7],lines2[8],lines2[9],lines2[10],lines2[11],lines2[12],lines2[13],lines2[14],lines2[15],lines2[16])
lb.insert('insert', textvar + '\n')
lb.update()
# And when the user manipulates the scroll bar,自動調用 Treeview 組件的 yview()與xview() 方法
# That is, the scroll bar is synchronized with the position of the page content
scrollBar.config(command=lb.yview)
scrollBarx.config(command=lb.xview) def show_data_frame(self): #Output the content of the query to the screen
pass
def save_data_frame(self):
messagebox.showinfo('提示','Your file has been saved inD:\mysql_check.txt中!')
問題處理:
1.How to contrastrootIs the login successful?,從上面代碼可以看到,I can't go directly to the database to verify the username and password,But I can let the user name login successful to execute the command to determine whether the login,如果rootLog in and execute the command successfully,I will return a result asTRUE,如果執行失敗,returns a result ofFALSE,This command is to query the version of the database itself to get,任何用戶都可以執行
2.Output the inspection results on the screen,Originally, I can get the database return value and then put it on the screen.,但是我的views.py調用class MySQL類失敗,So in the end, the query results are directly saved in the file,Open the file when outputting in the foreground,Then adjust the file format and output,This step is a failure
3.將mysqlThe error returned by the connection can be handled as an exception.,It's just that there was a little problem with the logic when I did it at the time, and it didn't show success.
Conclusion Harvest:
Originally wanted to do a full set of database inspectionsGUI系統,The desktop version is ready,But not to the light to do oneGUI+mysqlThe version took two weeks,However, this general structure,If you want to do behind should be simple.This time, a deeper understanding of object-oriented,did not study well,Gotta make it up after graduation
一.python gui(圖形化)模塊介紹: Tkinter :是python最簡單的圖形化模塊,總共只有14種組建 Pyqt :是python最復雜也是使用最廣泛的圖形化 Wx ...
HeidiSQL 是一款用於簡單化的 MySQL server和數據庫管理的圖形化界面.該軟件同意你浏覽你的數據庫,管理表,浏覽和編輯記錄,管理用戶權限等等.此外,你能夠從文本文件導入數據,執行 SQ ...
黑馬程序員:Java基礎總結 GUI圖形化界面 ASP.Net+Android+IO開發 . .Net培訓 .期待與您交流! GUI(Graphical User Interface)圖形化界 ...
[.net 面向對象程序設計進階] (26) 團隊開發利器(五)分布式版本控制系統Git——圖形化Git客戶端工具TortoiseGit 讀前必備: 接上篇: 分布式版本控制系統Git——使用GitS ...
Atiti qq空間破解(3)------------gui圖形化通用cli執行器atiuse 結構:::命令行+以及反饋log框1 cli_guiUI/index.htm1 /AtiPlatf_c ...
追加一個zookeeper圖形化的客戶端工具: 1.zookeeper圖像化客戶端工具的下載地址:https://issues.apache.org/jira/secure/attachment/12 ...
在上一章裡,重點分享了命令行SQL分析工具的使用方法.在本章將重點分享PL/SQL的SQL分析工具. 一.如何打開PL/SQL執行計劃 開啟PL/SQL這工具,推薦如下方法: 點擊 ...
追加一個zookeeper圖形化的客戶端工具: 1.zookeeper圖像化客戶端工具的下載地址:https://issues.apache.org/jira/secure/attachment/12 ...
matplotlib是python中常用的數據圖形化工具,用法跟matlab有點相似.調用簡單,功能強大.在Windows下可以通過命令行 pip install matplotlib 來進行安裝. ...
MYSQLThe official website also launchedLinuxthe graphical connection tool-MySQL Workbench.MySQL Workbench不僅僅是一個簡單的MySQL客戶端.簡而言之,Workbench是一個跨平台的 ( ...
在C#.NET的開發中,Events are frequently encountered concepts,For example, add a click event to a button,and write the code to run when the button is clicked to trigger the event.不管是ASP.NET還是WinFormvarious forms of applications,Most often writing concrete code for system-generated events ...
/*"Flood patrol problem"模擬退火算法.This is a salesman problem,本題有53個點,All possibilities are approximatelyexp(53),There is currently no good way to find an exact solution,Since no exact solution can be found,We use simulated annealing to find a better solution, ...
前面的話 events模塊是node的核心模塊,幾乎所有常用的node模塊都繼承了events模塊,比如http.fs等.本文將詳細介紹nodeJS中的事件機制 EventEmitter 多數 Nod ...
APPThis requirement is often encountered in development,需要檢查當前的APP是不是可見的,比如,If it is visible just to maintain asocket長連接,If you switch to the background it is not visible,just disconnect this connection.Androidwould not have allowedAPP去監聽home鍵 ...
一.PCA簡介 1. 相關背景 在許多領域的研究與應用中,往往需要對反映事物的多個變量進行大量的觀測,收集大量數據以便進行分析尋找規律.多變量大樣本無疑會為研究和應用提供了豐富的信息,但也在一定程度上 ...
一.Connections connection function interfacelibvirt.open(name); //read-write connectionQEMU 參數說明: name:連接名稱libvirt.openAuth(uri, auth, fl ...
圓滑:Theme download corresponding themejsAfter the introduction, inject the corresponding name parameter to use the theme 初始化:tabInitializing the chart when clicked involvestabSwitch to needs lazy loading otherwise the default width is100px 1.創建macarons.js文件 2.page add ...
hdoj 1004The topic is probably about,Divide the input string according to the number of times of input,輸出出現次數最多的字符串. The logic of the topic is simple,It is necessary to select the corresponding data structure,Look at the submitted by othersdiscuss,It is obvious that this can be solved using a variety of data structures ...
http://acm.zzuli.edu.cn/problem.php?id=1783 1783: 簡單的求和 Time Limit: 1 Sec Memory Limit: 128 MBSubmi ...
CSS:層疊樣式表(英文全稱:Cascading Style Sheets) 後綴名:css 標志 style Pixel-level refinement of the typography of element positions in web pages ...