Reputation: 393
I'm currently trying to learn while using the Kivy GUI language. I'm trying to create a layout with different widget on it (button, file browser ...) with one of the button accessing a custom Setting panel to set some parameters and then a button to run a command using these parameters.
I'm having trouble to get the command button working and it is probably a simple object oriented problem but I can't see what's wrong. Any help would be greatly appreciated. Also if anyone have an idea how to use the command button ( btn) to access some of the values stored from the settings it would be great.
Here is my code so far:
# main.pyfrom kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.settings import SettingsWithSidebar
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.button import Button
from settingsjson import settings_json
Builder.load_string('''
<Interface>:
Button:
text: 'Analysis Settings'
pos_hint: {"x": 0.2, 'y': 0.3}
on_release: app.open_settings()
size_hint: 0.2, 0.2
''')
class Interface(FloatLayout): #
pass
class SettingsApp(App):
def build(self):
#Color setting#
blue = (0, 0, 1.5, 2.5)
self.settings_cls = SettingsWithSidebar
self.use_kivy_settings = False
setting = self.config.get('example', 'boolexample')
btn = Button(text='Run!',
background_color=blue,
size_hint=(.2, .2),
pos_hint={'x':.5, 'y':.3})
btn.bind(on_press=self.command1)
Interface.add_widget(Interface.btn)
return Interface()
def command1(self, event):
print("button touched")
def build_config(self, config):
config.setdefaults('example', {
'boolexample': True,
'numericexample': 10,
'optionexample': 'Analysis type1',
'stringexample': 'PO12345'})
def build_settings(self, settings):
settings.add_json_panel('Parameter of Analysis',
self.config,
data=settings_json)
def on_config_change(self, config, section,
key, value):
print config, section, key, value
SettingsApp().run()
settings.ini
[example]
boolexample = 1
optionexample = Analysis type1
stringexample = 46464, hdfhf, jhdgfjhf, hjdgfjhf
numericexample = 455
optionsexample = Analysis type2
import json
settings_json = json.dumps([
{'type': 'title',
'title': 'Analysis parameters'},
{'type': 'bool',
'title': 'Add accessin number list?',
'desc': 'Choose if you want to add an Accession list to your analysis',
'section': 'example',
'key': 'boolexample'},
{'type': 'numeric',
'title': 'Select maximum number of protei to display',
'desc': 'This will determine maximum protein displayed on graph',
'section': 'example',
'key': 'numericexample'},
{'type': 'options',
'title': 'Selection your Analysis option',
'desc': 'Choose for an analysis option',
'section': 'example',
'key': 'optionsexample',
'options': ['Analysis type1', 'Analysis type2', 'Analysis type3']},
{'type': 'string',
'title': 'Type specific accession number to display',
'desc': 'Type some accession numbers to display',
'section': 'example',
'key': 'stringexample'}])
Upvotes: 0
Views: 852
Reputation: 48649
I'm having trouble to get the command button working and it is probably a simple object oriented problem but I can't see what's wrong.
You wrote:
Interface.add_widget(Interface.btn)
Have a look at your Interface class--there's no btn
property defined anywhere. However, prior to that line you constructed a widget named btn
, so you should write:
Interface.add_widget(btn)
That leads to another error:
TypeError: unbound method add_widget() must be called with Interface instance as first argument (got Button instance instead)
When you call a method with a class name
, it's different than when you call a method with an instance
of the class:
class Dog:
def bark(self):
print('woof')
d = Dog()
d.bark()
Dog.bark()
--output:--
woof
Traceback (most recent call last):
File "main.py", line 9, in <module>
Dog.bark()
TypeError: unbound method bark() must be called with
Dog instance as first argument (got nothing instead) #<****HEY!
When you call bark() with an instance of the Dog class, python automatically passes the instance as the first argument to the method, which gets assigned to the variable self
. That doesn't happen when you call the method with the class.
To fix that error, you need to change the line:
Interface.add_widget(btn)
to:
i = Interface()
i.add_widget(btn)
Or, more tortuously:
class Dog:
def __init__(self):
print(self)
def bark(self):
print(self)
print('woof')
d = Dog()
Dog.bark(d) #<*** Manually pass an instance.
--output:--
woof
Upvotes: 1
Reputation: 48649
Also if anyone have an idea how to use the command button ( btn) to access some of the values stored from the settings it would be great.
The App class has a config property, which gives you access to all the settings:
class SettingsApp(App):
...
...
def onpress_button(self, button):
print "button touched"
config = self.config
print config.getint("example", "numericexample")
print config.getfloat("example", "numericexample")
print config.getboolean("example", "boolexample")
print config.get("example", "stringexample")
print config.getdefault("example", "non-existent", "hello")
print config.items('example')
--output:--
button touched
10
10.0
True
PO12345
hello
[('boolexample', 'True'), ('optionexample', 'Analysis type1'), ('stringexample', 'PO12345'), ('numericexample', '10')]
Check out the python docs for ConfigParser as well as the kivy docs for the Config object to see all the methods that are available.
Upvotes: 0