简体   繁体   English

Tkinter 与 OOP python

[英]Tkinter with OOP python

My goal is to get a very basic GUI with two tabs where the first one has the options of log in, register a new user and unregister this user.我的目标是获得一个非常基本的 GUI,其中包含两个选项卡,其中第一个选项卡具有登录、注册新用户和取消注册该用户的选项。 If i want to click to the second option (register the user or called "darse de alta") it should appear a second window (and closing the first one) where i can put my information to register (name, dni and phone number).如果我想点击第二个选项(注册用户或称为“darse de alta”),它应该会出现第二个 window(并关闭第一个),我可以在其中注册我的信息(姓名、dni 和电话号码) . Then the last point of this program should be adding this new user to a database called self.socios.那么这个程序的最后一点应该是将这个新用户添加到名为 self.socios 的数据库中。 This is because in the method "agregar" inside the class Registro_socios whenever i want to register a new user he has to be added to the database.这是因为在 class Registro_socios 中的方法“agregar”中,每当我想注册一个新用户时,他都必须添加到数据库中。 I don't know how to connect the new user with the class previously created.我不知道如何将新用户与之前创建的 class 连接起来。 Thanks to anyone who can explain and clarify in some way.感谢任何可以以某种方式解释和澄清的人。

class Socio:
    
    def __init__(self,nombre_socio,dni,telefono):
        self.nombre = nombre_socio
        self.dni = dni
        self.telefono = telefono
    
    def __str__(self):
        return "Nombre: {0}\nDNI: {1}\nTelefono: {2}".format(self.nombre,self.dni,self.telefono)

class Registro_socios: 
    
    def __init__(self,baseDatos_socios = None):
        if baseDatos_socios is None:
            baseDatos_socios = {} # Diccionario vacío con DNIs como Keys
            self.socios = baseDatos_socios
    
    def agregar(self,socio):
        if self.existe(socio): # En el caso que existe retorne True
            raise KeyError(f'{socio.__class__.__name__} ya existente') # A Python KeyError exception is what is raised when you try to access a key that isn't in a dictionary ( dict )
        self.socios[socio.dni] = socio
    
    def existe(self,socio):
        if socio.dni in self.socios:
            return True
        return False

root = tk.Tk()
miFrame = Frame(root) 
# miFrame = Frame(root,width=1000,height=500) 
miFrame.pack()

def alta_socio():
    otra_ventana = tk.Toplevel(root)
    miFrame2 = Frame(otra_ventana)
    miFrame2.pack()
    
    texto_nombreUsuario = Entry(miFrame2).grid(row=0,column=1, padx=5, pady=5)
    nombre_usuario = Label(miFrame2, text='Nombre de socio: ').grid(row=0,column=0, padx=5, pady=5)

    texto_DNI = Entry(miFrame2).grid(row=1,column=1, padx=5, pady=5)
    nombre_usuario = Label(miFrame2, text='DNI: ').grid(row=1,column=0, padx=5, pady=5)

    texto_nombreUsuario = Entry(miFrame2).grid(row=2,column=1, padx=5, pady=5)
    nombre_usuario = Label(miFrame2, text='Teléfono de contacto: ').grid(row=2,column=0, padx=5, pady=5)
    
    root.iconify() 

botonInicio = Button(root, text='Entrar',bg='orange')
botonInicio.pack()

boton_AltaSocio = Button(root, text='Darse de alta',bg='orange', command=alta_socio) 
boton_AltaSocio.pack()

boton_BajaSocio = Button(root, text='Darse de baja',bg='orange', command=baja_socio)
boton_BajaSocio.pack()

root.mainloop()

I see many mistakes here.我在这里看到很多错误。 The first one is you call the mainwindow with tk.Tk() and the frames as Frame , so I imagine that you are importing tkinter twice like this:第一个是你用tk.Tk()和框架调用主窗口Frame ,所以我想你是这样导入 tkinter 两次:

import tkinter as tk
from tkinter import *

Forget the second import and put the tk before each widget.忘记第二次导入并将tk放在每个小部件之前。

Then the Button 'dar-se baja' calls a method that is not defined.然后 Button 'dar-se baja' 调用一个未定义的方法。

Inside the alta_socio method you are doing this:alta_socio方法中,您正在执行以下操作:

texto_nombreUsuario = tk.Entry(miFrame2).grid(row=0,column=1, padx=5, pady=5)

This is bad because while the tk.Entry() returns an instance of the class Entry, the Entry.grid() method does not return anything.这很糟糕,因为虽然tk.Entry()返回 class 条目的实例,但Entry.grid()方法不返回任何内容。 so texto_nombeUsuario will be None and you will not to be able to access what is in the entry widget.所以texto_nombeUsuario将是None并且您将无法访问条目小部件中的内容。 You should do like this instead:你应该这样做:

texto_nombreUsuario = tk.Entry(miFrame2)
texto_nombreUsuario.grid(row=0,column=1, padx=5, pady=5)

Another option is to use a StringVar:另一种选择是使用 StringVar:

texto_nombreUsuario = tk.StringVar(root)
tk.Entry(miFrame2, textvariable=texto_nombreUsuario).grid(row=0,column=1, padx=5, pady=5)

For the third Entry in alta_socio() you are using for the telephone the same variable you used for the name.对于alta_socio()中的第三个条目,您对电话使用的变量与您用于名称的变量相同。 Fix it.修理它。 Finally you can add a tk.Button that will call a method which will create a Socio .最后,您可以添加一个tk.Button ,它将调用一个创建Socio的方法。 Like:喜欢:

tk.Button(miFrame2, text='Confirmar', command=add_socio).grid()

The method add_socio() can be a nested method from alta_socio() this way it will have access to the variables texto_nombreUsuario , texto_DNI and texto_telefono .方法add_socio()可以是alta_socio() () 的嵌套方法,这样它就可以访问变量texto_nombreUsuariotexto_DNItexto_telefono It get the text from texto_nombreUsuario with the command texto_nombreUsuario.get() and call the previously created classes:它使用命令texto_nombreUsuario.get()texto_nombreUsuario获取文本并调用先前创建的类:

def alta_socio():
    def add_socio(): # this function is nested so it can access variables defined in alta_socio
        nombre = texto_nombreUsuario.get()
        tel = texto_telefono.get()
        dni = texto_dni.get()
        socio = Socio(nombre, dni, telefono) # here you call the Socio class previously defined

    otra_ventana = tk.Toplevel(root)
    miFrame2 = tk.Frame(otra_ventana)
    miFrame2.pack()
    
    texto_nombreUsuario = tk.StringVar(root) # this is a tkinter variable which contains the user name
    # this entry saves it values in the tkinter variable above:
    tk.Entry(miFrame2, textvariable=texto_nombreUsuario).grid(row=0,column=1, padx=5, pady=5)
    tk.Label(miFrame2, text='Nombre de socio: ').grid(row=0,column=0, padx=5, pady=5)
    ...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM