Am trying to Learn Tkinter. The following program works fine. It creates a textbox and a scrolllbar connected to the textbox. There is also a button, which when pressed inserts a line into the text box. Now what I want to do is to move the scrollbar such that when the text goes beyond the first screen, the scrollbar automatically scrolls down so that the user sees only the last line of the input. What I want to do is for the text box to behave like an extended stats window, so that the user is able to see the progress so far. Right now the user will continuously have to scroll down by using the scrollbar to the last line. I want this process to be automatic. Is there a command which I can use to do that?
Thanks!
from Tkinter import *
root = Tk()
def checkFn():
text.insert(END, ' --> The check button has been pressed ... \n')
# ............... Frame 1 .................................
frame1 = Frame(root)
frame1.pack(side=TOP, fill=X)
b = Button(frame1, text='Check', command=checkFn)
b.pack(side=LEFT, padx=5)
# .............. Text Frame .................................
frame10 = Frame(root)
frame10.pack(side=TOP, fill=X)
scrlBar = Scrollbar(frame10)
scrlBar.pack(side=RIGHT, fill=Y)
text = Text(frame10, yscrollcommand=scrlBar.set)
text.insert(INSERT, 'abcd\n')
text.pack(side=LEFT, fill=BOTH)
scrlBar.config(command=text.yview)
root.mainloop()
The easiest method I would say is see(index)
In your checkFn() method, use text.see(END)
Related
I am a newbie trying to use tkinter to build a GUI for an application. So far, I have a frame that I'd like to put several buttons into. However, every time I attempt to position this button, it isn't placed properly, being put outside of the frame itself. I wouldn't like to use the place function because of the several buttons I have to dynamically generate coming from an excel sheet so I was hoping to use the grid function instead.
Here is what I have so far
from tkinter import *
from customtkinter import *
window = Tk()
window.geometry("1920x1080")
window.state("zoomed")
window.title("My Company's Description Printer")
main_frame = CTkFrame(window, width=1920, height=1080, fg_color="grey21")
main_frame.place(x=0, y=0)
title = Label(main_frame,
text="My Company",
bg="grey21",
fg="white",
font=("Trajan Pro", 20)).place(x=626, y=30)
button_frame = CTkCanvas(main_frame,
width=800,
height=600,
highlightthickness=3,
highlightbackground="black",
relief="ridge",
bg="grey19").place(x=60, y=110)
test_button = CTkButton(button_frame, text="test").grid(row=0, column=0)
window.mainloop()
Example of code being ran
As you can see, the button is being placed in the top left corner of the entire window rather than the top left corner of the black bordered button frame. Any help would be appreciated. Thank you so much.
Note that button_frame is None because it is the result of .place(...), so the button (test_button is None as well due to same reason) is a child of the root window instead of the instance of CTkCanvas. .place(...) should be called in separate line.
Also .create_window() is used instead of tkinter layout manager to put widget into a canvas:
...
button_frame = CTkCanvas(main_frame,
width=800,
height=600,
highlightthickness=3,
highlightbackground="black",
relief="ridge",
bg="grey19")
# call .place(...) in separate line
button_frame.place(x=60, y=110)
test_button = CTkButton(button_frame, text="test") # don't use .grid(row=0, column=0)
# use .create_window() to put widget into canvas
button_frame.create_window(0, 0, window=test_button, anchor="nw")
I'm trying to create a GUI using Tkinter for a Pip-boy from Fallout 3. I'm running into a problem where after I click a button in one of the frames, the spacing between the buttons gets messed up. This spacing change happens for all but one of the buttons in the frame (the Lockpick one).
This is what I want the button spacing to look like (what it looks like before I click a button):
This is what happens after I click a button (in this case the Barter one)
Here is the code I am using:
from tkinter import *
# to read descriptions of each skill from a text file
with open("skills.txt") as f:
lines = f.readlines()
# function that updates the label with a different description when the corresponding button is clicked
def show_skill_desc(index):
desc['text'] = lines[index-1]
# makes the window and frame
root = Tk()
root.geometry("1024x600")
root.title("Skills")
frame = Frame(root)
frame.grid()
# creates the label
Label(root, text="Stats").grid(row=0, column=0)
# list of skills which will each have their separate labels
skills_list = ["Barter", "Big Guns", "Energy Weapons", "Explosives", "Lockpick", "Medicine",
"Melee Weapons", "Repair", "Science", "Small Guns", "Sneak", "Speech", "Unarmed"]
# placing the label in the frame
desc = Label(root, text="", padx=30, wraplength=600, justify=LEFT)
desc.grid(row=2, column=1)
# creates a button for each skill
button_list = []
for i in range(12):
button_list.append(Button(root, text=skills_list[i], width=40,
height=2, command=lambda c=i: show_skill_desc(button_list[c].grid_info()['row']), padx=0, pady=0))
button_list[i].grid(row=i+1, column=0)
root.mainloop()
The purpose of the GUI is to display the description of each skill, when the button for a skill is clicked.
Does anyone know why the spacing change happens? Thank you!
I want to limit the area where the popup menu can be triggered
My current code allows the popup menu be triggered anywhere in the tkinter window when the user right clicks
from tkinter import *
root = Tk()
w = Label(root, text="Right-click to display menu", width=40, height=20)
w.pack()
popup = Menu(root, tearoff=0)
popup.add_command(label="Next") # , command=next) etc...
popup.add_command(label="Previous")
popup.add_separator()
popup.add_command(label="Home")
def do_popup(event):
try:
popup.tk_popup(event.x_root, event.y_root, 0)
finally:
popup.grab_release()
w.bind("<Button-3>", do_popup)
b = Button(root, text="Quit", command=root.destroy)
b.pack()
mainloop()
I want the popup menu to be triggered when the user right clicks over the label "Right-click to display menu" only
Your code is working exactly as designed. You've created a really huge label widget (40 characters wide, 20 characters high, or roughly 350x325 pixels depending on your system font and resolution settings). So while you think you're clicking outside the label, you're not since it takes up the whole window.
To see what I mean, give your label a distinctive background color. For example:
w = Label(root, text="Right-click to display menu", width=40, height=20, background="pink")
The above results in a window that looks like the following image. Anywhere you click that is pink is part of the label, and thus will show the menu.
I am making a simple GUI that starts with a main menu them the user can click a button to proceed to a new window which has a picture of a keyboard and the user can press key on their keyboard to play the paino. Right now I cant figure out how to make a button that when pressed closes the main menu (labeled mainMenu()) and open the game menu (playGame).
import tkinter
from tkinter import *
class mainMenu:
def _init_(self, master):
frame = Frame(master)
frame.pack()
self.quitButton = Button(frame, text = "Quit", command = frame.quit)
self.quitButton.pack(side = LEFT)
self.proceedButton = Button(frame, text = "Play", command = playGame)
self.proceedButton.pack(side = LEFT)
def playGame(self):
frame.quit
gameMenu()
def gameMenu(self):
root = Tk()
b = mainMenu(root)
topFrame = Frame(root)
topFrame.pack()
bottomFrame = Frame(root)
bottomeFrame.pack(side = BOTTOM)
photo = PhotoImage(file = "piano.png")
label = Label(root, image = photo)
label.pack()
root.mainloop()
You'll have to forgive me for removing your class but I've never personally worked with classes in python before. However I seem to have you code working to some degree.
import tkinter
from tkinter import *
def playGame():
frame.quit
gameMenu()
def gameMenu():
b = mainMenu(root)
topFrame = Frame(root)
topFrame.pack()
bottomFrame = Frame(root)
bottomFrame.pack(side = BOTTOM)
photo = PhotoImage(file = "piano.png")
label = Label(root, image = photo)
label.pack()
root=Tk()
frame = Frame(root)
frame.pack()
quitButton = Button(frame, text = "Quit", command = frame.quit)
quitButton.pack(side = LEFT)
proceedButton = Button(frame, text = "Play", command = playGame)
proceedButton.pack(side = LEFT)
root.mainloop()
The main problem you had was that you were using both root and master. When declaring the main window in tkinter you normally use either root = Tk() or master = Tk() either one is acceptable, personally I use master. This variable contains the main window that everything else is placed into. You also hadn't put Tk() into any variable, meaning that when you hit root.mainloop() there was nothing to enter the main loop, this was because you were trying to declare root = Tk() inside gameMenu, which wasn't getting called in your program.
If you want to open windows within tkinter it's probably easier to write something like this:
from tkinter import *
master = Tk() #Declaring of main window
def ProceedButtonCommand(mainframe, master): #Command to attach to proceed button
mainframe.destroy()
DrawSecondScreen(master) #This line is what lets the command tied to the button call up the second screen
def QuitButtonCommand(master):
master.destroy()
def DrawFirstScreen(master):
mainframe = Frame(master) #This is a way to semi-cheat when drawing new screens, destroying a frame below master frame clears everything from the screen without having to redraw the window, giving the illusion of one seamless transition
ProceedButton = Button(mainframe, text="Proceed", command=lambda: ProceedButtonCommand(mainframe, master)) #Lambda just allows you to pass variables with the command
QuitButton = Button(mainframe, text = "Quit", command=lambda: QuitButtonCommand(master))
mainframe.pack()
ProceedButton.pack()
QuitButton.pack()
def DrawSecondScreen(master):
mainframe = Frame(master)
Label1 = Label(mainframe, text="Temp")
mainframe.pack()
Label1.pack()
DrawFirstScreen(master)
master.mainloop() #The mainloop handles all the events that occur in a tkinter window, from button pressing to the commands that a button runs, very important
This little script just draws a screen with two buttons, one draws a new screen with the text "temp" on it and the other button closes the master window.
In the future it's probably a better idea to ask a friend who is experienced in programming to help with this kind of stuff. Get talking on some computing forums, I'm sure you'll find a group of sharing and fixing code quickly.
I am trying to add an entry from a toplevel window into a listbox in the main window.
So far I have managed to create a button that opens a new window containing 4 entry widgets(name, address, phone number and DOB). Is there any way, after I press the OK button on the pop up window, that all four entries are added to the listbox on the main window?
Thanks.
Unless I'm missing something in your problem description, the OK button command just needs to copy the values from the Entry fields to the Listbox. Was there more to it than that?
from tkinter import Tk, Frame, Label, Entry, Button, Listbox
def ok_button():
li.delete(0, "end")
for i in range(len(fields)):
li.insert("end", e[i].get())
root = Tk()
root.title("Listbox")
cf = Frame(root)
cf.pack()
fields = ("Name", "Address", "Phone", "DOB")
e = []
for f in fields:
i = len(e)
Label(cf, text=f).grid(column=2, row=i, sticky="e")
e.append(Entry(cf, width=16))
e[i].grid(column=4, row=i)
Button(cf, text="OK", command=ok_button).grid(column=2, row=10, columnspan=3)
li = Listbox(cf)
li.grid(column=2, row=8, columnspan=3)
root.mainloop()