I am trying to hide the labels made with Canvas when I go to click on the entrybox
not when I write but simply on the click
How can I proceed?
Thanks in advance
import tkinter as tk
def handle_click():
mainCanvas.itemconfig(1, state='hidden')
window = tk.Tk()
window.geometry("500x300")
window.title("window")
mainCanvas = tk.Canvas(window, width = 500, height = 300)
mainCanvas.pack(fill = "both", expand = True)
text_input_name = tk.Entry(window, width = 25)
text_input_name_canvas = mainCanvas.create_window(250, 100, window = text_input_name)
text_input_name.bind("<1>", handle_click)
mainCanvas.create_text(250, 200, text="text", font=("Helvetica", 18), fill="red")
if __name__ == "__main__":
window.mainloop()
You already have the solution. Instead of passing 1 you need to pass the tag/id of the text. If you want to delete it, use canvas.delete(tag_or_id)
Here is an example.
import tkinter as tk
def handle_click(event):
mainCanvas.itemconfig(text, state='hidden')
#mainCanvas.delete(text)
window = tk.Tk()
window.geometry("500x300")
window.title("window")
mainCanvas = tk.Canvas(window, width = 500, height = 300)
mainCanvas.pack(fill = "both", expand = True)
text_input_name = tk.Entry(window, width = 25)
text_input_name_canvas = mainCanvas.create_window(250, 100, window = text_input_name)
text_input_name.bind("<1>", handle_click)
text = mainCanvas.create_text(250, 200, text="text", font=("Helvetica", 18), fill="red")
if __name__ == "__main__":
window.mainloop()
Related
I want to create a scrollable frame and add some widgets but I have a problem, when I use entry.place() it doesn't show any entry but if I use pack() it works perfectly, any solution?
from tkinter import *
from tkinter import ttk
root = Tk()
root.title("Entry Widgets")
mainframe = Frame(root)
mainframe.pack(fill = "both", expand = True)
canvas = Canvas(mainframe)
canvas.pack(side = "left", fill = "both", expand = True)
scrollbar = Scrollbar(mainframe, orient = "vertical", command = canvas.yview)
scrollbar.pack(side = "right", fill = "y")
canvas.configure(yscrollcommand = scrollbar.set)
frame = Frame(canvas)
frame.pack(fill = "both", expand = True)
y=0
for i in range(50):
entry = Entry(frame)
entry.place(x=0,y=y)
y = entry.winfo_y() + entry.winfo_height() + 5
canvas.create_window((0, 0), window = frame, anchor = 'nw')
frame.update_idletasks()
canvas.configure(scrollregion = canvas.bbox("all"))
root.mainloop()
Edited:
I want to create a scrollable frame and add some widgets but I have a
problem, when I use entry.place() it doesn't show any entry.
You cannot used pack() and place() when doing looping for Entry widget.
Just use grid() for second frame.
In case, you want to use ttk module.
Code:
from tkinter import *
from tkinter import ttk
root = Tk()
root.title("Entry Widgets")
mainframe = ttk.Frame(root)
mainframe.pack(fill = "both", expand = True)
canvas = Canvas(mainframe)
canvas.pack(side = "left", fill = "both", expand = True)
scrollbar = ttk.Scrollbar(canvas, orient = "vertical", command = canvas.yview)
scrollbar.pack(side = "right", fill = "y")
canvas.configure(yscrollcommand = scrollbar.set)
frame = ttk.Frame(root)
frame.pack(fill = "both", expand = True)
for i in range(50):
entry = Entry(frame, width=50)
entry.grid(column=0,row=i+10)
canvas.create_window((0, 0), window = frame, anchor = 'nw')
frame.update_idletasks()
canvas.configure(scrollregion = canvas.bbox("all"))
root.mainloop()
Screenshot:
I have a function that asks the user to answer a couple of question which prints out a result I have written my code inside a function called Script and I made it so when I press a button the function runs but in my terminal while I want it to run inside the frame I created
Here is my code:
from tkinter import *
def Script():
#My script/code is written here
root = tk.Tk()
root.configure(background = "#110a60")
canvas = tk.Canvas(root, height = 750, width = 800, bg = "#110a60")
canvas.pack()
root.resizable(False, False)
frame = tk.Frame(root, bg = "black")
frame.place(relheight = 0.8, relwidth = 0.8, relx = 0.1, rely = 0.1)
start_button = Button(root, text = 'Start Program', padx = 10, pady = 5, fg = "#FFFF00", bg = "#012456", command = Script)
start_button.place(x = 350, y = 680)
exit_button = Button(root, text = 'Exit', padx = 20, pady = 5, fg = "#FFFF00", bg = "#012456", command = exit)
exit_button.place(x = 368, y = 714.5 )
root.mainloop()
So how can I make it when I press the Start program button the text and input outputting to the terminal/console be printed inside the frame I made(inside the red borders)
And Thanks in advance
Simple answer: You can't. print() is for the console.
More elaborate answer:
You'll probably need a Label() widget for your questions and a Entry() widget for user input. Also your script() function should not print but return a string which you can then display in a Text() widget.
Edit (added some code to your code to get you going):
from tkinter import Tk, Canvas, Frame, Button, Label, Entry, StringVar, Text
def my_script():
questions=["What is your name?",
"What is your age?"]
answers = []
answer_box.config(background='grey')
answer_box.focus()
for question in questions:
question_label.config(text=question)
answer_box.wait_variable(answer_given)
answers.append(answer_box.get())
answer_box.delete(0, 'end')
answer_box.focus()
for answer in answers:
print_area.insert('end', answer+"\n")
root = Tk()
root.configure(background = "#110a60")
canvas = Canvas(root, height = 750, width = 800, bg = "#110a60")
canvas.pack()
root.resizable(False, False)
frame = Frame(root, bg = "black")
frame.place(relheight = 0.8, relwidth = 0.8, relx = 0.1, rely = 0.1)
start_button = Button(root, text = 'Start Program', padx = 10, pady = 5, fg = "#FFFF00", bg = "#012456", command = my_script)
start_button.place(x = 350, y = 680)
exit_button = Button(root, text = 'Exit', padx = 20, pady = 5, fg = "#FFFF00", bg = "#012456", command = exit)
exit_button.place(x = 368, y = 714.5 )
question_label = Label(frame, text="", bg='black', fg='white')
question_label.place(relx=0.5, y=80, anchor='center')
answer_given = StringVar()
answer_box = Entry(frame, bg='black', borderwidth=0)
answer_box.place(relx=0.5, y=110, anchor='center')
answer_box.bind('<Return>', lambda x: answer_given.set("foobar"))
print_area = Text(frame, bg='black', fg='white')
print_area.place(relx=0.5, y=180, height=300, width=500, anchor='n')
root.mainloop()
I have several larger tkinter / python program which I would like to incorporate into one program which would clear a frame when another program is called; each program currently being inside a function (I probably should use classes eventually when I understand them) and each of these function being displayed on a form being cleared of widgets from the previous if any do exist.
The code below is just a small trial for me to understand how to do this, but it's not working.
When I invoke the widget.destroy() function, it removes the frame (DisplayFrame) and does not clear the widgets inside it and hence not displaying the new widgets.
here is the current trial code:
#!/usr/bin/env python3
import tkinter as tk
from tkinter import *
from tkinter import ttk
#import pandas as pd
import MultiTempsP3
import datetime, time
from tkinter import messagebox
import sqlite3
from tkinter import colorchooser
from configparser import ConfigParser
import os
import csv
if os.environ.get('DISPLAY','') == "":
print('no display found.Using :0.0')
os.environ.__setitem__('DISPLAY',':0.0')
root = tk.Tk()
root.title("Kombucha Program")
root.geometry("1400x800")
root.minsize(width=900, height=600)
#root.maxsize(width=1400, height = 900)
root.grid_rowconfigure(3, weight=1)
root.grid_columnconfigure(2, weight=1)
root.configure( bg = '#000080' )
DisplayFrame = tk.Frame(root, width=1200, height = 630, bg = 'yellow') #0059b3')
DisplayFrame.grid(column=0,row=1, sticky = N, in_ = root)
rightFrame = tk.Frame(root, width = 120, height = 390, bg = 'white') # #000080
rightFrame.grid(column = 1, row = 0, pady = 10, padx = 10)
lblFrame = tk.Frame(root, height = 70, width = 670, bg = 'black')
lblFrame.grid(column = 0, row = 0, sticky =N, in_ = root)
##'W' stands for West = WrightFrmae (west fframe on the right of screen
#WrightFrame = tk.Frame(rightFrame, width = 70, height = 300, bg = 'green') # #000080
#WrightFrame.grid(column = 0, row = 1)
WidgetFrame = tk.Frame(root, height = 300, width = 120, bg = 'red') # #000080
WidgetFrame.grid(column=0,row=2, pady = 30)
fromTemp = MultiTempsP3.temps("65cd6bd")
lblTemp = Label(rightFrame, text=fromTemp).grid(row=1,column=0,pady=0 )
#lblTemp.pack()
def clearDisplayFrame():
for widgets in DisplayFrame.winfo_children():
widgets.destroy()
###***### - This section is in the right top little frame = rightFrame
state = "yes" ## delete this row and use below state=GPIO when on an RPi
#state = GPIO.input(17)
if state:
state_17="GPIO_17 (HeatPad) is On "
else:
state_17="GPIO_17 (HeatPad) is Off "
lblHeatPad = Label(rightFrame, text=state).grid(row=3,column=0,pady=0 ) #shows as text in the window
#lblHeatPad.pack() #organizes widgets in blocks before placing them in the parent.
###***### End of rightFrame widgets
def func_quit():
root.destroy()
def openData():
clearDisplayFrame()
print("I am inside openData()")
lbltrial=tk.Label(DisplayFrame,text="trial").grid(row=3, column=2)
def func_Temps():
clearDisplayFrame()
print("I am inside func_Temps()")
#DisplayFrame = tk.Frame(root, width=1200, height = 630, bg = 'yellow') #0059b3')
#DisplayFrame.grid(column=0,row=1, sticky = N, in_ = root)
lblSomething = tk.Label(DisplayFrame, text = "Open Temps").grid(row=2,column=2)
###***### This section is top of left = lblFrame
exitButton = tk.Button(lblFrame, text="Quit the Program", width = 12, command=root.destroy, bg= "magenta")
exitButton.grid(row = 0, column = 0, columnspan = 1, pady = 5, padx = 5)
dataButton = Button(lblFrame, text="Open Dates Window", command=openData).grid(row=0, column=1) ## the open refers to the above function
tempsButton= Button(lblFrame, text="Open Temps Info", command=func_Temps).grid(row=0, column=2)
###***### End of top left widget in lblFrame
mainloop()
As an answer, here is an approach that uses 2 frame and switches between them in the click of the switch. This is the way usually switching between frame is implemented in procedural programming, AFAIK:
from tkinter import *
root = Tk()
def change(frame):
frame.tkraise() # Raising the passed frame
window1 = Frame(root)
window2 = Frame(root)
window1.grid(row=0,column=0) # Grid in the same location so one will cover/hide the other
window2.grid(row=0,column=0)
# Contents inside your frame...
Label(window1,text='This is page 1',font=(0,21)).pack()
Label(window2,text='This is page 2',font=(0,21)).pack()
# Buttons to switch between frame by passing the frame as an argument
Button(root,text='Page 1',command=lambda: change(window1)).grid(row=1,column=0,stick='w')
Button(root,text='Page 2',command=lambda: change(window2)).grid(row=1,column=0,stick='e')
root.mainloop()
So instead of destroying all the items inside your frame, you should just raise the other frame, as destroyed widgets cannot be brought back.
I'm trying to create two frames and to put 2 labels into te second one. This is my code:
import tkinter as tk
root = tk.Tk()
root.geometry("500x500")
f1 = tk.Frame(root, bg = "red", width = 400, height = 250)
f2 = tk.Frame(root, bg = "blue", width = 400, height = 150)
f1.pack()
f2.pack()
text1 = tk.Label(f2, text = "lala")
text1.pack(side='left')
text2 = tk.Label(f2, text = "lalala")
text2.pack(side= "right")
root.mainloop()
Why do neither the backgroundcolour of f2 nor the side settings work?
When I run the code, it looks like this:
I want it to look like this:
Thank you.
Here is the example with f2.pack_propagate(0) added, plus the addition of anchor keywords to more closely match the example output above (thanks acw1668)
import tkinter as tk
root = tk.Tk()
root.geometry("500x500")
f1 = tk.Frame(root, bg = "red", width = 400, height = 250)
f2 = tk.Frame(root, bg = "blue", width = 400, height = 150)
f1.pack()
f2.pack()
f2.pack_propagate(0)
text1 = tk.Label(f2, bg='blue', text = "lala")
text1.pack(side='left', anchor='n')
text2 = tk.Label(f2, bg='blue', text = "lalala")
text2.pack(side= "right", anchor='n')
root.mainloop()
I have made "sticky notes" in python but how do I make the same open in another window when I press the new File (+ on the title bar) button? I thought of creating an object within the class but I don't think that's possible. Should I import and run similar file? Please suggest a method to do so. Suggestions to improve the code are welcomed.
Here's the code
from tkinter import *
import tkinter.scrolledtext as tkst
from tkinter import messagebox
from tkinter import font
class StickyNotes:
xclick = 0
yclick = 0
def __init__(self,master):
def get_pos(event):
self.xclick = event.x
self.yclick = event.y
def move_window(event):
master.geometry('+{0}+{1}'.format(event.x_root-self.xclick, event.y_root-self.yclick))
def another_window(event):
pass
def quit_window(event):
self.closebutton.config(relief = 'flat', bd = 0)
if(messagebox.askyesno('Delete Note?','Are you sure you want to delete this note?')):
master.destroy()
return
self.closebutton.config(relief = 'flat', bd = 0, bg = '#F8F7B6')
# master (root) window
master.overrideredirect(True)
master.geometry('250x250')
master.config(bg = '#838383')
master.resizable(True,True)
# titlebar
self.titlebar = Frame(root, bg = '#F8F796', relief = 'flat', bd = 2)
self.titlebar.bind('<Button-1>', get_pos)
self.titlebar.bind('<B1-Motion>', move_window)
self.titlebar.pack(fill = X, expand = 1, side = TOP)
self.closebutton = Label(self.titlebar, text = 'X', bg = '#F8F7B6', relief = 'flat')
self.closebutton.bind('<Button-1>', quit_window)
self.closebutton.pack(side = RIGHT)
self.newbutton = Label(self.titlebar, text = '+', bg = '#F8F7B6', relief = 'flat')
self.newbutton.pack(side = LEFT)
self.newbutton.bind('<Button-1>', another_window)
# main text area
self.mainarea = tkst.ScrolledText(master, bg = '#FDFDCA', font=('Comic Sans MS', 14, 'italic'), relief = 'flat', padx = 5, pady = 10)
self.mainarea.pack(fill = BOTH, expand = 1)
# frames to introduce shadows
self.shadow = Frame(root).pack(side=BOTTOM)
self.shadow = Frame(root).pack(side=RIGHT)
root = Tk()
root.attributes('-topmost', 'true')
sticky = StickyNotes(root)
root.mainloop()
You are using classes all wrong. One of the biggest advantages to using classes is the ability to steal code from Tkinter (or whatever GUI or framework you are trying to use). The Tkinter window class is called Toplevel, so you want to subclass that and use the class itself (named "self") for all your operations. I rewrote it for you:
from tkinter import *
import tkinter.scrolledtext as tkst
from tkinter import messagebox
from tkinter import font
class StickyNotes(Toplevel):
def __init__(self, master, **kwargs):
super().__init__(master, **kwargs)
self.xclick = 0
self.yclick = 0
# master (root) window
self.overrideredirect(True)
self.geometry('250x250+500+500')
self.config(bg = '#838383')
self.attributes('-topmost', 'true')
self.resizable(True,True)
# titlebar
self.titlebar = Frame(self, bg = '#F8F796', relief = 'flat', bd = 2)
self.titlebar.bind('<Button-1>', self.get_pos)
self.titlebar.bind('<B1-Motion>', self.move_window)
self.titlebar.pack(fill = X, expand = 1, side = TOP)
self.closebutton = Label(self.titlebar, text = 'X', bg = '#F8F7B6', relief = 'flat')
self.closebutton.bind('<Button-1>', self.quit_window)
self.closebutton.pack(side = RIGHT)
self.newbutton = Label(self.titlebar, text = '+', bg = '#F8F7B6', relief = 'flat')
self.newbutton.pack(side = LEFT)
self.newbutton.bind('<Button-1>', self.another_window)
# main text area
self.mainarea = tkst.ScrolledText(self, bg = '#FDFDCA', font=('Comic Sans MS', 14, 'italic'), relief = 'flat', padx = 5, pady = 10)
self.mainarea.pack(fill = BOTH, expand = 1)
# frames to introduce shadows
self.shadow = Frame(self).pack(side=BOTTOM)
self.shadow = Frame(self).pack(side=RIGHT)
def get_pos(self, event):
self.xclick = event.x
self.yclick = event.y
def move_window(self, event):
self.geometry('+{0}+{1}'.format(event.x_root-self.xclick, event.y_root-self.yclick))
def another_window(self, event):
sticky = StickyNotes(root)
def quit_window(self, event):
self.closebutton.config(relief = 'flat', bd = 0)
if(messagebox.askyesno('Delete Note?','Are you sure you want to delete this note?')):
self.destroy()
return
self.closebutton.config(relief = 'flat', bd = 0, bg = '#F8F7B6')
root = Tk()
root.withdraw()
sticky = StickyNotes(root) # make the first note.
root.mainloop()