0

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()
ThePyGuy
  • 17,779
  • 5
  • 18
  • 45
  • Does this answer your question? [Tkinter: AttributeError: NoneType object has no attribute ](https://stackoverflow.com/questions/1101750/tkinter-attributeerror-nonetype-object-has-no-attribute-attribute-name) – Matiiss Aug 31 '21 at 12:24
  • if you really want to keep it in one line check [this answer](https://stackoverflow.com/a/68782288/14531062) from the same question – Matiiss Aug 31 '21 at 12:26
  • I think you are better off customizing the `ComboBox` widget from `ttk` as for example `OptionMenu` doesn't have `width` argument (you can still probably pack or grid it so that it fills the container on x axis), also do not import everything from a module (do not use `*` (wildcard) when importing modules) – Matiiss Aug 31 '21 at 12:32

1 Answers1

0

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()
Derek
  • 1,916
  • 2
  • 5
  • 15