正文
python实战GUI界面+mysql
小程序:扫一扫查出行
【扫一扫了解最新限行尾号】
复制小程序
【扫一扫了解最新限行尾号】
复制小程序
前言
前面用tkinter做了一个巨丑的GUI界面,今天想把它变漂亮起来,重新找回page做了一个界面,它也是基于tkinter开发的所见即所得的界面编辑器,前面因为代码搞不明白没用上,现在重新研究一下。
一、打开page,软件自己在网上搜索下载的。它的界面挺有意思的,不是我们常见的形式,它分开了五个部分可以随便拖动,各部分间就是桌面,没有连在一起。
New Toplevel 就是工作台,可以将元件放置在上面。
Widget Toolbar 里就是可用的元件。
Attrbute Editor 编辑元件属性。
Widget Tree 元件导航树。
page手册:https://www.kancloud.cn/gnefnuy/python/1316391 (全网只找到这一个,谁还有其它资料的请留言,谢谢)
二、画好自己的界面,这下漂亮多了。
三、接下来导出python文件,这很重要,导出后就可以直接运行py文件生成界面。
1、选取菜单如截图
2、在弹出的页面点击‘save’,将这个GUI文件保存到你的project文件夹下。
3、选取菜单如截图
4、同样在弹出的页面点击‘save’,将这个文件保存到你的project文件夹下。(如果漏了这个文件,GUI运行就会报错)
5、现在试运行一下GUI的py文件。运行正常。
四、GUI做好,接下来要写逻辑了。
1、mysql的设置上一篇已经做过了,一些逻辑也可以照搬过来,现在主要的问题有两个。
一是原来的lisbox选择查找项改成了Combobox来做,要重新写代码。
二是原来所有东西都写在一个py上,现在出现了两个py文件(UI.py和UI_support.py),逻辑该写在哪,要研究一下。
2、combobox是从ttk引用的元件,不是tkinter上的,所以要记得import ttk(page生成的py文件已有)。
两个文件研究不出所以,先直接在UI.py上写Combobox的数据来源。
#从student表表头加载下拉列表
sql_sr = "SELECT COLUMN_NAME FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'test' AND TABLE_NAME = 'student'"
cbox_val = sql().select(sql_sr)
self.input_name = ttk.Combobox(top)
self.input_name.place(relx=0.192, rely=0.067, relheight=0.051
, relwidth=0.172)
self.input_name.configure(values = cbox_val) #设置下拉列表的值
self.input_name.configure(state='readonly') #设置为只读
self.input_name.configure(takefocus="")
下面还有一个插入时的Combobox,代码类似。
#加载下拉列表来源
sql_sr2 = "select class.name from class"
cbox_val2 = sql().select(sql_sr2) self.insert_class = ttk.Combobox(top)
self.insert_class.place(relx=0.6, rely=0.733, relheight=0.051
, relwidth=0.172)
self.insert_class.configure(values = cbox_val2)
self.insert_class.configure(textvariable=UI_support.combobox)
self.insert_class.configure(state='readonly') #设置为只读
self.insert_class.configure(takefocus="")
self.insert_class.configure(cursor="fleur")
结果:
修改: 读了一下page手册,发现UI.py是尽量不动的(修改界面后再生成代码会覆盖掉修改内容),要写到UI_support.py,尝试将下拉列表初始化写入def init
def init(top, gui, *args, **kwargs):
global w, top_level, root
w = gui
top_level = top
root = top sql_sr = "SELECT COLUMN_NAME FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'test' AND TABLE_NAME = 'student'"
cbox_val = sql().select(sql_sr)
w.input_name.configure(values = cbox_val) #设置下拉列表的值
w.input_name.configure(state='readonly') #设置为只读 sql_sr2 = "select class.name from class"
cbox_val2 = sql().select(sql_sr2) w.insert_class.configure(values = cbox_val2)
w.insert_class.configure(state='readonly')
运行显示倒是正常的,但一选择值就出问题了,两个下拉列表值同时变了,得再找原因。
CSDN上找到这个说法:
再回头查看代码,在UI_support.py中作如下修改:
def set_Tk_var():
global combobox
combobox = tk.StringVar()
global combobox2 #增加一个数据源给第二个commbox引用
combobox2 = tk.StringVar()
在UI.py中修改第二个commbox元件的数据源
self.insert_class = ttk.Combobox(top)
self.insert_class.place(relx=0.6, rely=0.733, relheight=0.051
, relwidth=0.172)
self.insert_class.configure(textvariable=UI_support.combobox2)#修改数据源
self.insert_class.configure(takefocus="")
运行测试OK,不过存在一个问题就是还是修改了UI.py的代码,要是有界面调整,用page再生成代码会覆盖掉修改的地方,估计修改数据源可以直接从page下手修改,这个放到后面再研究吧。
3、接下来要写从下拉列表获取焦点值,以及‘查找’和‘新增’按钮的逻辑。目前点击这两个按钮发现调用的是UI_support.py里的函数,那么就应该去UI_support.py里去写这两个按钮的逻辑了,试试看。
先写“查找”按钮
def on_select():
w.show_list.delete(0,'end') #清空显示区原有信息
name = w.input_name.get() #获取下拉列表当前值
varlue = w.input_valuse.get()
sql_sr = "select * from Student where student." + name + "=" + "'" + varlue +"'"
result = sql().select(sql_sr)
for x in result:
w.show_list.insert('end',x)
sys.stdout.flush()
查找成功
再写“新增”按钮
def on_insert():
name = w.insert_name.get()
age = w.insert_age.get()
sex = w.insert_sex.get()
myclass = w.insert_class.get()
sql_sr = "INSERT INTO Student (name,age,sex,class) VALUES ('"+name+"',"+age+","+sex+",'"+myclass+"')"
print(sql_sr)
sql().insert(sql_sr)
sys.stdout.flush()
运行成功,新增一条记录
4、至此,这个小工具算是完成了,前后搞了一个多星期,碰到啥问题就去查找资料,编程小白没办法,不过做成了还是有些许窃喜的,最后贴上两个文件的最终代码。
UI.py
1 #! /usr/bin/env python
2 # -*- coding: utf-8 -*-
3 #
4 # GUI module generated by PAGE version 5.4
5 # in conjunction with Tcl version 8.6
6 # Nov 13, 2020 11:21:14 AM CST platform: Windows NT
7
8 import sys
9
10 try:
11 import Tkinter as tk
12 except ImportError:
13 import tkinter as tk
14
15 try:
16 import ttk
17 py3 = False
18 except ImportError:
19 import tkinter.ttk as ttk
20 py3 = True
21
22 import UI_support
23
24 def vp_start_gui():
25 '''Starting point when module is the main routine.'''
26 global val, w, root
27 root = tk.Tk()
28 UI_support.set_Tk_var()
29 top = database (root)
30 UI_support.init(root, top)
31 root.mainloop()
32
33 w = None
34 def create_database(rt, *args, **kwargs):
35 '''Starting point when module is imported by another module.
36 Correct form of call: 'create_database(root, *args, **kwargs)' .'''
37 global w, w_win, root
38 #rt = root
39 root = rt
40 w = tk.Toplevel (root)
41 UI_support.set_Tk_var()
42 top = database (w)
43 UI_support.init(w, top, *args, **kwargs)
44 return (w, top)
45
46 def destroy_database():
47 global w
48 w.destroy()
49 w = None
50
51 class database:
52 def __init__(self, top=None):
53 '''This class configures and populates the toplevel window.
54 top is the toplevel containing window.'''
55 _bgcolor = '#d9d9d9' # X11 color: 'gray85'
56 _fgcolor = '#000000' # X11 color: 'black'
57 _compcolor = '#d9d9d9' # X11 color: 'gray85'
58 _ana1color = '#d9d9d9' # X11 color: 'gray85'
59 _ana2color = '#ececec' # Closest X11 color: 'gray92'
60 self.style = ttk.Style()
61 if sys.platform == "win32":
62 self.style.theme_use('winnative')
63 self.style.configure('.',background=_bgcolor)
64 self.style.configure('.',foreground=_fgcolor)
65 self.style.configure('.',font="TkDefaultFont")
66 self.style.map('.',background=
67 [('selected', _compcolor), ('active',_ana2color)])
68
69 top.geometry("600x450+518+418")
70 top.minsize(120, 1)
71 top.maxsize(1924, 1061)
72 top.resizable(1, 1)
73 top.title("Database")
74 top.configure(background="#ffffff")
75 top.configure(highlightbackground="#d9d9d9")
76 top.configure(highlightcolor="black")
77
78 self.select_button = tk.Button(top)
79 self.select_button.place(relx=0.817, rely=0.06, height=28, width=55)
80 self.select_button.configure(activebackground="#ececec")
81 self.select_button.configure(activeforeground="#000000")
82 self.select_button.configure(background="#d9d9d9")
83 self.select_button.configure(command=UI_support.on_select)
84 self.select_button.configure(disabledforeground="#a3a3a3")
85 self.select_button.configure(foreground="#000000")
86 self.select_button.configure(highlightbackground="#d9d9d9")
87 self.select_button.configure(highlightcolor="black")
88 self.select_button.configure(pady="0")
89 self.select_button.configure(text='''查找''')
90
91 self.menubar = tk.Menu(top,font="TkMenuFont",bg=_bgcolor,fg=_fgcolor)
92 top.configure(menu = self.menubar)
93
94 self.input_valuse = tk.Entry(top)
95 self.input_valuse.place(relx=0.5, rely=0.067,height=27, relwidth=0.173)
96 self.input_valuse.configure(background="white")
97 self.input_valuse.configure(disabledforeground="#a3a3a3")
98 self.input_valuse.configure(font="TkFixedFont")
99 self.input_valuse.configure(foreground="#000000")
100 self.input_valuse.configure(highlightbackground="#d9d9d9")
101 self.input_valuse.configure(highlightcolor="black")
102 self.input_valuse.configure(insertbackground="black")
103 self.input_valuse.configure(selectbackground="blue")
104 self.input_valuse.configure(selectforeground="white")
105
106 self.Label1 = tk.Label(top)
107 self.Label1.place(relx=0.083, rely=0.067, height=23, width=54)
108 self.Label1.configure(activebackground="#f9f9f9")
109 self.Label1.configure(activeforeground="black")
110 self.Label1.configure(background="#d9d9d9")
111 self.Label1.configure(disabledforeground="#a3a3a3")
112 self.Label1.configure(foreground="#000000")
113 self.Label1.configure(highlightbackground="#d9d9d9")
114 self.Label1.configure(highlightcolor="black")
115 self.Label1.configure(text='''查找项:''')
116
117 self.Label2 = tk.Label(top)
118 self.Label2.place(relx=0.41, rely=0.067, height=23, width=42)
119 self.Label2.configure(activebackground="#f9f9f9")
120 self.Label2.configure(activeforeground="black")
121 self.Label2.configure(background="#d9d9d9")
122 self.Label2.configure(disabledforeground="#a3a3a3")
123 self.Label2.configure(foreground="#000000")
124 self.Label2.configure(highlightbackground="#d9d9d9")
125 self.Label2.configure(highlightcolor="black")
126 self.Label2.configure(text='''数值:''')
127
128 self.insert_button = tk.Button(top)
129 self.insert_button.place(relx=0.817, rely=0.844, height=28, width=55)
130 self.insert_button.configure(activebackground="#ececec")
131 self.insert_button.configure(activeforeground="#000000")
132 self.insert_button.configure(background="#d9d9d9")
133 self.insert_button.configure(command=UI_support.on_insert)
134 self.insert_button.configure(disabledforeground="#a3a3a3")
135 self.insert_button.configure(foreground="#000000")
136 self.insert_button.configure(highlightbackground="#d9d9d9")
137 self.insert_button.configure(highlightcolor="black")
138 self.insert_button.configure(pady="0")
139 self.insert_button.configure(text='''新增''')
140
141 self.input_name = ttk.Combobox(top)
142 self.input_name.place(relx=0.183, rely=0.067, relheight=0.051
143 , relwidth=0.172)
144 self.input_name.configure(textvariable=UI_support.combobox)
145 self.input_name.configure(takefocus="")
146 self.input_name.configure(cursor="X_cursor")
147
148 self.Label1_2 = tk.Label(top)
149 self.Label1_2.place(relx=0.083, rely=0.156, height=23, width=42)
150 self.Label1_2.configure(activebackground="#f9f9f9")
151 self.Label1_2.configure(activeforeground="black")
152 self.Label1_2.configure(background="#d9d9d9")
153 self.Label1_2.configure(disabledforeground="#a3a3a3")
154 self.Label1_2.configure(foreground="#000000")
155 self.Label1_2.configure(highlightbackground="#d9d9d9")
156 self.Label1_2.configure(highlightcolor="black")
157 self.Label1_2.configure(text='''结果:''')
158
159 self.show_list = tk.Listbox(top)
160 self.show_list.place(relx=0.083, rely=0.2, relheight=0.267
161 , relwidth=0.823)
162 self.show_list.configure(background="white")
163 self.show_list.configure(disabledforeground="#a3a3a3")
164 self.show_list.configure(font="TkFixedFont")
165 self.show_list.configure(foreground="#000000")
166 self.show_list.configure(highlightbackground="#d9d9d9")
167 self.show_list.configure(highlightcolor="black")
168 self.show_list.configure(selectbackground="blue")
169 self.show_list.configure(selectforeground="white")
170
171 self.Label1_3 = tk.Label(top)
172 self.Label1_3.place(relx=0.09, rely=0.518, height=23, width=64)
173 self.Label1_3.configure(activebackground="#f9f9f9")
174 self.Label1_3.configure(activeforeground="black")
175 self.Label1_3.configure(background="#d9d9d9")
176 self.Label1_3.configure(disabledforeground="#a3a3a3")
177 self.Label1_3.configure(foreground="#000000")
178 self.Label1_3.configure(highlightbackground="#d9d9d9")
179 self.Label1_3.configure(highlightcolor="black")
180 self.Label1_3.configure(text='''新增数据:''')
181
182 self.Label1_4 = tk.Label(top)
183 self.Label1_4.place(relx=0.1, rely=0.622, height=23, width=54)
184 self.Label1_4.configure(activebackground="#f9f9f9")
185 self.Label1_4.configure(activeforeground="black")
186 self.Label1_4.configure(background="#d9d9d9")
187 self.Label1_4.configure(disabledforeground="#a3a3a3")
188 self.Label1_4.configure(foreground="#000000")
189 self.Label1_4.configure(highlightbackground="#d9d9d9")
190 self.Label1_4.configure(highlightcolor="black")
191 self.Label1_4.configure(text='''姓名:''')
192
193 self.Label1_5 = tk.Label(top)
194 self.Label1_5.place(relx=0.467, rely=0.622, height=23, width=54)
195 self.Label1_5.configure(activebackground="#f9f9f9")
196 self.Label1_5.configure(activeforeground="black")
197 self.Label1_5.configure(background="#d9d9d9")
198 self.Label1_5.configure(disabledforeground="#a3a3a3")
199 self.Label1_5.configure(foreground="#000000")
200 self.Label1_5.configure(highlightbackground="#d9d9d9")
201 self.Label1_5.configure(highlightcolor="black")
202 self.Label1_5.configure(text='''年龄:''')
203
204 self.Label1_6 = tk.Label(top)
205 self.Label1_6.place(relx=0.1, rely=0.733, height=23, width=54)
206 self.Label1_6.configure(activebackground="#f9f9f9")
207 self.Label1_6.configure(activeforeground="black")
208 self.Label1_6.configure(background="#d9d9d9")
209 self.Label1_6.configure(disabledforeground="#a3a3a3")
210 self.Label1_6.configure(foreground="#000000")
211 self.Label1_6.configure(highlightbackground="#d9d9d9")
212 self.Label1_6.configure(highlightcolor="black")
213 self.Label1_6.configure(text='''性别:''')
214
215 self.Label1_7 = tk.Label(top)
216 self.Label1_7.place(relx=0.467, rely=0.738, height=23, width=54)
217 self.Label1_7.configure(activebackground="#f9f9f9")
218 self.Label1_7.configure(activeforeground="black")
219 self.Label1_7.configure(background="#d9d9d9")
220 self.Label1_7.configure(disabledforeground="#a3a3a3")
221 self.Label1_7.configure(foreground="#000000")
222 self.Label1_7.configure(highlightbackground="#d9d9d9")
223 self.Label1_7.configure(highlightcolor="black")
224 self.Label1_7.configure(text='''班级:''')
225
226 self.insert_name = tk.Entry(top)
227 self.insert_name.place(relx=0.233, rely=0.622, height=27, relwidth=0.173)
228
229 self.insert_name.configure(background="white")
230 self.insert_name.configure(disabledforeground="#a3a3a3")
231 self.insert_name.configure(font="TkFixedFont")
232 self.insert_name.configure(foreground="#000000")
233 self.insert_name.configure(highlightbackground="#d9d9d9")
234 self.insert_name.configure(highlightcolor="black")
235 self.insert_name.configure(insertbackground="black")
236 self.insert_name.configure(selectbackground="blue")
237 self.insert_name.configure(selectforeground="white")
238
239 self.insert_age = tk.Entry(top)
240 self.insert_age.place(relx=0.6, rely=0.622,height=27, relwidth=0.173)
241 self.insert_age.configure(background="white")
242 self.insert_age.configure(disabledforeground="#a3a3a3")
243 self.insert_age.configure(font="TkFixedFont")
244 self.insert_age.configure(foreground="#000000")
245 self.insert_age.configure(highlightbackground="#d9d9d9")
246 self.insert_age.configure(highlightcolor="black")
247 self.insert_age.configure(insertbackground="black")
248 self.insert_age.configure(selectbackground="blue")
249 self.insert_age.configure(selectforeground="white")
250
251 self.insert_sex = tk.Entry(top)
252 self.insert_sex.place(relx=0.233, rely=0.733,height=27, relwidth=0.173)
253 self.insert_sex.configure(background="white")
254 self.insert_sex.configure(disabledforeground="#a3a3a3")
255 self.insert_sex.configure(font="TkFixedFont")
256 self.insert_sex.configure(foreground="#000000")
257 self.insert_sex.configure(highlightbackground="#d9d9d9")
258 self.insert_sex.configure(highlightcolor="black")
259 self.insert_sex.configure(insertbackground="black")
260 self.insert_sex.configure(selectbackground="blue")
261 self.insert_sex.configure(selectforeground="white")
262
263 self.insert_class = ttk.Combobox(top)
264 self.insert_class.place(relx=0.6, rely=0.733, relheight=0.051
265 , relwidth=0.172)
266 self.insert_class.configure(textvariable=UI_support.combobox2)#修改数据源
267 self.insert_class.configure(takefocus="")
268
269 if __name__ == '__main__':
270 vp_start_gui()
UI_support.py
1 #! /usr/bin/env python
2 # -*- coding: utf-8 -*-
3 #
4 # Support module generated by PAGE version 5.4
5 # in conjunction with Tcl version 8.6
6 # Oct 20, 2020 09:35:42 AM CST platform: Windows NT
7 # Nov 03, 2020 05:18:17 PM CST platform: Windows NT
8 # Nov 03, 2020 05:19:47 PM CST platform: Windows NT
9
10 import sys
11
12 try:
13 import Tkinter as tk
14 except ImportError:
15 import tkinter as tk
16
17 try:
18 import ttk
19 py3 = False
20 except ImportError:
21 import tkinter.ttk as ttk
22 py3 = True
23
24 import mysql.connector
25 class sql:
26 def __init__(self):
27 self.con = mysql.connector.connect(
28 host="localhost", # 数据库主机地址
29 user="root", # 数据库用户名
30 passwd="123456", # 数据库密码
31 database="test" #数据库名称
32 )
33 self.cursor = self.con.cursor()
34
35 def select(self,sql_sr): #类定义了init后下面的函数第一参数必须是self否则引用报错
36 self.cursor.execute(sql_sr)
37 result = self.cursor.fetchall()
38 return result
39
40 def insert(self,sql_sr):
41 self.cursor.execute(sql_sr)
42 self.con.commit()
43 print(self.cursor.rowcunt,'新增成功')
44
45 def set_Tk_var():
46 global combobox
47 combobox = tk.StringVar()
48 global combobox2 #增加一个数据源给第二个commbox引用
49 combobox2 = tk.StringVar()
50 global selectedButton
51 selectedButton = tk.IntVar()
52
53 def init(top, gui, *args, **kwargs):
54 global w, top_level, root
55 w = gui
56 top_level = top
57 root = top
58
59 sql_sr = "SELECT COLUMN_NAME FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'test' AND TABLE_NAME = 'student'"
60 cbox_val = sql().select(sql_sr)
61 w.input_name.configure(values = cbox_val) #设置下拉列表的值,前面定义w是引用UI.py的意思
62 w.input_name.configure(state='readonly') #设置为只读
63
64 sql_sr2 = "select class.name from class"
65 cbox_val2 = sql().select(sql_sr2)
66
67 w.insert_class.configure(values = cbox_val2)
68 w.insert_class.configure(state='readonly')
69
70 def on_select():
71 w.show_list.delete(0,'end') #清空显示区原有信息
72 name = w.input_name.get() #获取下拉列表当前值
73 varlue = w.input_valuse.get()
74 sql_sr = "select * from Student where student." + name + "=" + "'" + varlue +"'"
75 result = sql().select(sql_sr)
76 for x in result:
77 w.show_list.insert('end',x)
78 sys.stdout.flush()
79
80 def on_insert():
81 name = w.insert_name.get()
82 age = w.insert_age.get()
83 sex = w.insert_sex.get()
84 myclass = w.insert_class.get()
85 sql_sr = "INSERT INTO Student (name,age,sex,class) VALUES ('"+name+"',"+age+","+sex+",'"+myclass+"')"
86 print(sql_sr)
87 sql().insert(sql_sr)
88 sys.stdout.flush()
89
90 def destroy_window():
91 # Function which closes the window.
92 global top_level
93 top_level.destroy()
94 top_level = None
95
96 if __name__ == '__main__':
97 import UI
98 UI.vp_start_gui()