tkiner output isnt on the same pop-up window - python

Okay so what I'm trying to figure out is how to control the location of output.
Currently when you run the code a window comes up and allows you to type into a label "manual". with the option to press enter or click the 'submit' button. The typed entry is then put in a new pop-up window every time I.e. Input1(test) and input2(testing) will show up in separate windows. How do I set it so it shows up in the same pop-up window preferably spaced on the y axis so it isn't cluttered. As this is a manual entry there is no telling how many entries will be submitted and it may be possible once so many entries have been entered it will need to move over on the X axis and start again at the top of the Y axis.
I'd also like to know how to pick where the pop-up ends up on the screen I tried using
win.place(x=200, y=50) but the .Toplevel() doesn't have an attribute of .place()
import tkinter as tk
#function that prints the entry
def entry_function(e=None):
name = entry.get()
win = tk.Toplevel()
tk.Label(win, text=name).pack()
win.geometry('100x100')
#Setup for the window
window = tk.Tk()
window.title("Title_Name")
window.geometry("500x500")
window.bind('<Return>', entry_function)
#widgets
label = tk.Label(window, text = "Manual:", bg = "dark grey", fg = "white")
entry = tk.Entry()
button = tk.Button(text = "submit",
command = entry_function)
#widget placement
label.place(x=0,y=20)
entry.place(x=52,y=21)
button.place(x=177, y=18)
window.mainloop()

For displaying the entry on same popup, you can use the below code for entry function
import tkinter as tk
flag = False
win=""
def setflag(event):
global flag
flag = False
#function that prints the entry
def entry_function(e=None):
global flag,win
name = entry.get()
if not flag:
win = tk.Toplevel()
win.geometry('100x100')
win.bind('<Destroy>', setflag)
tk.Label(win, text=name).pack()
flag = True
win.geometry("+%d+%d" % (x + 200, y + 50))
else:
tk.Label(win, text=name).pack()
#Setup for the window
window = tk.Tk()
window.title("Title_Name")
window.geometry("500x500")
window.bind('<Return>', entry_function)
x = window.winfo_x()
y = window.winfo_y()
sh = window.winfo_screenheight()
sw = window.winfo_screenwidth()
x_cord = int((sw/2)-550)
y_cord = int((sh/2)-300)
wh = 550
ww = 1100
window.geometry("{}x{}+{}+{}".format(ww, wh, x_cord, y_cord))
#widgets
label = tk.Label(window, text = "Manual:", bg = "dark grey", fg = "white")
entry = tk.Entry(window)
button = tk.Button(window,text = "submit",
command = entry_function)
#widget placement
label.place(x=0,y=20)
entry.place(x=52,y=21)
button.place(x=177, y=18)
window.mainloop()

