method() missing 1 required positional argument

0

Witam,

Czy ktoś mógłby mnie naprowadzić na rozwiązanie tego problemu?


class DetailsScreen(Screen):
    detailslabel = StringProperty()

    def change_text(self, detailslabel):
        if not os.path.isfile("details.pickle"):
            return detailslabel == 'Choose your details'
        else:
            return detailslabel == 'We have your details.'

    change_text(detailslabel)

TypeError: change_text() missing 1 required positional argument: 'detailslabel'

2

self jest pierwszym, detailslabel jest drugim argumentem.

1

Powinno być

self.change_text(detailslabel)
2

Żeby Ci zadziałała metoda Musisz mieć utworzony obiekt:

class Foo():
    val = "a"
    def change(self, val):
        return "Function changes is working"


bar = Foo()
print(bar.change(bar.val))
0

Ta klasa jest utworzona do screen managera, kiedy w kv wpisuje na przykład on_press: root.change_details wszystko działa. Chciałbym, żeby zawartość labela zmieniała się bez naciskania na buttony, żeby za każdym razem po odpaleniu screena, funkcja się wykonywała. Kod, który wysłałeś nie działa w tym przypadku. Obiekt musiałbym stworzyć ale wywołać go wewnątrz klasy.

0

To Musisz zmienić design, przecież nie można stworzyć obiektu klasy wewnatrz tej klasy, po prostu w przestrzeni nazw w środku klasy nie ma nazwy klasy.

0

Zrób tak, żeby klasa była zdefiniowana tak, żebyś w ja miał w przestrzeni nazw w miejscu gdzie Chcesz wykonać ten kod, czyli w tym samym module, albo w imporcie.

0

Yhm, zaimportowaną do modułu

0

Przy definicji klasy wszystko co jest po dwukropku

class MojaKlasa(...):
#....

Zostanie zdefiniowane i wywołane.
Dlatego change_text nie działa, bo jako instancję obiektu podajesz parametr detailslabel, a jako drugi parametr nic nie podajesz, a w funkcja wymaga dwóch pozycyjnych argumentów przez co masz błąd.

Na poziomie deklaracji klasy i jej interpretacji self jako instancja obiektu jeszcze nie istnieje.

0

Próbuje teraz zrobić to w ten sposób(fragment kodu), żeby label aktualizował się na bieżąco:


Builder.load_string('''

    DetailsLabel:
        id: detailslabel
        background_color:1, 0, 1, 1
        pos_hint: {'x': .4, 'y': .93}
        size_hint: .5, .3
        text_size: self.size

''')

class DetailsLabel(Label):


    def __init__(self, text):
        self.text = text

    def update_text(self):
        if not os.path.isfile("details.pickle"):
            return self.text == 'Wprowadz dane'
        else:
            return self.text == 'Mamy dane'


class MyApp(App):


    def build(self):
        labelclock = DetailsLabel()
        Clock.schedule_interval(labelclock.update_text, 1)
        return sm



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

TypeError: init() got an unexpected keyword argument '__no_builder'

Co tym razem jest nie tak z tą klasą?

0

Konstruktor oczekuje argumentu, Daj: labelclock = DetailsLabel("string").

0

Problem rozwiązany, pojawił się następny:
TypeError: init() missing 1 required positional argument: 'text'

:D ale w końcu się uda

0

Jaki dałeś argument do konstruktora, jest jakieś stack trace? Poka kod.

0

Cały kod? Trochę tego jest

0

Tak, jak ostatnio, tą klasę Detailslabel i jak ją Uruchamiasz.

0

Skróciłem do konkretów, skasowałem funkcje do saveowania inputu ze spinnerów.


import os
os.environ['KIVY_GL_BACKEND'] = 'angle_sdl2'


from kivy.app import App
import pickle
import os.path
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.image import Image
from kivy.properties import ObjectProperty
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.config import Config
from kivy.factory import Factory
from kivy.properties import ListProperty, ObjectProperty, BooleanProperty, StringProperty
from kivy.uix.dropdown import DropDown
from kivy.uix.spinner import Spinner
from kivy.clock import Clock
from kivy.base import runTouchApp
from kivy.uix.textinput import TextInput
from functools import partial





#Window configuration

Config.set('graphics', 'width', '400')
Config.set('graphics', 'height', '800')
Config.write()

#Kivy

