I keep getting an error saying that the button failed to call the function when I press it here is the function it's failing to run
import re
from tkinter import *
from tkinter import ttk
import time
from turtle import bgcolor
import webbrowser
from tkinter import messagebox
from tkinter import filedialog
root = Tk()
root.title('Notepad')
root.iconbitmap('C:/Users/Hero/Documents/Visual Studio code/My project/notes.ico')
root.geometry("640x500")
root.tk.call("source", "C:/Users/Hero/Documents/Visual Studio code/My project/azure.tcl")
root.tk.call("set_theme", "dark")
global x
x = 20
def change_theme():
if root.tk.call("ttk::style", "theme", "use") == "azure-dark":
root.tk.call("set_theme", "light")
else:
root.tk.call("set_theme", "dark")
def increase_font_size():
global x
global f
x = x + 1
print(x)
text.config(font=(f, x))
def decrease_font_size():
global x
global f
x = x - 1
print(x)
text.config(font=(f, x))
def pfonts():
font_page = Tk()
font_page.title('Fonts')
font_page.geometry('295x200')
font_page.configure(bg='#292929')
font_page.tk.call("source", "C:/Users/Hero/Documents/Visual Studio code/My project/azure.tcl")
font_page.tk.call("set_theme", "dark")
global f
fentry1 = ttk.Entry(font_page, width=80)
fentry1.pack()
label1 = Label(font_page, text='Enter the font name you want', font=("Tekton Pro", 17), bg='#292929')
label2 = Label(font_page, text='warning: caps lock sensitive', font=("Tekton Pro", 8), bg='#292929')
label1.pack()
label2.pack(side=BOTTOM)
def change_font():
global f
f = fentry1.get()
text.config(font=(f, x))
print(f)
bbfont = ttk.Button(font_page, text='Confirm font', command=change_font)
bbfont.pack(side=BOTTOM)
def killer():
print("killing the instence")
root.destroy()
def savefile():
global filename
filename = filedialog.asksaveasfilename(initialdir='/', title='Save File', filetypes=(('Text Files', '*.txt'), ('All Files', '*.*')))
textContent = text.get("1.0",END)
textContent = str(textContent)
myfile = open(filename, "w+")
myfile.write(textContent)
style=ttk.Style()
style.theme_use('azure-dark')
style.configure("Vertical.TScrollbar", background="grey", bordercolor="black", arrowcolor="white")
barframe = Frame()
barframe.pack(side=BOTTOM)
bfonts = ttk.Button(barframe, text='Fonts', style='Accent.TButton', command=pfonts)
open = ttk.Button(barframe, text='Open', style='Accent.TButton')
save = ttk.Button(barframe, text='Save', style='Accent.TButton', command=savefile)
close = ttk.Button(barframe, text='Close', style='Accent.TButton', command=killer)
#fonts = ttk.Entry(barframe, width=10)
calculater = ttk.Button(barframe, text='Calculater', width=10, style='Accent.TButton')
calander = ttk.Button(barframe, text='Calander', width=10, style='Accent.TButton')
increase_size = ttk.Button(barframe, text='+', width=2, command=increase_font_size)
decrease_size = ttk.Button(barframe, text='-', width=2, command=decrease_font_size)
bfonts.grid(row=0, column=0)
open.grid(row=0, column=1)
save.grid(row=0, column=2)
close.grid(row=0, column=3)
#fonts.grid(row=0, column=1)
calculater.grid(row=0, column=4)
calander.grid(row=0, column=5)
increase_size.grid(row=0, column=6)
decrease_size.grid(row=0, column=7)
scroll = ttk.Scrollbar(root, orient='vertical')
scroll.pack(side=RIGHT, fill='y')
text=Text(root, font=("Georgia", x), yscrollcommand=scroll.set, bg='#292929', height=1, width=1)
scroll.config(command=text.yview)
text.pack(fill=BOTH, expand=1)
root.mainloop()
Error code
Traceback (most recent call last):
File "C:\Users\Hero\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py", line 1921, in __call__
return self.func(*args)
File "c:\Users\Hero\Documents\Visual Studio code\My project\MainFrame.py", line 82, in savefile
myfile = open(filename, "w+")
TypeError: 'Button' object is not callable
thats everything the whole script and the whole error i hope that helps i just thought it would get in the way if i posted the whole code as its really big lol
After testing it, the problem was you assigning a predefined python variable to the open button. Where you have:
open = ttk.Button(barframe, text='Open', style='Accent.TButton')
Just change that to something like:
openButton = ttk.Button(barframe, text='Open', style='Accent.TButton')
And then downstream change to this:
openButton.grid(row=0, column=1)
Related
I'm making an HTML editor/interpreter with Python tkinter and I'm also using selenium in order to open chrome and display the output of the html code above the tkinter window. It will do so when the run button is clicked. After I click the run button, the browser opens but suddenly closes a second later. And then an error shows up in the console. Here is the error:
Exception ignored in: <function Popen.__del__ at 0x0000021819AA1430>
Traceback (most recent call last):
File "C:\Users\Meirom\AppData\Local\Programs\Python\Python39\lib\subprocess.py", line 1055, in __del__
self._internal_poll(_deadstate=_maxsize)
File "C:\Users\Meirom\AppData\Local\Programs\Python\Python39\lib\subprocess.py", line 1457, in _internal_poll
if _WaitForSingleObject(self._handle, 0) == _WAIT_OBJECT_0:
OSError: [WinError 6] The handle is invalid
How do I fix this?
Code:
import tkinter as tk
from tkinter.filedialog import askopenfilename, asksaveasfilename
from tkinter import messagebox
import os
from selenium import webdriver
window = tk.Tk()
window.title("HTML Editor")
window.configure(bg="grey")
window.state("zoomed")
title = tk.Label(window, text="HTML Editor", font=("Arial Rounded MT Bold", 40, "underline"), bg="grey")
title.place(x=400, y=20)
screen_width = window.winfo_screenwidth()
screen_height = window.winfo_screenheight()
def open_file():
file_path = askopenfilename(filetypes=[("HTML Files", "*.html"), ("All Files", "*.*")])
if not file_path:
return
text_box.delete("1.0", tk.END)
file_func()
with open(file_path, "r") as file_read:
text = file_read.read()
text_box.insert(tk.END, text)
window.title(f"HTML Editor - {file_path}")
def save_file():
file_path = asksaveasfilename(defaultextension="txt", filetypes=[("HTML Files", "*.html"), ("All Files", "*.*")])
if not file_path:
return
with open(file_path, "w") as file_write:
text = text_box.get(1.0, tk.END)
file_write.write(text)
window.title(f"HTML Editor - {file_path}")
file_func()
def stop_program(driver):
driver.close()
stop.pack_forget()
def run_code():
global screen_width, screen_height
window_title = window.title()
index = window_title.index("-") + 2
window_title = window_title[index::]
with open(window_title, "w") as path:
content = text_box.get("1.0", tk.END)
path.write(content)
basename = os.path.basename(window_title)
new_file = open(basename, "w")
new_file.write(content)
new_file.close()
driver = webdriver.Chrome("C:\chromedriver.exe")
new_width = screen_width - 680
driver.get("file:///" + os.getcwd() + "/" + basename)
driver.set_window_size(new_width, screen_height)
driver.set_window_position(680, 0, windowHandle="current")
stop.pack(padx=50, pady=5)
stop.configure(command=stop_program(driver))
def get_stringvar(event):
line = text_box.get("insert linestart", "insert")
if (line[-1] == ">") and ("<" in line) and "<!DOCTYPE html>" not in line:
new_line = "</" + line[line.rindex("<") + 1:-1] + ">"
text_box.insert("insert", new_line)
text_box.mark_set("insert", f"insert-{len(new_line)}c")
return "break"
def on_closing():
if window.title() != "HTML Editor":
window_title = window.title()
index = window_title.index("-") + 2
window_title = window_title[index::]
file = open(window_title, "w")
file.write(text_box.get("1.0", tk.END))
quit()
def file_func():
frame.pack(side="left", fill="y")
text_box.pack(side="left", expand=True)
scroll_bar.pack(side="left", fill="y")
run_b.pack(padx=50, pady=(100, 5), anchor="n")
create = tk.Button(window, text="Create a new file", width=17, height=3, font=("Arial Rounded MT Bold", 20),
command=save_file)
create.place(x=420, y=200)
open_e = tk.Button(window, text="Open an existing file", width=17, height=3, font=("Arial Rounded MT Bold", 20),
command=open_file)
open_e.place(x=420, y=350)
window.protocol("WM_DELETE_WINDOW", on_closing)
frame = tk.Frame(window, bd=2, relief="raised")
text_box = tk.Text(window, font=("Flux-Regular", 12), fg="black", undo=True, width=600, height=720)
text_box.bind("<Tab>", get_stringvar)
scroll_bar = tk.Scrollbar(window, command=text_box.yview)
run_b = tk.Button(frame, text="Run", width=6, height=2, bg="white", command=run_code)
text_box.configure(yscrollcommand=scroll_bar.set)
stop = tk.Button(frame, bg="red", text="Stop", width=6, height=2)
window.mainloop()
I've managed to fix the problem very shortly after I posted this question. I noticed that I forgot to use a lambda function in my stop button's command, so its command ran without me pressing the button. I only modified the run_code function. Updated code:
import tkinter as tk
from tkinter.filedialog import askopenfilename, asksaveasfilename
from tkinter import messagebox
import os
from selenium import webdriver
window = tk.Tk()
window.title("HTML Editor")
window.configure(bg="grey")
window.state("zoomed")
title = tk.Label(window, text="HTML Editor", font=("Arial Rounded MT Bold", 40, "underline"), bg="grey")
title.place(x=400, y=20)
screen_width = window.winfo_screenwidth()
screen_height = window.winfo_screenheight()
def open_file():
file_path = askopenfilename(filetypes=[("HTML Files", "*.html"), ("All Files", "*.*")])
if not file_path:
return
text_box.delete("1.0", tk.END)
file_func()
with open(file_path, "r") as file_read:
text = file_read.read()
text_box.insert(tk.END, text)
window.title(f"HTML Editor - {file_path}")
def save_file():
file_path = asksaveasfilename(defaultextension="txt", filetypes=[("HTML Files", "*.html"), ("All Files", "*.*")])
if not file_path:
return
with open(file_path, "w") as file_write:
text = text_box.get(1.0, tk.END)
file_write.write(text)
window.title(f"HTML Editor - {file_path}")
file_func()
def stop_program(driver):
driver.close()
stop.pack_forget()
def run_code():
global screen_width, screen_height
window_title = window.title()
index = window_title.index("-") + 2
window_title = window_title[index::]
with open(window_title, "w") as path:
content = text_box.get("1.0", tk.END)
path.write(content)
basename = os.path.basename(window_title)
new_file = open(basename, "w")
new_file.write(content)
new_file.close()
driver = webdriver.Chrome("C:\chromedriver.exe")
new_width = screen_width - 680
driver.get("file:///" + os.getcwd() + "/" + basename)
driver.set_window_size(new_width, screen_height)
driver.set_window_position(680, 0, windowHandle="current")
stop.pack(padx=50, pady=5)
stop.configure(command=lambda: stop_program(driver))
def get_stringvar(event):
line = text_box.get("insert linestart", "insert")
if (line[-1] == ">") and ("<" in line) and "<!DOCTYPE html>" not in line:
new_line = "</" + line[line.rindex("<") + 1:-1] + ">"
text_box.insert("insert", new_line)
text_box.mark_set("insert", f"insert-{len(new_line)}c")
return "break"
def on_closing():
if window.title() != "HTML Editor":
window_title = window.title()
index = window_title.index("-") + 2
window_title = window_title[index::]
file = open(window_title, "w")
file.write(text_box.get("1.0", tk.END))
quit()
def file_func():
frame.pack(side="left", fill="y")
text_box.pack(side="left", expand=True)
scroll_bar.pack(side="left", fill="y")
run_b.pack(padx=50, pady=(100, 5), anchor="n")
create = tk.Button(window, text="Create a new file", width=17, height=3, font=("Arial Rounded MT Bold", 20),
command=save_file)
create.place(x=420, y=200)
open_e = tk.Button(window, text="Open an existing file", width=17, height=3, font=("Arial Rounded MT Bold", 20),
command=open_file)
open_e.place(x=420, y=350)
window.protocol("WM_DELETE_WINDOW", on_closing)
frame = tk.Frame(window, bd=2, relief="raised")
text_box = tk.Text(window, font=("Flux-Regular", 12), fg="black", undo=True, width=600, height=720)
text_box.bind("<Tab>", get_stringvar)
scroll_bar = tk.Scrollbar(window, command=text_box.yview)
run_b = tk.Button(frame, text="Run", width=6, height=2, bg="white", command=run_code)
text_box.configure(yscrollcommand=scroll_bar.set)
stop = tk.Button(frame, bg="red", text="Stop", width=6, height=2)
window.mainloop()
I have two functions and two GUI.
I cannot get them to work after each other.
first, I want to open my browse GUI then editing GUI.
help me out, please.
from tkinter import *
from tkinter import filedialog
window = Tk()
def fileme():
root = Tk()
root.withdraw()
file_path = filedialog.askopenfilenames(filetypes=[("Text file","*.txt")])
print(file_path)
window.withdraw()
with open(file_path[0]) as f:
f_contents = f.read()
b=(f_contents)
print(b)
window.title('Edit and save text files by Ali')
frame = Frame(window)
btn = Button(frame, text = 'Browse', command= fileme)
btn.pack(side = RIGHT , padx =55)
frame.pack(padx=100,pady = 30)
root=Tk()
x=filedialog.askopenfilename(filetypes=[("Text file","*.txt")])
T=Text(root,state='normal', height=20, width=70)
T.pack()
T.insert(END, open(x).read())
def save():
b = T.get('1.0', END)
f = open(x, 'wt')
f.write(b)
f.close()
btn= Button(root, text='Save', command=save)
btn.pack(side = RIGHT , padx =55)
window.mainloop()
root.mainloop()
I figured it out
Here is an answer to this type of questions.
hope to be useful for anyone who is learning programming.
from tkinter import *
from tkinter import filedialog
window=Tk()
def x():
x=filedialog.askopenfilename(filetypes=[("Text file","*.txt")])
T = Text(window, state='normal', height=20, width=70)
T.pack()
T.insert(END, open(x).read())
def save():
b = T.get('1.0', END)
f = open(x, 'wt')
f.write(b)
f.close()
btn1 = Button(window, text='Save', command=save)
btn1.pack(side=RIGHT, padx=55)
window.title('Edit and save text files by Ali')
frame = Frame(window)
btn = Button(frame, text = 'Browse', command= x)
btn.pack(side = RIGHT , padx =55)
frame.pack(padx=100,pady = 30)
window.mainloop()
#Epiphnac In your solution both the browser window and the text editor open in the same window. I think my solution is a little bit better than that.
I have put the editor inside a new window using Toplevel.
Like this:
import tkinter as tk
from tkinter import filedialog
window = tk.Tk()
def editor():
x = filedialog.askopenfilename(filetypes=[("Text file", "*.txt")])
new_window = tk.Toplevel()
t = tk.Text(new_window, state='normal', height=20, width=70)
t.pack()
t.insert(tk.END, open(x).read())
def save():
b = t.get('1.0', tk.END)
f = open(x, 'wt')
f.write(b)
f.close()
btn1 = tk.Button(new_window, text='Save', command=save)
btn1.pack(side=tk.RIGHT, padx=55)
window.title('Edit and save text files by Ali')
frame = tk.Frame(window)
btn = tk.Button(frame, text='Browse', command=editor)
btn.pack(side=tk.RIGHT, padx=55)
frame.pack(padx=100, pady=30)
window.mainloop()
I buid a code which takes python user input and insert it into a text file when pressing apply as shown in the picture bellow
and the text file will always be updated when the user inserts a new text, how to create an new button next to apply to show up to date text file to the user
and want prevent to enter the same text
example if the text file has a (go) the program do not enter (go) again
this is my code
root = Tk()
ivn = StringVar()
inputVarName = Entry(root, textvariable=str(ivn))
ivn.set(str("text1"))
inputVarName.grid(row=0, column=0)
ivn2 = StringVar()
inputVarName2 = Entry(root, textvariable=str(ivn2))
ivn2.set(str("text2"))
inputVarName2.grid(row=1, column=0)
def writetofile():
content_list = [ivn.get(), ivn2.get()]
print("\n".join(content_list))
with open("help.txt", "a") as f:
for item in content_list:
f.write("%s\n" % item)
applyButton = Button(root, text="Apply", command=writetofile)
applyButton.grid(row=2, column=1)
root.mainloop()
To prevent a user from inserting the same text just empty the two entries, and you can check if entries are not empty before saving to a file.
You can use a top-level window to show the file content.
Check the following example:
from tkinter import Tk, Toplevel, Button, Entry, StringVar, Text, DISABLED, END, W, E
import tkinter.ttk as ttk
import tkMessageBox
root = Tk()
ivn = StringVar()
inputVarName = Entry(root, textvariable=str(ivn))
ivn.set(str("text1"))
inputVarName.grid(row=0, column=0,columnspan=2)
ivn2 = StringVar()
inputVarName2 = Entry(root, textvariable=str(ivn2))
ivn2.set(str("text2"))
inputVarName2.grid(row=1, column=0,columnspan=2)
def writetofile():
content_list = [ivn.get(), ivn2.get()]
if any(content_list):
print("\n".join(content_list))
with open("help.txt", 'r+') as inFile:
for item in content_list:
if ("%s\n" % item).encode('UTF-8') in inFile:
tkMessageBox.showwarning("Warning", "'%s': Already exists!" % item)
return
with open("help.txt", "a") as f:
for item in content_list:
f.write( ("%s\n" % item).encode('UTF-8'))
ivn.set('')
ivn2.set('')
def showfile():
top = Toplevel()
top.title("help.txt")
textArea = Text(top)
scrollbar = ttk.Scrollbar(top, command=textArea.yview)
scrollbar.grid(row=0, column=1, sticky='nsew')
textArea['yscrollcommand'] = scrollbar.set
with open("help.txt", "r") as infile:
textArea.insert(END, infile.read())
textArea.grid(row=0, column=0)
textArea.config(state=DISABLED)
applyButton = Button(root, text="Apply", command=writetofile)
applyButton.grid(row=2, column=0, sticky=W+E)
showButton = Button(root, text="Show", command=showfile)
showButton.grid(row=2, column=1, sticky=W+E)
root.mainloop()
Edited to answer #IbrahimOzaeri question in comments.
You can use tkFileDialog.askopenfilename to ask user to select a file:
from Tkinter import Tk
import Tkinter, Tkconstants, tkFileDialog
root = Tk()
root.filename = tkFileDialog.askopenfilename(initialdir = "/",title = "Select file",filetypes = (("text files","*.txt"),("all files","*.*")))
print (root.filename)
I was trying something same but with one output
import tkinter.ttk as ttk
import tkMessageBox
root = Tk()
root.geometry("500x300")
root.title("The Gatway company")
ivn = StringVar()
inputVarName = Entry(root, textvariable=str(ivn))
ivn.set(str("text1"))
inputVarName.grid(row=0, column=0,columnspan=2)
def writetofile():
content_list = [ivn.get()]
if any(content_list):
with open("help.txt", 'r+') as inFile:
for item in content_list:
if ("%s\n" % item).encode('UTF-8') in inFile:
tkMessageBox.showwarning("Warning", "'%s': Already exists!" % item)
return
with open("help.txt", "a") as f:
for item in content_list:
f.write( ("%s\n" % item).encode('UTF-8'))
ivn.set('')
def showfile():
top = Toplevel()
top.title("help.txt")
textArea = Text(top)
scrollbar = ttk.Scrollbar(top, command=textArea.yview)
scrollbar.grid(row=0, column=1, sticky='nsew')
textArea['yscrollcommand'] = scrollbar.set
with open("help.txt", "r") as infile:
textArea.insert(END, infile.read())
textArea.grid(row=0, column=0)
textArea.config(state=DISABLED)
applyButton = Button(root, text="Apply", command=writetofile)
applyButton.grid(row=2, column=0, sticky=W+E)
applyButton.config( height = 5, width = 10 )
showButton = Button(root, text="Show", command=showfile)
showButton.grid(row=2, column=1, sticky=W+E)
showButton.config( height = 5, width = 10 )
root.mainloop()
it's same as your code but for one entry, I'm thinking to edit it in a such way that the user chooses the help.txt file like a file requester.
I have written the following code but for some reasons the .get() gives me nothing.
I have tried printing fullname.get()'s len and it gives me 0 with following error:
<class 'str'>
0
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Program Files (x86)\Python37-32\lib\tkinter\__init__.py", line 1705, in __call__
return self.func(*args)
TypeError: 'NoneType' object is not callable
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Program Files (x86)\Python37-32\lib\tkinter\__init__.py", line 1705, in __call__
return self.func(*args)
TypeError: 'NoneType' object is not callable
[Finished in 21.5s]
from tkinter import *
from tkinter.ttk import *
from tkinter.messagebox import *
from db import DBConnect
from listComp import ListComp
conn = DBConnect()
def Complaint():
comp = Tk()
comp.geometry('1366x768')
comp.title('Complaint Box')
comp.configure(background='#2919bf')
#Style
style1 = Style()
style1.theme_use('classic')
for elem in ['TLabel', 'TButton', 'TRadioutton']:
style1.configure(elem, background='#35a5e1')
labels = ['Full Name:', 'Gender:','Choose a Category', 'Comment:']
for i in range(4):
Label(comp, text=labels[i]).grid(row=i, column=0, padx=200, pady=25)
BuList = Button(comp, text='List Comp.')
BuList.grid(row=5, column=1)
BuSubmit = Button(comp, text='Submit Now')
BuSubmit.grid(row=5, column=2)
tkvar = StringVar(comp)
# Dictionary with options
choices = { 'Student','Teacher','Management','Infrastructure',''}
tkvar.set('') # set the default option
#Gridx1353
popupMenu = OptionMenu(comp, tkvar, *choices)
popupMenu.grid(row = 2, column =1)
tkvar.trace('w', change_dropdown(tkvar.get()))
#Entries
fullname = Entry(comp, width=40, font=('Arial', 14))
fullname.grid(row=0, column=1, columnspan=2)
SpanGender = StringVar()
r1 = Radiobutton(comp, text='Male', value='male', variable=SpanGender).grid(row=1, column=1)
r2 = Radiobutton(comp, text='Female', value='female', variable=SpanGender).grid(row=1, column=2)
comment = Text(comp, width=35, height=5, font=('Arial', 14))
comment.grid(row=3, column=1, columnspan=2, padx=10, pady=10)
f=fullname.get()
print(type(f))
print(len(f))
print(fullname.get())
s=SpanGender.get()
t=tkvar.get()
c=comment.get(1.0,'end')
BuSubmit.config(command=lambda:SaveData(f,s,t,c))
BuList.config(command=ShowList)
comp.mainloop()
# on change dropdown value
def change_dropdown(tkvar):
print( tkvar )
# link function to change dropdown
def SaveData(fullname,SpanGender,tkvar,comment):
msg1= "Failed please fill all information!."
#print(len(fullname))
if len(fullname) == 0 or len(SpanGender)==0:
showinfo(title='Add Info',message=msg1)
else:
msg = conn.Add(fullname,SpanGender,tkvar,comment)
#fullname.delete(0, 'end')
#comment.delete(1.0, 'end')
#r1.deselect()
#r2.deselect()
showinfo(title='Add Info', message=msg)
def ShowList():
listrequest = ListComp()
#Config
root = Tk()
root.geometry('1366x768')
root.title('Complaint Box')
root.configure(background='#2919bf')
style = Style()
style.theme_use('classic')
for elem in ['TLabel', 'TButton']:
style.configure(elem, background='#35a5e1')
Label(root, text="Welcome To Indian Government Complaint Department",font="Verdana 24 bold").grid(row=1, column=0,padx=150,pady=10)
BuRegister = Button(root, text='Register Complaint',command=Complaint)
BuRegister.grid(row=5,pady=200,padx=10)
#BuRegister.place(relx=0.5, rely=0.5, anchor=CENTER)
BuView = Button(root, text='View Complaint',command=ShowList)
BuView.grid(row=7,pady=0,padx=10)
root.mainloop()
There is no way for me to reproduce your error. I suspect it could be caused by import * or one of your bad get() methods. Likely the get() methods as you do not even set value of entry's text and probably getting the Null value from that.
Keep in mind you need to run the get() method inside of a function and not in the same location you are initializing your code.
One of the other major problems is the use of Tk() more than once. You always want to use only one instance of Tk() when building a Tkinter GUI. For new windows use Toplevel().
I have cleaned up your code to follow PEP8 more closely. Let me know if this helps.
import tkinter as tk # use these imports so you do not overwrite other imports.
import tkinter.ttk as ttk # use these imports so you do not overwrite other imports.
import tkinter.messagebox as messagebox # avoid import *. Its normally not needed.
from db import DBConnect
from listComp import ListComp
def complaint(master):
comp = tk.Toplevel(master)
comp.geometry('1366x768')
comp.title('Complaint Box')
comp.configure(background='#2919bf')
style1 = ttk.Style()
style1.theme_use('classic')
tkvar = tk.StringVar(master)
tkvar.set('')
labels = ['Full Name:', 'Gender:', 'Choose a Category', 'Comment:']
choices = {'Student', 'Teacher', 'Management', 'Infrastructure', ''}
for elem in ['TLabel', 'TButton', 'TRadiobutton']: # fixed typo
style1.configure(elem, background='#35a5e1')
for i in range(4):
ttk.Label(comp, text=labels[i]).grid(row=i, column=0, padx=200, pady=25)
popup_menu = tk.OptionMenu(comp, tkvar, *choices)
popup_menu.grid(row=2, column=1)
tkvar.trace('w', lambda: change_dropdown(tkvar)) # corrected your trace command.
fullname = tk.Entry(comp, text='', width=40, font=('Arial', 14))
fullname.grid(row=0, column=1, columnspan=2)
span_gender = tk.StringVar(master)
ttk.Radiobutton(comp, text='Male', value='male', variable=span_gender).grid(row=1, column=1)
ttk.Radiobutton(comp, text='Female', value='female', variable=span_gender).grid(row=1, column=2)
comment = tk.Text(comp, width=35, height=5, font=('Arial', 14))
comment.grid(row=3, column=1, columnspan=2, padx=10, pady=10)
ttk.Button(comp, text='List Comp.', command=show_list).grid(row=5, column=1)
ttk.Button(comp, text='Submit Now', command=lambda: save_data(fullname, span_gender,
tkvar, comment)).grid(row=5, column=2)
def change_dropdown(tkvar):
print(tkvar.get())
def save_data(fullname, span_gender, tkvar, comment):
msg1 = "Failed please fill all information!."
if len(fullname.get()) == 0 or len(span_gender.get()) == 0:
messagebox.showinfo(title='Add Info', message=msg1)
else:
conn = DBConnect() # moved conn to the function. No point in opening connection until its needed.
msg = conn.Add(fullname.get(), span_gender.get(), tkvar.get(), comment.get(1.0, 'end-1c'))
messagebox.showinfo(title='Add Info', message=msg)
# you should probably close the connection here.
def show_list():
# cannot test this function as I do not know what `ListComp()` is doing.
# That said this function is currently pointless as the local variable
# will be basically deleted when the function finishes.
listrequest = ListComp()
root = tk.Tk()
root.geometry('1366x768')
root.title('Complaint Box')
root.configure(background='#2919bf')
style = ttk.Style()
style.theme_use('classic')
for elem in ['TLabel', 'TButton']:
style.configure(elem, background='#35a5e1')
ttk.Label(root, text="Welcome To Indian Government Complaint Department",
font="Verdana 24 bold").grid(row=1, column=0, padx=150, pady=10)
ttk.Button(root, text='Register Complaint', command=lambda: complaint(root)).grid(row=5, pady=200, padx=10)
ttk.Button(root, text='View Complaint', command=show_list).grid(row=7, pady=0, padx=10)
root.mainloop()
below is my code for creating a tool that takes a file path, stores the value, and then opens the specific file path selected by the user.
Currently, I'm looking to take the user entry mypathEntry that is stored in the mypathList listbox after clicking the Save button and add a command to it. The command will open that selected file path. My current code returns an error message regarding mypathList.add_command(command=Open) stating that Listbox instance has no attribute 'add_command'.
What is the syntax for adding a command to a listbox item?
from Tkinter import *
import os
root = Tk()
def Save():
fp = mypathEntry.get()
scribe = open('filepath.txt', 'w')
scribe.write(fp)
mypathEntry.delete(0, 'end')
mypathList.insert(1, fp)
def Open():
path = fp
menu = Menu(root)
##root.config(menu=menu)
##subMenu = Menu(menu)
##menu.add_cascade(label="Filepaths", menu=subMenu)
##subMenu.add_command(command=Save)
mypathLabel = Label(root, text="Copy and Paste your filepath here:")
mypathEntry = Entry(root, bg="black", fg="white", relief=SUNKEN)
mypathSaveButton = Button(root, text="Save Path", bg="black", fg="white", command=Save)
mypathList = Listbox(root, bg="black", fg="white")
mypathList.add_command(command=Open)
mypathLabel.pack()
mypathEntry.pack()
mypathSaveButton.pack()
mypathList.pack()
root.mainloop()
According to this,
http://effbot.org/tkinterbook/listbox.htm
The listbox item does not have a command option. So what you need to do instead is to bind an event to it. Here is a complete working example.
from tkinter import *
import os
root = Tk()
class MainGui:
def __init__(self, master):
self.mypathLabel = Label(master, text="Copy and Paste your filepath here:")
self.mypathEntry = Entry(master, bg="black", fg="white", relief=SUNKEN)
self.mypathSaveButton = Button(master, text="Save Path", bg="black", fg="white", command=self.save_path)
self.mypathList = Listbox(master, bg="black", fg="white")
self.mypathLabel.pack()
self.mypathEntry.pack()
self.mypathSaveButton.pack()
self.mypathList.pack()
self.mypathList.bind("<Double-Button-1>", self.open_path)
def save_path(self):
fp = self.mypathEntry.get()
self.mypathEntry.delete(0, 'end')
self.mypathList.insert(1, fp)
def open_path(self, event):
list_item = self.mypathList.curselection()
fp = self.mypathList.get(list_item[0])
print(fp)
try:
with open(fp, 'r') as result:
print(result.read())
except Exception as e:
print(e)
MainGui(root)
root.mainloop()