开发者

How do I update a menu after a button press in PyGTK?

I am not that familiar with PyGTK. Please see the following code. Is it possible to make it do the following?

  1. There are two buttons, which we refer to as "generate" and "view".
  2. The "generate" button will generate random values for variables A and B.
  3. The "view" button will pop up a menu showing A and B.

The problem with the following code is that the "view" menu shows A and B, but the menu does not update as the user presses the "generate" button.

I ran the code with Python 2.6.6.

Please also suggest any ways that I can improve the code (formatting, style, PyGTK conventions, ...). Thank you in advance.

   """Generate values for two variables A and B."""
# ------------------------------------------------------------------------------
# Winston C. Yang
# Created 2010-12-04
# ------------------------------------------------------------------------------
# Python modules. Be alphabetical.
import random
# --------------------------------------------------------------------------开发者_开发问答----
# Other Python modules. Be alphabetical.
import gtk
import pygtk
pygtk.require("2.0")
# ------------------------------------------------------------------------------
class Generator:

    """Generate values for two variables A and B."""

    def __init__(self):

        # Create a dictionary in which a key is a variable name and a
        # (dictionary) value is the variable value.
        self.d_variable_value = {}
        # ----------------------------------------------------------------------
        window = gtk.Window()
        window.set_title("Generate")
        window.connect("destroy", self.quit_event)
        # ----------------------------------------------------------------------
        # Create a vertical box with two buttons.
        vbox = gtk.VBox()

        # Create a button to generate values for A and B.
        b = gtk.Button("Generate A and B")
        vbox.pack_start(b)
        b.connect("clicked", self.generate_variable_values)

        # Create a button to view A and B.
        b = gtk.Button("View A and B")
        vbox.pack_start(b)
        b.connect_object("event", self.button_press, self.create_menu())
        # ----------------------------------------------------------------------
        window.add(vbox)
        window.show_all()
    # --------------------------------------------------------------------------
    def quit_event(self, widget=None, event=None):
        """Quit."""
        gtk.main_quit()
    # --------------------------------------------------------------------------
    def generate_variable_values(self, widget=None):
        """Generate values for A and B."""
        self.d_variable_value = {
            "A" : random.randint(0, 10),
            "B" : random.randint(0, 10),
            }

        print "I generated " + str(self.d_variable_value)
    # --------------------------------------------------------------------------
    def button_press(self, widget, event):
        """button_press method."""
        if event.type == gtk.gdk.BUTTON_PRESS:
            widget.popup(None, None, None, event.button, event.time)
            return True

        return False
    # --------------------------------------------------------------------------
    def create_menu(self):
        """Create a menu showing A and B."""
        # How can I update the menu after the user presses the
        # "generate" button?

        # If there are no values for A and B, generate them.
        if not self.d_variable_value:
            self.generate_variable_values()

        # Show A and B in a menu.
        menu = gtk.Menu()

        for key, value in sorted(self.d_variable_value.items()):

            text = key + " " + str(value)
            item = gtk.MenuItem(text)
            item.show()
            menu.append(item)

        return menu
# ------------------------------------------------------------------------------
if __name__ == "__main__":
    Generator()
    gtk.main()


This line b.connect_object("event", self.button_press, self.create_menu()) is connecting self.button_press to the event signal on a gtk.Menu created by self.create_menu(). This line is never executed again, so the menu is always the same.

What I did was connect the event signal for the View A and B button to the self.button_press handler, and that handler creates an updated menu every time it's run.

# ------------------------------------------------------------------------------
# Python modules. Be alphabetical.
import random
# ------------------------------------------------------------------------------
# Other Python modules. Be alphabetical.
import gtk
import pygtk
pygtk.require("2.0")
# ------------------------------------------------------------------------------
class Generator:

    """Generate values for two variables A and B."""

    def __init__(self):

        # Create a dictionary in which a key is a variable name and a
        # (dictionary) value is the variable value.
        self.d_variable_value = {}
        # ----------------------------------------------------------------------
        window = gtk.Window()
        window.set_title("Generate")
        window.connect("destroy", self.quit_event)
        # ----------------------------------------------------------------------
        # Create a vertical box with two buttons.
        vbox = gtk.VBox()

        # Create a button to generate values for A and B.
        b = gtk.Button("Generate A and B")
        vbox.pack_start(b)
        b.connect("clicked", self.generate_variable_values)

        # Create a button to view A and B.
        b = gtk.Button("View A and B")
        vbox.pack_start(b)
        b.connect("event", self.button_press)
        # ----------------------------------------------------------------------
        window.add(vbox)
        window.show_all()
    # --------------------------------------------------------------------------
    def quit_event(self, widget=None, event=None):
        """Quit."""
        gtk.main_quit()
    # --------------------------------------------------------------------------
    def generate_variable_values(self, widget=None):
        """Generate values for A and B."""
        self.d_variable_value = {
            "A" : random.randint(0, 10),
            "B" : random.randint(0, 10),
            }

        print "I generated " + str(self.d_variable_value)
    # --------------------------------------------------------------------------
    def button_press(self, button, event):
        """button_press method."""
        if event.type == gtk.gdk.BUTTON_PRESS:
            menu = self.create_menu()
            menu.popup(None, None, None, event.button, event.time)
            return True

        return False
    # --------------------------------------------------------------------------
    def create_menu(self):
        """Create a menu showing A and B."""
        # How can I update the menu after the user presses the
        # "generate" button?

        # If there are no values for A and B, generate them.
        if not self.d_variable_value:
            self.generate_variable_values()

        # Show A and B in a menu.
        menu = gtk.Menu()

        print self.d_variable_value
        for key, value in sorted(self.d_variable_value.items()):

            text = key + " " + str(value)
            item = gtk.MenuItem(text)
            item.show()
            menu.append(item)

        return menu
# ------------------------------------------------------------------------------
if __name__ == "__main__":
    Generator()
    gtk.main()
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