作为一个刚学习Python不久的小白,成长之路上的坑坑坎坎沟沟壑壑必不可少,在我完成我的第一个程序之后(或许并不能称为程序,因为它实在是漏洞百出),通过我的自我总结我发现,学习前人的经验是一个少走弯路的最简单的捷径,哪怕这个经验是如此简单幼稚甚至是错误的,它总有自己的价值,所以在此写下我的经验和经历,希望哪怕有一个人在这里吸收一丁点的经验。
我们就此开始,但是必须要事先声明的是,软件和程序以及系统的开发是有具体的流程的,不过在这里只是作为学习用途使用,可以先忽略不计(这样是不对的,如果你有兴趣可以参考“何处锦绣不灰堆”大大的博客一个软件完整的开发流程介绍)。
- 程序的功能
虽然我们略过了一些步骤,但是必要的思考还是要做的,比如这个程序都要实现哪些功能。一个程序查询系统首先要进行登录(而且要区分教师和学生的登陆,毕竟教师和学生的权限不应该相同);然后要有注册;个人信息查询;个人成绩查询;查看全体成绩;学生间成绩互评;教师修改和重置学生的登陆密码;甚至是教师还有权限修改学生成绩。
在我看来一个系统的登陆是需要一个主界面的,然后在点击“学生登陆”或是“教师登陆”后弹出登录窗口来让你输入账号和密码。但在此我们略过此步,直接进入登录界面。
- 登陆
登录界面相信大家见过许多,每天使用的QQ,微信,微博都需要登陆,但是它们是很完善的,我们只是简单的系统而已,并不需要考虑一些“验证码”和“记住密码”、“忘记密码”的问题。当然,如果你喜欢的话,它们并不十分困难。
我们只需要一个具备基本功能的界面而已,类似下面这样:
当然,所有的文本都可以按你喜欢的样子来编辑,不论你习惯把Password称为密码还是口令。
接下来,便是如何实现这个界面(我使用的是WX和MySQL数据库,你可以根据自己的需要进行修改):
import wx
import pymysql
class MyApp(wx.Frame):
def __init__(self, *args, **kw):
wx.Frame.__init__(self, *args, **kw)
# frame = wx.Frame(parent=None, title='登陆界面', size=(450, 300))
self.Center()
self.panel = wx.Panel(self)
self.LoginInterface()
def LoginInterface(self):
# 添加静态标签
label_user = wx.StaticText(self.panel, -1, "学号:", pos=(80, 50))
label_pass = wx.StaticText(self.panel, -1, "密码:", pos=(80, 100))
# 设置输入
self.entry_user = wx.TextCtrl(self.panel, -1, size=(200, 30), pos=(130, 50))
self.entry_pass = wx.TextCtrl(self.panel, -1, size=(200, 30), pos=(130, 100), style=wx.TE_PASSWORD)
# 添加按钮
self.but_teclogin = wx.Button(self.panel, -1, "教师登陆", size=(80, 30), pos=(80, 150))
self.but_login = wx.Button(self.panel, -1, "登陆", size=(80, 30), pos=(165, 150))
self.but_register = wx.Button(self.panel, -1, "注册", size=(80, 30), pos=(250, 150))
#绑定事件
if __name__ == '__main__':
app = wx.App()
login = MyApp(None, title="CSDN学生信息管理系统", size=(450, 300))
login.Show()
app.MainLoop()
这样运行,便会实现上述的窗口,只不过现在它还只是一个窗口而已,它并没有用处,因为你并没有为它的按钮定义和绑定事件。
这个程序段有很多不完善和不符合规则之处,因为时间问题,没有做什么修改,只是简单地编写出来,事实上你并不能像我这样做,否则你的同事可能会揍你一顿。
没有选择使用Qt Designer是因为我觉得WX更为简单一点而已,在此并不想讨论哪个更为优秀,因为存在即为合理,它们必然有自己的独到之处。你也可以忽略这句话,因为我也还只是还在入门处挣扎的一只小白而已。
言归正传,在你添加完按钮之后,你还要为他们绑定事件:
# 给按钮绑定事件
self.Bind(wx.EVT_BUTTON, self.on_but_login, self.but_login)
self.Bind(wx.EVT_BUTTON, self.on_but_register, self.but_register)
self.Bind(wx.EVT_BUTTON, self.on_but_teclogin, self.but_teclogin)
除此之外,你还要做一些工作:
定义on_but_login、on_but_register、on_but_teclogin以及弹出提示窗口的事件。
def show_message(self, word=""):
dlg = wx.MessageDialog(None, word, u"提示", wx.YES_NO | wx.ICON_QUESTION)
if dlg.ShowModal() == wx.ID_YES:
pass
dlg.Destroy()
# 点击登陆后的绑定事件
def on_but_login(self, event):
# 将输入赋值给定量
user_name = self.entry_user.GetValue()
pass_word = self.entry_pass.GetValue()
sql = """select * from t_user where USERNAME ='%s' """ % (user_name)
# 判断用户名和密码是否为空
if user_name and pass_word:
# 连接数据库
db = pymysql.connect(host="localhost", user="用户名",
password="密码", db="数据库名", port=3306)
cur = db.cursor()
try:
cur.execute(sql)
results = cur.fetchall()
# 察看用户名是否存在
if results:
# 察看密码是否正确
if results[0][2] == pass_word:
self.show_message(word="登陆成功")
from information import MyApp_information
operation = MyApp_information(name=user_name,parent=None, title='查询界面', size=(450, 300))
operation.Show()
self.Close(True)
#from information import MyApp_information
#MyApp_information()
pass
else:
self.show_message(word="密码错误")
else:
self.show_message(word='用户名不存在')
except Exception as e:
db.rollback()
finally:
# 关闭连接
db.close()
else:
self.show_message(word='学号和密码不能为空')
def on_but_register(self, event):
from register import MyApp_register
operation = MyApp_register(parent=None, title='登陆界面', size=(450, 300))
operation.Show()
self.Close(True)
def on_but_teclogin(self, event):
from teacherlogin import MyApp_teclogin
operation = MyApp_teclogin(parent=None, title='教师登陆界面', size=(450, 300))
operation.Show()
self.Close(True)
你可以选择在点击注册按钮和教师登陆按钮后不关闭登陆界面,你只需要将
self.Close(True)
注释掉即可,但在普遍的逻辑中,登录界面需要被关掉。当然这是后话,现在你点击一些按钮会出现错误,因为你并没有register、teacherlogin、information的py文件。这些会在之后慢慢完善。
其中,数据库的链接以及sql语句需要按你自己的实际情况进行修改。而我用的t_user表结构如下:
UID | USERNAME | RND | IDENTITY |
---|---|---|---|
1 | 12345601 | 01 | 0 |
2 | 12345602 | 02 | 0 |
3 | 12345603 | 03 | 0 |
4 | 12345604 | 04 | 0 |
5 | 12345605 | 05 | 0 |
6 | 12345606 | 06 | 0 |
7 | 12345607 | 07 | 0 |
IDENTITY这一列你可以选择忽略不计,因为它只存在于我最初的设想之中。设想中,教师和学生的账户密码存在于同一个表中,通过IDENTITY这一列中的“0”和“1”以及程序中添加一段代码来区分教师和学生身份。只是因为这样可能引起不必要的麻烦,而且…再创建一个教师登录表的话更为简单一点。
缩进是一个很简单但是很重要的问题,你可以按你的习惯来使用空格或是Tab键,但是缩进一定要正确。不然他会在编写代码过程中提示你“这个定义没有被用到”,转而在程序报错中告诉你“这个东西没有被定义”。
下面给出这个登录界面的完整代码,以防像我一样出现缩进错误这样的愚蠢的问题。
import wx
import pymysql
class MyApp(wx.Frame):
def __init__(self, *args, **kw):
wx.Frame.__init__(self, *args, **kw)
# frame = wx.Frame(parent=None, title='登陆界面', size=(450, 300))
self.Center()
self.panel = wx.Panel(self)
self.LoginInterface()
def LoginInterface(self):
# 添加静态标签
label_user = wx.StaticText(self.panel, -1, "学号:", pos=(80, 50))
label_pass = wx.StaticText(self.panel, -1, "密码:", pos=(80, 100))
# 设置输入
self.entry_user = wx.TextCtrl(self.panel, -1, size=(200, 30), pos=(130, 50))
self.entry_pass = wx.TextCtrl(self.panel, -1, size=(200, 30), pos=(130, 100), style=wx.TE_PASSWORD)
# 添加按钮
self.but_teclogin = wx.Button(self.panel, -1, "教师登陆", size=(80, 30), pos=(80, 150))
self.but_login = wx.Button(self.panel, -1, "登陆", size=(80, 30), pos=(165, 150))
self.but_register = wx.Button(self.panel, -1, "注册", size=(80, 30), pos=(250, 150))
# 给按钮绑定事件
self.Bind(wx.EVT_BUTTON, self.on_but_login, self.but_login)
self.Bind(wx.EVT_BUTTON, self.on_but_register, self.but_register)
self.Bind(wx.EVT_BUTTON, self.on_but_teclogin, self.but_teclogin)
# 单击登陆按钮弹出的对话框----成功
def show_message(self, word=""):
dlg = wx.MessageDialog(None, word, u"提示", wx.YES_NO | wx.ICON_QUESTION)
if dlg.ShowModal() == wx.ID_YES:
pass
dlg.Destroy()
# 点击登陆后的绑定事件
def on_but_login(self, event):
# 将输入赋值给定量
user_name = self.entry_user.GetValue()
pass_word = self.entry_pass.GetValue()
sql = """select * from t_user where USERNAME ='%s' """ % (user_name)
# 判断用户名和密码是否为空
if user_name and pass_word:
# 连接数据库
db = pymysql.connect(host="localhost", user="root",
password="Passw0rd", db="testdb", port=3306)
cur = db.cursor()
try:
cur.execute(sql)
results = cur.fetchall()
# 察看用户名是否存在
if results:
# 察看密码是否正确
if results[0][2] == pass_word:
self.show_message(word="登陆成功")
from information import MyApp_information
operation = MyApp_information(name=user_name,parent=None, title='查询界面', size=(450, 300))
operation.Show()
self.Close(True)
#from information import MyApp_information
#MyApp_information()
pass
else:
self.show_message(word="密码错误")
else:
self.show_message(word='用户名不存在')
except Exception as e:
db.rollback()
finally:
# 关闭连接
db.close()
else:
self.show_message(word='学号和密码不能为空')
def on_but_register(self, event):
from register import MyApp_register
operation = MyApp_register(parent=None, title='登陆界面', size=(450, 300))
operation.Show()
self.Close(True)
def on_but_teclogin(self, event):
from teacherlogin import MyApp_teclogin
operation = MyApp_teclogin(parent=None, title='教师登陆界面', size=(450, 300))
operation.Show()
self.Close(True)
if __name__ == '__main__':
app = wx.App()
login = MyApp(None, title="CSDN学生信息管理系统", size=(450, 300))
login.Show()
app.MainLoop()
随缘更新,望诸君共勉。
编程新人,漏洞百出,感谢随时指正。