How can I customize tkinter dropdown menu? [duplicate] - python

This question already has answers here:
Python Tkinter: OptionMenu modify dropdown list width
(6 answers)
Closed 1 year ago.
I want to create a dropdown menu in tkinter of custom width and height and certain styling options like fore background etc. but when I am running my this code it is giving AttributeError: 'NoneType' object has no attribute 'config' and when I run my code without config it gives 'TypeError: 'dict_keys' object is not subscriptable
These are my both two codes please help me in this problem.
from tkinter import *
from tkinter import ttk
import tkinter
root=Tk()
root.geometry('500x500')
seletion=StringVar()
def show():
label=Label(root,text=seletion.get()).pack(pady=10)
drop=OptionMenu(root,seletion,'one','two','three',width=10).pack(pady=10)
button=Button(root,text='show',command=show).pack(pady=10)
root.mainloop()
Second code:
from tkinter import *
from tkinter import ttk
import tkinter
root=Tk()
root.geometry('500x500')
seletion=StringVar()
def show():
label=Label(root,text=seletion.get()).pack(pady=10)
pass
drop=OptionMenu(root,seletion,'one','two','three').pack(pady=10)
button=Button(root,text='show',command=show).pack(pady=10)
drop.config(width=10)
root.mainloop()

It is possible to alter OptionMenu attributes including width and height as well as color, font and menu position.
It would probably be better to use ttk.ComboBox however to answer your question I will post this code.
Included is a function called find that will extract all attributes and their values from tkinter objects and display them in a human friendly way.
You can also display an image or bitmap so I've imported filedialog to assist with image selection.
This is your program with errors removed and extra code for attribute testing.
def find( obj ):
name = f"{type(obj).__name__}:\n "
try:
return name + "\n ".join( [ f"{x} = '{obj.cget(x)}'" for x in obj.keys() if x not in ['bg', 'fg', 'bd']] )
except:
return f"'{obj}' has no keys attribute"
import tkinter as tk
from tkinter import filedialog as fido
root = tk.Tk()
root.geometry('500x500')
selection = tk.StringVar()
def show():
label["text"] = selection.get()
label = tk.Label(root,text = selection.get())
label.pack()
drop = tk.OptionMenu(root,selection,'one','two','three')
drop.pack(pady = 10)
# Extra controls
image = fido.askopenfilename(title = "Choose a Picture")
if image:
photo = tk.PhotoImage(file = image)
photo_wide = photo.width()
photo_high = photo.height()
drop.config(height = photo_high, width = photo_wide,
takefocus = 1, image = photo, compound = "center")
else:
drop["height"] = '2'
drop['width'] = '10'
drop["direction"] = ["above", "below", "flush", "left", "right"][2]
drop["anchor"] = ["n", "ne", "e", "se", "s", "sw", "w", "nw", "center"][0]
drop["justify"] = ["left", "right", "center"][1]
# drop["bitmap"] = "warning"
drop["background" ] = "cyan"
drop["activebackground" ] = "cyan"
drop["highlightbackground"] = "red"
drop["font"] = 'TkDefaultFont 14'
drop["menu"]["background"] = "red"
drop["menu"]["foreground"] = "yellow"
drop["menu"]["font"] = "TkDefaultFont 15"
drop["menu"]["selectcolor"] = "green"
drop["menu"]["activeborderwidth"] = '4'
button = tk.Button(root, text = 'show', command = show)
button.pack(pady = 10)
print(find( drop ))
print(find( drop[ "menu" ] ))
root.mainloop()

Related

_tkinter.TclError: image "pyimage1" doesn't exist, I am new to python

