前言
前面用tkinter做了一个巨丑的GUI界面,今天想把它变漂亮起来,重新找回page做了一个界面,它也是基于tkinter开发的所见即所得的界面编辑器,前面因为代码搞不明白没用上,现在重新研究一下。
一、打开page,软件自己在网上搜索下载的。它的界面挺有意思的,不是我们常见的形式,它分开了五个部分可以随便拖动,各部分间就是桌面,没有连在一起。
New Toplevel 就是工作台,可以将元件放置在上面。
Widget Toolbar 里就是可用的元件。
Attrbute Editor 编辑元件属性。
Widget Tree 元件导航树。
二、画好自己的界面,这下漂亮多了。
三、接下来导出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):globalw, 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中作如下修改:
defset_Tk_var():globalcombobox
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里去写这两个按钮的逻辑了,试试看。
先写“查找”按钮
defon_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 inresult:
w.show_list.insert('end',x)
sys.stdout.flush()
查找成功
再写“新增”按钮
defon_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 importsys9
10 try:11 importTkinter as tk12 exceptImportError:13 importtkinter as tk14
15 try:16 importttk17 py3 =False18 exceptImportError:19 importtkinter.ttk as ttk20 py3 =True21
22 importUI_support23
24 defvp_start_gui():25 '''Starting point when module is the main routine.'''
26 globalval, w, root27 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 =None34 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 globalw, w_win, root38 #rt = root
39 root =rt40 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 defdestroy_database():47 globalw48 w.destroy()49 w =None50
51 classdatabase: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 importsys11
12 try:13 importTkinter as tk14 exceptImportError:15 importtkinter as tk16
17 try:18 importttk19 py3 =False20 exceptImportError:21 importtkinter.ttk as ttk22 py3 =True23
24 importmysql.connector25 classsql: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 returnresult39
40 definsert(self,sql_sr):41 self.cursor.execute(sql_sr)42 self.con.commit()43 print(self.cursor.rowcunt,'新增成功')44
45 defset_Tk_var():46 globalcombobox47 combobox =tk.StringVar()48 global combobox2 #增加一个数据源给第二个commbox引用
49 combobox2 =tk.StringVar()50 globalselectedButton51 selectedButton =tk.IntVar()52
53 def init(top, gui, *args, **kwargs):54 globalw, top_level, root55 w =gui56 top_level =top57 root =top58
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 defon_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 inresult:77 w.show_list.insert('end',x)78 sys.stdout.flush()79
80 defon_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 defdestroy_window():91 #Function which closes the window.
92 globaltop_level93 top_level.destroy()94 top_level =None95
96 if __name__ == '__main__':97 importUI98 UI.vp_start_gui()