-1

I'm trying to build a random OTP generator but I coming across this error message, can anyone help me

error :

File "C:\Users\HP\AppData\Local\Programs\Python\Python37\lib\tkinter\__init__.py", line 2692, in insert
    self.tk.call(self._w, 'insert', index, string)
_tkinter.TclError: wrong # args: should be ".!entry3 insert index text"

my code:

import random
from tkinter import *
from tkinter.ttk import *

root = Tk()

#generting otp
def generate():
    entry.delete(0,END)
    digits = "0123456789"
    otp1 =""
    for i in range (4):
        opt1 = otp1 + random.choice (digits)

    entry.insert(10,otp1)


#GUI

Usn_label = Label(root , text = "USN")
Usn_label.grid(row = 0 )
Usn_entry = Entry(root , textvariable='usn_var')
Usn_entry.grid(row =0 , column = 1)

phone_label = Label (root , text = " Phone Number ")
phone_label.grid (row = 2)
phone_entry = Entry (root , textvariable='phone number')
phone_entry.grid(row = 2, column = 1)
Gen_label =Button(root , text= 'Generate', command = generate)
Gen_label.grid (row = 3 , column = 1 , sticky='w')

Random_otp = Label (root, text = "OTP")
Random_otp.grid (row = 4 )
entry = Entry(root)
entry.grid(row = 4, column = 1)

root.title("Otp Generator ")

root.mainloop()
buran
  • 13,682
  • 10
  • 36
  • 61
  • what does your question has to do with OTP - it's about error with using tkinter.Entry widget? Please edit the title to reflect your problem correctly. – buran Oct 10 '20 at 13:27
  • Does this answer your question? [How to set the text/value/content of an \`Entry\` widget using a button in tkinter](https://stackoverflow.com/questions/16373887/how-to-set-the-text-value-content-of-an-entry-widget-using-a-button-in-tkinter) – buran Oct 10 '20 at 13:29

1 Answers1

0

I ran your script and didn't get any errors, but you made at least one mistake (arguably more).

  1. you delete the entry text, but then try to insert text at index 10
  2. you misspelled otp1 (as 'opt1') in your loop

#generting otp
def generate(L=4):
    entry.delete(0, END)
    entry.insert(0, f'{random.choice(range(0, pow(10, L)))}'.zfill(L))

I believe this is much cleaner. The logic is dead simple. Generate a number from 0 to 9999 and pad the left side with zeroes for any number that has less than 4 characters. For longer or shorter numbers just change L.

If you wanted to clean up your entire script. You may want to consider the following:

  1. Unless you intend to do something with your Labels, such as: change their text or remove them entirely, there is no reason to store a reference to them.

  2. textvariable expects a tk.StringVar(), dumping an arbitrary str into it does nothing (for me), but is probably the source of the error for you.

  3. The user does not need to click a Button to generate an arbitrary random number. You can simply generate it automatically as soon as the program executes.

  4. Labels with text like "USN" and "OTP" are not user-friendly.


import random
import tkinter as tk

root = tk.Tk()
root.title("OTP Generator ")

def random_key(L=4):
    return f'{random.choice(range(0, pow(10, L)))}'.zfill(L)

#generate otp for this session
otp = random_key(8)

#GUI
tk.Label(root, text="Username:", anchor='e').grid(row=0, sticky='e')

usn_entry = tk.Entry(root)
usn_entry.grid(row=0 , column=1, sticky='w')

tk.Label(root, text="Phone Number:", anchor='e').grid(row=2, sticky='e')

phone_entry = tk.Entry(root)
phone_entry.grid(row=2, column=1, sticky='w')

tk.Label(root, text="PIN:", anchor='e').grid(row=4, sticky='e')

pin = tk.Entry(root, width=len(otp))
pin.grid(row=4, column=1, sticky='w')
pin.insert(0, otp)
pin.configure(state='read')

root.mainloop()      

If you wanted to take it even further, you could consider that you keep creating the same Label/Entry combo, over and over. You could simply create a class that represents that combination, and use it instead.

import random
import tkinter as tk

class LabeledEntry(tk.Frame):
    @property
    def text(self) -> str:
        return self.__entry.get()
        
    @text.setter
    def text(self, value:str):
        self.__entry.delete(0, 'end')
        self.__entry.insert(0, value)
    
    @property    
    def entry(self) -> tk.Entry:
        return self.__entry
        
    @property
    def state(self) -> str:
        return self.__entry['state']
        
    @state.setter
    def state(self, value:str):
        self.__entry.configure(state=value)
        
    def __init__(self, master, text:str, column=None, row=None, **kwargs):
        tk.Frame.__init__(self, master, **kwargs)
        self.grid(column=column, row=row)
        
        tk.Label(self, text=text, anchor='e', width=12).grid(row=0, column=0, sticky='e')
        
        self.__entry = tk.Entry(self)
        self.__entry.grid(row=0, column=1, sticky='w')
        

root = tk.Tk()
root.title("OTP Generator ")

def random_key(L=4):
    return f'{random.choice(range(0, pow(10, L)))}'.zfill(L)

#generate otp for this session
otp = random_key(8)

#GUI
user_field  = LabeledEntry(root, 'Username: ')
phone_field = LabeledEntry(root, 'Phone Number: ')
pin_field   = LabeledEntry(root, 'PIN: ')

pin_field.text  = otp
pin_field.state = 'read'

root.mainloop()      

    
    
OneMadGypsy
  • 4,640
  • 3
  • 10
  • 26