I need help with creating a button with an image, the creation of the image seems to not be a problem as when I hover over the file location of the image, the image pops up. However, the error image "pyimage1" doesn't exist shows up as seen in the screenshots. This is for a cookie clicker type game for a school project and I am very knew to Python (3 days of learning so far).
from tkinter import *
gui = Tk()
clicks = 0
class Game():
multiplier = 0
global upgrades
upgrades = ["2", "4", "6", "8", "10", "20"], ["Upgrade 1", "Upgrade 2", "Upgrade 3", "Upgrade 4", "Upgrade 5", "Maxed"]
def setMultiplier(x):
multiplier = x
print(multiplier)
def clickcmd(multiplier):
global clicks
clicks += 1 * (multiplier)
return clicks
def up1cmd(x):
setMultiplier(upgrades[0][x])
# x = Which upgrade was bought, returns upgrade[x]
def getUpgrade(x):
return upgrades[0, x], upgrades[1, x]
`
from tkinter import *
from Game import Game
gui = Tk()
gui.title("Clicking Mania")
gui.geometry("600x600")
# Inside GUI title
title = Label(gui, text="Clicking Mania")
title.pack()
title.grid_location(3, 2)
# Images
image = PhotoImage(file='../GameImages/DPic.png')
imagelabel = Label(image=image)
imageshop = PhotoImage(file='../GameImages/upgrade.png')
imageupgrade = Label(image=imageshop)
# Buttons
pickaxebutton = Button(gui, image=image, command=Game.clickcmd(1), borderwidth=0)
pickaxebutton.pack(pady=100)
upgradebutton = Button(gui, image=imageshop, borderwidth=0)
# change image
up1button = Button(gui, image=image, command=Game.up1cmd(), borderwidth=0)
balance = Label(gui, text="Balance: ", padx=20, pady=10)
balance.pack()
gui.mainloop()
Hard to tell with just seeing a couple lines of your code, but most likely the path to the image is wrong. Try using the OS library to print out your current path.
import os
os.getcwd()
Then from there you can figure out what path you need to give. Or you can give an absolute path to see if that is the issue or not.

how do i add stuff to listbox (tkinter python) [duplicate]

This question already has answers here:
Tkinter: AttributeError: NoneType object has no attribute <attribute name>
(4 answers)
Closed last year.
I'm making a log/chat system in my program (just Tkinter default looks) and i came across a problem where I can't add or change a listbox. Here is what I'm trying to do:
import tkinter
from tkinter import *
from tkinter import messagebox
import random
window = tkinter.Tk()
window.geometry("250x195")
window.title(" ")
window.iconbitmap("icon.ico")
global loglength, log
log = []
loglength = len(log)
inventorylist = []
def sendmessage(event):
chatstring = chatentry.get()
log.append(chatstring)
print(log, loglength)
checknew() #dont worry abt this it works
serverlog = tkinter.Listbox(
width=20,
height=11,
bg="darkgray",
listvariable=log
).place(x=128,y=-2)
I want to add items to the listbox. Here is an image of my program:
When I press enter (the key bound to the function to add the string to the listbox) this happens:
is Listbox like a program u want?
if u want a program that will make u program list in tkinder this is the code :
from tkinter import *
a= Tk()
a.geometry("400x400")
a.title("test")
Lb1 = Listbox(a,bg = "pink", bd = 10, fg = "black",\
font = "Castellar", cursor = "target")
Lb1.insert(1, "lion")
Lb1.insert(2, "tiger")
Lb1.insert(3, "zebra")
Lb1.insert(4, "elephant")
Lb1.insert(5, "deer")
Lb1.insert(6, "fox")
Lb1.insert(7, "Wolf")
Lb1.insert(8, "Gorilla")
Lb1.insert(9, "Jackal")
Lb1.insert(10, "Otter")
Lb1.pack()
a.mainloop()
hope that i helped u.

How can I get the option selected by a user from a combobox in toplevel

I'm new to Python and Tkinter and was trying to create an interface to search & plot data. I created a very simple toplevel window to get the values from a combobox that would be selected from users. However, I find the script would only print the first item in the list if comboxlist2.current(0) was set or it would print nothing, no matter which one is selected in the box. I created a sample script to test this. If I click on the "search & create", then the return values can change according to the user selection in comboxlist1, while it would all return "1" no matter what the user selected in comboxlist2. So may I ask where is the issue and how to solve?
Thanks in advance for the potential suggestions or solutions!
import tkinter as tk
from tkinter import ttk
from tkinter import *
def root_print():
reg_in = comboxlist1.get()
print(reg_in) #print the value selected
def on_click():
tl = Toplevel()
comvalue2 = tk.StringVar()
comboxlist2 = ttk.Combobox(tl,textvariable=comvalue2)
comboxlist2["values"] = ("1","2","3")
comboxlist2.grid()
comboxlist2.current(0) #select the first one as default
#mm = comboxlist2.get()
#print(mm) #print directly
go(comboxlist2,tl)
tl.wait_window()
return
def go(comboxlist2,tl):
mm = comboxlist2.get()
Button(tl,text='go', command=lambda:test(mm)).grid()
def test(mm):
print(mm) #do the same thing for the comboxlist2
root = Tk()
root.title('search') #create an interface
root.geometry('+400+200') #size and position
Label(text='region ').grid(row=2,column=0)
comvalue1 = tk.StringVar()
comboxlist1=ttk.Combobox(root,textvariable=comvalue1)
comboxlist1["values"]=("all","africa","asia","australia","canada","europe","mexico","southamerica","usa")
comboxlist1.grid(row=2,column=1)
comboxlist1.current(0)
Button(text='search & create', command=root_print).grid(row=0,column=4)
Button(text='click', command=on_click).grid(row=1, column=4)
loop = mainloop()#go!
Here is the working code, which should take care of your needs. I have removed the imports and some code snippets which are not useful.
import tkinter as tk
from tkinter import ttk
def root_print():
reg_in = comboxlist1.get()
print(reg_in)
def on_click():
tl = tk.Toplevel()
comvalue2 = tk.StringVar()
comboxlist2 = ttk.Combobox(tl,textvariable=comvalue2)
comboxlist2["values"] = ("1","2","3")
comboxlist2.grid()
comboxlist2.current(0) #select the first one as default
tk.Button(tl,text='go', command=lambda: test(comboxlist2.get())).grid()
tl.wait_window()
def test(mm):
print(mm)
root = tk.Tk()
root.title('search') #create an interface
root.geometry('+400+200') #size and position
tk.Label(text='region ').grid(row=2,column=0)
comvalue1 = tk.StringVar()
comboxlist1=ttk.Combobox(root,textvariable=comvalue1)
comboxlist1["values"]=("all","africa","asia","australia","canada","europe","mexico","southamerica","usa")
comboxlist1.grid(row=2,column=1)
comboxlist1.current(0)
tk.Button(text='search & create', command=root_print).grid(row=0,column=4)
tk.Button(text='click', command=on_click).grid(row=1, column=4)
root.mainloop()

How to make a label with the background color as a color chosen by the user?

So, here is my code. Essentially, what I want to do is to make a label with the background color the same as the color chosen in the color dialog, so that the person can see the color and the color hexadecimal code. Please help.
import sys
from tkinter import *
from tkinter import colorchooser
mGui = Tk()
mGui.geometry("600x300+500+500")
mGui.title("Hexadecimal Color Chooser")
def getColor():
mycolor = colorchooser.askcolor()
label = Label(mGui, bg = mycolor).pack()
mycolor = str(mycolor)
start = mycolor.index("#")
stop = mycolor.index("')")
mycolor = mycolor[start:stop]
label = Label(mGui, text = "The hexadecimal color code is: " + mycolor).pack()
button = Button(mGui, text = "Choose a color", command = getColor).place(x=0, y=0)
There are three issues here:
Importing sys if you are not going to use it does nothing.
The place, pack, and grid methods of Tkinter widgets always return None. Hence, any calls to them should always be placed on their own line.
tkinter.colorchooser.askcolor returns a two-item tuple like this:
((128.5, 64.25, 64.25), '#804040')
Futhermore, the last item in this tuple is the hex code of the chosen color.
Below is a fixed version of the script:
from tkinter import *
from tkinter import colorchooser
mGui = Tk()
mGui.geometry("600x300+500+500")
mGui.title("Hexadecimal Color Chooser")
def getColor():
color_choice = colorchooser.askcolor()[1] # get the hex code
color = Label(mGui, bg=color_choice)
color.pack()
hexcode = Label(mGui, text="The hexadecimal color code is: "+color_choice)
hexcode.pack()
button = Button(mGui, text="Choose a color", command=getColor)
button.place(x=0, y=0)
mGui.mainloop()

2nd Page not showing up?

This is my code :
import sys
from tkinter import *
#first new screen
def next_screen(names):
for widget in names:
widget.place_forget()
buttonhyp = Button (text = "button1",fg = "blue",command = hypoténusegetdef())
buttonhyp.grid (row = 1,column = 2)
def forget_page1():
widgets = [mLabel1, button]
next_screen(widgets)
################################################################################
def hypténusegetdef ():
widgets1 = [buttonhyp]
nextscreen1(widgets1)
def next_screen(names):
for widget in names:
widget.place_forget()
hyplabel1 = Label (text = "This is my text")
#first page things
mGui = Tk ()
mGui.geometry("600x600+545+170")
mGui.title("MyMathDictionary")
mLabel1 = Label (text = "Welcome to MyMathDictionary. Press Next to continue.",
fg = "blue",bg = "white")
mLabel1.place (x= 150,y = 200)
button = Button (text = "Next", command = forget_page1 )
button.place(x = 275,y = 230)
mGui.mainloop()
What i'm trying to do is to open the program and get the user to click on "Next" and then to show another button which is called "button1" and when the user clicks on "button1" it shows up a text called which says "This is my text" in my code.But when i run it i click on "Next" and nothing shows up i checked and re- checked but nothing seems to work.Any help would be appreciated.
#
I am not an expert, but i will give it a try.
Firstly, import sys is not necessary. And importing all the objects from tkinter module using from tkinter import* is not recommended. You should use import tkinter or import tkinter as tk to avoid unexepcted consequences.
You have 2 functions with the same name. next_screen(names) which should not happen.
Instead of using widgets = [mLabel1, button] to hide the widgets, you should put them in a frame so that you can use winfo_children() to find all the children widgets.
You should put the parent widget name when you create buttons and labels. for example,
import tkinter as tk
root = tk.Tk()
mylabel = tk.Label(root,text='this is a label')
mylabel.pack()
root.mainloop()
In your first next_screen(names) function , you used grid method to display the button. You should not mix the grid method and place method.
This is something i came up with
import tkinter as tk
def Screen_1():
Clear(myframe)
mybutton2= tk.Button(myframe,text = "Button1", command = Screen_2)
mybutton2.pack()
def Screen_2():
Clear(myframe)
mylabel2= tk.Label(myframe,text = "This is my text",fg = "blue",bg = "white")
mylabel2.pack(side='top')
def Clear(parent):
for widget in parent.winfo_children():
widget.pack_forget()
root =tk.Tk()
myframe=tk.Frame(root)
myframe.pack()
mylabel1= tk.Label(myframe,text = "Welcome to MyMathDictionary. Press Next to continue.",fg = "blue",bg = "white")
mylabel1.pack(side='top')
mybutton1= tk.Button(myframe,text = "Next", command = Screen_1)
mybutton1.pack(side='bottom')
root.mainloop()
hope it helps!

Categories

Resources