Я делаю приложения графического интерфейса для работы много. Основная идея состоит в том, чтобы привязать одну функцию к каждой кнопке, но с каждой кнопкой передать другую переменную.
Вот полный пример для 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 не позволяет передавать аргументы в функции. Вы можете обойти это ограничение, выполнив то, что говорит Флориан Бош на 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")
в месте, где вы обычно подключить кнопку к функции)
идея здесь, независимо от модуля графического интерфейса, используемого, чтобы связать одну функцию для всех ваших известково ulator и просто передайте другое значение для каждой кнопки.
Предполагаю, вы делаете что-то вроде калькулятора? Я не уверен, что вы подразумеваете под значением кнопки, поскольку кнопки не могут удерживать значения, но если вы имеете в виду использование номера с каждой кнопки номера, просто настройте функцию обратного вызова, которая соединяется с сигналом 'clicked', тогда инициализируйте свои переменные статическим числом, жестко закодированным в каждом обратном вызове. – oldtechaa
Итак, я добавил функцию для кнопки с числом «2». Нужно ли инициализировать переменные в этой функции? Или я ошибаюсь? И btw да, я работаю над калькулятором. –
это будет работать. Вы также можете использовать свой первоначальный план и просто установить 'self.first_num' в два, когда эта кнопка будет нажата. Ответ выглядит так, как будто он должен работать. Я не использую Python, поэтому у меня нет опыта в Iambdas Python. – oldtechaa