I have searched for similar questions but I can't seem to figure out what i am doing wrong. I have this code for a very simple gui. The code in googl1 is a scraper that extracts information from google. But I have this problem where when I run the code for the gui, the scraper starts before the gui is shown.
Could someone explain why this is?
import tkinter as tk
from tkinter import ttk
from tkinter import filedialog, messagebox
from functools import partial
HEIGHT = 500
WIDTH = 600
import google1
#----Functions----------------------------------------------------------------
def fileDialog():
global filename
filename = filedialog.askopenfilename(initialdir = "/",title = "Select file",filetypes = (("excel workbook","*.xlsx"),("all files","*.*")))
label = ttk.Label(labelFrame, text = "")
label.grid(column = 1, row = 4)
label.configure(text = filename)
print(filename)
def start_program(filename):
if filename:
print("this is the filename", filename)
google1.start_program
else:
messagebox(title="No file detected", message="Please select file first")
#----Tkinter-setup------------------------------------------------------------
root = tk.Tk()
#initial placeholder for gui
canvas = tk.Canvas(root, height=HEIGHT, width=WIDTH)
canvas.pack()
#a frame within the canvas
frame = tk.Frame(root, bg='#80c1ff')
frame.place(relx=0.1, rely=0.1, relwidth=0.8, relheight=0.8)
labelFrame = tk.LabelFrame(frame, text = "Select File")
labelFrame.grid(column = 0, row = 1, padx = 20, pady = 20)
labelFrame_start = tk.LabelFrame(frame, text = "Start Program")
labelFrame_start.grid(column = 0, row = 3, padx = 20, pady = 20)
button = tk.Button(labelFrame, text = "Browse Files", command = fileDialog)
button.grid(column = 1, row = 1)
button = tk.Button(labelFrame_start, text = "Click to start program", command = lambda: start_program(filename))
button.grid(column = 1, row = 1)
root.mainloop()
edit: this (the scraper starting before seeing the gui) also happens when I comment out the google1.start_program, but still have the import. When I also comment out the import, that is when i do get the gui first.
Can you please help me with follwing issue I face:
When I am creating radiobutton with tkinter, I don't have a problem to select from the list.
However, if I put the same script under a menu, then selected option is always the default one, ("Python",1) in this specific case. Do you have any idea how to overcome this? Thanks in advance!
import tkinter as tk
root_m = tk.Tk()
root_m.geometry("400x200")
frame_m = tk.Frame(root_m)
root_m.title("NUMERIC UNIVERSE")
frame_m.pack()
def chars_merging():
languages = [
("Python",1),
("Perl",2),
("Java",3),
("C++",4),
("C",5)
]
root = tk.Tk()
root.geometry("400x200")
frame = tk.Frame(root)
root.title("SELECT SOMETHING")
frame.pack()
v = tk.IntVar()
v.set(0) # initializing the choice, i.e. Python
label = tk.Label(frame,
text="""Choose your favourite
programming language:""",
justify = tk.LEFT,
padx = 20)
label.pack()
def ShowChoice():
global data_sel
data_sel = v.get()
print(data_sel)
for val, language in enumerate(languages):
tk.Radiobutton(frame,
text=language,
indicatoron = 0,
width = 20,
padx = 20,
variable=data_sel,
command=ShowChoice,
value=val).pack(anchor=tk.W)
root.mainloop()
#return(languages[v.get()])
print("You selected", languages[v.get()])
button3 = tk.Button(frame_m,
text="3.Prepare and merge chars",
command=chars_merging,
width=25)
button3.pack()
# CLOSING THE WINDOW ---------------------------------------------------------
def finish():
root_m.destroy()
button_n = tk.Button(frame_m,
text="Finish",
command=finish,
width=25)
button_n.pack()
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
root_m.mainloop()
from tkinter import *
import tkinter.messagebox
def message():
text='''sfjkasjdfkjasdfjsdjfjsdlfjasd
fjsdkfjksadjfsajdjfl
sdfasdjflsjdlfsldjflsjd'''
tkinter.messagebox.showinfo("showing",text)
def _price_inputs():
win2 = Tk()
win2.title("Transactions for the project Botique")
win2.geometry("1600x800+0+0")
win2.configure(bg="black")
framex = Frame(win2,width=1600,bg="RoyalBlue4",height=100,relief=GROOVE).pack(side=TOP)
frame1 = Frame(win2,width=1000, height=400,bg="white", relief=SUNKEN).pack(side=RIGHT,fill=Y)
frame2 = Frame(win2, width=775,height=100,bg="white", relief=FLAT).pack(side=BOTTOM)
frame3 = Frame(win2,width=600,height=430,bg="gray",relief=FLAT).pack(side=LEFT,fill=X)
#framex == heading
#frame1 == showing the infos
#frame2 == bottom_infos
#frme3 == adding the buttons and widgets
#==++++===========================title=============================
lbl1 = Label(framex,font=("arial", 30, "bold"),bg="powder blue",fg="green",text="Hello this is the title of the page",bd=10,relief=GROOVE).pack(side=TOP)
btn1 = Button(frame1,font=("arial",20,"bold"),bg="powder blue",fg="white",text="click me").pack()
win2.mainloop()
I am trying to create the gui with tkinter.I am using python3.6
I made frames using tkinter and now when i try to add buttons , Labels etc it doesen't show the buttons or Labels in the output screen.
And how to i use pack for frames and grid for widgets in that frame using the pack.
You haven't call function in which you have defined properties. Just call function by adding _price_inputs() to your code at last:
from tkinter import *
import tkinter.messagebox
def message():
text='''sfjkasjdfkjasdfjsdjfjsdlfjasd
fjsdkfjksadjfsajdjfl
sdfasdjflsjdlfsldjflsjd'''
tkinter.messagebox.showinfo("showing",text)
def _price_inputs():
win2 = Tk()
win2.title("Transactions for the project Botique")
win2.geometry("1600x800+0+0")
win2.configure(bg="black")
framex = Frame(win2,width=1600,bg="RoyalBlue4",height=100,relief=GROOVE).pack(side=TOP)
frame1 = Frame(win2,width=1000, height=400,bg="white", relief=SUNKEN).pack(side=RIGHT,fill=Y)
frame2 = Frame(win2, width=775,height=100,bg="white", relief=FLAT).pack(side=BOTTOM)
frame3 = Frame(win2,width=600,height=430,bg="gray",relief=FLAT).pack(side=LEFT,fill=X)
#framex == heading
#frame1 == showing the infos
#frame2 == bottom_infos
#frme3 == adding the buttons and widgets
#==++++===========================title=============================
lbl1 = Label(framex,font=("arial", 30, "bold"),bg="powder blue",fg="green",text="Hello this is the title of the page",bd=10,relief=GROOVE).pack(side=TOP)
btn1 = Button(frame1,font=("arial",20,"bold"),bg="powder blue",fg="white",text="click me").pack()
win2.mainloop()
_price_inputs()
You can't see new items, lbl1 and btn1 as they're:
Children to win2, not any frames
Blocked by another frame, frame3
1
lbl1 and btn1 are children to win2, because passing None as the first positional argument or by default, the widget's parent is assigned as the Tk instance.
lbl1 and btn1 are instantiated with parent arguments as None, because:
framex = Frame(win2,width=1600,bg="RoyalBlue4",height=100,relief=GROOVE).pack(side=TOP)
...
frame1 = Frame(win2,width=600,height=430,bg="red",relief=FLAT).pack(side=LEFT,fill=X)
lines are identical to that of:
Frame(win2,width=1600,bg="RoyalBlue4",height=100,relief=GROOVE).pack(side=TOP)
framex = None
...
Frame(win2,width=600,height=430,bg="red",relief=FLAT).pack(side=LEFT,fill=X)
frame1 = None
Because both framex and frame3 are the return of the method pack which is always None.
One could fix this by separating the geometry manager line with the widget instantiation line:
framex = Frame(win2,width=1600,bg="RoyalBlue4",height=100,relief=GROOVE)
framex.pack(side=TOP)
...
frame1 = Frame(win2,width=600,height=430,bg="red",relief=FLAT)
frame1.pack(side=LEFT,fill=X)
2
Comment out frame3 line to see that lbl1 and btn1 actually exists:
#frame3 = Frame(win2,width=600,height=430,bg="red",relief=FLAT).pack(side=LEFT,fill=X)
from tkinter import *
import tkinter.messagebox
"""def message():
text='''sfjkasjdfkjasdfjsdjfjsdlfjasd
fjsdkfjksadjfsajdjfl
sdfasdjflsjdlfsldjflsjd'''
tkinter.messagebox.showinfo("showing",text)"""
def _price_inputs():
win2 = Tk()
win2.title("Transactions for the project Botique")
win2.geometry("1600x800+0+0")
win2.configure(bg="white")
framex = Frame(win2,width=1600,bg="RoyalBlue4",height=100,relief=GROOVE).pack(side=TOP)
#frame1 = Frame(win2,width=1000, height=400,bg="white", relief=SUNKEN).pack(side=RIGHT,fill=Y)
frame2 = Frame(win2, width=775,height=100,bg="black", relief=FLAT).pack(side=BOTTOM)
frame3 = Frame(win2,width=800,height=450,bg="gray",relief=FLAT).pack(side=LEFT,fill=X)
#framex == heading
#frame1 == showing the infos
#frame2 == bottom_infos
#frme3 == adding the buttons and widgets
#==++++===========================title=============================
lbl1 = Label(framex,font=("arial", 30, "bold"),bg="black",fg="green",text="Hello this is the title of the page",bd=10,relief=GROOVE).pack(side=TOP)
btn1 = Button(frame3,font=("arial",15,"bold"),bd=8,bg="black",fg="white",text="before 60 hrs",relief=GROOVE).pack(side=BOTTOM)
btn2 = Button(frame3,font=("arial",15,"bold"),bd=8,bg="black",fg="white",text="full_stock",relief=GROOVE).pack(side=BOTTOM)
btn3 = Button(frame3,font=("arial",15,"bold"),bd=8,bg="black",fg="white",text="delivery_report",relief=GROOVE).pack(side=BOTTOM)
before = IntVar()
stock_full = IntVar()
delivery_report = IntVar()
btn4 = Button(win2,font=("arial",15,"bold"),bd=8,bg="black",fg="white",text="hello",relief=GROOVE).pack(side=BOTTOM)
'''import Tkinter as tk
import ImageTk
FILENAME = 'image.png'
root = tk.Tk()
canvas = tk.Canvas(root, width=250, height=250)
canvas.pack()
tk_img = ImageTk.PhotoImage(file = FILENAME)
canvas.create_image(125, 125, image=tk_img)
quit_button = tk.Button(root, text = "Quit", command = root.quit, anchor = 'w',
width = 10, activebackground = "#33B5E5")
quit_button_window = canvas.create_window(10, 10, anchor='nw', window=quit_button)
root.mainloop()
'''
win2.mainloop()
Why doesn't my style change the background of any of these objects? I got annoyed and just assigned them to everything. Also why does it make two windows? I see that it's something to do with style being different then the style in the object's options... I feel like it's also with my class, am I suppose to def _init_(self) it? the class?
import tkinter as tk
import tkinter.ttk as ttk
style = ttk.Style()
style.configure("color1.TFrame", foreground = "black", background = "red")
class main:
parent = tk.Tk()
n = ttk.Notebook(parent,style = "color1.TFrame")
f1 = ttk.Frame(n,style = "color1.TFrame") # first page tab
f2 = ttk.Frame(n,style = "color1.TFrame") # second page 2nd tab
window = f1
frame1 = ttk.Frame(window,style = "color1.TFrame")
frame1.grid(row = 1, column = 1, padx = 200, pady = 150)
frame2 = ttk.Frame(window)
frame2.grid(row = 2, column = 1,padx = 200, pady = 150)
main()
The reason why nothing seems to appear and your styles don't work is because you're not actually drawing all of your widgets.
You never tell the below widgets to actually draw on your window:
n
f1
f2
Additionally, a second window loads when you're calling ttk.Style() you haven't yet created a root window. This is explained much better than I could explain it here.
By changing your program to the below you can see that the styles do actually work:
import tkinter as tk
import tkinter.ttk as ttk
class main:
parent = tk.Tk()
style = ttk.Style()
style.configure("color1.TFrame", foreground = "black", background = "red")
n = ttk.Notebook(parent,style = "color1.TFrame")
n.pack()
f1 = ttk.Frame(n,style = "color1.TFrame") # first page tab
f2 = ttk.Frame(n,style = "color1.TFrame") # second page 2nd tab
window = f1
f1.pack()
f2.pack()
frame1 = ttk.Frame(window,style = "color1.TFrame")
frame1.grid(row = 1, column = 1, padx = 200, pady = 150)
frame2 = ttk.Frame(window)
frame2.grid(row = 2, column = 1,padx = 200, pady = 150)
main()
Arguably a better way of doing this would be something like the below:
import tkinter as tk
import tkinter.ttk as ttk
root = tk.Tk()
style = ttk.Style()
style.configure("color1.TFrame", foreground = "black", background = "red")
class main:
def __init__(self, root):
n = ttk.Notebook(root, style = "color1.TFrame")
f1 = ttk.Frame(n, style = "color1.TFrame")
f2 = ttk.Frame(n, style = "color1.TFrame")
n.pack()
f1.pack()
f2.pack()
frame1 = ttk.Frame(f1, style = "color1.TFrame")
frame2 = ttk.Frame(f1, style = "color1.TFrame")
frame1.grid(row = 1, column = 1, padx = 200, pady = 150)
frame2.grid(row = 2, column = 1,padx = 200, pady = 150)
main(root)
root.mainloop()
Although this is subjective and accomplishes the same goal.
I have a string 'currentMessage' and a Label to display it.
I have a Toplevel widget, which contains a Text widget to provide new value for 'currentMessage':
from tkinter import *
from tkinter import ttk
root = Tk()
mainFrame = ttk.Frame(root)
mainFrame.grid()
currentMessage = 'current Message'
ttk.Label(mainFrame, text = currentMessage).grid(padx = 10, pady = 10)
def updateCurrentMessage(popupWindow):
currentMessage = popupWindow.textBox.get(0.0, END)
def changeValues():
popup = Toplevel(mainFrame)
popup.grid()
textBox = Text(popup, width = 20, height = 5)
textBox.grid(column = 0, row = 0)
textBox.insert(END, 'new message here')
b = ttk.Button(popup, command = lambda: updateCurrentMessage(popup))
b.grid(column = 0, row = 1, padx = 5, pady = 5)
b['text'] = 'Update'
theButton = ttk.Button(mainFrame, command = changeValues, text = 'Click')
theButton.grid(padx = 10, pady = 10)
mainFrame.mainloop()
I tried to get the content of 'textBox' Text widget of the Toplevel by using this function:
def updateCurrentMessage(popupWindow):
currentMessage = popupWindow.textBox.get(0.0, END)
But I got an error
'Toplevel' object has no attribute 'textBox'
So how do I access content of the widget 'textBox', which is a child widget of 'popup' (this Toplevel widget is only created when function changeValues() is called)?
I think probably this is what you are looking for -- although I'm just guessing, because you are asking for a solution for a specific problem you think you have, however if I were you I would rethink what exactly do I want to do:
from tkinter import *
from tkinter import ttk
# Create Tk Interface root
root = Tk()
# Initialize mainFrame
mainFrame = ttk.Frame( root )
mainFrame.grid()
# Initialize label of mainframe
theLabel = ttk.Label( mainFrame, text='Current Message' )
theLabel.grid( padx=10, pady=10 )
def createPopup():
# Initialize popup window
popup = Toplevel( mainFrame )
popup.grid()
# Initialize text box of popup window
textBox = Text( popup, width=20, height=5 )
textBox.grid( column = 0, row = 0 )
textBox.insert( END, 'New Message Here' )
# Initialize button of popup window
button = ttk.Button( master = popup,
command = lambda: theLabel.config(text=textBox.get(0.0, END)),
text = 'Update')
button.grid( column=0, row=1, padx=5, pady=5 )
# Initialize button of main frame
theButton = ttk.Button( mainFrame, command=createPopup, text='Click' )
theButton.grid( padx=10, pady=10 )
# Enter event loop
mainFrame.mainloop()
There is a way indeed, like this:
def updateCurrentMessage(popupWindow):
currentMessage = popupWindow.nametowidget('textBox').get(0.0, END)
def changeValues():
popup = Toplevel(mainFrame)
popup.grid()
textBox = Text(popup, width = 20, height = 5, name = 'textBox')
textBox.grid(column = 0, row = 0)
textBox.insert(END, 'new message here')
b = ttk.Button(popup, command = lambda: updateCurrentMessage(popup))
b.grid(column = 0, row = 1, padx = 5, pady = 5)
b['text'] = 'Update'
You can choose whatever you want for the 'name'.