In the toolbar I press a button and a drop-down menu with buttons opens. The images are. gif for buttons. I want the button in the toolbar to open a drop-down menu with buttons (image - gif). How can I do this?
# Image Toolbar
img1 = PhotoImage(file = r\path\"img.gif")`
# Toolbar
toolbar = Frame(root, bd=1, relief=RAISED)
toolbar.pack(side=TOP, fill=X)
btn1 = Button(toolbar, relief=FLAT, compound= LEFT, text="",image=img1, command=submenu1)
btn1.pack(side=LEFT, padx=0, pady=0)
def submenu1():
# gif icon for submenu1:
imgvar1 = PhotoImage(file=r\path\.gif)
???
To make a button with a drop-down menu I suggest you use a Menubutton which was designed for that purpose — it's the part that stays on the screen all the time. After creating one you should create a Menu widget and configure the Menubutton to use it.
Once you have a Menu instance, you can populate it with different kinds of menu items, including ones made of images by using the Menu.insert_cascade() method. Also see this Menu item creation documentation which describes all the different kinds of menu items you can create and add to one.
Below is some sample code illustrating what I mean. For simplicity I used the same image twice — on the Menubutton and on one of the items on the drop-down menu that is displayed when it's clicked.
import tkinter as tk
from tkinter.constants import *
root = tk.Tk()
# Image Toolbar
img1 = tk.PhotoImage(file="8-ball.png")
# Toolbar
toolbar = tk.Frame(root, bd=1, relief=RAISED)
toolbar.pack(side=TOP, fill=X)
menubtn = tk.Menubutton(toolbar, relief=FLAT, compound=LEFT, text="", image=img1)
menubtn.pack(side=LEFT, padx=0, pady=0)
menu = tk.Menu(menubtn, tearoff=0)
menubtn.config(menu=menu)
menu.insert_command(0, label='Submit', command=lambda: print('Submit clicked'))
imgvar1 = tk.PhotoImage(file="8-ball.png")
menu.insert_cascade(1, image=imgvar1, command=lambda: print('Image pop out clicked'))
root.mainloop()
Related
I have been struggling with merging my code.
I am creating an arcade game on Python and have a main file where I have an image and clickable assets which link to a game I have imported.
Now I am working on creating constant features in the game, including a menu bar which displays reminders, can change the volume and brightness setting etcetura.
However, I don't know how to make this on my main project file.
Could you help me out?
I am using Python Pygame, Tkinter and Turtle.
It sounds like you need to think some more about what exactly you want. Your question is rather vague and tkinter has several options that can be presented in various ways to a user for making selections. Below is a quick example of some ideas you may want to explore.tkinter widgets
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
root.geometry("400x400")
root.resizable(False, False)
root.title("Sample")
menu = tk.Menu(root)
root.config(menu=menu)
file_menu = tk.Menu(menu, tearoff=0)
menu.add_cascade(label="File", menu=file_menu)
file_menu.add_command(label="Quit", command=quit)
file_menu.add_command(label="Something", command=quit)
file_menu.add_command(label="New Option", command=quit)
label = tk.Label(root, text="Choose an option below", font="times 14")#label
label.pack()
items = ["Hi", "Something", "Bye"]
combo_box = ttk.Combobox(root, font=20, state="normal")#combo box
combo_box['values'] = items
combo_box.pack()
lblabel = tk.Label(root, text="Choose an item from the list", font="times 14")#label
lblabel.pack()
items_var = tk.StringVar(value=items)
list_box = tk.Listbox(root, listvariable=items_var, selectmode=tk.BROWSE)#list box
list_box.pack()
rblabel = tk.Label(root, text="Choose an option below", font="times 14")#label
rblabel.pack()
choices = tk.StringVar(value=items)
radio_button = ttk.Radiobutton(root, text="some_option")#radio button
radio_button.pack()
root.mainloop()
I built a button image (first image), but I manually added the neighboring text as plain text. I would like to make sure that clicking on the button (image or text) the background color of the button becomes permanent (second image).
I don't like the effect of pressing the button, I just want the background color of the button. Can I modify the button I created by merging image + text into a single selection? Or do you have to create the button in another way? If so, can you show me how? I found some buttons on the web, but they're not how I want them: I don't like that it looks like a button (I don't want the rectangular outline, I don't want the effect of pressing). How can I do?
Code:
from tkinter import *
from tkinter import ttk
from tkinter import messagebox
import tkinter as tk
from tkinter import ttk
from PIL import ImageTk, Image
root = Tk()
root.title("xxxx")
root.geometry("1920x1080+0+0")
root.config(bg="#f0f0f0")
root.state("normal")
topbar=Frame(root, width=2200, height=43, background="#e10a0a")
topbar.place(x=0, y=0)
leftbar=Frame(root, width=250, height=1400, background="white")
leftbar.place(x=1, y=44)
button1= tk.PhotoImage(file="/image.png")
btn1 = tk.Button(root, image=button1, borderwidth=0, highlightthickness=0, bg="white", text="sdsdsd", foreground='green')
btn1.place(x=2, y=43)
text1 = Label(root, text="aaaaa", bg="white", foreground='black', font='Verdana 12')
text1.place(x=70, y=58)
button2= tk.PhotoImage(file="/image.png")
btn2 = tk.Button(root, image=button2, borderwidth=0, highlightthickness=0, bg="white", text="sdsdsd", foreground='green')
btn2.place(x=2, y=100)
text2 = Label(root, text="bbbbbb", bg="white", foreground='black', font='Verdana 12')
text2.place(x=70, y=120)
UPDATE 1
After using compound, I get this. I don't know if it's the best solution. I get closer, but I still don't have what I need. I would like to stretch the selection color to the end of the white rectangle, then I would like to permanently color the background of the button
UPDATE 2
By applying width = 224, I fix the button background color length problem, but the button is centered. Now there is space to his left, before it wasn't there. I would like it in the starting position on the left
You can combine image and text in a button by setting compound option.
Also suggest to use pack() instead of place() for laying out the frames and buttons for your case.
And I think the parent of those buttons should be leftbar instead of root.
Below is the modified code:
from tkinter import messagebox
import tkinter as tk
from tkinter import ttk
from PIL import ImageTk, Image
root = tk.Tk()
root.title("xxxx")
root.geometry("1920x1080+0+0")
root.config(bg="#f0f0f0")
root.state("normal")
topbar = tk.Frame(root, background="#e10a0a", height=43)
topbar.pack(fill='x') # use pack() instead of place()
leftbar = tk.Frame(root, width=250, background="white")
leftbar.pack(side='left', fill='y') # use pack() instead of place()
leftbar.pack_propagate(0) # disable size auto-adjustment
def clicked(btn):
for w in leftbar.winfo_children():
w['bg'] = 'white' if w is not btn else 'yellow'
button1 = tk.PhotoImage(file="/image.png")
btn1 = tk.Button(leftbar, image=button1, borderwidth=0, highlightthickness=0,
bg="white", text="aaaaa", foreground='green', compound='left', anchor='w')
btn1.pack(fill='x') # use pack() instead of place()
btn1['command'] = lambda: clicked(btn1)
button2 = tk.PhotoImage(file="/image.png")
btn2 = tk.Button(leftbar, image=button2, borderwidth=0, highlightthickness=0,
bg="white", text="bbbbb", foreground='green', compound='left', anchor='w')
btn2.pack(fill='x') # use pack() instead of place()
btn2['command'] = lambda: clicked(btn2)
root.mainloop()
The output:
I'm trying to center text in the frame using LabelFrame function. My code is below.
import tkinter as tk
window = tk.Tk()
for i in range(9):
for j in range(9):
frame = tk.LabelFrame(
master=window,
relief=tk.RAISED,
borderwidth=5,
width=50,
height=50,
text=i+j,
labelanchor = 'n'
)
frame.grid(row=i, column=j)
window.geometry("500x500")
window.mainloop()
Argument labelanchor that specify position gives only options on the edge of the frame. Is there any simple way to center text inside of the frame using LabelFrame?
Is there any simple way to center text inside of the frame using LabelFrame?
The text of the labelframe can only appear along the edges of the frame. If you wish for text to appear inside the frame, you must create a Label and add it to the frame.
Using a frame and a label
If you wish to put other widgets in the frame and don't want this text to interfere with the other widgets, this is a perfect opportunity to use place.
The following example adds the label "Hello, world" to appear in the center of the widget. A button is placed in the frame just to show that its placement is not affected by the label, or vise versa. The screenshots show what the frame looks like naturally and when the window is resized.
import tkinter as tk
root = tk.Tk()
lf = tk.Frame(root, bd=2, relief="groove")
lf_label = tk.Label(lf, text="Hello, world")
lf_label.place(relx=.5, rely=.5, anchor="c")
lf.pack(padx=20, pady=20, fill="both", expand=True)
b = tk.Button(lf, text="Click me")
b.pack(padx=10, pady=10)
root.mainloop()
Using only a label
You can add widgets inside any other widget. So, instead of a frame you could just use a label. By default, the text will be centered, and just like with the previous example it won't affect the layout of other widgets.
I haven't included screenshots because the results are identical to the previous example.
import tkinter as tk
root = tk.Tk()
lf = tk.Label(text="Hello, world", bd=2, relief="groove")
lf.pack(padx=20, pady=20, fill="both", expand=True)
b = tk.Button(lf, text="Click me")
b.grid(row=0, column=0)
root.mainloop()
I have created a menu bar on the parent window. And I have made a child window as userguide.py which is assigned to one of the button on the menu that is "USER GUIDE". When I click on the button the child window opens, but when again clicked it opens one more window and so continues if clicked on the menu button. How do I disable the menu button until the child window is closed. I am sharing the code below.
Below this is code of the menu in parent window
from tkinter import *
from tkinter import ttk
from userguide import userGuide
root = Tk()
root.title("GhostTube - by RuSher")
root.iconbitmap(r"C:\Users\ayush\Desktop\BOTRAW\main\ghost.ico")
root.maxsize(400, 685)
root.minsize(400, 685)
root.geometry("400x685")
style = ttk.Style()
style.theme_use("clam")
menubar = Menu(root)
menubar.add_command(label="USER GUIDE I", command=userGuide)
menubar.add_command(label="ABOUT I")
menubar.add_command(label="CONTACT", command=contactInfo)
root.config(menu=menubar)
root.mainloop()`
Menu bar image
Below given code is the child window code i.e. userguide.py
from tkinter import *
from tkinter import ttk
def userGuide():
master = Tk()
master.title("GhostTube - by RuSher")
master.iconbitmap(r"C:\Users\ayush\Desktop\BOTRAW\main\ghost.ico")
master.maxsize(400, 685)
master.minsize(400, 685)
master.geometry("400x685")
style = ttk.Style()
style.theme_use("clam")
userLabel = Label(master, text=" HOW TO USE ", bg="black", fg="white", font=("Elephant", 18))
userLabel.grid(pady=10)
guide1Frame = LabelFrame(master, text="STEP 1 :", padx=5, pady=10)
guide1Frame.grid(row=1, column=0, padx=5)
step1label = Label(guide1Frame, text="First step is to add accounts to the bot, for that click on \n“Load Accounts” then locate the “YT accounts.txt” file and select it.\nIt will load all the accounts in the file.")
step1label.grid()
guide2Frame = LabelFrame(master, text="STEP 2 :", padx=5, pady=10)
guide2Frame.grid(row=2, column=0, padx=5)
step2label = Label(guide2Frame, text="Add the video URL of which you want to boost. Type or copy paste \nyour video URL on (Type Here) space and click on “Add”. \nOr you can make a text file of your video URLs and load it \nby clicking on “Load Video URLs” and selecting the text file.")
step2label.grid()
guide3Frame = LabelFrame(master, text="STEP 3 :", padx=5, pady=10)
guide3Frame.grid(row=3, column=0, padx=5)
step3label = Label(guide3Frame, text="Now you need to select the action you want to have \non the video to be performed, that are: LIKE, DISLIKE, \nSUBSCRIBE, UNSUBSCRIBE or COMMENT. You can select multiple \nactions at a time. After completing this Click on “START” button.")
step3label.grid()
guide4Frame = LabelFrame(master, text="STEP 4 :", padx=5, pady=10)
guide4Frame.grid(row=4, column=0, padx=5)
step4label = Label(guide4Frame, text="For Comments, You can Type or copy paste comments on\n(Type Here) of your choice, one comment at a time then click\non “Add” button and then type next comment of your choice then\nclick on “Add” and repeat if you want more. Or you can make\na text file of comments of your choice (one comment per line)\nand load it by clicking on “Load Comments”and locate your\ncomments text file and select it. Then click on “START”.")
step4label.grid()
guide5Frame = LabelFrame(master, text="STEP 5 :", padx=5, pady=10)
guide5Frame.grid(row=5, column=0, padx=5)
step5label = Label(guide5Frame, text="When the bot runs first time it can take time because of it prepares\nthe system, after the process starts please do not intercept it.\nLet it complete all the actions. The process goes in steps; \nfirst, a CMD interface will open then a Firefox window will start and\nit will complete one action then the Firefox window will close and\nthe same steps will repeat according to the actions to be taken.")
step5label.grid()
quote = Frame(master, padx=5, pady=10)
quote.grid(row=6, columnspan=2)
enjoy = Label(quote, text="Experience The Best", font=("Elephant",16), bg="black", fg="white")
enjoy.grid(padx=5)
master.mainloop()
Please help me out, because I am a fresh starter in this topic.
Try something like this:
import tkinter as tk
def create_window(root):
# Create the new window
top = tk.Toplevel(root)
# Stop the user from interacting with the main window
top.grab_set()
root = tk.Tk()
menubar = tk.Menu(root)
menubar.add_command(label="Create new window", command=lambda: create_window(root))
root.config(menu=menubar)
root.mainloop()
It uses top.grab_set() to stop the user from interacting with the main window. It blocks all events until the user closes the pop up.
I am doing a GUI using for my code and finding it hard to develop what i want.
First ...
on the window an image and label appear and disappear after couple of seconds. after that a frame should arrive, followed by a menu option, when the menu option is selected it should disappear from frame and another image should appear.
self.gui = Tk()
def configure_window(self):
self.gui.geometry('700x500')
self.gui.resizable(height=False, width=False)
self.gui.update()
self.welcome_label()
self.welcome_image()
def welcome__image(self):
image = Image.open(image path)
photo = ImageTk.PhotoImage(image)
welcome_image = Label(master=self.gui, image=photo, justify='center',relief='raised')
welcome_image.image = photo
welcome_image.pack(padx=100, pady=100)
welcome_image.place(bordermode='outside', x=200,y=100)
welcome_image.after(ms=1000, func=welcome_image.place_forget)
def welcome_label(self):
welcome_label = Label(master=self.gui, text=welcome_label_text,font=welcome_label_font, justify='center',
state='active', fg='blue', anchor='center', pady=10, relief='raised' )
welcome_label.place(x=100, y=350)
welcome_label.after(ms=1000, func=welcome_label.place_forget)
def first_frame(self):
self.first_frame = LabelFrame( master = self.gui,text='Select First File',font= 'arial 10 bold underline', bg=self.background_colour,
height=200,width=690, bd=1, padx=5, pady=5)
self.first_frame.pack()
self.first_frame.place(x=0, y=0)
def select_button1(self):
self.file_open_button1 = Button(master=self.first_frame,text='...',state='disabled',command=self.cmd_file_select_button1)
when i run the code, welcome_image and welcome_frame places and forgets places after 1000 ms, but, first_frame also loads with parent widget. i want frame to arrive after the welcome_label disappears.
and the same sequence continues for LabelFrame
i have widgets in LabelFrame in which i have OptionMenu and button, i want optionMenu to disappear when user selects an option and another button should appear, same sequence in the button, button returns some sting and a label should appear in the place of button etc.
how to generate the sequence e.g. if an widget has place_forget() a sequence will be generated and another widget should be bind on that sequence. please help.
apology, if i am unable to make you understand my problem.