from tkinter import Tk, scrolledtext, INSERT, Button, PhotoImage, Label, Text
root = Tk()
root.geometry('1000x550')
bg = PhotoImage(file='./assets/bg.png')
root.resizable(False, False)
root.title('Testing Classes')
window = Label(root, image=bg)
window.place(relheight=1, relwidth=1)
tokenBox = Text(window, bd=0, height=1, width=30)
def get_token():
token = tokenBox.get('1.0', 'end-1c')
print(token)
return token
prefixBox = Text(window, bd=0, height=1, width=20)
prefixBox.place(x=400, y=100)
tokenBox.place(x=350, y=150)
def get_prefix():
prefix = prefixBox.get('1.0', 'end-1c')
print(prefix)
return prefix
def codeInsert():
prefixBox.place(x=400, y=100)
tokenBox.place(x=350, y=150)
code = f'''
import discord
from discord.ext import commands
bot = commands.Bot(prefix={get_prefix()})
bot.run({get_token()})
'''
codeBox = scrolledtext.ScrolledText(window, width=50, height=15, bg='Black', fg='Red')
codeBox.insert(INSERT, code)
codeBox.configure(state='disabled')
codeBox.place(x=300, y=300)
submit = Button(window, command=codeInsert, text='Submit Everything', bd=0)
submit.place(x=425, y=250)
window.mainloop()
When I click on the Submit button, it hides all the textboxes. The textboxes only comes back, when I click on them. I still see the cursor change, when I hover on them, but the Labels also get hidden, and they are never shows back. It's like they become transparent, and become opaque only when I click on them.
Try this:
from tkinter import Tk, scrolledtext, INSERT, Button, PhotoImage, Label, Text
root = Tk()
root.geometry('1000x550')
bg = PhotoImage(file='./assets/bg.png')
root.resizable(False, False)
root.title('Testing Classes')
window = Label(root, image=bg)
window.place(relheight=1, relwidth=1)
tokenBox = Text(root, bd=0, height=1, width=30)
def get_token():
token = tokenBox.get('1.0', 'end-1c')
print(token)
return token
prefixBox = Text(root, bd=0, height=1, width=20)
prefixBox.place(x=400, y=100)
tokenBox.place(x=350, y=150)
def get_prefix():
prefix = prefixBox.get('1.0', 'end-1c')
print(prefix)
return prefix
def codeInsert():
# Add these lines here if you want to remove the button/entries.
#tokenBox.place_forget()
#prefixBox.place_forget()
#submit.place_forget()
code = f'''
import discord
from discord.ext import commands
bot = commands.Bot(prefix={get_prefix()})
bot.run({get_token()})
'''
codeBox = scrolledtext.ScrolledText(root, width=50, height=15, bg='Black', fg='Red')
codeBox.insert(INSERT, code)
codeBox.configure(state='disabled')
codeBox.place(x=300, y=300)
submit = Button(root, command=codeInsert, text='Submit Everything', bd=0)
submit.place(x=425, y=250)
window.mainloop()
The problem is that you had the label (named window) as the master for the other widgets. You should never have a tk.Label as a parent for anything. When I changed all their parents to root it worked.
Related
Using Python I have created a frame with empty ComboBox, TextBox and a Button. My ComboBox values are taken from List acitivity_list which initialy is empty. I am looking for a solution where user can insert a text into a TextBox and append the List activity_list so it appears in ComboBox by clicking the Button.
I failed implementing the append() function to update the List. My goal is to have a functionality where I write the name of activity in the TextBox, click the 'Add' Button and it appears in my ComboBox.
Thank you.
from tkinter import *
from tkinter import ttk
class Activity:
def __init__(self,root):
self.root=root
self.root.title("database")
self.root.geometry("1350x700+0+0")
title=Label(self.root, text="Daily Activities Database", font=("Calibri",40,"bold"))
title.pack(side=TOP)
#ComboBox
activity_list = []
Frame1=Frame(self.root,bd=4, relief=RIDGE)
Frame1.place(x=20, y=75, width=355, height=560 )
combo_activity=ttk.Combobox(Frame1, font=("Calibri",20))
combo_activity["values"]= activity_list
combo_activity.grid(row=10, column=1, padx=20, pady=10)
#Textbox
txt_act=Entry(Frame1, font=("Calibir",20))
txt_act.grid(row=11, column=1, padx=20, pady=20)
#Button
bt1 = ttk.Button(Frame1, text = "Add")
bt1.grid(row=12, column=1, padx=20, pady=20)
root=Tk()
ob=Activity(root)
root.mainloop()
Add an instance method which is triggered when Add is clicked. In the function, add the user input into activity_list and then update the values option of combo_activity.
However, you need to change some local variables to instance variables, otherwise they cannot be accessed inside the new function:
from tkinter import *
from tkinter import ttk
class Activity:
def __init__(self, root):
self.root = root
self.root.title("database")
self.root.geometry("1350x700+0+0")
title=Label(self.root, text="Daily Activities Database", font=("Calibri",40,"bold"))
title.pack(side=TOP)
Frame1 = Frame(self.root,bd=4, relief=RIDGE)
Frame1.place(x=20, y=75, width=355, height=560 )
#ComboBox
self.activity_list = []
self.combo_activity = ttk.Combobox(Frame1, font=("Calibri",20))
self.combo_activity["values"] = self.activity_list
self.combo_activity.grid(row=10, column=1, padx=20, pady=10)
#Textbox
self.txt_act = Entry(Frame1, font=("Calibir",20))
self.txt_act.grid(row=11, column=1, padx=20, pady=20)
#Button
bt1 = ttk.Button(Frame1, text="Add", command=self.add_activity) # added command option
bt1.grid(row=12, column=1, padx=20, pady=20)
def add_activity(self):
activity = self.txt_act.get().strip()
if activity:
self.activity_list.append(activity)
self.combo_activity["values"] = self.activity_list
root = Tk()
ob = Activity(root)
root.mainloop()
Thank you for help. I have adjusted the code like this and the button disappeared for the frame. Perhaps there is something wrong with indentation?
from tkinter import *
from tkinter import ttk
class Activity:
def __init__(self,root):
self.root=root
self.root.title("database")
self.root.geometry("1350x700+0+0")
title=Label(self.root, text="Daily Activities Database", font=("Calibri",40,"bold"))
title.pack(side=TOP)
#ComboBox
activity_list = []
Frame1=Frame(self.root,bd=4, relief=RIDGE)
Frame1.place(x=20, y=75, width=355, height=560 )
combo_activity=ttk.Combobox(Frame1, font=("Calibri",20))
combo_activity["values"]= activity_list
combo_activity.grid(row=10, column=1, padx=20, pady=10)
#Textbox
txt_act=Entry(Frame1, font=("Calibir",20))
txt_act.grid(row=11, column=1, padx=20, pady=20)
#Button
def add_task(self):
activity = txt_act.get()
activity_list.append(activity)
return activity_list
bt1 = ttk.Button(Frame1, text = "Add")
bt1.grid(row=12, column=1, padx=20, pady=20, command=add_task)
root=Tk()
ob=Activity(root)
root.mainloop()
I have a window with two parts. One part is to do some settings. I want to hide it until the user press a setting button. is it possible to hide a part of the frame that contains many widgets?
I have seen many examples to hide a widget in tkinter (eg. pack_forget and grid_forget). In my case, I am trying to hide a part of the frame through a button press (that contains more than one widgets). Any suggestions please
I can't use more than one frames because of some issues.
import tkinter as tk
def startFn():
pass
#fn body
def stopFn():
pass
#fn body
def FnToShow():
pass
#fn body ???
def FnToHide():
pass
#fn body ???
root = tk.Tk()
root.geometry('600x400')
#two containers like this.
#trying to hide container_2 untill the user press settingBtn
container_1 = tk.Frame(root, borderwidth=2, relief="solid")
container_2 = tk.Frame(root, borderwidth=2, relief="solid")
startBtn = tk.Button(container_1, text = "Start", command =startFn)
startBtn.grid(row=4, column=4)
stopBtn = tk.Button(container_1, text = "Stop", command= stopFn)
stopBtn.grid(row=5, column=4)
settingBtn = tk.Button(container_1, text = "Settings", command= FnToShow)
settingBtn.grid(row=6, column=4)
setting_1 = tk.Label(container_2, text = "Setting-1", fg='#000000')
setting_1.grid(row=3, column=10)
setting_2 = tk.Label(container_2, text = "Setting-2", fg='#000000')
setting_2.grid(row=4, column=10)
closeSettingBtn = tk.Button(container_2, text = "close Settings", command= FnToHide)
closeSettingBtn.grid(row=5, column=10)
container_1.pack(side="left", expand=True, fill="x", padx=1, pady=1)
container_2.pack(side="right",expand=True, fill="x", padx=1, pady=1)
root.mainloop()
You could show/hide the entire container_2 using the functions FnToShow and FnToHide:
something like this:
import tkinter as tk
def startFn():
pass
def stopFn():
pass
def FnToShow():
container_2.pack(side="right",expand=True, fill="x", padx=1, pady=1)
def FnToHide():
container_2.pack_forget()
root = tk.Tk()
root.geometry('600x400')
container_1 = tk.Frame(root, borderwidth=2, relief="solid")
container_2 = tk.Frame(root, borderwidth=2, relief="solid")
startBtn = tk.Button(container_1, text="Start", command =startFn)
startBtn.grid(row=4, column=4)
stopBtn = tk.Button(container_1, text="Stop", command= stopFn)
stopBtn.grid(row=5, column=4)
settingBtn = tk.Button(container_1, text="Settings", command= FnToShow)
settingBtn.grid(row=6, column=4)
setting_1 = tk.Label(container_2, text="Setting-1", fg='#000000')
setting_1.grid(row=3, column=10)
setting_2 = tk.Label(container_2, text="Setting-2", fg='#000000')
setting_2.grid(row=4, column=10)
closeSettingBtn = tk.Button(container_2, text="close Settings", command= FnToHide)
closeSettingBtn.grid(row=5, column=10)
container_1.pack(side="left", expand=True, fill="x", padx=1, pady=1)
root.mainloop()
when ever I click register it come up with this error
AttributeError: 'function' object has no attribute 'destroy'
I don't understand why it doesn't work i've tried every thing.
the aim of my program for now is that when I run the program it starts with a login screen and if I click sign up it will close the window be going to the log_to_reg definition where it says login_screen and open register_screen
#importing moduels
from tkinter import *
from tkinter import messagebox
from tkinter import ttk
def login_screen():
#adding the login screen
login_screen = Tk()
login_screen.geometry("400x250")
login_screen.title("Tree Road School server")
login_screen.resizable(False,False)
login_screen.configure(background = "Light blue")
#adding the title label
label_title = Label(login_screen, text="LOGIN", width = '6',
font=('Arial', 25)).place(x=135, y= 25)
#adding the labels for loging in
label_username = Label(login_screen, text = "username: ", font=(15))\
.place(x=100, y= 100)
label_username1 = Label(login_screen, text = " ", font=(15), width='13')\
.place(x=175, y= 100)
label_space = Label(login_screen, text = " ", font=(15), width='13')\
.place(x=100, y= 120)
label_space1 = Label(login_screen, text = " ", font=(15), width='13')\
.place(x=175, y= 120)
label_password = Label(login_screen, text = "password: ", font=(15))\
.place(x=100, y= 130)
label_password1 = Label(login_screen, text = " ", font=(15), width='13')\
.place(x=175, y= 130)
#adding the entry
username = Entry(login_screen, width = 15, bg = "White")
username.place(x=200, y=102)
#space to make it look nicer
password = Entry(login_screen, width = 15, bg = "White", show = "*")
password.place(x=200, y=132)
#adding the buttons
login_button = Button(login_screen, text = "login",
width = 10).place(x=100, y=175)
sign_up_button = Button(login_screen, text = "Register",
width = 14, command = log_to_reg).place(x=190, y=175)
#run mainloop
login_screen.mainloop()
def register_screen():
register_screen = Tk()
register_screen.geometry("400x250")
register_screen.title("Register")
register_screen.resizable(False,False)
register_screen.configure(background = "Light blue")
def log_to_reg():
login_screen.destroy()
rigister_screen()
login_screen()
The answer to your error:
AttributeError: 'function' object has no attribute 'destroy'
You have a function named login_screen and you are attempting to call destroy() on that function so it throws an error.
This is partly because you named your function and the root window the same thing. The other part is because the root window is only a local variable within the function so functions outside of the login_screen function cannot see the tkinter instance inside.
You could use global to manage stuff like this but all and all that is not the best option. You really want to avoid using Tk() more than once in tkinter and avoid the use of global.
Instead we can set up each item as a class and use tkinters Toplevel() to open the register window.
Here is a modified version of your code using grid() to manage everything in the window. We can also use withdrow() and deiconify() to manage what windows are visible.
import tkinter as tk
class Login(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.geometry("400x250")
self.title("Tree Road School server")
self.resizable(False,False)
self.configure(background = "Light blue")
self.columnconfigure(0, weight=1)
self.columnconfigure(2, weight=1)
self.rowconfigure(0, weight=1)
self.rowconfigure(2, weight=1)
center_frame = tk.Frame(self)
center_frame.grid(row=1, column=1, sticky="nsew")
tk.Label(center_frame, text="LOGIN", width = '6', font=('Arial', 25)).grid(row=0, column=0, columnspan=2, padx=10, pady=5)
tk.Label(center_frame, text="username: ", font=(15)).grid(row=1, column=0, padx=10, pady=5)
tk.Label(center_frame, text="password: ", font=(15)).grid(row=2, column=0, padx=10, pady=5)
self.username = tk.Entry(center_frame, width=15, bg="White")
self.username.grid(row=1, column=1, padx=10, pady=5)
self.password = tk.Entry(center_frame, width=15, bg="White", show="*")
self.password.grid(row=2, column=1, padx=10, pady=5)
tk.Button(center_frame, text="login", width=10).grid(row=3, column=0, padx=10, pady=5)
tk.Button(center_frame, text="Register", width=14, command=self.atempt_register).grid(row=3, column=1, padx=10, pady=5)
self.mainloop()
def atempt_register(self):
self.withdraw()
RegisterScreen(self, self.username.get(), self.password.get())
class RegisterScreen(tk.Toplevel):
def __init__(self, controller, username, password):
tk.Toplevel.__init__(self)
self.controller = controller
self.protocol("WM_DELETE_WINDOW", self.on_close)
self.geometry("400x250")
self.title("Register")
self.resizable(False, False)
self.configure(background = "Light blue")
self.username = username
self.password = password
tk.Label(self, text=username).grid(row=0, column=0)
tk.Label(self, text=password).grid(row=1, column=0)
def on_close(self):
self.controller.deiconify()
self.destroy()
Login()
On create window, tkinter.scrolledtext look up for SearchIP() to insert but never update layout. When I have different input for SearchIP() method never show up. It only shows the initial value.
Note: I added a couple of print statements to watch if SearchIP() returns the right thing, which is the case, for example for 'www.google.com' it prints '216.58.192.4', but this value never shows up in ScrolledText.
import socket
try:
# for Python2
import Tkinter as tk
import ScrolledText as tkst
except ImportError:
# for Python3
import tkinter as tk
import tkinter.scrolledtext as tkst
global Filename
root = tk.Tk()
frame = tk.Frame(root,width=100)
label = Label(root,text="http://")
label.grid(row=0,column=0)
entryVar = tk.StringVar()
entry = Entry(root,width=50,textvariable=entryVar)
entry.grid(row='0',column='1',columnspan=8)
def SearchIP():
print(entryVar.get())
add = str(entryVar.get())
ip_a = socket.gethostbyname(add)
print(str(ip_a))
return str(ip_a);
button1 = Button(root, text="Search IP", command=SearchIP)
button1.grid(row=1, column=0)
button2 = Button(root, text="DNS Recon")
button2.grid(row=1, column=1)
button3 = Button(root, text="Port Scanner")
button3.grid(row=1, column=2)
button4 = Button(root, text="Web Crawl")
button4.grid(row=1, column=3)
button5 = Button(root, text="Email Gathering")
button5.grid(row=1, column=4)
frame.grid(row=2, column=0, columnspan=30, rowspan=30)
edit_space = tkst.ScrolledText(
master = frame,
wrap = 'word', # wrap text at full words only
width = 45, # characters
height = 10, # text lines
# background color of edit area
)
# the padx/pady space will form a frame
edit_space.pack(fill='both', expand=True, padx=8, pady=8)
root.title("E-Z Security Audting")
root.resizable(True, True)
edit_space.insert('insert', SearchIP())
root.mainloop()
I also tried to modify the SearchIP() method and remove the return statement, but then I got this error:
File "C:/Users/kero/Desktop/Robert_HodgesKeroles_Hakeem_secproject/secproject/newUser_Interface.py", line 50, in <module>
edit_space.insert('insert', SearchIP())
File "C:\Python27\lib\lib-tk\Tkinter.py", line 2986, in insert
self.tk.call((self._w, 'insert', index, chars) + args)`
SearchIP after modification
def SearchIP():
add = str(entryVar.get())
ip_a= socket.gethostbyname(add)
You have to use insert() inside SearchIP()
import socket
try:
# for Python2
import Tkinter as tk
import ScrolledText as tkst
except ImportError:
# for Python3
import tkinter as tk
import tkinter.scrolledtext as tkst
# --- functions ---
def SearchIP():
add = entryVar.get()
ip_a = socket.gethostbyname(add)
edit_space.insert('insert', ip_a + "\n")
# --- main ---
root = tk.Tk()
root.title("E-Z Security Audting")
root.resizable(True, True)
frame = tk.Frame(root, width=100)
frame.grid(row=2, column=0, columnspan=30, rowspan=30)
label = tk.Label(root, text="http://")
label.grid(row=0, column=0)
entryVar = tk.StringVar()
entry = tk.Entry(root, width=50, textvariable=entryVar)
entry.grid(row=0, column=1, columnspan=8)
button1 = tk.Button(root, text="Search IP", command=SearchIP)
button1.grid(row=1, column=0)
button2 = tk.Button(root, text="DNS Recon")
button2.grid(row=1, column=1)
button3 = tk.Button(root, text="Port Scanner")
button3.grid(row=1, column=2)
button4 = tk.Button(root, text="Web Crawl")
button4.grid(row=1, column=3)
button5 = tk.Button(root, text="Email Gathering")
button5.grid(row=1, column=4)
edit_space = tkst.ScrolledText(
master=frame,
wrap='word', # wrap text at full words only
width=45, # characters
height=10, # text lines
# background color of edit area
)
edit_space.pack(fill='both', expand=True, padx=8, pady=8)
root.mainloop()
def WhoisWin():
win1 = Toplevel()
win1.title("Whois")
win1.config(bg="black")
win1.geometry("300x300")
win1.resizable(0,0)
text = Text()
text1 = Text()
text1.config(width=15, height=1)
text1.config(bg="black", fg="white")
text1.pack()
def button1():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("com.whois-servers.net", 43))
s.send(text1.get("1.0", END) + "\r\n")
response = ''
while True:
a = s.recv(4096)
response += a
if a == '':
break
s.close()
text.insert(END, response)
def clear():
text.delete("1.0", END)
text1.delete("1.0", END)
frame = Frame(win1)
frame.config(bg="black")
frame.pack(pady=10, padx=5)
b = Button(frame, text="Enter", width=10, height=2, command=button1)
b.config(fg="white", bg="black")
b.pack(side=LEFT, padx=5)
c = Button(frame, text="Clear", width=10, height=2, command=clear)
c.config(fg="white", bg="black")
c.pack(side=RIGHT, padx=5)
scrollbar = Scrollbar(win1)
scrollbar.pack(side=RIGHT, fill=Y)
text.config(width=35, height=15, bg="black", fg="white")
text.pack(side=LEFT, fill=Y)
scrollbar.config(command=text.yview)
text.config(yscrollcommand=scrollbar.set)
This is just a child window that will popup when you click on the menu, I don't get any errors, but Text and Tex1 is not visible on the child window, but when I run this code on its own root window it works just find, maybe the ident is messed up or something? Any help will be appreciated, Thanks.
You don't provide a parent for text or text1. When you call Text() you need to give it an argument like Text(win1) or Text(frame) so that Tkinter knows what to pack the Text widget on.