Python3程序设计实验三

Python3程序设计实验三

文章摘自:Python3程序设计实验|PengWill

面向对象战争游戏

程序设计说明

设计一个父类,表示游戏角色:派生出多个子类用于表示不同职业的角色,为每个类设置必要的属性和方法,并实例化对象进行测试。

程序设计思路

职业类简介

父类名称为People,其基本属性有生命值,护甲,魔法抗性,物理伤害,魔法伤害,技能数量,速度(表示攻击的先后顺序),是否已经阵亡等。派生出3个子类,表示不同的职业,分别有战士Warrior,法师Wizard,以及医疗者Healer。战士的普通攻击比较高,其技能伤害也是物理伤害。法师的魔法伤害比较高,技能伤害主要是魔法伤害,并且部分技能有AOE(群体伤害)效果。医疗者主要是进行增加攻击力,增加防御,削减对面的攻击力和削减对面魔抗,还可以治疗己方的受伤单位,但不可以复活已经阵亡的角色。

游戏类BattleField简介

游戏有两个阵营,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

“`

你可能感兴趣的:(Python,Python3程序设计)