user12833369
user12833369

Reputation:

TypeError: Function takes 1 positional argument but 2 were given kivy python

I tried to add instance after the self, but still not working

this is the error message

File "kivy\_event.pyx", line 703, in kivy._event.EventDispatcher.dispatch

File "kivy\_event.pyx", line 1214, in kivy._event.EventObservers.dispatch

File "kivy\_event.pyx", line 1138, in kivy._event.EventObservers._dispatch

TypeError: sss() takes 1 positional argument but 2 were given

here is the full kivy python code

import kivy

from kivy.uix.widget import Widget

from kivy.properties import ObjectProperty

from kivy.app import App

from kivy.uix.label import Label

from kivy.uix.gridlayout import GridLayout

from kivy.uix.textinput import TextInput

from kivy.uix.button import Button

from kivy.uix.screenmanager import ScreenManager, Screen



class Touch(Widget):

    def __init__(self, **kwargs):

        super(Touch, self).__init__(**kwargs)

        self.cols = 1

        self.Rc1 = Button(text="Submit", font_size=40)

        self.Rc1.bind(on_press=self.sss)

        self.add_widget(self.Rc1)


    def sss(self):

        self.Rc1 = Button(text="Push Me !",

                          font_size="20sp",

                          background_color=[1, 0, 0, 1],

                          color=(1, 1, 1, 1),

                          size=(32, 32),

                          size_hint=(.2, .2),

                          pos=(300, 250))

class MyApp(App):

    def build(self):

        return Touch()


if __name__ == "__main__":

    MyApp().run()

Upvotes: 1

Views: 3692

Answers (1)

furas
furas

Reputation: 143197

When you click button then it executes your function with some information. In different GUIs it can use different information. In some GUIs it can be info about event, in others it can be info about widget, etc.

Kivy sends information about clicked widget and you have to receive it

def sss(self, widget):

If you want to change existing Button then don't create new button - it will not change existing if you assing it to the same variable. You would have to remove old button and add new button using add_widget()

You have existing button in self.Rc1 so you can do

def sss(self, widget):
    self.Rc1.text = "Push Me !"
    self.Rc1.font_size = "20sp"
    self.Rc1.background_color = [1, 0, 0, 1]
    self.Rc1.color = (1, 1, 1, 1)
    self.Rc1.size = (32, 32)
    self.Rc1.size_hint = (.2, .2)
    self.Rc1.pos = (300, 250)

But more interesting is that you get also this widget in sss(self, widget): and you can do

def change_button(self, widget):
    widget.text = "Push Me !"
    widget.font_size = "20sp"
    widget.background_color = [1, 0, 0, 1]
    widget.color = (1, 1, 1, 1)
    widget.size = (32, 32)
    widget.size_hint = (.2, .2)
    widget.pos = (300, 250)

This way you can use the same function with different buttons

enter image description here

import kivy
from kivy.uix.widget import Widget
from kivy.app import App
from kivy.uix.button import Button


class Touch(Widget):

    def __init__(self, **kwargs):
        super(Touch, self).__init__(**kwargs)
        
        #self.all_buttons = []
        
        for row in range(10):
            for col in range(10):
                x = col * 100
                y = row * 100
                button = Button(text=f"{row},{col}", pos = (x, y))
                button.bind(on_press=self.change_button)
                
                self.add_widget(button)
                
                #self.all_buttons.append(button)

    def change_button(self, widget):
        if widget.background_color == [1,1,1,1]:
            widget.background_color = [1, 0, 0, 1]
        else:
            widget.background_color = [1, 1, 1, 1]


class MyApp(App):

    def build(self):
        return Touch()

if __name__ == "__main__":
    MyApp().run()

Upvotes: 3

Related Questions