Builder.load_string('''

<MainScreen>:
    MainLayout:
        canvas.before:
            BorderImage:
                border: 10, 10, 10, 10
                texture: self.background_image.texture
                pos: self.pos
                size: self.size
        size_hint: .99, .99
        pos_hint: {'center_x': .5, 'center_y': .5}
        
    Button: #  Details
        background_color:0, 0, 0, 0
        pos_hint: {'x': .03, 'y': .46}
        size_hint: .40, .20
        on_press:
            root.manager.current = 'Details'
            root.manager.transition.direction = "right"
            
            

    Button: #  Menu
        background_color:0, 0, 0, 0
        pos_hint: {'x': .55, 'y': .24}
        size_hint: .40, .20
        on_press:
            root.manager.current = 'Menu'
            root.manager.transition.direction = "left"

    Button: #  Max_weights
        background_color:0, 0, 0, 0
        pos_hint: {'x': .55, 'y': .46}
        size_hint: .40, .20
        on_press:
            root.manager.current = 'Max_weight'
            root.manager.transition.direction = "left"

            
    Button: #  About
        background_color:0, 0, 0, 0
        pos_hint: {'x': .55, 'y': .01}
        size_hint: .40, .20
        on_press:
            root.manager.current = 'About'
            root.manager.transition.direction = "left"
   
    Button: #  Sessions
        background_color:0, 0, 0, 0
        pos_hint: {'x': .03, 'y': .24}
        size_hint: .40, .20
        on_press:
            root.manager.current = 'Sessions'
            root.manager.transition.direction = "right"        

    Button: #  Timetable
        background_color:0, 0, 0, 0
        pos_hint: {'x': .03, 'y': .01}
        size_hint: .40, .20
        on_press:
            root.manager.current = 'Timetable'
            root.manager.transition.direction = "right"


<AboutScreen>
    AboutLayout:
        canvas.before:
            BorderImage:
                border: 10, 10, 10, 10
                texture: self.background_image.texture
                pos: self.pos
                size: self.size
        size_hint: .99, .99
        pos_hint: {'center_x': .5, 'center_y': .5}
    Button:
        pos_hint: {'x': .01, 'y': .90}
        size_hint: .50, .10
        background_color:0, 0, 0, 0
        on_press: 
            root.manager.current = "Main"
            root.manager.transition.direction = 'right'
   
    Button:
        text: 'Some very long line which will be cut'
        text_size: self.size
        pos_hint: {'x': .21, 'y': .20}
        size_hint: .50, .30
        

<DetailsScreen>:
    DetailsLayout:
        canvas.before:
            BorderImage:
                border: 10, 10, 10, 10
                texture: self.background_image.texture
                pos: self.pos
                size: self.size
        size_hint: .99, .99
        pos_hint: {'center_x': .5, 'center_y': .5}
    Button:
        pos_hint: {'x': .01, 'y': .90}
        size_hint: .50, .10
        background_color:0, 0, 0, 0
        on_press: 
            root.manager.current = "Main"
            root.manager.transition.direction = 'left'
    Spinner:
        id: spinner_sex
        pos_hint: {'x': .35, 'y': .65}
        size_hint: .30, .05
        background_color:0, 0, 0, 0
        text: '< Select >'
        values: ('Male', 'Female')
        on_text: root.save_input_spinner(spinner_sex.id, spinner_sex.text)
     
        
    Spinner:
        id: spinner_goal
        pos_hint: {'x': .35, 'y': .04}
        size_hint: .30, .05
        background_color:0, 0, 0, 0
        text: '< Select >'
        values: ('Strenght', 'Mass', 'Sculpture')
        on_text: root.save_input_spinner(spinner_goal.id, spinner_goal.text)
       
        
    Spinner:
        id: spinner_activity
        pos_hint: {'x': .35, 'y': .23}
        size_hint: .30, .05
        background_color:0, 0, 0, 0
        text: '< Select >'
        values: ('Bardzo', 'Aktywny', 'średni', 'nisko')
        on_text: root.save_input_spinner(spinner_activity.id, spinner_activity.text)
        
    
    SpinnerKg:
        id: spinner_kg
        pos_hint: {'x': .45, 'y': .45}
        size_hint: .1, .05
        text: '<Select>'
        background_color:0, 0, 0, 0
        on_text: root.save_input_spinner(spinner_kg.id, spinner_kg.text)
       
    
    Label:
        id: but
        background_color:1, 0, 0, 0
        text: 'Kg'
        text_size: self.size
        pos_hint: {'x': .6, 'y': .46}
        size_hint: .1, .05
        
    DetailsLabel:
        id: detailslabel
        background_color:1, 0, 1, 1
        pos_hint: {'x': .4, 'y': .93}
        size_hint: .5, .3
        text_size: self.size
        
        
        
        
       

<Max_weightScreen>:
    Max_weightLayout:
        canvas.before:
            BorderImage:
                border: 10, 10, 10, 10
                texture: self.background_image.texture
                pos: self.pos
                size: self.size
        size_hint: .99, .99
        pos_hint: {'center_x': .5, 'center_y': .5}
    Button:
        pos_hint: {'x': .01, 'y': .90}
        size_hint: .50, .10
        background_color:0, 0, 0, 0
        on_press: 
            root.manager.current = "Main"
            root.manager.transition.direction = 'right'


<SessionsScreen>:
    SessionsLayout:
        canvas.before:
            BorderImage:
                border: 10, 10, 10, 10
                texture: self.background_image.texture
                pos: self.pos
                size: self.size
        size_hint: .99, .99
        pos_hint: {'center_x': .5, 'center_y': .5}
    Button:
        pos_hint: {'x': .01, 'y': .90}
        size_hint: .50, .10
        background_color:0, 0, 0, 0
        on_press: 
            root.manager.current = "Main"
            root.manager.transition.direction = 'left'
            

<TimetableScreen>:
    TimetableLayout:
        canvas.before:
            BorderImage:
                border: 10, 10, 10, 10
                texture: self.background_image.texture
                pos: self.pos
                size: self.size
        size_hint: .99, .99
        pos_hint: {'center_x': .5, 'center_y': .5}
    Button:
        pos_hint: {'x': .01, 'y': .90}
        size_hint: .50, .10
        background_color:0, 0, 0, 0
        on_press: 
            root.manager.current = "Main"
            root.manager.transition.direction = 'left'

<MenuScreen>:
    MenuLayout:
        canvas.before:
            BorderImage:
                border: 10, 10, 10, 10
                texture: self.background_image.texture
                pos: self.pos
                size: self.size
        size_hint: .99, .99
        pos_hint: {'center_x': .5, 'center_y': .5}
    Button:
        pos_hint: {'x': .01, 'y': .90}
        size_hint: .50, .10
        background_color:0, 0, 0, 0
        on_press: 
            root.manager.current = "Main"
            root.manager.transition.direction = 'right'
    
''')

