【问题标题】:How can I store values of buttons in variables? (Python Gtk)如何将按钮的值存储在变量中? (Python Gtk)
【发布时间】:2017-05-09 03:54:33
【问题描述】:

我需要将单击的按钮的值存储到变量中。所以我需要将按钮与变量连接起来,我该怎么做?这是我的变量:

    self.first_num = 0
    self.second_num = 0
    self.result = 0
    self.operation = ""

然后我需要在这个函数中使用它们,例如另外:

    def equal_clicked(self, result):
    if self.operation == "plus":
        self.result = self.first_num + self.second_num
        self.entry.set_text(self.result)

    def button2_clicked(self, button2):
    self.entry.set_text(self.entry.get_text() + str(2))

我希望这是足够的代码来向您展示我的问题,我将不胜感激。

    button5 = Gtk.Button(label="5")
    button5.connect("clicked", self.button_clicked)
    vbox.pack_start(button5, True, True, 0)
    vbox.pack_end(button5, True, True, 0)
    self.add(button5)

【问题讨论】:

  • 我假设您正在制作类似计算器的东西?我不确定按钮的值是什么意思,因为按钮不能保存值,但如果你的意思是使用每个数字按钮的数字,只需设置一个连接到 clicked 信号的回调函数,然后使用硬编码到每个回调中的静态数字初始化变量。
  • 所以我为数字为“2”的按钮添加了功能。我必须初始化该函数中的变量吗?还是我假设错了?顺便说一句,是的,我正在研究计算器。
  • 那行得通。您也可以使用您的原始计划,并在单击该按钮时将 self.first_num 设置为 2。答案看起来应该可行。我不使用 Python,所以我没有 Python lambda 的经验。

标签: python gtk


【解决方案1】:

我经常为工作制作 GUI 应用程序。主要思想是将单个函数绑定到每个按钮,但为每个按钮传递不同的变量。

这是 Python Gtk 的完整示例:

import pygtk
import gtk

class Example:
    def __init__(self):
        #Setup window
        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.window.set_border_width(10)
        self.boxSizer = gtk.HBox(False, 0)

        #Create widgets
        self.button1     = gtk.Button("1")
        self.button2     = gtk.Button("2")
        self.button3     = gtk.Button("3")
        self.buttonPlus  = gtk.Button("+")
        self.buttonEqual = gtk.Button("=")
        self.entry       = gtk.Entry(max=0)

        #Bind Events to a single function
        #You would do this for every button. 
        #The first parameter in the connect() function is the name, 
        #the second is the function you are binding, 
        #and the third is the argument we are passing into the function.
        self.button1.connect("clicked", self.button_clicked, 1)
        self.button2.connect("clicked", self.button_clicked, 2)
        self.button3.connect("clicked", self.button_clicked, 3)
        self.buttonPlus.connect("clicked", self.button_clicked, "+")
        self.buttonEqual.connect("clicked", self.button_clicked, "=")

        #Build Window
        self.window.add(self.boxSizer)
        self.boxSizer.pack_start(self.button1, True, True, 0)
        self.boxSizer.pack_start(self.button2, True, True, 0)
        self.boxSizer.pack_start(self.button3, True, True, 0)
        self.boxSizer.pack_start(self.buttonPlus, True, True, 0)
        self.boxSizer.pack_start(self.buttonEqual, True, True, 0)
        self.boxSizer.pack_start(self.entry, True, True, 0)

        #Show objects
        self.button1.show()
        self.button2.show()
        self.button3.show()
        self.buttonPlus.show()
        self.buttonEqual.show()
        self.entry.show()
        self.boxSizer.show()
        self.window.show()

    def button_clicked(self, widget, value):
        """Your first function and second function could be combined like this.
        What this would do is have a single function that is bound to each button. 
        The arguments passed into it would be different for each button.

        Despite using the 'evil eval' function, I figure this is the route you are going.

        This removes the need to (1) have a different function for each button, 
        and (2) you do not need to store values in variables like this:
            self.first_num = 0
            self.second_num = 0
            self.operation = ""

        Your code will be cleaner and easier to modify for future projects.
        """
        if (value != None):
            if (value != "="):
                #Add something to the text
                self.entry.set_text(self.entry.get_text() + str(value))
            else:
                #Evaluate the text
                self.result = eval(self.entry.get_text())
                self.entry.set_text(str(self.result))
        else:
            #Clear the text
            self.entry.set_text("")

    def main(self):
        gtk.main()

