设计一个父类,表示游戏角色:派生出多个子类用于表示不同职业的角色,为每个类设置必要的属性和方法,并实例化对象进行测试。
父类名称为People,其基本属性有生命值,护甲,魔法抗性,物理伤害,魔法伤害,技能数量,速度(表示攻击的先后顺序),是否已经阵亡等。派生出3个子类,表示不同的职业,分别有战士Warrior,法师Wizard,以及医疗者Healer。战士的普通攻击比较高,其技能伤害也是物理伤害。法师的魔法伤害比较高,技能伤害主要是魔法伤害,并且部分技能有AOE(群体伤害)效果。医疗者主要是进行增加攻击力,增加防御,削减对面的攻击力和削减对面魔抗,还可以治疗己方的受伤单位,但不可以复活已经阵亡的角色。
游戏有两个阵营,A阵营和B阵营。游戏类为这两个阵营分别创建角色,每个职业各创建一个角色。角色创建完成后,其攻击,防御、技能、速度等属性已经设置完毕。然后将AB两个阵营的角色放入一个SpeedList,用来维护每个角色的速度值,将他们的速度值按照由小到大排序,表示执行攻击的先后顺序。SpeedList是个循环队列,用来表示每个角色循环攻击。
BattleField同时还维护了双方玩家的增/减益效果,双方未阵亡玩家的数目以及增/减益效果的重置。对于Healer的增/减益效果,只保持到双方玩家攻击一轮结束。
首先创建一个BattleField对象,在构造函数中分别为两个阵营AB各创建一个战士Warrior,法师Wizard,以及医疗者Healer。在实例化对象的时候,在其默认的属性定值上加上随机数。Warrior的攻击和物理防御较高,Wizard的法术强度和魔抗较高,Healer的攻击和防御都较低。并未每个对象都随机初始化一个speed,并将其加入SpeedList来确定攻击的先后顺序。同时每个对象随机学习技能。通过GameStart()方法来开始游戏,双方循环进行攻击。在攻击的时候,产生一个随机数,通过技能的范围(技能表中的sta-end)来定时发动技能还是普通攻击。
在攻击之前,随机制定一个对方未阵亡的对象,作为潜在攻击目标。
若发动技能,则判定技能是群体攻击(AOE)还是单体攻击(Single),若是群体攻击,则对地方所有未阵亡的单位进行造成伤害。若是单体攻击或者是普通攻击,则对潜在攻击目标造成伤害。攻击完成之后,进行伤害判定,若HP小于等于0,则该角色阵亡,其实例化对象的IsDead属性为True。
特别的,若是Healer发动技能,造成增益或者减益,则传入BattleField类,其中有Abuff和Bbuff用来维护双方的增益和减益效果,在每轮攻击结束后(即列表中每个角色都发动一次攻击),增益或者减益效果清零通过BattleField类的Refresh方法来实现。
伤害计算较为简单,伤害 = ceil (攻击 * (1 – 防御*0.01 ) ),其中攻击可以是物理攻击或魔法攻击,也同时包括物理技能伤害和魔法的技能伤害;而防御包括物理防御,即护甲(Armor),也包括魔法防护,即魔抗(MagicResistance)。
每次攻击,造成的伤害或者造成的阵亡消息,都会在屏幕上输出显示,这个功能写入在每个角色的类中。若由一方角色全部死亡,则另一方获胜,游戏结束。
设计时遇到的第一个问题是伤害的计算方法,从之前的玩过的游戏,有的
是有自己的伤害计算方法,通过查看相关资料,选择了最简单的百分比减伤的方法,但是在设计Healer的增益或者减益效果的时候,就不能太过,否则游戏的平衡性就大打折扣。
第二个难点是在维护双方状态时的设定,最后选择将他放在了战场类。这么做的原因是在没轮结束后会更新双方状态,由于轮流攻击的判定是在战场类实现的,这样在双方攻击完后,再重置状态,比在外面维护比较方便。还有一种解决方案就是在People类中加上Buff的状态维护,这样的话对于每个实例化对象都可以有个性化的增益或者衰减值,同时维护的成本比较大。两种方法各有千秋。
可以改进的地方有很多。比如这里的Buff只可以维护一轮攻击,实际游戏中常常是每种Buff都有不同的状态,削减效果,增益效果或者持续时间。解决办法是为Buff单独创建一个类,其中包含各种效果,通过战场类来维护维护时间,在角色类上维护效果,这样就可解决。
MidWar.py
import random
import math
NameList = ['高斯','威尔逊','艾米','哈伦','路西法','詹姆斯','鲍勃','吉米','提姆','爱丽丝','汤姆逊','罗宾逊']
WarriorSkills = [
{'SkillName':'降龙十八掌','Damage':35,'Type':'Single','Sta':1,'End':25},
{'SkillName':'排山倒海','Damage':25,'Type':'AOE','Sta':26,'End':45},
{'SkillName':'猛龙摆尾','Damage':25,'Type':'Single','Sta':46,'End':70},
{'SkillName':'回旋破击斩','Damage':30,'Type':'Single','Sta':71,'End':95},
{'SkillName':'万箭穿心','Damage':45,'Type':'Single','Sta':96,'End':100 }
]
WizardSkills = [
{'SkillName':'寒冰掌','Damage':30,'Type':'Single','Sta':1,'End':50},
{'SkillName':'暴风雪','Damage':40,'Type':'AOE','Sta':51,'End':60},
{'SkillName':'火球术','Damage':45,'Type':'Single','Sta':61,'End':70},
{'SkillName':'黑暗沼泽','Damage':30,'Type':'AOE','Sta':71,'End':95},
{'SkillName':'致命衰弱','Damage':65,'Type':'Single','Sta':96,'End':100 }
]
HealerSkills = [
{'SkillName':'攻击增强术','Damage':15,'Type':'AtaE','Sta':1,'End':25},
{'SkillName':'防御增强术','Damage':15,'Type':'DefE','Sta':26,'End':45},
{'SkillName':'攻击削减术','Damage':-15,'Type':'AtaD','Sta':46,'End':65},
{'SkillName':'防御削减术','Damage':-15,'Type':'DefD','Sta':66,'End':85},
{'SkillName':'妙手回春','Damage':15,'Type':'Cure','Sta':86,'End':100}
]
class People():
def __init__(self):
self.Name = random.choice(NameList)
self.HealthPoint = 100 # 生命值
self.Armor = 0 # 护甲
self.MagicResistance = 0 # 魔法抗性
self.AbilityDamage = 0 # 物理伤害
self.MagicDamage = 0 # 魔法伤害
self.SkillNum = 0 # 技能数量
self.Speed = 0 # 速度-攻击先后顺序
self.IsDead = False # 是否已经死亡
self.Players = 3 # 队伍玩家数量
class Warrior (People):
def __init__(self,Team):
super(Warrior , self).__init__()
self.LearnSkills()
self.SetAttri(Team)
self.Name = '[战士]'+ self.Name
print(self.SkillList)
def LearnSkills(self):
self.SkillNum = random.randint(1,2)
self.SkillList = []
TempSet = set()
TempNum = self.SkillNum
while TempNum:
TempSkill = random.choice(WarriorSkills)
if TempSkill['SkillName'] in TempSet:
continue
else:
TempSet.add(TempSkill['SkillName'])
self.SkillList.append(TempSkill)
TempNum -= 1
def SetAttri(self,Team):
self.Armor = 30 + random.randint(-5,5)
self.AbilityDamage = 25 + random.randint(-10,10)
self.MagicDamage = 0
self.MagicResistance = 15 + random.randint(-5,5)
self.Speed = random.randint(1,100)
self.Team = Team
def Attack(self,target,friends):
seed = random.randint(1,100) # 普攻/技能判定种子
targetseed = -1 # 攻击目标判定种子
AttackType = -1 # 攻击种类
DeadNum = 0 # 本轮攻击死亡人数
while 1: # 找到一个攻击目标
targetseed = random.randint(0,self.Players-1)
if target[targetseed].IsDead == False:
break
else:
continue
for i in range(len(self.SkillList)):
if seed >= self.SkillList[i]['Sta'] and seed <= self.SkillList[i]['End']:
AttackType = i
break
# 判断攻击是类型
if AttackType == -1:
# 普通攻击
print(self.Team+'队的'+self.Name+'发动了'+'普通攻击',end = '')
TempDamage = int(math.ceil(self.AbilityDamage * (1 - target[targetseed].Armor * 0.01)))
target[targetseed].HealthPoint -= TempDamage
print(',对'+target[targetseed].Name+'造成了'+str(TempDamage)+'点伤害!',end = '')
if target[targetseed].HealthPoint <=0:
target[targetseed].IsDead = True
print('【并使其死亡!!】',end = '')
DeadNum += 1
print('\n\r')
else:
# 技能攻击
if self.SkillList[i]['Type'] == 'AOE':
# 范围伤害
print(self.Team+'队的'+self.Name+'发动了【'+self.SkillList[AttackType]['SkillName']+'】',end = '')
for i in target:
if i.IsDead:
continue
TempDamage = int(math.ceil(self.SkillList[AttackType]['Damage'] * (1 - i.Armor * 0.01)))
print(',对'+i.Name+'造成了'+str(TempDamage)+'点伤害!',end = '')
i.HealthPoint -= TempDamage
if i.HealthPoint <=0 :
i.IsDead = True
print('【并使其死亡!!】',end = '')
DeadNum += 1
print('\n\r')
else:
# 单体伤害
print(self.Team+'队的'+self.Name+'发动了【'+self.SkillList[AttackType]['SkillName'],end = '')
TempDamage = int(self.SkillList[AttackType]['Damage'] * (1 - target[targetseed].Armor * 0.01))
target[targetseed].HealthPoint -= TempDamage
print('】,对'+target[targetseed].Name+'造成了'+str(TempDamage)+'点伤害!',end = '')
if target[targetseed].HealthPoint <=0:
target[targetseed].IsDead = True
print('【并使其死亡!!】',end = '')
DeadNum +=1
print('\n\r')
return DeadNum
class Wizard (People):
def __init__(self,Team):
super(Wizard , self).__init__()
self.LearnSkills()
self.SetAttri(Team)
self.Name = '[法师]'+ self.Name
print(self.SkillList)
def LearnSkills(self):
self.SkillNum = random.randint(1,3)
self.SkillList = []
TempSet = set()
TempNum = self.SkillNum
while TempNum:
TempSkill = random.choice(WizardSkills)
if TempSkill['SkillName'] in TempSet:
continue
else:
TempSet.add(TempSkill['SkillName'])
self.SkillList.append(TempSkill)
TempNum -= 1
def SetAttri(self,Team):
self.Armor = 10 + random.randint(-5,5)
self.AbilityDamage = 10 + random.randint(-5,10)
self.MagicDamage = 40 + random.randint(-25,15)
self.MagicResistance = 35 + random.randint(-5,5)
self.Speed = random.randint(1,100)
self.Team = Team
def Attack(self,target,friends):
seed = random.randint(1,100) # 普攻/技能判定种子
targetseed = -1 # 攻击目标判定种子
AttackType = -1 # 攻击种类
DeadNum = 0 # 本次攻击死亡人数
while 1: # 找到一个攻击目标
targetseed = random.randint(0,self.Players-1)
if target[targetseed].IsDead == False:
break
else:
continue
for i in range(len(self.SkillList)):
if seed >= self.SkillList[i]['Sta'] and seed <= self.SkillList[i]['End']:
AttackType = i
break
# 判断攻击是类型
if AttackType == -1:
# 普通攻击
print(self.Team+'队的'+self.Name+'发动了'+'普通攻击',end = '')
TempDamage = int(math.ceil(self.AbilityDamage * (1 - target[targetseed].Armor * 0.01)))
target[targetseed].HealthPoint -= TempDamage
print(',对'+target[targetseed].Name+'造成了'+str(TempDamage)+'点伤害!',end = '')
if target[targetseed].HealthPoint <=0:
target[targetseed].IsDead = True
print('【并使其死亡!!】',end = '')
DeadNum += 1
print('\n\r')
else:
# 技能攻击
if self.SkillList[i]['Type'] == 'AOE':
# 范围伤害
print(self.Team+'队的'+self.Name+'发动了【'+self.SkillList[AttackType]['SkillName']+'】',end = '')
for i in target:
if i.IsDead:
continue
TempDamage = int(math.ceil(self.SkillList[AttackType]['Damage'] * (1 - i.Armor * 0.01)))
print(',对'+i.Name+'造成了'+str(TempDamage)+'点伤害!',end = '')
i.HealthPoint -= TempDamage
if i.HealthPoint <=0 :
i.IsDead = True
print('【并使其死亡!!】',end = '')
DeadNum += 1
print('\n\r')
else:
# 单体伤害
print(self.Team+'队的'+self.Name+'发动了【'+self.SkillList[AttackType]['SkillName'],end = '')
TempDamage = int(self.SkillList[AttackType]['Damage'] * (1 - target[targetseed].Armor * 0.01))
target[targetseed].HealthPoint -= TempDamage
print('】,对'+target[targetseed].Name+'造成了'+str(TempDamage)+'点伤害!',end = '')
if target[targetseed].HealthPoint <=0:
target[targetseed].IsDead = True
print('【并使其死亡!!】',end = '')
DeadNum += 1
print('\n\r')
return DeadNum
class Healer (People):
def __init__(self,Team):
super(Healer , self).__init__()
self.LearnSkills()
self.SetAttri(Team)
self.Name = '[治疗者]'+ self.Name
print(self.SkillList)
def LearnSkills(self):
self.SkillNum = random.randint(1,3)
self.SkillList = []
TempSet = set()
TempNum = self.SkillNum
while TempNum:
TempSkill = random.choice(HealerSkills)
if TempSkill['SkillName'] in TempSet:
continue
else:
TempSet.add(TempSkill['SkillName'])
self.SkillList.append(TempSkill)
TempNum -= 1
def SetAttri(self,Team):
self.Armor = 20 + random.randint(-5,5)
self.AbilityDamage = 20 + random.randint(-5,5)
self.MagicDamage = 3 + random.randint(-2,3)
self.MagicResistance = 20 + random.randint(-5,5)
self.Speed = random.randint(1,100)
self.Team = Team
def Refresh(self,obj,num,type):
# type = 0 攻击
# type = 1 防御
if type == 0:
Amount = num['Attack']
for i in obj:
if i.IsDead == False:
i.AbilityDamage += Amount
i.MagicDamage += Amount
else:
Amount = num['Defence']
for i in obj:
if i.IsDead == False:
i.MagicResistance += Amount
i.Armor += Amount
def Attack(self,target,friends,tarbuf,fribuf):
seed = random.randint(1,100) # 普攻/技能判定种子
targetseed = -1 # 攻击目标判定种子
AttackType = -1 # 攻击种类
DeadNum = 0 # 本次攻击死亡人数
while 1: # 找到一个攻击目标
targetseed = random.randint(0,self.Players-1)
if target[targetseed].IsDead == False:
break
else:
continue
for i in range(len(self.SkillList)):
if seed >= self.SkillList[i]['Sta'] and seed <= self.SkillList[i]['End']:
AttackType = i
break
# 判断攻击是类型
if AttackType == -1:
# 普通攻击
print(self.Team+'队的'+self.Name+'发动了'+'普通攻击',end = '')
TempDamage = int(math.ceil(self.AbilityDamage * (1 - target[targetseed].Armor * 0.01)))
target[targetseed].HealthPoint -= TempDamage
print(',对'+target[targetseed].Name+'造成了'+str(TempDamage)+'点伤害!',end = '')
if target[targetseed].HealthPoint <=0:
target[targetseed].IsDead = True
print('【并使其死亡!!】',end = '')
DeadNum += 1
print('\n\r')
else:
# 技能攻击
if self.SkillList[AttackType]['Type'] == 'AtaE': # 我方攻击增强
fribuf['Attack'] += self.SkillList[AttackType]['Damage'] + self.MagicDamage
print(self.Team+'队的'+self.Name+'发动了【'+self.SkillList[AttackType]['SkillName']+'】,我方攻击增加'+str(fribuf['Attack'])+'点!!!',end = '')
self.Refresh(friends,fribuf,0)
elif self.SkillList[AttackType]['Type'] == 'DefE': # 我方防御增强
fribuf['Defence'] += self.SkillList[AttackType]['Damage'] + self.MagicDamage
print(self.Team+'队的'+self.Name+'发动了【'+self.SkillList[AttackType]['SkillName']+'】,我方防御增加'+str(fribuf['Defence'])+'点!!!',end = '')
self.Refresh(friends,fribuf,1)
elif self.SkillList[AttackType]['Type'] == 'AtaD': # 敌方攻击减弱
tarbuf['Attack'] -= self.SkillList[AttackType]['Damage'] + self.MagicDamage
print(self.Team+'队的'+self.Name+'发动了【'+self.SkillList[AttackType]['SkillName']+'】,敌方攻击减弱'+str(tarbuf['Attack'])+'点!!!',end = '')
self.Refresh(target,tarbuf,0)
elif self.SkillList[AttackType]['Type'] == 'DefD': # 敌方防御减弱
tarbuf['Defence'] -= self.SkillList[AttackType]['Damage'] + self.MagicDamage
print(self.Team+'队的'+self.Name+'发动了【'+self.SkillList[AttackType]['SkillName']+'】,敌方防御减弱'+str(tarbuf['Defence'])+'点!!!',end = '')
self.Refresh(target,tarbuf,1)
elif self.SkillList[AttackType]['Type'] == 'Cure': # 我方治疗
CureAmount = self.SkillList[AttackType]['Damage'] + self.MagicDamage
print(self.Team+'队的'+self.Name+'发动了【'+self.SkillList[AttackType]['SkillName']+'】,全体队员恢复'+str(CureAmount)+'点生命值!!!',end = '')
for i in friends:
if i.IsDead == True: # 死亡的无法复活
continue
i.HealthPoint += CureAmount
if i.HealthPoint > 100:
i.HealthPoint = 100
print('\n\r')
return DeadNum
class BattleField():
def __init__(self):
self.CallPlayers()
def CallPlayers(self):
self.TotNum = 6
self.Aleft = 3
self.Bleft = 3
self.AList = [Warrior('A'),Wizard('A'),Healer('A')]
self.BList = [Warrior('B'),Wizard('B'),Healer('B')]
self.ABuff = {'Attack':0,'Defence':0}
self.BBuff = {'Attack':0,'Defence':0}
self.SpeedList = []
for i in self.AList:
self.SpeedList.append([i.Speed,i])
for i in self.BList:
self.SpeedList.append([i.Speed,i])
for i in range(len(self.SpeedList)):
for j in range(len(self.SpeedList)-i-1):
if self.SpeedList[j][0] > self.SpeedList[j+1][0]:
self.SpeedList[j], self.SpeedList[j+1] = self.SpeedList[j+1], self.SpeedList[j]
def GameStart(self):
while self.Aleft!=0 and self.Bleft!=0:
self.FlushRound()
if self.Aleft == 0:
print('队伍B获胜')
else:
print('队伍A获胜')
def FlushRound(self):
Number = self.Aleft + self.Bleft
# 遍历速度列表,分别执行攻击
while Number:
NowSpeed, NowGamer = self.SpeedList.pop(0)
Dead = 0
if NowGamer.IsDead != True:
# 判断是否存活
if NowGamer.Team == 'A':
if type(NowGamer) == Healer:
Dead = NowGamer.Attack(self.BList,self.AList,self.BBuff,self.ABuff)
else:
Dead = NowGamer.Attack(self.BList,self.AList)
if Dead !=0 :
self.Bleft -= Dead
else:
if type(NowGamer) == Healer:
Dead = NowGamer.Attack(self.AList,self.BList,self.ABuff,self.BBuff)
else:
Dead = NowGamer.Attack(self.AList,self.BList)
if Dead != 0:
self.Aleft -= Dead
if self.Aleft == 0 or self.Bleft ==0:
break
Number-=1
self.SpeedList.append([NowSpeed,NowGamer])
self.Refresh()
def Refresh(self):
# 重置Buff
for i in self.AList:
i.AbilityDamage -= self.ABuff['Attack']
i.MagicDamage -= self.ABuff['Attack']
i.Armor -= self.ABuff['Defence']
i.MagicResistance -= self.ABuff['Defence']
for i in self.BList:
i.AbilityDamage -= self.BBuff['Attack']
i.MagicDamage -= self.BBuff['Attack']
i.Armor -= self.BBuff['Defence']
i.MagicResistance -= self.BBuff['Defence']
self.ABuff['Attack'] = self.ABuff['Defence'] = self.BBuff['Attack'] = self.BBuff['Defence'] = 0
if __name__ == '__main__':
BattleField = BattleField()
BattleField.GameStart()
设计一个密码记录及查询小软件,模拟记录自己在各个网站上所使用的账号及密码,保存在文件中。要求自行设计存储方式,并实现浏览、查询、增加、删除、修改等基本功能,可以自行拓展其他功能,
程序分为3个Frame,打开程序的默认Frame为VFrame,即浏览的界面,通过ttk的Treeview来实现,分别展示每个账户的所属网站,用户名和密码,同时还展示用户注册时的邮箱,在单击的时候还会在显示出登陆网址。单击登陆网址标签,会将其负值到剪切板,方便进行访问操作。
账户的添加/修改/删除为MFrame,在Treeview中单击一个项目,会在相应的输入框中更新对应项目的值,可以修改此项目的相关值。
若在同一网站下添加相同用户名的账户,则给出警告提示。
在搜索界面SFrame中,可以针对某一关键字进行搜索,包括搜索用户名,网站,密码,邮箱等等。搜索的结果包括精确匹配和模糊匹配,优先展示精确匹配的其次展示模糊匹配的结果。
账户使用字典来维护,字典维护每个网站下的账户,每个账户又是一个字典,键为用户名,值为用户的密码,注册用邮箱等等。每个网站的登陆网址,是再另外的一个字典中来维护的
对于查询,每次将一个网站的字典读入,对于字典的item累次迭代,如果搜索的关键字在键中,则将该条记录加入精确匹配结果字典中,若关键字在键中出现,但不是完全相同,则将该条记录加入模糊匹配结果字典中。最后将两个字典的结果输出在Treeview中。对于每个单独的搜索项,则只在特定的键值中搜索,而不是累次迭代搜索。
首先是GUI的设计。对于单独的ListBox,不能很好的展示很多项目,所以Treeview是个不错的选择。对于Treeview要单独设计每个栏目的展会内容。好在插入记录的时候,只需要按顺序插入即可,不需要指定某个栏目插入什么值。
在搜索算法,涉及到多层迭代,因为我在维护信息的Dict中添加了很多额外的信息,如当前保存的网站个数,当前保存的账户个数,还有其他可拓展的信息等等。由于又是以网站为索引的,所以在迭代的过程中需要层层迭代。在搜索结果方面,使用的是全局变量,两个列表来保存搜索结果,然后输出展示。对于在不同迭代层的结果,匹配的结果也保存不同,所以要判断是在哪一个方面实现匹配的。这样才可以在TreeView中加以展示。
pwbox.py
“`python
#-- coding:utf-8 --
import os, sys
import base64
import json, pyperclip
from tkinter import *
from tkinter.font import Font
from tkinter.ttk import *
from tkinter.messagebox import *
LoginWeb = {}
websitelist = []
TempList = [] # 用于暂存每个网站对应的账号
SearchAnsA = [] # 用于保存搜索结果精确匹配
SearchAnsM = [] # 用于保存搜索结果的模糊
class Application_ui(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.master.title('密码箱')
self.master.geometry('550x350')
self.LoadMenu()
self.LoadFrames()
self.ViewFrame()
def LoadFrames(self):
self.style = Style()
self.style.configure('VFrame.TLabelframe',font=('宋体',9))
self.VFrame = Frame(self.top, style='VFrame.TLabelframe')
self.style.configure('SFrame.TLabelframe',font=('宋体',9))
self.SFrame = Frame(self.top, style='SearchFrame.TLabelframe')
self.style.configure('MFrame.TLabelframe',font=('宋体',9))
self.MFrame = Frame(self.top, style='MFrame.TLabelframe')
def LoadMenu(self):
self.top = self.winfo_toplevel()
self.MainMenu = Menu(self.top, tearoff=0)
self.Function = Menu(self.MainMenu, tearoff=0)
self.Function.add_command(label='浏览账户', command=self.View_Cmd)
self.Function.add_command(label='查询账户', command=self.Search_Cmd)
self.Function.add_command(label='添加/修改/删除账户', command=self.Add_Cmd)
self.MainMenu.add_cascade(menu=self.Function, label='功能')
self.top['menu'] = self.MainMenu
def SearchFrame(self):
self.SFrame.grid(row=0, column=0, padx=0, pady=0)
self.style.configure('Tips.TLabel',anchor='w', font=('宋体',9))
self.TagTips = Label(self.SFrame, text='请输入要查询的关键字', style='Tips.TLabel')
self.TagTips.grid(row = 0, column = 0, sticky = W)
self.KeynameVar = StringVar(value='')
self.Key = Entry(self.SFrame, text='', textvariable=self.KeynameVar, font=('宋体',9))
self.Key.grid(row = 0, column = 0,padx = 150,sticky = NW)
self.style.configure('SearchAll.TButton',font=('宋体',9))
self.SearchAll = Button(self.SFrame, text='搜索全部', command=self.SearchAll_Cmd, style='SearchAll.TButton')
self.SearchAll.grid(row = 1, column = 0, padx = 0, pady = 2, sticky = NW)
self.style.configure('SearchWeb.TButton',font=('宋体',9))
self.SearchWeb = Button(self.SFrame, text='搜索网站', command=self.SearchWeb_Cmd, style='SearchWeb.TButton')
self.SearchWeb.grid(row = 1, column = 0, padx = 100, pady = 2,sticky = NW)
self.style.configure('SearchUser.TButton',font=('宋体',9))
self.SearchUser = Button(self.SFrame, text='搜索用户名', command=self.SearchUser_Cmd, style='SearchUser.TButton')
self.SearchUser.grid(row = 1, column = 0, padx = 200, pady = 2, sticky = NW)
self.style.configure('SearchPw.TButton',font=('宋体',9))
self.SearchPw = Button(self.SFrame, text='搜索密码', command=self.SearchPw_Cmd, style='SearchPw.TButton')
self.SearchPw.grid(row = 1, column = 0, padx = 300, pady = 2, sticky = NW)
self.style.configure('SearchEmail.TButton',font=('宋体',9))
self.SearchEmail = Button(self.SFrame, text='搜索邮箱', command=self.SearchEmail_Cmd, style='SearchEmail.TButton')
self.SearchEmail.grid(row = 1, column = 0, padx = 400, pady = 2, sticky = NW)
self.Tree = Treeview(self.SFrame, height = 10,show="headings", columns = ('id','type','web','user','pw','email'))
self.Tree.column('id', width=45, anchor='center')
self.Tree.column('type', width=110, anchor='center')
self.Tree.column('web', width=50, anchor='center')
self.Tree.column('user', width=110, anchor='center')
self.Tree.column('pw', width=110, anchor='center')
self.Tree.column('email', width=110, anchor='center')
self.Tree.heading('id', text='编号')
self.Tree.heading('type', text='匹配类型')
self.Tree.heading('web', text='网站')
self.Tree.heading('user', text='用户名')
self.Tree.heading('pw', text='密码')
self.Tree.heading('email', text='注册邮箱')
self.vbar = Scrollbar(self.SFrame, orient=VERTICAL, command=self.Tree.yview)
self.Tree.configure(yscrollcommand=self.vbar.set)
self.Tree.bind('',self.UpdateForModify)
self.Tree.grid(row=2, column=0, pady = 3, sticky = NW)
self.vbar.grid(row=2, column=1, pady = 3, sticky=NS)
def ModifyFrame(self):
self.MFrame.grid(row=0, column=0, padx=0, pady=0)
self.style.configure('User.TLabel',anchor='w', font=('宋体',9))
self.TagUser = Label(self.MFrame, text='用户名:', style='User.TLabel')
self.TagUser.grid(row = 0, column = 0, sticky = W)
self.UsernameVar = StringVar(value='')
self.User = Entry(self.MFrame, text='', textvariable=self.UsernameVar, font=('宋体',9))
self.User.grid(row = 0, column = 0,padx = 70,sticky = NW)
self.style.configure('Password.TLabel',anchor='w', font=('宋体',9))
self.TagPassword = Label(self.MFrame, text='密码:', style='Password.TLabel')
self.TagPassword.grid(row = 1, column = 0 ,pady = 2, sticky = W)
self.PasswordVar = StringVar(value='')
self.Password = Entry(self.MFrame, text='', textvariable=self.PasswordVar, font=('宋体',9))
self.Password.grid(row = 1, column = 0,padx = 70,pady = 2, sticky = NW)
self.style.configure('Email.TLabel',anchor='w', font=('宋体',9))
self.TagEmail = Label(self.MFrame, text='电子邮箱:', style='Email.TLabel')
self.TagEmail.grid(row = 2, column = 0 , pady = 2, sticky = W)
self.EmailVar = StringVar(value='')
self.Email = Entry(self.MFrame, text='', textvariable=self.EmailVar, font=('宋体',9))
self.Email.grid(row = 2, column = 0,padx = 70, pady = 2, sticky = NW)
self.style.configure('Web.TLabel',anchor='w', font=('宋体',9))
self.TagWeb = Label(self.MFrame, text='网站:', style='Web.TLabel')
self.TagWeb.grid(row = 3, column = 0, pady = 2, sticky = W)
self.WebnameVar = StringVar(value='')
self.Web = Entry(self.MFrame, text='', textvariable=self.WebnameVar, font=('宋体',9))
self.Web.grid(row = 3, column = 0,padx = 70, pady = 2,sticky = NW)
self.style.configure('Login.TLabel',anchor='w', font=('宋体',9))
self.TagLogin = Label(self.MFrame, text='登陆网址:', style='Login.TLabel')
self.TagLogin.grid(row = 4, column = 0,pady = 2, sticky = W)
self.LoginnameVar = StringVar(value='')
self.Login = Entry(self.MFrame, text='', textvariable=self.LoginnameVar, font=('宋体',9))
self.Login.grid(row = 4, column = 0,padx = 70,pady = 2, sticky = NW)
self.style.configure('ModifyMes.TButton',font=('宋体',9))
self.ModifyMes = Button(self.MFrame, text='修改账户', command=self.ModifyMes_Cmd, style='ModifyMes.TButton')
self.ModifyMes.grid(row = 0, column = 0, padx = 250, sticky = NW)
self.style.configure('ModifyMes.TButton',font=('宋体',9))
self.ModifyMes = Button(self.MFrame, text='添加账户', command=self.AddMes_Cmd, style='ModifyMes.TButton')
self.ModifyMes.grid(row = 1, column = 0, padx = 250,pady = 2, sticky = NW)
self.style.configure('Delete.TButton',font=('宋体',9))
self.Delete = Button(self.MFrame, text='删除账户', command=self.DelMes_Cmd, style='Delete.TButton')
self.Delete.grid(row = 2, column = 0, padx = 250, pady = 2, sticky = NW)
self.Tree = Treeview(self.MFrame, height = 10,show="headings", columns = ('id','web','user','pw','email'))
self.Tree.column('id', width=50, anchor='center')
self.Tree.column('web', width=50, anchor='center')
self.Tree.column('user', width=140, anchor='center')
self.Tree.column('pw', width=140, anchor='center')
self.Tree.column('email', width=140, anchor='center')
self.Tree.heading('id', text='编号')
self.Tree.heading('web', text='网站')
self.Tree.heading('user', text='用户名')
self.Tree.heading('pw', text='密码')
self.Tree.heading('email', text='注册邮箱')
self.vbar = Scrollbar(self.MFrame, orient=VERTICAL, command=self.Tree.yview)
self.Tree.configure(yscrollcommand=self.vbar.set)
self.Tree.bind('',self.UpdateForModify)
self.Tree.grid(row=5, column=0, sticky = NW)
self.vbar.grid(row=5, column=1, sticky=NS)
self.LoadMes()
def ViewFrame(self):
self.VFrame.grid(row=0, column=0, padx=0, pady=0)
self.Tree = Treeview(self.VFrame, height = 10,show="headings", columns = ('id','web','user','pw','email'))
self.Tree.column('id', width=50, anchor='center')
self.Tree.column('web', width=50, anchor='center')
self.Tree.column('user', width=140, anchor='center')
self.Tree.column('pw', width=140, anchor='center')
self.Tree.column('email', width=140, anchor='center')
self.Tree.heading('id', text='编号')
self.Tree.heading('web', text='网站')
self.Tree.heading('user', text='用户名')
self.Tree.heading('pw', text='密码')
self.Tree.heading('email', text='注册邮箱')
self.vbar = Scrollbar(self.VFrame, orient=VERTICAL, command=self.Tree.yview)
self.Tree.configure(yscrollcommand=self.vbar.set)
self.Tree.bind('',self.UpdateCur)
self.Tree.grid(row = 0, column = 0, sticky = NW)
self.vbar.grid(row=0, column=1, sticky=NS)
self.style.configure('Tips.TLabel',anchor='w', font=('宋体',9))
self.Tips = Label(self.VFrame, text='登陆网址:', style='Tips.TLabel')
self.Tips.bind('',self.CopyWeb)
self.Tips.grid(row=1, column=0)
self.LoadMes()
def DestroyAll(self):
self.VFrame.destroy()
self.MFrame.destroy()
self.SFrame.destroy()
def LoadMes(self):
self.id = 1
for _ in map(self.Tree.delete, self.Tree.get_children("")):
pass
TempList = pwlist['mes']
for kweb,vweb in TempList.items():
for k,v in vweb.items():
self.Tree.insert('','end',values = (self.id,kweb,v['user'],v['password'],v['email']))
self.id+=1
class Application(Application_ui):
def init(self, master=None):
Application_ui.init(self, master)
self.curmes = {}
self.curid = -1
def View_Cmd(self, event=None):
self.DestroyAll()
self.LoadFrames()
self.ViewFrame()
def Search_Cmd(self, event=None):
self.DestroyAll()
self.LoadFrames()
self.SearchFrame()
def Add_Cmd(self, event=None):
self.DestroyAll()
self.LoadFrames()
self.ModifyFrame()
def Name(self,name):
if name == 'user':
return '用户名'
elif name == 'password':
return '密码'
elif name == 'email':
return '电子邮箱'
def SearchAll_Cmd(self, event=None):
# 搜索全部的匹配项
# 包括网站名称,电子邮箱,用户名密码等等
global SearchAnsA
global SearchAnsM
SearchAnsA = []
SearchAnsM = []
SearTar = self.Key.get()
if SearTar == '':
messagebox.showwarning(title = '警告',message = '请输入有效的搜索内容!')
else:
TempList = pwlist['mes']
for k,v in TempList.items():
if k == SearTar:
for a,b in v.items():
SearchAnsA.append(['精确匹配网站',k,b])
continue
elif SearTar in k:
for a,b in v.items():
SearchAnsA.append(['精确匹配网站',k,b])
continue
for a,b in v.items():
if a == SearTar:
SearchAnsA.append(['精确匹配用户名',k,b])
continue
elif SearTar in a:
SearchAnsM.append(['模糊匹配用户名',k,b])
continue
for c,d in b.items():
if d == SearTar:
SearchAnsA.append(['精确匹配'+self.Name(c),k,b])
break
elif SearTar in d:
SearchAnsM.append(['模糊匹配'+self.Name(c),k,b])
break
self.ShowSearchMes()
def ShowSearchMes(self):
# 展示搜索结果
self.id = 1
for _ in map(self.Tree.delete, self.Tree.get_children("")):
pass
for i in SearchAnsA:
t,tw,tmes = i[0], i[1], i[2]
self.Tree.insert('','end',values = (self.id,t,tw,tmes['user'],tmes['password'],tmes['email']))
self.id+=1
for i in SearchAnsM:
t,tw,tmes = i[0], i[1], i[2]
self.Tree.insert('','end',values = (self.id,t,tw,tmes['user'],tmes['password'],tmes['email']))
self.id+=1
def SearchWeb_Cmd(self, event=None):
# 搜索网站名称部分的匹配项
global SearchAnsA
global SearchAnsM
SearchAnsA = []
SearchAnsM = []
SearTar = self.Key.get()
if SearTar == '':
messagebox.showwarning(title = '警告',message = '请输入有效的搜索内容!')
else:
TempList = pwlist['mes']
for k,v in TempList.items():
if k == SearTar:
for a,b in v.items():
SearchAnsA.append(['精确匹配网站',k,b])
continue
elif SearTar in k:
for a,b in v.items():
SearchAnsA.append(['精确匹配网站',k,b])
continue
self.ShowSearchMes()
def SearchUser_Cmd(self, event=None):
# 搜索用户名部分的匹配项
global SearchAnsA
global SearchAnsM
SearchAnsA = []
SearchAnsM = []
SearTar = self.Key.get()
if SearTar == '':
messagebox.showwarning(title = '警告',message = '请输入有效的搜索内容!')
else:
TempList = pwlist['mes']
for k,v in TempList.items():
for a,b in v.items():
if a == SearTar:
SearchAnsA.append(['精确匹配用户名',k,b])
continue
elif SearTar in a:
SearchAnsM.append(['模糊匹配用户名',k,b])
self.ShowSearchMes()
def SearchPw_Cmd(self, event=None):
global SearchAnsA
global SearchAnsM
SearchAnsA = []
SearchAnsM = []
SearTar = self.Key.get()
if SearTar == '':
messagebox.showwarning(title = '警告',message = '请输入有效的搜索内容!')
else:
TempList = pwlist['mes']
for k,v in TempList.items():
for a,b in v.items():
if b['password'] == SearTar:
SearchAnsA.append(['精确匹配'+self.Name('password'),k,b])
break
elif SearTar in b['password']:
SearchAnsM.append(['模糊匹配'+self.Name('password'),k,b])
break
self.ShowSearchMes()
def SearchEmail_Cmd(self, event=None):
global SearchAnsA
global SearchAnsM
SearchAnsA = []
SearchAnsM = []
SearTar = self.Key.get()
if SearTar == '':
messagebox.showwarning(title = '警告',message = '请输入有效的搜索内容!')
else:
TempList = pwlist['mes']
for k,v in TempList.items():
for a,b in v.items():
if b['email'] == SearTar:
SearchAnsA.append(['精确匹配'+self.Name('email'),k,b])
break
elif SearTar in b['email']:
SearchAnsM.append(['模糊匹配'+self.Name('email'),k,b])
break
self.ShowSearchMes()
def DelMes_Cmd(self, event=None):
NowWeb = self.Web.get()
NowUser = self.User.get()
TempList = pwlist['mes'][NowWeb]
del(TempList[NowUser])
pwlist['mes'][NowWeb] = TempList
self.LoadMes()
def AddMes_Cmd(self, event=None):
NowWeb = self.Web.get()
NowUser = self.User.get()
NowLogin = self.Login.get()
NowPassword= self.Password.get()
NowEmail = self.Email.get()
if NowWeb not in pwlist['mes'].keys():
TempList = {}
else:
TempList = pwlist['mes'][NowWeb]
if NowWeb not in LoginWeb.keys():
LoginWeb[NowWeb] = NowLogin
pwlist['totalweb']+=1
if NowUser in TempList.keys():
messagebox.showwarning(title = '警告',message = NowWeb+'网站下已经存在用户名为'+NowUser+'的用户!')
else:
TempList[NowUser] = {'user':NowUser,'password':NowPassword,'email':NowEmail}
pwlist['totaluser']+=1
pwlist['mes'][NowWeb] = TempList
self.LoadMes()
def ModifyMes_Cmd(self, event=None):
LastWeb = self.curmes['web']
NowWeb = self.Web.get()
LastUser = self.curmes['user']
NowUser = self.User.get()
NowLogin = self.Login.get()
NowPassword= self.Password.get()
NowEmail = self.Email.get()
TempList = pwlist['mes'][LastWeb]
if NowWeb not in LoginWeb.keys():
LoginWeb[NowWeb] = NowLogin
pwlist['totalweb']+=1
if NowWeb == LastWeb: # 没有更改Web
if NowUser == LastUser: # 没有更改用户名
TempList[LastUser] = {'user':NowUser,'password':NowPassword,'email':NowEmail}
else: # 更改了用户名
del(TempList[LastUser])
TempList[NowUser] = {'user':NowUser,'password':NowPassword,'email':NowEmail}
pwlist['mes'][LastWeb] = TempList
print(TempList)
else: # 更改了网站
del(TempList[LastUser])
pwlist['mes'][LastWeb] = TempList
if NowWeb not in pwlist['mes'].keys(): # 当前网站不存在
TempList[NowUser] = {'user':NowUser, 'password':NowPassword,'email':NowEmail}
else:
TempList = pwlist['mes'][NowWeb]
TempList[NowUser] = {'user':NowUser, 'password':NowPassword,'email':NowEmail}
pwlist[NowWeb] = TempList
self.LoadMes()
def UpdateForModify(self, event=None):
self.curid = int(self.Tree.focus()[1:])
self.curmes = self.Tree.set(self.Tree.focus())
print(self.curmes)
self.User.delete(0,END)
self.User.insert(0,self.curmes['user'])
self.Password.delete(0,END)
self.Password.insert(0,self.curmes['pw'])
self.Email.delete(0,END)
self.Email.insert(0,self.curmes['email'])
self.Web.delete(0,END)
self.Web.insert(0,self.curmes['web'])
self.Login.delete(0,END)
self.Login.insert(0,LoginWeb[self.curmes['web']])
def UpdateCur(self, event=None):
self.curid = int(self.Tree.focus()[1:])
self.curmes = self.Tree.set(self.Tree.focus())
self.Tips['text'] = '登录网址:' + LoginWeb[self.curmes['web']]
def CopyWeb(self, event=None):
pyperclip.copy(LoginWeb[self.curmes['web']])
if name == “main“:
with open(‘pw.json’, ‘r’) as f:
pwlist = json.load(f)
with open(‘LoginWeb.json’, ‘r’) as f:
LoginWeb = json.load(f)
top = Tk()
Application(top).mainloop()
with open('pw.json','w') as f:
json.dump(pwlist,f)
f.close()
with open('LoginWeb.json','w') as f:
json.dump(LoginWeb,f)
f.close()
try: top.destroy()
except: pass
“`