Search code examples
pythonkivykivymd

TypeError: add_widget() missing 1 required positional argument: 'widget' kivy


am trying to create a simple housing mobile application that takes data from the user stores them in mysql database and retrieve the data and display the output.i was able to insert the data to the database but am unable .`

from kivy.core.window import Window
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager
from kivymd.app import MDApp
from kivymd.uix.button import MDFlatButton
from kivymd.uix.dialog import MDDialog
from kivymd.uix.label import MDLabel
from plyer import filechooser
import mysql.connector

Window.size = (310, 580)


class Galaxy(MDApp):
    dialog = None

    def build(self):
        mydb = mysql.connector.connect(
            host="localhost",
            user="root",
            passwd="password123",
            database="housing_details"

        )
        c = mydb.cursor()
        c.execute("CREATE DATABASE IF NOT EXISTS housing_details")

        c.execute("""CREATE TABLE if not exists test_two(
                  rental VARCHAR(100) NOT NULL, 
                  location VARCHAR(100),
                  photo LONGBLOB,
                  price INT NOT NULL, 
                  cont_info INT NOT NULL,
                  more_info VARCHAR(255))""")
        mydb.commit()
        mydb.close()

        global screen_manager

        screen_manager = ScreenManager()
        screen_manager.add_widget(Builder.load_file("Galaxy.kv"))
        screen_manager.add_widget(Builder.load_file("login.kv"))
        screen_manager.add_widget(Builder.load_file("entry.kv"))
        screen_manager.add_widget(Builder.load_file("selection.kv"))
        screen_manager.add_widget(Builder.load_file("single.kv"))

        return screen_manager

    def file_chooser(self):
        filechooser.open_file(on_selection=self.selected)

    def selected(self, selection):
        if selection:
            self.root.get_screen('login').ids.img.source = selection[0]

    def submit(self, **kwargs):
        mydb = mysql.connector.connect(
            host="localhost",
            user="root",
            passwd="password123",
            database="housing_details"

        )
        c = mydb.cursor()
        # assigning variable to kivy ids
        rental = self.root.get_screen('login').ids.my_textinput.text
        location = self.root.get_screen('login').ids.text_location.text
        price = self.root.get_screen('login').ids.text_price.text
        cont_info = self.root.get_screen('login').ids.text_cont.text
        more_info = self.root.get_screen('login').ids.text_more.text
        BinaryData = self.root.get_screen('login').ids.img.source

        sql_command = 'INSERT INTO test_two(rental,location,photo,price,cont_info,more_info) VALUES(%s,%s,%s,%s,%s,%s)'
        values = (rental, location, BinaryData, price, cont_info, more_info)

        c.execute(sql_command, values)
        # clearing the input area
        self.root.get_screen('login').ids.my_textinput.text = ''
        self.root.get_screen('login').ids.text_location.text = ''
        self.root.get_screen('login').ids.text_price.text = ''
        self.root.get_screen('login').ids.text_cont.text = ''
        self.root.get_screen('login').ids.text_more.text = ''
        self.root.get_screen('login').ids.img.source = ''
        # pop-up notification for successful upload of details
        if not self.dialog:
            self.dialog = MDDialog(
                title="successfully uploaded",
                buttons=[
                    MDFlatButton(text="CANCEL", on_release=self.close_dialog)
                ],
            )
        self.dialog.open()

        """"# retrieving uploaded details from the database
        # assign variable to kivy ids
        rental_lbl = self.root.get_screen('single').ids.rental.text
        location_lbl = self.root.get_screen('single').ids.location.text
        price_lbl = self.root.get_screen('single').ids.price.text
        contact_lbl = self.root.get_screen('single').ids.contact.text
        info_lbl = self.root.get_screen('single').ids.info.text
        image = self.root.get_screen('single').ids.image.source

        mydb.commit()
        mydb.close()"""

    def close_dialog(self, obj):
        self.dialog.dismiss()

    def show_records(self):
        screen_manager.current = "single"
        mydb = mysql.connector.connect(
            host="localhost",
            user="root",
            passwd="password123",
            database="housing_details"

        )
        c = mydb.cursor()
        c.execute('SELECT * FROM test_two')

        myresults = c.fetchall()

        for x in myresults:
            self.root.get_screen('single').ids.card_load.add_widget(
                label=MDLabel(text='safe space')
            )
            self.root.get_screen('single').ids.rental.text = x[0]


        mydb.commit()
        mydb.close()


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

in (show_records) function am trying to iterate through the MDcard in the .kv file to output the retrieved data but i keep getting an error

  line 127, in show_records
     self.root.get_screen('single').ids.card_load.add_widget(
 TypeError: add_widget() missing 1 required positional argument: 'widget'

not the best screen to display am still working on it. i want the card to display the outcome

MDScreen:
  name: "single"

  ScrollView:
    MDFloatLayout:
      md_bg_color:1,1,1,1
      MDIconButton:
        icon:"arrow-left"
        pos_hint:{"center_y":.95}
        user_font_size:"30sp"
        theme_text_color:"Custom"
        text_color:rgba(26,24,58,255)
        on_release:
          root.manager.transition.direction= "right"
          root.manager.current="login"

      MDGridLayout:
        rows:1
        cols:1
        adaptive_height: True
        id:grid
        MDCard:
          id:card_load
          radius:25
          size_hint_y:None
          height:"450"
          padding:"20dp"
          md_bg_color:1,1,1,1
          MDBoxLayout:
            orientation:"vertical"
            Image:
              size_hint_y:None
              id:image
              height:"200"
              pos_hint:{"center_y":.7}
            MDBoxLayout:
              orientation:"horizontal"
              MDBoxLayout:
                orientation:"vertical"
                MDLabel:
                  text:"RENTAL"
                MDLabel:
                  text:"LOCATION:"
                MDLabel:
                  text:"PRICE:"
                MDLabel:
                  text:"CONTACT:"
              MDBoxLayout:
                orientation:"vertical"
                MDLabel:
                  text:""
                  id:rental
                MDLabel:
                  text:""
                  id: location
                MDLabel:
                  text:""
                  id:price
                MDLabel:
                  text:""
                  id:contact

            MDLabel:
              text:""
              id:info



Solution

  • change:

            self.root.get_screen('single').ids.card_load.add_widget(
                label=MDLabel(text='safe space')
            )
    

    to:

            self.root.get_screen('single').ids.card_load.add_widget(
                MDLabel(text='safe space')
            )
    

    When you use a statement like label=MDLabel(text='safe space'), there is nothing returned, so the add_widget() method does not get its required widget.