python实战GUI界面+mysql

前言

前面用tkinter做了一个巨丑的GUI界面,今天想把它变漂亮起来,重新找回page做了一个界面,它也是基于tkinter开发的所见即所得的界面编辑器,前面因为代码搞不明白没用上,现在重新研究一下。

一、打开page,软件自己在网上搜索下载的。它的界面挺有意思的,不是我们常见的形式,它分开了五个部分可以随便拖动,各部分间就是桌面,没有连在一起。

New Toplevel 就是工作台,可以将元件放置在上面。

Widget Toolbar 里就是可用的元件。

Attrbute Editor 编辑元件属性。

Widget Tree 元件导航树。

page手册://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()