if __name__ == "__main__":
    example = Example()
    example.main()

这个概念应该适用于任何 GUI 创建包。不过,有些软件包可能比其他软件包需要更多的工作。 例如,wxPython 不允许您将参数传递给函数。您可以按照“Florian Bosch”在Is it possible to pass arguments into event bindings? 上所说的操作来绕过这个限制。 (注意:此方法适用于任何不允许您将参数传递给绑定函数的 GUI 包)

对于 wxPython:像这样绑定所有按钮:

self.Bind(wx.EVT_BUTTON, lambda event: button_clicked(event, "1"), button1)
self.Bind(wx.EVT_BUTTON, lambda event: button_clicked(event, "2"), button2)
self.Bind(wx.EVT_BUTTON, lambda event: button_clicked(event, "3"), button2)
self.Bind(wx.EVT_BUTTON, lambda event: button_clicked(event, "4"), button2)
self.Bind(wx.EVT_BUTTON, lambda event: button_clicked(event, "5"), button2)
self.Bind(wx.EVT_BUTTON, lambda event: button_clicked(event, "6"), button2)
self.Bind(wx.EVT_BUTTON, lambda event: button_clicked(event, "7"), button2)
self.Bind(wx.EVT_BUTTON, lambda event: button_clicked(event, "8"), button2)
self.Bind(wx.EVT_BUTTON, lambda event: button_clicked(event, "9"), button2)
self.Bind(wx.EVT_BUTTON, lambda event: button_clicked(event, "0"), button2)
self.Bind(wx.EVT_BUTTON, lambda event: button_clicked(event, "+"), buttonAdd)
self.Bind(wx.EVT_BUTTON, lambda event: button_clicked(event, "-"), buttonSubtract)
self.Bind(wx.EVT_BUTTON, lambda event: button_clicked(event, "*"), buttonMultiply)
self.Bind(wx.EVT_BUTTON, lambda event: button_clicked(event, "/"), buttonDivide)
self.Bind(wx.EVT_BUTTON, lambda event: button_clicked(event, "="), buttonEqual)
self.Bind(wx.EVT_BUTTON, lambda event: button_clicked(event, None), buttonClear)

(使用此部分:lambda event: button_clicked(event, "1") 代替通常将按钮连接到功能的位置。)


这里的想法,不管使用什么 GUI 模块,都是绑定单个函数 到计算器的所有按钮,并为每个按钮传入不同的值。

【讨论】:

  • 所以我在我的问题中添加了一个按钮的定义。这是正确的方法吗?而且我不明白如何或在哪里定义 button_clicked 函数中的值?顺便说一句,感谢您的回答。
  • 我对 Python Gtk 做了一些研究。看起来绑定函数比 wxPython 更容易。我在答案中添加了更多信息。
  • 感谢您的回答。所以我尝试使用代码并更改了一些东西,但它不起作用。对我来说,这是我只需要改变一些东西的解决方案。你试过代码了吗?
  • 我已经稍微修改了我的代码,你可以在上面看到它。这就是我之前绑定按钮的方式。
  • 我下载了 Python Gtk 并为您创建了一个简单的示例。我希望这会有所帮助。
猜你喜欢
  • 1970-01-01
  • 2023-03-17
  • 1970-01-01
  • 2017-10-01
  • 2022-09-30
  • 1970-01-01
  • 2019-10-11
  • 2020-10-29
  • 1970-01-01
相关资源
最近更新 更多