#Layout classes

class MainLayout(FloatLayout):

    background_image = ObjectProperty(
        Image(
            source='main1.jpg'))

class AboutLayout(FloatLayout):

    background_image = ObjectProperty(
        Image(
            source='aboutb.png'))

class AboutbLayout(FloatLayout):

    background_image = ObjectProperty(
        Image(
            source='about.png'))

class DetailsLayout(FloatLayout):

    background_image = ObjectProperty(
        Image(
            source='Details.png'))

class Max_weightLayout(FloatLayout):

    background_image = ObjectProperty(
        Image(
            source='max_weight.png'))

class SessionsLayout(FloatLayout):

    background_image = ObjectProperty(
        Image(
            source='sessions.png'))

class TimetableLayout(FloatLayout):

    background_image = ObjectProperty(
        Image(
            source='timetable.png'))

class MenuLayout(FloatLayout):

    background_image = ObjectProperty(
        Image(
            source='menu.png'))

#Screen classes

class MainScreen(Screen):
    pass


class AboutScreen(Screen):
    pass

class SpinnerKg(Spinner):
    values=(str(n) for n in range(40, 120))

class DetailsLabel(Label):



    def __init__(self, text, **kwargs):
        super().__init__(**kwargs)
        self.text = text

    def update_text(self):
        if not os.path.isfile("details.pickle"):
            return self.text == 'Wprowadz dane'
        else:
            return self.text == 'Mamy dane'


class DetailsScreen(Screen):
    pass



class Max_weightScreen(Screen):
    pass


class SessionsScreen(Screen):
    pass

class MenuScreen(Screen):
    pass


class TimetableScreen(Screen):
    pass


#Screen manager

sm = ScreenManager()
sm.add_widget(MainScreen(name='Main'))
sm.add_widget(AboutScreen(name='About'))
sm.add_widget(DetailsScreen(name='Details'))
sm.add_widget(Max_weightScreen(name='Max_weight'))
sm.add_widget(SessionsScreen(name='Sessions'))
sm.add_widget(MenuScreen(name='Menu'))
sm.add_widget(TimetableScreen(name='Timetable'))

#App class

class App(App):


    def build(self):
        crudeclock = DetailsLabel('string')
        Clock.schedule_interval(crudeclock.update_text, 1)
        return sm



if __name__ == '__main__':
    App().run()
1

konstruktor w klasie Detailslabel chce dwóch argumentów: text, **kwargs - zmiennej i słownika, a dajesz mu tylko jeden: crudeclock = DetailsLabel('string').

0

Jak w konstruktorze dam crudeclock = DetailsLabel(text, **kwargs) to mam unresolved reference, próbowałem tego wcześniej

1

Ehh, chyba Musisz powtórzyć materiał. Konstruktor oczekuje dwóch argumentów formalnych: jakiejś zmiennej, na przykład napisu, integera (Python jest dynamiczny); a drugi argument **kwargs - to skrót - w tym miejscu funkcja oczekuje, że Dasz jej słownik (inaczej hash, parę: klucz, wartość). https://docs.python.org/3/tutorial/datastructures.html#dictionaries

