2014-02-04 3 views
0

Так что проблема в том, что когда я нажимаю радиокнопки, ничего не меняется - их команда не обрабатывается. Я всегда получаю результат так, как если бы были нажаты radio2 и radio4. Пожалуйста помоги!Radiobutton, команда не работает (python)

# -*- coding: cp1250 -*- 

import numpy as np 
from scipy.optimize import minimize 
import Tkinter 

class numerika(Tkinter.Tk): 

def __init__(self, parent): 
    Tkinter.Tk.__init__(self, parent) 
    self.parent = parent 
    self.title('Optimizacija funkcije') 
    self. geometry('500x300') 
    self.uvjeti = ({'type': 'ineq', 'fun': lambda x: np.array([-x[0]-2*x[1]+4.0])}, 
        {'type': 'ineq', 'fun': lambda x: np.array([-4*x[0] - 2*x[1] +12.0])}, 
        {'type': 'ineq', 'fun': lambda x: np.array([x[0]-x[1]+1.0])}, 
        {'type': 'ineq', 'fun': lambda x: np.array([x[0]])}, 
        {'type': 'ineq', 'fun': lambda x: np.array([x[1]])}) 
    self.initialize() 


def initialize(self): 

    label1 = Tkinter.Label(self, text = u'Ovaj kod može izračunavati globalne ekstreme ravnine:').place(x = 10, y = 10) 
    label2 = Tkinter.Label(self, text = u'z = x1 +x2,').place(x = 70, y = 30) 
    label3 = Tkinter.Label(self, text = u'za zadane uvjete:').place(x = 70, y = 50) 
    label4 = Tkinter.Label(self, text = u'x1+2*x2 <= 4, 4*x1+2*x2 <= 12, -x1+x2 <= 1, x1 >= 0, x2 >= 0.').place(x = 70, y = 70) 
    label5 = Tkinter.Label(self, text = u'Odaberi tip ekstrema:').place(x = 10, y = 110) 
    label6 = Tkinter.Label(self, text = u'Odaberi metodu solvera:').place(x = 200, y = 110) 

    redio1 = Tkinter.Radiobutton(self, text = 'Maksimum', value = 1, variable = 1, command = self.a(-1)).place(x = 30, y = 140) 
    radio2 = Tkinter.Radiobutton(self, text = 'Minimum', value = 2, variable = 1, command = self.a(1)).place(x = 30, y = 170) 

    radio3 = Tkinter.Radiobutton(self, text = 'COBYLA', value = 3, variable = 2, command = self.b('COBYLA')).place(x = 220, y = 140) 
    radio4 = Tkinter.Radiobutton(self, text = 'SLSQP', value = 4, variable = 2, command = self.b('SLSQP')).place(x = 220, y = 170) 

    dugmic1 = Tkinter.Button(self, text = u'Izračunaj!', height = 3, bd = 3, command = self.racunaj).place(x = 390, y = 140) 

def racunaj(self): 
    rj = minimize(self.f, [1.0, 1.0], method = self.m, constraints = self.uvjeti) 
    self.rj = rj 

def f(self,x): 
    x1 = x[0] 
    x2 = x[1] 
    return self.k*(x1+x2) 

def a(self, k): 
    self.k = k 


def b(self, m): 
    self.m = m 


app=numerika(None)  

app.mainloop() 



print app.rj 

ответ

1

Определение кнопки команд

Проблема начинается здесь:

redio1 = Tkinter.Radiobutton(..., command = self.a(-1)...) 

Вы просите питона запустить команду self.a(-1)в момент создания кнопки и правопреемником результат этой функции с атрибутом command. Атрибут command требует ссылки на функцию, а не на вызов функции.

Короткий ответ, сделайте command=lambda: self.a(-1). Существуют и другие альтернативы (например: functools.partial), но это самый простой и не требует каких-либо других функций или импортированных модулей. Когда вы вызываете lambda, вы просите его вернуть ссылку на новую (неназванную или анонимную) функцию. Вы просите, чтобы при запуске этой функции он должен был позвонить self.a(-1). Затем эта функция назначается атрибуту command.

Разметка виджеты

У вас есть еще одна проблема на той же строке кода, так что я обращусь здесь, тоже. Когда вы сделаете это:

redio1 = Tkinter.Radiobutton(...).place(...) 

... что происходит, создается экземпляр RadioButton, метод place называется, а затем результат команды место присваивается redio1. placegrid, и pack) все возврат None. Таким образом, redio1redio2 и redio3 и ...) установлены на None.

Если вы хотите сохранить дескриптор своих виджетов, вы должны создать их и разложить в два отдельных оператора. Помимо того факта, что ваши переменные не будут None, это также упростит ваш код, если вы поместите весь свой код макета в блок. По моему опыту, макет меняет гораздо больше во время разработки, чем основные виджеты, поэтому совместное использование упрощает визуализацию и модификацию.

К примеру, я бы организовать такой код:

label1 = Tkinter.Label(...) 
label2 = Tkinter.Label(...) 
... 
dugmic1 = Tkinter.Button(...) 

label1.place(...) 
label2.place(...) 
label3.place(...) 
... 

Геометрия Менеджеры

Наконец, позвольте мне дать вам еще один совет: не используйте place. Это затрудняет работу с вашим графическим интерфейсом и делает его более сложным, чтобы дать правильное поведение вашего GUI при изменении размера окна или когда у людей разные шрифты или разрешения. place полезен в очень редких ситуациях, но по большей части вы должны научиться использовать pack и/или grid.

Смежные вопросы