使用Tkinter按钮更改变量

时间:2019-01-26 01:49:48

标签: python tkinter

我目前正在从事一个有趣的项目,其中有一个登录屏幕,后跟一个主菜单。这是我的第一个主要项目,因为我刚接触Python并仍在学习。

我想做的是,在用户正确登录后,他们面对的是主菜单(根窗口后面的顶级窗口)。在这个菜单中,我希望用户能够选择一个难度(简单,中等,困难)

这是我得到的错误:UnboundLocalError:赋值之前引用了局部变量'radius'

这是我的代码:

from turtle import Turtle, Screen
from random import random, randint
from time import time
import os
import sys
import tkinter.messagebox as tm
import hashlib, uuid
import re
import turtle

CURSOR_SIZE = 20

from tkinter import *

user_get = 0
variable = 1
diffSetting = 9



class Application(Frame):
    def __init__(self,master):
        Frame.__init__(self, master)#Set __init__ to the master class
        self.grid()
        self.create_main()#Creates function
        self.Read()
        changeVariable1(self)
        changeVariable2(self)
        changeVariable3(self)

def Read(self):
    top = Tk()
    top.geometry("%dx%d%+d%+d" % (420, 500, 250, 125))

    top.title = Label(top, text="Menu ", font='Helvetica 10 bold')#TITLE 
    top.title.grid(row=0, column=2)

    top.title = Label(top, text="    ", font='Helvetica 10 bold')#blank line
    top.title.grid(row=1, column=1)

    top.user_entry_label = Label(top, text="Difficulty: ", font='Helvetica 10 bold')#USERNAME LABEL
    top.user_entry_label.grid(row=3, column=1)

    top.easybutt = Button(top, text="Easy",  font='Helvetica 10 bold', command = changeVariable1(self))#easy
    top.easybutt.grid(row=3, column=2)

    top.medbutt = Button(top, text="Medium",  font='Helvetica 10 bold', command = changeVariable2(self))#med
    top.medbutt.grid(row=3, column=3)

    top.hrdbutt = Button(top, text="Hard",  font='Helvetica 10 bold', command = changeVariable3(self))#hrd
    top.hrdbutt.grid(row=3, column=4)

    top.title = Label(top, text="    ", font='Helvetica 10 bold')#blank line
    top.title.grid(row=4, column=1)




    def create_main(self):
        self.title = Label(self, text="Reflex Login ", font='Helvetica 10 bold')#TITLE 
        self.title.grid(row=0, column=2)

        self.user_entry_label = Label(self, text="Username: ", font='Helvetica 10 bold')#USERNAME LABEL
        self.user_entry_label.grid(row=1, column=1)

        self.user_entry = Entry(self)                        #USERNAME ENTRY BOX
        self.user_entry.grid(row=1, column=2)

        self.pass_entry_label = Label(self, text="Password: ", font='Helvetica 10 bold')#PASSWORD LABEL
        self.pass_entry_label.grid(row=2, column=1)

        self.pass_entry = Entry(self, show="●")                        #PASSWORD ENTRY BOX
        self.pass_entry.grid(row=2, column=2)

        self.sign_in_butt = Button(self, text="Sign In",  font='Helvetica 10 bold', command = self.logging_in)#SIGN IN BUTTON
        self.sign_in_butt.grid(row=3, column=2)

        self.register_butt = Button(self, text="Register",font='Helvetica 10 bold', command = self.register)#Register button
        self.register_butt.grid(row=4, column=2)

        self.title = Label(self, text="    ", font='Helvetica 10 bold')#blank line 
        self.title.grid(row=5, column=2)

        self.title = Label(self, text="    ", font='Helvetica 10 bold')#blank line
        self.title.grid(row=6, column=2)

    #username criteria
        self.title = Label(self, text="---------------------------------------", font='Helvetica 10 bold')#seperator 
        self.title.grid(row=6, column=2)
        self.title = Label(self, text="Username Criteria: ", font='Helvetica 10 bold')#TITLE 
        self.title.grid(row=7, column=2)
        self.title = Label(self, text="One number 1-9.", font='Helvetica 10') 
        self.title.grid(row=8, column=2)
        self.title = Label(self, text="6-12 characters in length.", font='Helvetica 10') 
        self.title.grid(row=9, column=2)
        self.title = Label(self, text="Include no spaces.", font='Helvetica 10')
        self.title.grid(row=10, column=2)

    #password criteria
        self.title = Label(self, text="    ", font='Helvetica 10 bold')#blank line
        self.title.grid(row=11, column=2)
        self.title = Label(self, text="---------------------------------------", font='Helvetica 10 bold')#seperator
        self.title.grid(row=11, column=2)
        self.title = Label(self, text="Password Criteria: ", font='Helvetica 10 bold')#TITLE 
        self.title.grid(row=12, column=2)
        self.title = Label(self, text="One number 1-9.", font='Helvetica 10') 
        self.title.grid(row=13, column=2)
        self.title = Label(self, text="6-12 characters in length.", font='Helvetica 10') 
        self.title.grid(row=14, column=2)
        self.title = Label(self, text="One uppercase letter and one lowercase letter.", font='Helvetica 10') 
        self.title.grid(row=15, column=2)
        self.title = Label(self, text="One special character [~!@#$%^&*].", font='Helvetica 10')
        self.title.grid(row=16, column=2)
        self.title = Label(self, text="Include no spaces.", font='Helvetica 10')
        self.title.grid(row=17, column=2)
        self.title = Label(self, text="---------------------------------------", font='Helvetica 10 bold')#seperator
        self.title.grid(row=18, column=2)


    def logging_in(self):
        global user_get
        user_get = self.user_entry.get()#Retrieve Username
        global pass_get
        pass_get = self.pass_entry.get()#Retrieve Password
        hash_object = hashlib.md5(pass_get.encode())
        for line in open("details.txt","r").readlines(): #Read the lines
            login_info = line.split() #Split on the space, and store the results in a list of two strings
            if user_get == login_info[0] and (hash_object.hexdigest()) == login_info[1]:
                tm.showinfo("Success", 'Login Correct!')
                root.destroy()
                return True
        tm.showerror('Error', 'Login Incorrect')
        return False


    def register(self):
        global user_get
        user_get = self.user_entry.get()
        pass_get = self.pass_entry.get()
        user_get = self.user_entry.get()#Retrieve Username
        pass_get = self.pass_entry.get()#Retrieve Password
        hash_object = hashlib.md5(pass_get.encode())

    #validation check#
    #passvalidation
        is_valid = False 
        if (len(pass_get)<6 or len(pass_get)>12):
            tm.showerror("Invalid!", 'Password should be between 6 and 12. Try again')
            is_valid = False
        elif not re.search("[A-Z]",pass_get):
            tm.showerror("Invalid!", 'Password should contain one letter between [A-Z]. Try again')
            is_valid = False
        elif not re.search("[a-z]",pass_get):
            tm.showerror("Invalid!", 'Password should contain one letter between [a-z]. Try again')
            is_valid = False
        elif not re.search("[1-9]",pass_get):
            tm.showerror("Invalid!", 'Password should contain one number between [1-9]. Try again')
            is_valid = False
        elif not re.search("[~!@#$%^&*]",pass_get):
            tm.showerror("Invalid!", 'Password should contain at least one letter in [~!@#$%^&*]. Try again')
            is_valid = False
        elif re.search("[\s]",pass_get):
            tm.showerror("Invalid!", 'Password should not contain any space. Try again')
            is_valid = False
        else:
            is_valid = True

    #uservalidation
        user_valid = False 
        if (len(user_get)<6 or len(user_get)>12):
            tm.showerror("Invalid!", 'Username should be between 6 and 12. Try again')
            user_valid = False
        elif not re.search("[1-9]",user_get):
            tm.showerror("Invalid!", 'Username should contain one number between [1-9]. Try again')
            user_valid = False
        elif re.search("[\s]",user_get):
            tm.showerror("Invalid!", 'Username should not contain any space. Try again')
            user_valid = False
    else:
            user_valid = True

        if(is_valid) and (user_valid): 
            tm.showinfo("Valid!", 'Username and Password is valid')    
            file = open('details.txt', 'a+')
            file.write(user_get)
            file.write(" ")
            file.write(hash_object.hexdigest())
            file.write("\n")
            file.close()

