简体   繁体   中英

Radiobutton, command is not working (python)

So the problem is that when I press radiobuttons, nothing changes - their command is not processed. I always get the result as it would be if radio2 , and radio4 are pressed. Please help!

# -*- 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

Defining button commands

The problem starts here:

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

You are asking python to run the command self.a(-1) at the time you create the button , and the assign the result of that function to the command attribute. The command attribute requires a reference to a function, not a call to a function.

The short answer is, do command=lambda: self.a(-1) . There are other alternatives (eg: functools.partial ), but this is the simplest, and doesn't require any other functions or imported modules. When you call lambda , you are asking it to return a reference to a new (unnamed, or anonymous ) function. You are asking that, when that function runs, it should call self.a(-1) . This function then gets assigned to the command attribute.

Laying out your widgets

You have another problem on the same line of code, so I'll address it here, too. When you do this:

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

... what happens is the RadioButton instance is created, the place method is called, and then the result of the place command is assigned to redio1 . place (and grid , and pack ) all return None . Thus, redio1 (and redio2 and redio3 and ...) are all set to None .

If you want to keep a handle to your widgets, you must create them and lay them out in two separate statements. Beyond the fact that your variables won't be None , this also makes your code easier to modify, if you put all of your layout code together in a block. In my experience, layout changes a lot more during development than the core widgets, so having that all together makes it easier to visualize and modify.

For example, I would organize the code like this:

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

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

Geometry Managers

Finally, let me give you one more piece of advice: don't use place . It makes your GUI harder to write and maintain, and makes it much harder to give your GUI proper behavior when the window is resized or when people have different fonts or resolutions. place is useful in very rare situations, but for the most part you should learn to use pack and/or grid .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM