I am trying to create a pop up help window for a tool. I managed to add the scrollbar to a frame that contains canvas and label widget. However that Scrollbar does not shows the img_canvas_3 that I added.
Here is my code:
from tkinter import *
import tkinter.filedialog
from tkinter.filedialog import askopenfilename
from tkinter.filedialog import askdirectory
import PIL
from PIL import Image, ImageTk
help_window = tkinter.Tk()
help_window.title("Help")
help_window.geometry("400x800")
#frame.grid(row=0,column=0)
canvas=Canvas(help_window,bg='red',width=300,height=800,scrollregion=(0,0,500,500))
scroll_y = Scrollbar(help_window, orient="vertical", command = canvas.yview)
frame=Frame(canvas,width=300,height=800, bg="green")
description_label = Label(frame, text = "\n\tMy Tool\n",anchor = "w").pack(side = TOP, fill = "both")
introduction = "This tool provides a basic workflow"
introduction_text = Label(frame, text = introduction, anchor = "w", font = "Verdana 10", bg="yellow").pack(fill = "both")
label_1 = Label(frame, text = "Input Data 1", anchor = "w", font = "Verdana 10", justify=CENTER).pack(fill = "both")
img_canvas_1 = Canvas(frame, bg = "black", height = 300, width = 300)
img_canvas_1.pack(side = TOP)
label_2 = Label(frame, text = "Input Data 2", anchor = "w", font = "Verdana 10", justify = CENTER).pack(fill = "both")
img_canvas_2 = Canvas(frame, bg = "black", height = 300, width = 300)
img_canvas_2.pack(side = TOP)
label_3 = Label(frame, text = "Input Data 3", anchor = "w", font = "Verdana 10", justify = CENTER).pack(fill = "both")
img_canvas_3 = Canvas(frame, bg = "black", height = 300, width = 300)
img_canvas_3.pack(side = TOP)
canvas.create_window(0, 0, anchor = 'nw', window = frame)
canvas.update_idletasks
canvas.configure(scrollregion=canvas.bbox('all'),
yscrollcommand = scroll_y.set)
canvas.pack(fill = 'both', expand = TRUE, side = 'left')
scroll_y.pack(fill = 'y', side = 'right')
help_window.mainloop()
I expected to have the scroll bar working, basically showing all the widgets and elements in the frame as I am adding more and more. That is only true for the untill img_canvas_2
Does anyone have an idea why this is not the case with my code? I tried by playing around with the scrollregion parameter in the canvas variable, but it did not work.
Thanks in advance.
Related
I'm trying to incorporate a 'back button' in my Tkinter app in my 'second_home' to allow the user to return to the previous page - from second_home to home. I've incorporated a hide_frames() function to allow all the frames to disappear when called. I have this done on the second_home but I've commented out the function on the home function - the app won't run with the function called. I also have the home function called when launching the app.
When clicking on the back button titled "Previous Page" I receive the error 'TclError: bad window path name ".!labelframe.!canvas'
from tkinter import *
from tkinter import ttk
from tkinter.font import BOLD
win = Tk()
# Creating Frames
wrapper1 = LabelFrame(win, width = 900, height = 950)
wrapper2 = LabelFrame(win, width = 900, height = 950)
wrapper3 = LabelFrame(win, width = 900, height = 950)
wrapper4 = LabelFrame(win, width = 900, height = 950)
mycanvas = Canvas(wrapper1)
mycanvas.pack(side = LEFT, fill = "both", expand ="yes")
# Creating a Hide Frame Function
def hide_frames():
# Destroying the widgets in each frame
for widget in wrapper1.winfo_children():
widget.destroy()
for widget in wrapper2.winfo_children():
widget.destroy()
for widget in wrapper3.winfo_children():
widget.destroy()
for widget in wrapper4.winfo_children():
widget.destroy()
# Hiding all frames
wrapper1.pack_forget()
wrapper2.pack_forget()
wrapper3.pack_forget()
wrapper4.pack_forget()
def home():
#hide_menu_frames()
global myframe
myframe = Frame(mycanvas)
mycanvas.create_window((0,0), window = myframe, anchor = "nw")
wrapper1.pack(fill = "both", expand = "yes", padx = 10, pady = 10)
myframe.pack(fill = "both", expand = 1)
start_label = Label(myframe, text = "Choose Length of Loan Model", font = ("Helvetica", 19)).pack(pady = 100)
# Creating buttons
home_button1 = Button(myframe, text = "12 Month Model", bg='#ffffff', activeforeground='#4444ff', font = ("Helvetica", 16, BOLD), command = second_home).pack(pady = 10)
def second_home():
hide_frames()
mycanvas = Canvas(wrapper2)
mycanvas.pack(side = LEFT, fill = "both", expand ="yes")
yscrollbar = ttk.Scrollbar(wrapper2, orient = VERTICAL, command = mycanvas.yview)
yscrollbar.pack(side = RIGHT, fill = "y")
mycanvas.configure(yscrollcommand = yscrollbar.set)
mycanvas.bind('<Configure>',lambda e: mycanvas.configure(scrollregion = mycanvas.bbox('all')))
wrapper2.pack(fill = "both", expand = "yes", padx = 10, pady = 10)
myframe = Frame(mycanvas)
mycanvas.create_window((0,0), window = myframe, anchor = "nw")
second_label = Label(myframe, text = "Please Input Loan Parameters", font = ("Helvetica", 18), pady = 10, padx = 325).pack()
# Creating a Back Button
back_button = Button(myframe, text = "Previous Page", command = home)
back_button.pack(pady = 10)
# Defining a Main Menu
my_menu = Menu(win)
win.config(menu = my_menu)
# Creating Menu Items
app_menu = Menu(my_menu)
my_menu.add_cascade(label = "Options", menu = app_menu)
app_menu.add_command(label = "Home", command = home)
app_menu.add_separator()
app_menu.add_command(label = "Exit", command = win.quit)
win.geometry("900x950")
#win.resizable(False, False)
win.title("Loan Cash Flow Model Creator")
home()
win.mainloop()
I am a newb and I have a small script that uses guizero to create a small app that reads a rfid tag and activates door lock. The problem I am having is, when the power goes off and the raspberry pi reboots. the script launches but I have to manually click in the texts box before it will start working. how can I have it automatically set focus on the textbox when it launches?
thanks
Mark
Here is code, I found this project online and modified some to work for me.
from gpiozero import LED, Buzzer
from guizero import App, Box, Text, TextBox, warn
import gpiozero
import csv
RELAY_PIN = 17
led8 = LED(5)
led9 = LED(6)
relay= gpiozero.OutputDevice(RELAY_PIN,active_high=False, initial_value=False)
def clearDisplay():
print("Clear display")
rfidStatus.value = "—"
rfidText.value = ""
led8.off()
led9.off()
relay.off()
rfidStatus.repeat(1000, checkRFidTag)
def checkRFidTag():
tagId = rfidText.value
if tagId != "":
RFidRegistered = False
print(tagId)
with open("Database.csv") as csvfile:
reader = csv.DictReader(csvfile)
for row in reader:
if row["RFid"] == tagId:
RFidRegistered = True
print("Welcome " + row["User"])
rfidStatus.value = "Welcome " + row["User"]
led8.on()
relay.toggle()
rfidStatus.after(5000, clearDisplay)
if RFidRegistered == False:
print("RFid tag is not registered")
rfidStatus.value = "RFid tag is not registered"
led9.on()
rfidStatus.after(3000, clearDisplay)
rfidStatus.cancel(checkRFidTag)
app = App(title="RFID EM4100 Simple GUI", width=350, height=150, layout="auto")
instructionText = Text(app, text="Click on the text button below\nand scan your RFid tag.")
rfidText = TextBox(app,text="")
rfidStatus = Text(app, text="—")
rfidStatus.repeat(1000, checkRFidTag)
#designBy = Text(app, text="Design by Idris – Cytron Technologies", align="bottom")
app.display()
view
You could use a timer associated with the app to call a fuction shortly after starting up. For example, use:
app.after(1000,setFocus)
to call:
def setFocus():
nameOfTextBox.focus()
The example below sets up two text boxes and two buttons. By commenting out one or other of the lines in setFocus it sets focus to the right hand text box or the cancel button after one second:
from guizero import App, Text, Box, TextBox, PushButton
import sys
app = App(title="Give Focus")
app.width = 500
app.height = 100
paddingHeight = 1
paddingWidth = 10
buttonWidth = 10
topBoxHeight = 100
bottomBoxHeight = 100
app.height = topBoxHeight + bottomBoxHeight
def setFocus():
rightTextBox.focus()
# buttonCancel.focus()
def call_exit():
buttonCancel.text="Exiting"
buttonCancel.enabled=False
app.update()
app.destroy()
sys.exit()
topBox = Box(app, align="top", width= "fill", height = topBoxHeight, border= True)
textFieldBox = Box(topBox, align="top", width= "fill", height= "fill", border= True, layout = "grid")
paddingT00 = Text(textFieldBox, text="", width = paddingWidth, height = paddingHeight, grid = [0,0])
paddingT10 = Text(textFieldBox, text="", width = paddingWidth, height = paddingHeight, grid = [1,0])
message = Text(textFieldBox, text="Text Field Box", grid = [2,0])
paddingT01 = Text(textFieldBox, text="", width = paddingWidth, height = paddingHeight, grid = [0,1])
leftTextBox = TextBox(textFieldBox, text="Type here", width = paddingWidth, height = 1, grid = [1,1])
paddingT21 = Text(textFieldBox, text="", width = paddingWidth, height = paddingHeight, grid = [2,1])
rightTextBox = TextBox(textFieldBox, text="...or here", width = paddingWidth, height = 1, grid = [3,1])
bottomBox = Box(app, align="top", width= "fill", height = bottomBoxHeight, border= True)
buttonBox = Box(bottomBox, align="top", width= "fill", height= "fill", border= True, layout = "grid")
paddingB00 = Text(buttonBox, text="", width = paddingWidth, height = paddingHeight, grid = [0,0])
paddingB10 = Text(buttonBox, text="", width = paddingWidth, height = paddingHeight, grid = [1,0])
message = Text(buttonBox, text="Button Box", grid = [2,0])
paddingB01 = Text(buttonBox, text="", width = paddingWidth, height = paddingHeight, grid = [0,1])
buttonOK = PushButton(buttonBox, text="OK", width = paddingWidth, height = 1, grid = [1,1])
paddingB21 = Text(buttonBox, text="", width = paddingWidth, height = paddingHeight, grid = [2,1])
buttonCancel = PushButton(buttonBox, text="Cancel", command = call_exit, width = paddingWidth, height = 1, grid = [3,1])
app.after(1000,setFocus)
app.display()
I'm trying to put a scrollbar on entry that created on canvas..
I've tried this code
from tkinter import *
root = Tk()
root.geometry('400x600')
root.resizable(0,0)
page = Canvas(root, width=400, height=600, bd=0, highlightthickness=0,scrollregion=(0,0,500,500))
MyImage1 = PhotoImage(file='Study With4.png')
CanvasImage = page.create_image(0,0,image= MyImage1, anchor='nw')
entry =Text(page,height=29,width =46,wrap=WORD,bg='#F8F8F8')
scroll = Scrollbar(entry, orient=VERTICAL)
scroll.pack(side=RIGHT, fill=Y)
scroll.config(command=page.yview)
page.config(yscrollcommand=scroll.set)
page.create_window(200,285, window=entry)
page.pack()
mainloop()
but it doesn't work and I don't know where is the problem.
I've made minimal changes to your code, the biggest is creating a Frame called "label"
to contain Text and Scrollbar then inserting that into Canvas window.
Your scroll object was not defined properly with confusion around page and entry objects.
from tkinter import *
root = Tk()
root.geometry('500x600')
root.resizable(0,0)
page = Canvas(
root, width = 500, height = 600, bd = 0,
highlightthickness = 0,scrollregion = (0,0,1000,1000))
page.pack(side = LEFT, fill = BOTH, expand = True)
MyImage1 = PhotoImage(file='Study With4.png')
CanvasImage = page.create_image(0, 0, image = MyImage1, anchor = NW)
label = Frame(root)
label.pack(fill = BOTH, expand = True)
entry = Text(label, height = 29, width = 46, wrap = NONE, bg = '#F8F8F8')
entry.pack(side = LEFT, fill = BOTH, expand = True)
scroll = Scrollbar(label, orient = VERTICAL)
scroll.pack(side=RIGHT, fill=Y)
scroll.config(command = entry.yview)
entry.config(yscrollcommand = scroll.set)
page.pack()
page.create_window(25, 25, window = label, anchor = NW)
mainloop()
The problem:
I am trying to update the same text widget box from a function that contains some text. Instead a whole new text window appears every time.
Here is my code:
from tkinter import *
import os
#Tkinter graphics
homepage = Tk()
homepage.title("My first GUI")
# set size of window
homepage.geometry('1200x400')
# Add image file
bg = PhotoImage(file = "maxresdefault.png")
# Show image using label
label1 = Label( homepage, image = bg)
label1.place(x = 0, y = 0)
label2 = Label( homepage, text = "Test App")
label2.pack()
# Create Frame
frame1 = Frame(homepage)
frame1.pack()
#button initatiors
def buttonupdate():
S = Scrollbar(homepage)
T = Text(homepage, height=100, width=30)
T.pack()
T.pack(side=RIGHT, fill= Y)
S.pack(side = RIGHT, fill = Y)
S.config(command=T.yview)
T.insert(END, "test")
T.config(yscrollcommand=S.set, state=DISABLED)
# Static buttons
tickets30button = Button(text = "This is button 1", command=buttonupdate)
tickets30button.place(x=0, y=26)
mcibutton = Button(text = "This is button 2")
mcibutton.place(x=0, y=52)
hdebutton = Button(text = "This is button 3")
hdebutton.place(x=0, y=78)
homepage.mainloop()
Here is the result if I click on the first button three times:
Let me know if you have any suggestions that I can try.
Thank you for your time,
I was able to update my text window instead of create a new one, upon each click of a button, thanks to #TheLizzard.
He mentioned to move the section of code that creates the text window outside of the function and keep the section of code that creates the text, inside the function.
Before:
#button initiators
def buttonupdate():
S = Scrollbar(homepage)
T = Text(homepage, height=100, width=30)
T.pack()
T.pack(side=RIGHT, fill= Y)
S.pack(side = RIGHT, fill = Y)
S.config(command=T.yview)
T.insert(END, "test")
T.config(yscrollcommand=S.set, state=DISABLED)
After: (UPDATED)
S = Scrollbar(homepage)
T = Text(homepage, height=100, width=30)
T.pack(side=RIGHT, fill= Y)
S.pack(side = RIGHT, fill = Y)
S.config(command=T.yview)
T.config(yscrollcommand=S.set, state=DISABLED)
#button initatiors
def myTicketstatusbutton():
T.delete(1.0,END)
T.insert(END, "test")
I am using Tkinter to display images in a Toplevel() but when I put it inside of a function it doesn't work(This is very beginner I know)
# -*- coding: utf-8 -*-
import Tkinter
from Tkinter import *
import tkMessageBox
from tkMessageBox import *
import Image, ImageTk
import PIL.Image, PIL.ImageTk
import os
import subprocess
root = Tk()
root.title("Test")
quin=Toplevel()
C = Tkinter.Canvas(quin, bg="white", height = 350, width = 350)
directory=os.path.dirname(os.path.abspath(__file__))
filename=os.path.join(directory, 'un.png')
img=PIL.Image.open(filename)
tkimg=PIL.ImageTk.PhotoImage(img)
image = C.create_image(175,175,image=tkimg)
C.grid(row=5,column=5)
def Head():
h1 = Label(root, text = "How to Secure a Computer", fg ="white", bg = "#00b8ff", width = 6,bd=2, height =2, font = "Arial", relief = RAISED)
h1.grid(row= 0, column = 0, ipadx=122, pady=3, padx=5,columnspan=3)
def Mainmenu():
menubar = Menu(root)
filemenu = Menu(menubar, tearoff=0)
filemenu.add_command(label="Exit", command=root.destroy)
menubar.add_cascade(label="Options", menu=filemenu)
helpmenu = Menu(menubar, tearoff=0)
helpmenu.add_radiobutton(label="Help")
helpmenu.add_radiobutton(label="User Manual Security Configuration Guide")
menubar.add_cascade(label="Help", menu=helpmenu)
root.config(menu=menubar)
def Mainbuttons():
B1=Button(root,text="Services",height=2, width=6,bd=2, font = "Arial", fg = "#FFFFFF", bg = "#156cff",command=Services)
B2=Button(root,text="Account Policies",height=2, width=6,bd=2, font = "Arial", fg = "#FFFFFF", bg = "#156cff")
B3=Button(root,text="Firewall Config",height=2, width=6,bd=2, font = "Arial", fg = "#FFFFFF", bg = "#156cff")
B4=Button(root,text="User Logon Time",height=2, width=6,bd=2, font = "Arial", fg = "#FFFFFF", bg = "#156cff")
B5=Button(root,text="Security Policies",height=2, width=6,bd=2, font = "Arial", fg = "#FFFFFF", bg = "#156cff")
B1.grid(row = 1, column = 0, ipadx=120,pady=2,padx=5)
B2.grid(row = 1, column = 1, ipadx=120,pady=2,padx=5)
B3.grid(row = 2, column = 1, ipadx=120,pady=2,padx=5)
B4.grid(row = 2, column = 0, ipadx=120,pady=2,padx=5)
B5.grid(row = 3, column = 0, ipadx=120,pady=2,padx=5)
def Services():
serv=Toplevel()
servcanv=Canvas(serv,height=250, width=250)
servtext=Text(serv,width=26)
servtext.insert(INSERT, "To start go to your start menu, in the search bar\ntype services.msc")
servtext.grid(row=0, column=0)
servcanv.grid(row=0, column=1)
s = Tkinter.Canvas(serv, bg="white", height = 350, width = 350)
directory=os.path.dirname(os.path.abspath(__file__))
filename=os.path.join(directory, 'un.png')
img=PIL.Image.open(filename)
tkimg=PIL.ImageTk.PhotoImage(img)
image=s.create_image(175,175,image=tkimg)
s.grid(row=5,column=5)
Mainmenu()
Mainbuttons()
Head()
root.mainloop()
As you can see the code used to display the image is used twice, once inside a function and once outside. When outside it works perfectly, but when inside it doesn't work, it says the variable image is assigned but never used.
It does not work inside function, since tkimg is garbage collected after function finishes. You need to bind your images into variables that wont be garbage collected. For example to global variables, or instance variables in a class, rather than local variables.
To make tkimg be able to write to the global tkimg use global tkimg in the function.