def changeVariable1(self):
    global difficulty
    self.difficulty = 12

def changeVariable2(self):
    global difficulty
    self.difficulty = 16

def changeVariable3(self):
    global difficulty
    self.difficulty = 20



######watch video



root = Tk()
root.title("Reflex Aim Training")
root.geometry("%dx%d%+d%+d" % (420, 500, 250, 125))
app = Application(root)#The frame is inside the widgit
#root.overrideredirect(True)                                                                                                                                        ###############################
root.mainloop()#Keeps the window open/running
top = Toplevel()
top.title("Main Menu")



#reset
reset = int(input("Would you like to continue or start fresh? 1 for fresh start, Any other number for continue: "))

if reset == 1:
    os.remove('stats.txt')
    os.remove('maths.txt')    
    print("Your previous scores have been deleted")
else:
    print("We will keep your previous scores stored.")


#while True:
#    diffSetting=int(input("Set the difficulty(1-3): "))
#    
#    if diffSetting == 1:
#        difficulty = 12
#        break
##    elif diffSetting == 2:
 #       difficulty = 16
  #      break
   # elif diffSetting == 3:
    #    difficulty = 20
     #   break
   # else:
        #print("Please choose a difficulty setting between 1 to 3.")

def addscore():
    global score
    score += 2

