I'm trying to run this code but it's giving "_tkinter.TclError: bad window path name ".!button2" " this error.
But If I run the same code without ebook function, it's working fine. As I'm new to coding, any help will be appreciated.
from tkinter import *
root = Tk()
root.title("Application")
root.resizable(width=False, height=False)
mylabel0= Label(root, text=" ")
mylabel0.grid(row=0, column=0)
def ebook():
import tkinter as tk
from tkinter import filedialog
from tkinter import messagebox
from gtts import gTTS
import pdfplumber
book = tk.Tk()
book.minsize(width=150, height=200)
book.maxsize(width=300, height=420)
canvas1 = tk.Canvas(book, width=300, height=420, bg='azure3', relief='raised')
canvas1.grid()
label1 = tk.Label(book, text="PDF Audio Store", bg='azure3')
label1.config(font=('helvetica', 16))
canvas1.create_window(150, 20, window=label1)
final = ""
def get_pdf():
global final
global pdf_checker
try:
import_file_path = filedialog.askopenfilename()
if (str(import_file_path).endswith(".pdf")):
pdf = pdfplumber.open(import_file_path)
pdf_checker = pdf
n = len(pdf.pages)
for page in range(n):
data = pdf.pages[page].extract_text()
final = final + "\n" + data
messagebox.showinfo("Information", "PDF is imported")
else:
raise Exception("Provide .pdf file only")
except Exception as e:
messagebox.showerror("Error", "{}".format(e))
else:
print("Continue to conversion")
brows_pdf = tk.Button(text="PDF entry", command=get_pdf, bg='royalblue', fg="white", font=('helvetica', 12, 'bold'),
border=0,
activebackground="green")
It's giving error in this(👇) area specifically, create_window.Error Image
canvas1.create_window(150, 60, window=brows_pdf)
def convert_audio():
global final
global pdf_checker
try:
print("File Information")
print(pdf_checker)
export_file_path = filedialog.asksaveasfilename(defaultextension=".mp3")
final_file = gTTS(text=final, lang="en")
final_file.save(export_file_path)
messagebox.showinfo("Information", "Audio file generated")
except NameError:
messagebox.showwarning("Warning", "Import PDF first")
audio_button = tk.Button(text="Convert to Audio", command=convert_audio, bg='royalblue', fg="white",
font=('helvetica', 12, 'bold'),
border=0,
activebackground="green")
canvas1.create_window(150, 100, window=audio_button)
book.mainloop()
button_ebook= Button(root, text="E-Book📖", font=30, padx=25, pady=25, command=ebook, fg="black", bg="white", borderwidth=1)
button_ebook.grid(row=3, column=2, padx=10)
root.mainloop()
The root of the problem is that you can't use a button in one window that is a descendant of another window.
The first problem is that you are creating two instances of Tk. Buttons created in one instance are not available in the other. In this case, your button is in the original instance of Tk but your canvas is in the other.
The second problem is similar. Even when replacing the second instance of Tk, the button is in the root window and thus can't be used as a child of the canvas which is in the second window.
The solution is to use Toplevel for the second window, and to make sure the button is a descendant of the second window and/or the canvas.
Related
import tkinter
from tkinter import ttk
from tkinter import *
window = tkinter.Tk()
window.title("wasans")
window.geometry('640x400')
window.resizable(False, False)
textbook = ['국어','영어','social']
textbookselecter = ttk.Combobox(window, text="교과서 선택", values=textbook)
textbookselecter.grid(column=0, row=0)
textbookselecter.place(x=140, y=200)
textbookselecter.set("목록 선택")
textbooksuntack = ttk.Label(window, width=11, borderwidth=2, background="#8182b8")
textbooksuntack.grid(column=0, row=0)
textbooksuntack.place(x=170, y=170)
textbooksuntack.anchor = CENTER
naeyong = textbookselecter.get()
if naeyong == "social":
open("../social.py", "w")
window.mainloop()
How can I open a py file using if statement and open?
Also, please give your overall review of the code.
I am not good at English, so there may be awkward sentences using a translator. Please understand.
You basically need to check every time the ttk.Combobox is changed to check if 'social' is generated.
ttk.Combobox raises a "<<ComboboxSelected>>" virtual event when selected.
import tkinter
from tkinter import ttk
from tkinter import *
window = tkinter.Tk()
window.title("wasans")
window.geometry('640x400')
window.resizable(False, False)
def callback(eventObject):
if textbookselecter.get() == "social":
print("Opening File...")
#file=open("...../social.py","r+")
textbook = ['국어','영어','social']
textbookselecter = ttk.Combobox(window, text="교과서 선택", values=textbook)
textbookselecter.grid(column=0, row=0)
textbookselecter.place(x=140, y=200)
textbookselecter.set("목록 선택")
textbooksuntack = ttk.Label(window, width=11, borderwidth=2, background="#8182b8")
textbooksuntack.grid(column=0, row=0)
textbooksuntack.place(x=170, y=170)
textbooksuntack.anchor = CENTER
textbookselecter.bind("<<ComboboxSelected>>",callback)
window.mainloop()
That's my code and I have a proplem with config() method it dosen't work with me when I use it with canvas it give me this error:
AttributeError: 'int' object has no attribute 'config'
so please help me because I stuck here....
from tkinter import ttk
from tkinter import filedialog
root = Tk()
root.title('3R')
root.geometry('350x300')
root.columnconfigure(0, weight=1)
myCanvas = Canvas(root, width=350, height=300)
myCanvas.pack(fill='both', expand=True)
#File location
Folder_Name =""
def openLocation():
global Folder_Name
Folder_Name = filedialog.askdirectory()
if(len(Folder_Name))>1:
LocError.config(text=Folder_Name, fg='green')
else:
LocError.config(text='Please Choose Folder!!',fg = 'red')
LocError = myCanvas.create_text(175,120, text='You must select a location',fill='red', font=('jost', 10))
#Button for location
SaveLoc = Button(root, text='Choose Path', command = openLocation)
myCanvas.create_window(130,87, anchor='nw', window=SaveLoc)
root.mainloop()```
You have to change your if statement as follows:
if len(Folder_Name) > 1:
myCanvas.itemconfig(LocError,text=Folder_Name, fill='green')
else:
myCanvas.itemconfig(LocError,text='Please Choose Folder!!',fill='red')
itemconfig takes an id or tag of the canvas item and edits the properties of it. Also there is no fg option for text of canvas, so change that to fill.
This is the working code:
from tkinter import *
from tkinter import ttk
from tkinter import filedialog
root = Tk()
root.title("3R")
root.geometry("350x300")
root.columnconfigure(0, weight=1)
myCanvas = Canvas(root, width=350, height=300)
myCanvas.pack(fill='both', expand=True)
#File location
Folder_Name = ""
def openLocation():
global Folder_Name, myCanvas, LocError
Folder_Name = filedialog.askdirectory()
myCanvas.delete(LocError) # Delete the old sprite
if len(Folder_Name) > 1:
# Create a new sprite with the correct parameters:
LocError = myCanvas.create_text(175, 120, text=Folder_Name, fill="green", font=("jost", 10))
else:
# Create a new sprite with the correct parameters:
LocError = myCanvas.create_text(175, 120, text="Please Choose Folder!!", fill="red", font=("jost", 10))
LocError = myCanvas.create_text(175, 120, text="You must select a location", fill="red", font=("jost", 10))
#Button for location
SaveLoc = Button(root, text="Choose Path", command=openLocation)
myCanvas.create_window(130, 87, anchor="nw", window=SaveLoc)
root.mainloop()
The variable LocError is an int. It is used to identify the sprite (for the text). To change it, I deleted it and created a new one with the correct text/fill.
So over here I am trying to make a little python-tkinter program which will store your passwords of your apps in files. However, when I try to make the second screen open, I get this error:
TypeError: 'Toplevel' object is not callable
Here is the code:
from tkinter import *
from tkinter import messagebox
import os
def screen2():
global screen2
screen2 = Toplevel(root)
screen2.title("Main Page")
screen2.geometry("260x230")
screen2.resizable("False","False")
Label(screen2, text="hello").pack()
def check_code():
code_requestget = code_request.get()
print(code_requestget)
if code_requestget == code:
screen2()
else:
messagebox.showwarning("Error", "Code is incorrect")
def mainscreen():
global root
global code
global code_request
code = "1234"
root = Tk()
root.title("Passwords")
root.geometry("260x230")
root.resizable("False","False")
code_request = StringVar()
label1 = Label(root, text="Welcome - Enter Code", width="40", height="3", background="SpringGreen3")
label1.pack()
Label(text="").pack()
enter_code = Entry(root, width="20", textvariable=code_request)
enter_code.pack()
Label(text="").pack()
continue_button = Button(root, text="Continue", width="16", command=check_code)
continue_button.pack()
root.mainloop()
mainscreen()
Unrelated to your question, but seeing your window names makes me think you don't want to use Toplevel at all. That's only needed when you want 2 active windows, but I suspect you want to use one window just to check the password, then close it and open a second, "main" window, right? If so you need to reconfigure the root window instead of using Toplevel to open a new window. Like this:
from tkinter import *
from tkinter import messagebox
import os
def screen2():
frame1.destroy() # remove all the pw check stuff
root.title("Main Page") # rename window
Label(root, text="hello").pack()
def check_code():
code_requestget = code_request.get()
print(code_requestget)
if code_requestget == code:
screen2()
else:
messagebox.showwarning("Error", "Code is incorrect")
def mainscreen():
global root, code, code_request, frame1
code = "1234"
root = Tk()
root.title("Passwords")
root.geometry("260x230")
root.resizable("False","False")
frame1 = Frame(root) # create a Frame to hold pw check components
frame1.pack()
code_request = StringVar()
label1 = Label(frame1, text="Welcome - Enter Code", width="40", height="3", background="SpringGreen3")
label1.pack()
Label(frame1, text="").pack()
enter_code = Entry(frame1, width="20", textvariable=code_request)
enter_code.pack()
Label(frame1, text="").pack()
continue_button = Button(frame1, text="Continue", width="16", command=check_code)
continue_button.pack()
root.mainloop()
mainscreen()
This is my first attempt at tkinter. I was using this tutorial, code below, where a user input a number, and with a button generate a result at another window.
import tkinter as tk
root= tk.Tk()
canvas1 = tk.Canvas(root, width = 400, height = 300)
canvas1.pack()
entry1 = tk.Entry (root)
canvas1.create_window(200, 140, window=entry1)
def getSquareRoot ():
x1 = entry1.get()
label1 = tk.Label(root, text= float(x1)**0.5)
canvas1.create_window(200, 230, window=label1)
button1 = tk.Button(text='Get the Square Root', command=getSquareRoot)
canvas1.create_window(200, 180, window=button1)
root.mainloop()
How can I do this directly, without the button? I.e., Enter number > result is generated immediately?
How about using bind for this effect, when you press a binded key, the function gets called and executed.
Here is an example:
import tkinter as tk
root = tk.Tk()
entry1 = tk.Entry(root)
entry1.pack(pady=(20, 0), padx=10)
label1 = tk.Label(root)
def getSquareRoot(event=None):
root.after(1000,getSquareRoot)
x1 = entry1.get()
try:
sqrt = float(x1)**0.5
except:
sqrt = ''
label1.config(text=sqrt)
label1.pack()
button1 = tk.Button(text='Get the Square Root', command=getSquareRoot)
button1.pack(pady=(0, 20))
entry1.bind('<Return>', getSquareRoot)
root.after(5000,getSquareRoot)
root.mainloop()
If you press the Enter key at the entry widget, it will generate the output for you, without hitting any buttons.
If you want to display Entry widget contents without using the keyboard then use a mouse key press.
entry1.bind('<Double-Button-1>', getSquareRoot)
or
entry1.bind('<Button-3>', getSquareRoot)
image for that
I have few lines of code here which is login system which works fine but i can click on the Toplevel button multiple times when i provide the wrong password without closing the messagebox.How can i make it so that it has to be closed messagebox before i can make attempt again.
from tkinter import *
from tkinter import messagebox
def top():
if entry1.get() == "333":
log.destroy()
root.deiconify()
else:
messagebox.showerror("error", "try again")
root = Tk()
root.geometry("300x300")
log = Toplevel(root)
log.geometry("200x200")
label1 = Label(log, text="password")
entry1 = Entry(log)
button1 = Button(log, text="login", command=top)
label1.pack()
entry1.pack()
button1.pack(side="bottom")
lab = Label(root, text="welcome bro").pack()
root.withdraw()
root.mainloop()
You need to make the log window the parent of the dialog:
messagebox.showerror("error", "try again", parent=log)
By default it will use the root window (the Tk instance) as the parent which in this case is not what you want.
With hint from #furas this how to implement this:
create another function to the call it when the entry doesn't match and use grab_set method for the Toplevel window tp.grab_set().You can add your customarised image to the Toplevel window as well as message to display in the box(here: i use label to depict that)
from tkinter import *
from tkinter import messagebox
def dialog(): # this function to call when entry doesn't match
tp = Toplevel(log)
tp.geometry("300x100")
tp.title('error')
tp.grab_set() # to bring the focus to the window for you to close it
tp.resizable(width=False, height=False)
l = Label(tp, text="try again\n\n\n\n add your customarize image to the window")
l.pack()
def top():
if entry1.get() == "333":
log.destroy()
root.deiconify()
else:
dialog() # being called here
root = Tk()
root.geometry("300x300")
log = Toplevel(root)
log.geometry("200x200")
label1 = Label(log, text="password")
entry1 = Entry(log)
button1 = Button(log, text="login", command=top)
label1.pack()
entry1.pack()
button1.pack(side="bottom")
lab = Label(root, text="welcome bro").pack()
root.withdraw()
root.mainloop()