alejandroautalan / pygubu

A simple GUI builder for the python tkinter module
MIT License
2.01k stars 213 forks source link

Disabling Menus #212

Closed maranhaoBruno closed 3 years ago

maranhaoBruno commented 3 years ago

I am trying to disable menus programmatically. In pygubu-designer I am able to adjust the state variable from normal to disabled to achieve what I want, but when I try to programmatically make the change, i.e. self.builder.get_object('menuItem').configure(state='disabled'), I get an error stating that tkinter.TclError: unknown option "-state"

If I can change this option within pygubu-designer, why am I not able to change it within the code of my application? If I am able to change it within the code of my application please inform me of how.

Thanks, B

alejandroautalan commented 3 years ago

Hello Bruno, thanks for trying pygubu.

I am trying to disable menus programmatically. In pygubu-designer I am able to adjust the state variable from normal to disabled to achieve what I want, but when I try to programmatically make the change, i.e. self.builder.get_object('menuItem').configure(state='disabled'), I get an error stating that tkinter.TclError: unknown option "-state"

When you do:

self.builder.get_object('menuItem')

pygubu will return the tk.Menu associated to that item. Once you have the menu, you can manipulate its items, using the entrycget and entryconfigure methods. Note that menu item manipulation uses indexes. More info here Here is a simple example. Let me know if you have more questions.

Regards Alejandro A.

File: issue212.py

import os
import pygubu

PROJECT_PATH = os.path.dirname(__file__)
PROJECT_UI = os.path.join(PROJECT_PATH, "issue212.ui")

class Issue212App:
    def __init__(self):
        self.builder = builder = pygubu.Builder()
        builder.add_resource_path(PROJECT_PATH)
        builder.add_from_file(PROJECT_UI)
        self.mainwindow = builder.get_object('mainwindow')

        self.mainmenu = builder.get_object('mainmenu', self.mainwindow)
        self.mainwindow.configure(menu=self.mainmenu)

        # Finally connect callbacks
        builder.connect_callbacks(self)

    def on_toggle_menu(self):
        # Toggle project menu
        #   Project menu is a submenu item of MainMenu
        #   is on position 1 (index starts on 0)

        newstate = 'normal'
        state = self.mainmenu.entrycget(1, 'state')
        if state == 'normal':
            newstate = 'disabled'
        self.mainmenu.entryconfigure(1, state=newstate)

    def on_toggle_options(self):
        # Toggle all extra options
        menu = self.builder.get_object('mproject_extra')

        newstate = 'normal'
        last = menu.index('end')
        state = menu.entrycget(last, 'state')
        if state == 'normal':
            newstate = 'disabled'
        for index in range(0, last+1):
            menu.entryconfigure(index, state=newstate)

    def on_mfile_item_clicked(self, itemid):
        if itemid == 'mfile_quit':
            self.mainwindow.quit()

    def run(self):
        self.mainwindow.mainloop()

if __name__ == '__main__':
    app = Issue212App()
    app.run()

File: issue212.ui

<?xml version='1.0' encoding='utf-8'?>
<interface version="1.0">
  <object class="tk.Toplevel" id="mainwindow">
    <property name="geometry">352x288</property>
    <property name="height">200</property>
    <property name="width">200</property>
    <child>
      <object class="ttk.Frame" id="fcontainer">
        <property name="height">200</property>
        <property name="width">200</property>
        <layout manager="pack">
          <property name="expand">true</property>
          <property name="fill">both</property>
          <property name="propagate">True</property>
          <property name="side">top</property>
        </layout>
        <child>
          <object class="ttk.Label" id="label_1">
            <property name="text" translatable="yes">Menu Example</property>
            <layout manager="pack">
              <property name="propagate">True</property>
              <property name="side">top</property>
            </layout>
          </object>
        </child>
        <child>
          <object class="ttk.Frame" id="frame_2">
            <property name="height">200</property>
            <property name="width">200</property>
            <layout manager="pack">
              <property name="expand">true</property>
              <property name="propagate">True</property>
              <property name="side">top</property>
            </layout>
            <child>
              <object class="ttk.Button" id="button_1">
                <property name="command">on_toggle_menu</property>
                <property name="text" translatable="yes">Toggle Project menu</property>
                <layout manager="pack">
                  <property name="propagate">True</property>
                  <property name="side">top</property>
                </layout>
              </object>
            </child>
            <child>
              <object class="ttk.Button" id="button_2">
                <property name="command">on_toggle_options</property>
                <property name="text" translatable="yes">Toggle Extra Options</property>
                <layout manager="pack">
                  <property name="propagate">True</property>
                  <property name="side">top</property>
                </layout>
              </object>
            </child>
          </object>
        </child>
      </object>
    </child>
  </object>
  <object class="tk.Menu" id="mainmenu">
    <property name="tearoff">false</property>
    <child>
      <object class="tk.Menuitem.Submenu" id="mfile">
        <property name="label" translatable="yes">File</property>
        <property name="tearoff">false</property>
        <child>
          <object class="tk.Menuitem.Command" id="mfile_quit">
            <property name="command">on_mfile_item_clicked</property>
            <property name="command_id_arg">true</property>
            <property name="label" translatable="yes">Quit</property>
          </object>
        </child>
      </object>
    </child>
    <child>
      <object class="tk.Menuitem.Submenu" id="mproject">
        <property name="label" translatable="yes">Project</property>
        <property name="state">disabled</property>
        <property name="tearoff">false</property>
        <child>
          <object class="tk.Menuitem.Command" id="mproject_item0">
            <property name="command_id_arg">false</property>
            <property name="label" translatable="yes">Option 1</property>
          </object>
        </child>
        <child>
          <object class="tk.Menuitem.Command" id="mproject_item1">
            <property name="command_id_arg">false</property>
            <property name="label" translatable="yes">Option 2</property>
          </object>
        </child>
        <child>
          <object class="tk.Menuitem.Command" id="mproject_item2">
            <property name="command_id_arg">false</property>
            <property name="label" translatable="yes">Option 3</property>
          </object>
        </child>
        <child>
          <object class="tk.Menuitem.Submenu" id="mproject_extra">
            <property name="label" translatable="yes">Extra</property>
            <child>
              <object class="tk.Menuitem.Command" id="extraitem0">
                <property name="command_id_arg">false</property>
                <property name="label" translatable="yes">command_4</property>
                <property name="state">disabled</property>
              </object>
            </child>
            <child>
              <object class="tk.Menuitem.Command" id="extraitem1">
                <property name="command_id_arg">false</property>
                <property name="label" translatable="yes">command_5</property>
                <property name="state">disabled</property>
              </object>
            </child>
          </object>
        </child>
      </object>
    </child>
  </object>
</interface>