You need to create the popup once and add label to it inside entry_function().
You can make the popup hidden initially and show it inside entry_function() and you can specify the position of the popup using geometry().
def entry_function(e=None):
MAX_ROWS = 20 # adjust this value to suit your case
name = entry.get().strip()
if name:
n = len(popup.winfo_children())
tk.Label(popup, text=name).grid(row=n%MAX_ROWS, column=n//MAX_ROWS, sticky='nsew', ipadx=2, ipady=2)
popup.deiconify() # show the popup
window.focus_force() # give focus back to main window
...
# create the popup
popup = tk.Toplevel()
popup.withdraw() # hidden initially
popup.geometry('+100+100') # place the popup to where ever you want
popup.title("Log Window")
popup.protocol('WM_DELETE_WINDOW', popup.withdraw) # hide popup instead of destroying it
...

Related

how would i have one entry box display individual entries into different places?

I am essentially trying to have my entry box display the entered text on the screen as a label, expect after each time the button is pressed (the button that displays the text), the newly entered data is displayed somewhere else on the screen. Essentially multiple labels from one entry box and button.
def writelabel():
labelentrval = Label(master, font = ("Helvetica", 15), text="" + str(entryvalue.get()))
labelentrval.place(x=645,y=621)
entryvalue.delete(first=0,last=22)
()
entryvalue = Entry(master)
entryvalue.place(x=700, y=515)
buttonpressy = Button(master,text="Enter", command=writelabel)
buttonpressy.place(x=845,y=510)
Code is above, and so far when I enter something into my entry box and press the button it displays it on the screen as a label. But how would I keep displaying my entries over and over in different places?
Thank you
You want to create a new label for every button press:
from tkinter import *
root = Tk()
def clicked():
text = e.get()
newLabel = Label(root, text=text)
newLabel.pack()
e = Entry(root)
e.pack()
b = Button(root, text='click', command=clicked)
b.pack()
root.mainloop()

How do I delete a Tkinter label using a button command?

I want my program to run in a way that once the user presses the Info button, a label called GameInfoLabel is displayed due to a command from the Info button. Within the same condition (if the Info button is pressed), I want to add a Back button that deletes/destroys the GameInfoLabel.
I have attempted to implement this in the code below, but I'm getting the message
NameError: name 'GameInfoLabel' is not defined.
from tkinter import *
root = Tk()
root.title("Game Menu")
root.geometry("1920x1080")
root.resizable(True, True)
def QuitGameInfo():
GameInfoLabel.destroy()
BackInfoButton['state'] = NORMAL
def GameInfo():
RulesNotepad = open("GameInfo.txt",'r')
Rules = RulesNotepad.read()
GameInfoLabel = Label(root, text = Rules, fg = "blue", bg = "red", height = "14", width = "140").pack()
BackInfoButton = Button(root, text = "Back", command = QuitGameInfo).pack()
RulesNotepad.close()
button3 = Button(root, text = "Info", command = GameInfo, width = "20", height = "3").pack()
root.mainloop()
The error is due to that GameInfoLabel is a local variable inside GameInfo() and it is not accessible inside QuitGameInfo().
You can fix this error by either declaring GameInfoLabel as global or pass it to QuitGameInfo() via argument. Same apply on BackInfoButton as well.
However you need to fix another issue: both GameInfoLabel and BackInfoButton are None because they are result of pack().
Below is the modified code using global solution:
from tkinter import *
root = Tk()
root.title("Game Menu")
root.geometry("1920x1080")
root.resizable(True, True)
def QuitGameInfo():
GameInfoLabel.destroy()
#BackInfoButton['state'] = NORMAL # why ??? Should it be destroyed as well?
BackInfoButton.destroy()
def GameInfo():
global GameInfoLabel, BackInfoButton
with open("GameInfo.txt",'r') as RulesNotepad:
Rules = RulesNotepad.read()
GameInfoLabel = Label(root, text = Rules, fg = "blue", bg = "red", height = "14", width = "140")
GameInfoLabel.pack()
BackInfoButton = Button(root, text = "Back", command = QuitGameInfo)
BackInfoButton.pack()
Button(root, text = "Info", command = GameInfo, width = "20", height = "3").pack()
root.mainloop()
However I would suggest to use a frame to hold the GameInfoLabel and BackInfoButton and the frame is hidden initially. When Info button is clicked, show the frame. When Back button is clicked, hide the frame.
from tkinter import *
root = Tk()
root.title("Game Menu")
root.geometry("1920x1080")
root.resizable(True, True)
def GameInfo():
with open("GameInfo.txt",'r') as RulesNotepad:
Rules = RulesNotepad.read()
GameInfoLabel.config(text=Rules)
info_frame.pack() # show the game info frame
Button(root, text="Info", command=GameInfo, width="20", height="3").pack()
# create the game info frame but don't show it initially
info_frame = Frame(root)
GameInfoLabel = Label(info_frame, fg="blue", bg="red", height="14", width="140")
GameInfoLabel.pack()
Button(info_frame, text="Back", command=info_frame.pack_forget).pack()
root.mainloop()
As mentioned in acw1668's comment GameInfoLabel is local to the GameInfo() method. This means once this method has finished running anything declared in it ceases to exist.
The usual solution to this is passing/returning variables to functions to get results for instance your game info could return the label, however since you want to call these functions automatically when an event occurs, e.g. your button is pressed, this is not so easy.
I believe the easiest solution to your problem would be to declare the GameInfoLabel variable globally (in the global scope), this is not always the best coding practice but I'm not certain of tkinter's ability to pass variables parameters to an event handler and this can be complicated.
Also as mentioned by acw1668 you call .pack() immediately on the new label which is returned from the initialization Label(...). Pack then does not return the label so we do that separately.
This should work, give it a careful read.
from tkinter import *
root = Tk()
root.title("Game Menu")
root.geometry("1920x1080")
root.resizable(True, True)
# Declare any global UI Components
GameInfoLabel = None # Dont set a Label yet
def QuitGameInfo():
GameInfoLabel.destroy()
BackInfoButton['state'] = NORMAL
def GameInfo():
RulesNotepad = open("GameInfo.txt",'r')
Rules = RulesNotepad.read()
GameInfoLabel = Label(root, text = Rules, fg = "blue", bg = "red", height = "14", width = "140")
GameInfoLabel.pack()
BackInfoButton = Button(root, text = "Back", command = QuitGameInfo).pack()
RulesNotepad.close()
button3 = Button(root, text = "Info", command = GameInfo, width = "20", height = "3")
button3.pack()
root.mainloop()

Tkinter Cancel button that stops the whole script

So, basically I am playing with Tkinter and automatization of web page in Python and the thing that I want to add is the window pop up that allows me to select one of two options (today vs tomorrow in my case).
This is the code:
root = tk.Tk()
def center_window(w=300, h=200):
# get screen width and height
ws = root.winfo_screenwidth()
hs = root.winfo_screenheight()
# calculate position x, y
x = (ws/2) - (w/2)
y = (hs/2) - (h/2)
root.geometry('%dx%d+%d+%d' % (w, h, x, y))
root.geometry("400x450")
Label = tk.Label(root, text = "Select Day", font = ("Helvetica", 15))
Label.pack(pady=50, padx=40)
helv15 = tkFont.Font(family = "Helvetica", size = 15)
root.lift()
v = tk.StringVar()
v.set("Today")
tk.Label(root, textvariable = v).pack()
def close_window():
root.destroy()
today = tk.Radiobutton(root, text = "Today", variable = v, value = "Today", font = helv15).pack()
tomorrow = tk.Radiobutton(root, text = "Tomorrow", variable = v, value = "Tomorrow", font = helv15).pack()
submit = tk.Button(root, text = "Submit", command = close_window, font = helv15).pack()
center_window(400, 400)
root.mainloop()
###THERE IS A CODE AFTER THIS POINT
The button that I want to add is "Cancel" button that stops the execution of the whole code and not just the loop of the Tkinter. Thanks!
This should do the trick, just call exit
cancel = tk.Button(root, text = "Cancel", command = exit, font = helv15)
cancel.pack()
The pack method doesn't return anything, so you'll need to split the lines like this if you want to store the widgets

Message is not printed Tkinter

When the user didn't chose any option, the code going into else, in if_button_ispressed function, and then I want to print an error message on the screen. I think I did all correct but the message is not shown on the screen.
import sys
from Tkinter import *
import Image, ImageTk
import ShareScreen
import Menu_WatchAnothersScreen
def if_button_is_pressed():
global user_selection, mGui
if(user_selection.get() == 1): # if the user want to share his screen
mGui.destroy()
ShareScreen.run()
#menu()
if(user_selection.get() == 2): # if the user want to watch another`s screen
mGui.destroy()
Menu_WatchAnothersScreen.run()
#menu()
else: # if the user didn`t chose any option <--------------- HERE IS MY PROBLEM
error_message = "Please select one of the options" #<--------------- HERE IS MY PROBLEM
error_label = Label(mGui, textvariable=error_message).pack(anchor=CENTER) # prints error message <--------------- HERE IS MY PROBLEM
def close(): # close the window
exit()
def menu():
global user_selection,mGui
mGui = Tk()
user_selection = IntVar()
menubar = Menu(mGui) # menu
filemenu = Menu(menubar, tearoff=0) # menu works
filemenu.add_command(label="Close", command=close)
menubar.add_cascade(label="File", menu=filemenu)
mGui.geometry('450x300+500+300')
mGui.title('Nir`s ScreenShare') # top of window
canvas = Canvas(mGui, width=500, height=150)
canvas.pack(pady = 10)
pilImage = Image.open("logo5.png")
image = ImageTk.PhotoImage(pilImage)# puts ScreenirShare`s logo on the menu
imagesprite = canvas.create_image(0, 0, image=image, anchor="nw")
Radiobutton(mGui, text="Share My Screen ", variable=user_selection, value=1).pack(anchor=CENTER) # 1 - FIRST OPTION - Share My Screen
Radiobutton(mGui, text="Watch Another`s Screen", variable=user_selection, value=2).pack(anchor=CENTER, pady = 7.5)# 2- SECOND OPTION - Watch Another`s Screen
start_button = Button(mGui, text='Start', command=if_button_is_pressed).pack() # Start Button
mGui.config(menu=menubar) # menu helper
mGui.mainloop()
menu()
If you are going to use plain string, you should use text option of label not textvariable.
Label(mGui, text=error_message)
If you want to use textvariable, you need StringVar, IntVar etc.
Also, packing on same line returns None, so you should pack after you create it if you want to use it again later.
error_label = Label(mGui, textvariable=error_message)
error_label.pack(anchor=CENTER)

How to put button widget on label widget and decide its position in Tkinter

How can I put the button widget on top of the background image?
from Tkinter import *
import tkMessageBox
root = Tk()
# load image
logo = PhotoImage(file="C:\\Users\\admin\\Desktop\\project\\front page.gif")
w = logo.width()
h = logo.height()
root.geometry('%dx%d+0+0' % (w,h))
def helloCallBack():
tkMessageBox.showinfo("Hello Python", "Hello World")
#create widgets
B = Button(root,text = "ASSOCIATIONS", command = helloCallBack,width = 20,padx = 20)
B.pack()
B1 = Button(root,text = "HELP", command = helloCallBack,width = 20,padx = 20)
B1.place(relx=1, x=-50, y=2, anchor=NE)
B1.pack()
w1 = Label(root, compound = CENTER, image = logo).pack(side="right")
root.mainloop()
The easiest thing to do is to put a background image in a widget using place, then put other widgets in that widget the way you normally do with either pack or grid
background=Label(root, image=logo).place(x=0,y=0,relwidth=1, relheight=1)
b = Button(root, ...).pack(...)
Make sure you create the background first so that it has a lower stacking order.
If you really want to put a button in a label, just make the label the parent of the button and use pack or grid the way you normally do -- it's perfectly legal to pack something inside a Button or Label or any other widget (though, the end result might not be what you expect).

Categories

Resources