def deletescore():
    global score
    score -= 1

def my_circle(color):

    if diffSetting==1:
        radius = (30)
    elif diffSetting==2:
        radius = (20)
    elif diffSetting==3:
        radius = (10)


    circle = Turtle('circle', visible=False)
    circle.shapesize(radius / CURSOR_SIZE)
    circle.color('black', color) 

    circle.penup()

    while True:
        nx = randint(2 * radius - width // 2, width // 2 - radius * 2)
        ny = randint(2 * radius - height // 2, height // 2 - radius * 2)

        circle.goto(nx, ny)

        for other_radius, other_circle in circles:
            if circle.distance(other_circle) < 2 * max(radius,         other_radius):
                break
            else:
                break

    circle.onclick(lambda x,y,t=circle: (circle.hideturtle(), addscore()))
    circle.showturtle()



    return radius, circle

def play():
    rgb = (random(), random(), random())

    timeTaken = time() - startTime

    circles.append(my_circle(rgb))

    screen.title('SCORE: {}, TIME LEFT: {}'.format(score, int(round(gameLength - timeTaken, 0))))

    if time() - startTime > gameLength:
        screen.title('FINAL SCORE: {}'.format(score))
        screen.onclick(None)
        screen.clear()
    else:
        screen.ontimer(play, 1000 // difficulty)



screen = Screen()
screen.title("Reflex Aim Training")
screen.bgcolor("grey")

width, height = screen.window_width(), screen.window_height()

score = 0

circles = []

gameLength = 30

screen.onclick(lambda x, y: deletescore())

startTime = time()

play()

screen.mainloop()



print ("{} points, Well Done!".format(score))

#storingscore
file = open('scoreboard.txt', 'r')
name = file.readline()
high_score = int(file.readline())
file.close()

plus_score = (score)-(high_score)
minus_score = (high_score)-(score)


if score > high_score:
    file = open('scoreboard.txt', 'w')
    file.write(str(user_get) + '\n' + str(score) + '\n' "You beat the         previous high score by: "+str(plus_score)+" points!")
    file.close()

if high_score > score:
    file = open('scoreboard.txt', 'w')
    file.write(str(user_get) + '\n' + str(score) + '\n' "You missed the high     score by: "+str(minus_score)+" points!")
    file.close()

if score == high_score:
    file = open('scoreboard.txt', 'w')
    file.write(str(user_get) + '\n' + str(score) + '\n' "You drew with the high score!")
    file.close()

file = open('stats.txt', 'a+')
file.write('\n' + 'Score: ' +str(score))
file.close()

numbers = []
with open('stats.txt') as fh:
    count = 0
    for line in fh:
        count += 1
        numbers.append(float(line.split()[1]))

file = open('maths.txt', 'w+')
file.write('Average Score: ' + str(sum(numbers)/len(numbers)) + "\n")
file.write('Maximum Score: ' + str(max(numbers)) + "\n")
file.write('Minimum Score: ' + str(min(numbers)) + "\n")
maxn = max(numbers)
minn = min(numbers)
rangex = (maxn) - (minn)
file.write('Range of Scores: ' + str(rangex) + "\n")

l = []

with open('stats.txt', 'r') as f:
    for i in f:
        l.append(int(i.split(':')[1].strip()))

import statistics
stdevi = statistics.stdev(l)
file.write('Standard Deviation: ' + str(stdevi) + "\n")

file.close()

不确定我需要多少代码

我的GUI如下:https://gyazo.com/db67e84b7d7b1dbff5408d8151c168be

在尝试使用其他人对此主题的答案时,我遇到了多个错误,这就是为什么我想重新提出这个问题。感谢您的帮助

1 个答案:

答案 0 :(得分:0)

问题不仅仅在于您收到错误,还在于您为什么认为此问题会一直运行。前半部分严重损坏,但至少与您对代码的描述匹配。下半部从######watch video开始,是一圈马戏团,视频,随机数,高分列表,统计信息等的马戏团。看起来您收集了所有看起来很有趣的东西,并将其全部粘贴在同一文件中,希望会发生一些积极的事情。

抛开这些废话,这是我对代码部分的重做,这些部分试图实现您概述的目标:

import re
import hashlib
from tkinter import *
import tkinter.messagebox as tm

class Application(Frame):
    def __init__(self, master):
        super().__init__(master)

        self.difficulty = -1

        self.grid()
        self.login = self.create_main()
        self.read = None

        self.changeVariable1()

    def changeVariable1(self):
        self.difficulty = 12

    def changeVariable2(self):
        self.difficulty = 16

    def changeVariable3(self):
        self.difficulty = 20

    def create_read(self):
        read = Toplevel()
        read.geometry("%dx%d%+d%+d" % (420, 500, 250, 125))

        Label(read, text="Menu ", font='Helvetica 10 bold').grid(row=0, column=2)
        Label(read, text="    ", font='Helvetica 10 bold').grid(row=1, column=1)
        Label(read, text="Difficulty: ", font='Helvetica 10 bold').grid(row=3, column=1)

        Button(read, text="Easy", font='Helvetica 10 bold', command=self.changeVariable1()).grid(row=3, column=2)
        Button(read, text="Medium", font='Helvetica 10 bold', command=self.changeVariable2()).grid(row=3, column=3)
        Button(read, text="Hard", font='Helvetica 10 bold', command=self.changeVariable3()).grid(row=3, column=4)

        Label(read, text="    ", font='Helvetica 10 bold').grid(row=4, column=1)

        return read

    def create_main(self):
        login = Toplevel()

        Label(login, text="Reflex Login ", font='Helvetica 10 bold').grid(row=0, column=2)
        Label(login, text="Username: ", font='Helvetica 10 bold').grid(row=1, column=1)

        self.user_entry = Entry(login)  # USERNAME ENTRY BOX
        self.user_entry.grid(row=1, column=2)

        Label(login, text="Password: ", font='Helvetica 10 bold').grid(row=2, column=1)

        self.pass_entry = Entry(login, show="●")  # PASSWORD ENTRY BOX
        self.pass_entry.grid(row=2, column=2)

        Button(login, text="Sign In", font='Helvetica 10 bold', command=self.logging_in).grid(row=3, column=2)
        Button(login, text="Register", font='Helvetica 10 bold', command=self.register).grid(row=4, column=2)

        Label(login, text="    ", font='Helvetica 10 bold').grid(row=5, column=2)
        Label(login, text="    ", font='Helvetica 10 bold').grid(row=6, column=2)

        # username criteria
        Label(login, text="---------------------------------------", font='Helvetica 10 bold').grid(row=6, column=2)
        Label(login, text="Username Criteria: ", font='Helvetica 10 bold').grid(row=7, column=2)
        Label(login, text="One number 1-9.", font='Helvetica 10').grid(row=8, column=2)
        Label(login, text="6-12 characters in length.", font='Helvetica 10').grid(row=9, column=2)
        Label(login, text="Include no spaces.", font='Helvetica 10').grid(row=10, column=2)

        # password criteria
        Label(login, text="    ", font='Helvetica 10 bold').grid(row=11, column=2)
        Label(login, text="---------------------------------------", font='Helvetica 10 bold').grid(row=11, column=2)
        Label(login, text="Password Criteria: ", font='Helvetica 10 bold').grid(row=12, column=2)
        Label(login, text="One number 1-9.", font='Helvetica 10').grid(row=13, column=2)
        Label(login, text="6-12 characters in length.", font='Helvetica 10').grid(row=14, column=2)
        Label(login, text="One uppercase letter and one lowercase letter.", font='Helvetica 10').grid(row=15, column=2)
        Label(login, text="One special character [~!@#$%^&*].", font='Helvetica 10').grid(row=16, column=2)
        Label(login, text="Include no spaces.", font='Helvetica 10').grid(row=17, column=2)
        Label(login, text="---------------------------------------", font='Helvetica 10 bold').grid(row=18, column=2)

        return login

    def logging_in(self):
        user_get = self.user_entry.get()  # Retrieve Username
        pass_get = self.pass_entry.get()  # Retrieve Password
        hash_object = hashlib.md5(pass_get.encode())

        for line in open("details.txt", "r").readlines():
            login_info = line.split()  # Split on the space, and store the results in a list of two strings

            if user_get == login_info[0] and hash_object.hexdigest() == login_info[1]:
                tm.showinfo("Success", 'Login Correct!')
                self.login.destroy()
                self.read = self.create_read()
                return True

        tm.showerror('Error', 'Login Incorrect')
        return False

    def register(self):
        user_get = self.user_entry.get()  # Retrieve Username
        pass_get = self.pass_entry.get()  # Retrieve Password
        hash_object = hashlib.md5(pass_get.encode())

        # validation check
        # pass validation
        is_valid = False

        if len(pass_get) < 6 or len(pass_get) > 12:
            tm.showerror("Invalid!", 'Password should be between 6 and 12. Try again')
        elif not re.search(r"[A-Z]", pass_get):
            tm.showerror("Invalid!", 'Password should contain one letter between [A-Z]. Try again')
        elif not re.search(r"[a-z]", pass_get):
            tm.showerror("Invalid!", 'Password should contain one letter between [a-z]. Try again')
        elif not re.search(r"[1-9]", pass_get):
            tm.showerror("Invalid!", 'Password should contain one number between [1-9]. Try again')
        elif not re.search(r"[~!@#$%^&*]", pass_get):
            tm.showerror("Invalid!", 'Password should contain at least one letter in [~!@#$%^&*]. Try again')
        elif re.search(r"\s", pass_get):
            tm.showerror("Invalid!", 'Password should not contain any space. Try again')
        else:
            is_valid = True

        # user validation
        user_valid = False

        if len(user_get) < 6 or len(user_get) > 12:
            tm.showerror("Invalid!", 'Username should be between 6 and 12. Try again')
        elif not re.search(r"[1-9]", user_get):
            tm.showerror("Invalid!", 'Username should contain one number between [1-9]. Try again')
        elif re.search(r"\s", user_get):
            tm.showerror("Invalid!", 'Username should not contain any space. Try again')
        else:
            user_valid = True

        if is_valid and user_valid:
            tm.showinfo("Valid!", 'Username and Password is valid')
            file = open('details.txt', 'a+')
            file.write(user_get)
            file.write(" ")
            file.write(hash_object.hexdigest())
            file.write("\n")
            file.close()

root = Tk()

app = Application(root)

root.mainloop()

它将打开一个初始窗口,让您注册和登录。如果您成功登录,它将关闭该窗口,并使用三个难度按钮打开另一个窗口。添加一小段代码,对其进行测试,一旦工作,请继续进行下一个代码段。