0

Dzięki, poczytam trochę i dalej będę kombinował.

0

Nie zauważyłem, brakuje jeszcze jednej gwiazdki:), jak Chcesz, żeby drugi argument rozwijał się do słownika, to wcześniejszy musi do listy, ewentualny jeszcze wcześniejszy argument mógłby być zmienną, wygląda to tak:

class Foo(object):
    def __init__(self, *args, **kwargs):
        self.field1 = args
        self.field2_dict = kwargs
    def f(self):
        return [self.field1, self.field2_dict]

arg = ["some-string", 90, 100]
dict1 = {"GIt87": 'coder', 'lion137': 'coder2', '4programmers': 'social_network'}
x = Foo(arg, dict1)
print(x.f()) # -> [(['some-string', 90, 100], {'GIt87': 'coder', 'lion137': 'coder2', '4programmers': 'social_network'}), {}]

Pierwszy argument rozwija sie do listy (może być listą, może być zmienna, lub może go nie być), a drugi do słownika, jak nie będzie on[drugi argument] parą: klucz, wartość, to *args "zje" wszystko i self.field2 zwróci pusty dict. Poeksperymentuj z różnymi danymi i initami, ale parametry formalne mogą być tylko w takich wariantach:

 def f(arg1, *args, **kwargs)
 def f(*args, **kwargs)   
 def f(**kwargs)
 def f(arg1, *args)    
 def f(*args)

Więcej: Wyszukiwarka i "**kwargs python".

0

Nie Musisz dawać "na siłę" słownika, skoro tam jest **kwargs, to pewnie jest potrzebny.

0

Chcę tylko, żeby funkcja zwróciła mi odpowiednią wartość zmiennej "text", do której odnosi się Label i żeby ta funkcja wywoływała się co sekundę. Napisałem funkjcę savujące dane obliczone na postawie inputu ze spinnerów a ta najprostsza mi coś nie idzie. Ma tylko sprawdzić czy jest plik details.pickle i na tej podstawie zwrócić jedną z 2 wartości Nic więcej. Twój wcześniejszy wpis przeanalizowałem, bardzo dziękuję, posprawdzałem w innym pliku z różnymi danymi - działa, ale ta najprostsza funkcja dalej nie działa.

0

To po prostu Napisz funkcję od jednego argumentu formalnego:

    def f(arg):
        # TODO
0

#kv:

DetailsLabel:
        id: detailslabel
        background_color:1, 0, 1, 1
        pos_hint: {'x': .4, 'y': .93}
        size_hint: .5, .3
        text_size: self.size
        text: str(root.text)


#python:

class DetailsLabel(Label):
        text = StringProperty

        def update_text(text):
        return 'works!'

class App(App):


    def build(self):
        x = DetailsLabel()
        Clock.schedule_interval(x.update_text, 1)
        return sm

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


#kv:

DetailsLabel:
        id: detailslabel
        background_color:1, 0, 1, 1
        pos_hint: {'x': .4, 'y': .93}
        size_hint: .5, .3
        text_size: self.size
        text: str(root.text)


#python:

class DetailsLabel(Label):
        text = StringProperty

        def update_text(self, text):
        return 'works!'

class App(App):


    def build(self):
        x = DetailsLabel()
        Clock.schedule_interval(x.update_text, 1)
        return sm

program działa ale w miejscu labela wyświetla mi się kivy properties.StringProperty

0

Popraw: def update_text(self, text)
I Clock.shcedule_interval(x.update_text(<some string variable here>), 1)

0

#kv:
 
DetailsLabel:
        id: detailslabel
        background_color:1, 0, 1, 1
        pos_hint: {'x': .4, 'y': .93}
        size_hint: .5, .3
        text_size: self.size
        text: str(root.text)
 
#python:
 
class DetailsLabel(Label):
        text = StringProperty
 
        def update_text(self, text):
        return 'works!'
 
class App(App):
 
    def build(self):
        x = DetailsLabel()
        Clock.schedule_interval(x.update_text('some string'), 1)
        return sm

ValueError: callback must be a callable, got works!

0

To to nie wiem, Kivy nie znam.

0

Jak coś wymyśle to dam znać.

0

Da się zrobić funkcję która ustawia odpowiedni string w text, później zapisuje ją lub zmienia wcześniej zapisaną w pickle/json i wczytuje jeszcze raz okno ładując przy okazji nowy text. Można ją przypisać do każdego możliwego w tym ekranie buttona, spinnera. Niestety Clock na razie mi nie działa.

1 użytkowników online, w tym zalogowanych: 0, gości: 1