0

I have a checkbox toolbar menu option in tkinter. Whenever, I click on the option, it enables word wrap and puts a check mark next to it.

# Toggle Word Wrap Function
def ToggleWordWrap(*args):
    # If there is no word wrap then add word wrap
    if TextBox.cget("wrap") == "none":
        TextBox.configure(wrap="word")
    # If there is word wrap then take out word wrap
    elif TextBox.cget("wrap") == "word":
        TextBox.configure(wrap="none")

# Check Marks for Options in Tools Menu
WordWrap_CheckMark = BooleanVar()
WordWrap_CheckMark.set(False)

# Tools Option for Menu Bar
ToolsOption = Menu(MenuBar, tearoff=False)
MenuBar.add_cascade(label="Tools", menu=ToolsOption, underline=0)
ToolsOption.add_command(label="Word Count")
ToolsOption.add_checkbutton(label="Toggle Word Wrap", onvalue=1, offvalue=0, variable=WordWrap_CheckMark, command=ToggleWordWrap)

I also decided that I should add a keyboard binding Alt-Z to the function.

# Toggle Word Wrap Function
def ToggleWordWrap(*args):
    # If there is no word wrap then add word wrap
    if TextBox.cget("wrap") == "none":
        TextBox.configure(wrap="word")
    # If there is word wrap then take out word wrap
    elif TextBox.cget("wrap") == "word":
        TextBox.configure(wrap="none")
root.bind("<Alt-Key-z>", ToggleWordWrap)

# Check Marks for Options in Tools Menu
WordWrap_CheckMark = BooleanVar()
WordWrap_CheckMark.set(False)

# Tools Option for Menu Bar
ToolsOption = Menu(MenuBar, tearoff=False)
MenuBar.add_cascade(label="Tools", menu=ToolsOption, underline=0)
ToolsOption.add_command(label="Word Count")
ToolsOption.add_checkbutton(label="Toggle Word Wrap", onvalue=1, offvalue=0, variable=WordWrap_CheckMark, command=ToggleWordWrap, accelerator="Alt-Z")

Whenever I use the keyboard binding, it does not turn the check mark on. How would I fix this?

Skcoder
  • 299
  • 1
  • 9

1 Answers1

1

you need to set WordWrap_CheckMark True when word-wrap is on.

Here is your function:

def toggleWordWrap(event=None):
   
   if textBox.cget("wrap") == "none":
        textBox.configure(wrap="word")
        WordWrap_CheckMark.set(True)
    # If there is word wrap then take out word wrap

   elif textBox.cget("wrap") == "word":
        textBox.configure(wrap="none")
        WordWrap_CheckMark.set(False)

Here is the full example:

from tkinter import *

def toggleWordWrap(event=None):
   
   if textBox.cget("wrap") == "none":
        textBox.configure(wrap="word")
        WordWrap_CheckMark.set(True)
    # If there is word wrap then take out word wrap

   elif textBox.cget("wrap") == "word":
        textBox.configure(wrap="none")
        WordWrap_CheckMark.set(False)

root = Tk()

root.bind_all("<Alt-Key-z>", toggleWordWrap)  # just Alt-z will also work fine

WordWrap_CheckMark = BooleanVar()
WordWrap_CheckMark.set(False)

menuBar = Menu(root)

tools = Menu(menuBar, tearoff=0)
tools.add_command(label='Word Count')
tools.add_checkbutton(label="Toggle Word Wrap", onvalue=1, offvalue=0, variable=WordWrap_CheckMark, command=toggleWordWrap, accelerator="Alt-Z")

menuBar.add_cascade(label ='Tools', menu=tools)

textBox = Text(root, wrap="none")
textBox.pack()

root.config(menu = menuBar)
root.mainloop()

JacksonPro
  • 3,135
  • 2
  • 6
  • 29
  • @Skcoder when you click on the "Toggle Word Wrap" it doesn't pass any argument during the function call but whereas the bind method passes an argument when the function is called so you need to assign an initial value to the event parameter. else you might receive TypeError. To know what argument is passed use print(event) inside the `toggleWordWrap` function. – JacksonPro Mar 05 '21 at 02:58
  • Could you explain what event, e, *args, event=None all do and what the difference between them is? – Skcoder Mar 05 '21 at 03:20
  • @Skcoder if you have not understood here's the thing `toggleWordWrap` is just a reference to the function it isn't a function call where as `toggleWordWrap()` is a function call meaning it will call the function immediately. So here `command=toggleWordWrap` you are just passing the reference to that method. The function call will be made when the event occurs. try this simple code `def function(string): print("Hello", string) def callFun(fun): fun("run") callFun(function)`. e, event are just names it could be anything. – JacksonPro Mar 05 '21 at 03:26
  • *args, in this case, is used when an unknown number of arguments are passed by the function call. Hope that clears everything. – JacksonPro Mar 05 '21 at 03:27
  • Also, you might want to read [this](https://stackoverflow.com/a/706735/12198502) – JacksonPro Mar 05 '21 at 03:35
  • Thank-you very much! – Skcoder Mar 05 '21 at 13:38