Groups keyboard shortcuts have been updated
Dismiss
See shortcuts

Kivy not Responsing

62 views
Skip to first unread message

Peanut

unread,
Dec 1, 2024, 3:57:35 AM12/1/24
to Kivy users support
Hello, I have this code where if I press the button and there is some processing happening, the app starts to crash if I do anything, like pressing the button and then starting to type numbers in the text field. How can I fix this?

```Kivy 2.3.0
Kivymd 1.1.1
request 2.32.2```

import time
from kivy.lang import Builder
import requests
from kivymd.app import MDApp


class Example(MDApp):
    def build(self):
        # Define the KV layout as a string
        self.kv = """
MDFloatLayout:
    MDCard:
        orientation: "vertical"
        size_hint: None, None
        size: "350dp", "300dp"
        pos_hint: {"center_x": 0.5, "center_y": 0.5}
        padding: 25
        spacing: 25
        radius: [20, 20, 20, 20]

        # Mobile Number Input Field
        MDTextField:
            mode: "round"
            id: mobile_number
            hint_text: "9xxxxxxxxx"
            helper_text: "Must be 10-digit only"
            helper_text_mode: "on_focus"
            icon_right: "cellphone"
            input_type: "number"
            max_text_length: 10
            size_hint_x: 1

        # Login Button
        MDFillRoundFlatButton:
            text: "Login"
            size_hint_x: 0.5
            pos_hint: {"center_x": 0.5}
            on_release: app.send_mobile_number()
        """
        return Builder.load_string(self.kv)

    def send_mobile_number(self):
        mobile_number = self.root.ids.mobile_number.text

        api_url = "api_here"
        time.sleep(5)
        payload = {"mobile_number": mobile_number}

        # Send POST request
        try:
            # response = requests.post(api_url, json=payload)
            # print(response.json())
            print("Mobile Number:", mobile_number)
        except requests.exceptions.RequestException as e:
            print("Error:", e)

    def on_leave(self):
        self.root.ids.mobile_number.text = ""


# Run the app
Example().run()

Peanut

unread,
Dec 1, 2024, 4:04:54 AM12/1/24
to Kivy users support

I added this video for more clarity.
2024-12-01 17-02-26.mp4

ElliotG

unread,
Dec 1, 2024, 7:51:05 PM12/1/24
to Kivy users support
The problem is the call to time.sleep().  Kivy is an event based system.  The events are handled in the main event loop.  The main loop is started when you call run.  Your functions generally return to the event loop.  When you use sleep on the main thread, you are stalling the event loop - so things lock up.
There is a description of the event loop (or main loop) is here: https://kivy.org/doc/stable/guide/events.html

I also recommend you use kivy's URL request rather than requests.  It is non blocking and uses callbacks.  See: https://kivy.org/doc/stable/api-kivy.network.urlrequest.html#module-kivy.network.urlrequest
If you want to create a delay you need to schedule the next event on the event loop.  Use Clock.schedule_once, see: https://kivy.org/doc/stable/api-kivy.clock.html#module-kivy.clock

I hope this helps.  Understanding the main loop is critical to understanding how kivy works.

Peanut

unread,
Dec 5, 2024, 9:33:37 AM12/5/24
to Kivy users support
Hello ElliotG, the Kivy URLRequest works perfectly. I have been reading about events, properties in Kivy, and also the Kivy Clock. Do you have any examples in terms of code? I’ll be using this in a scenario where I need to wait for a response from hardware.  Let’s say I need to wait for a response from hardware, which takes around 5 seconds for processing and response.

ELLIOT GARBUS

unread,
Dec 5, 2024, 11:15:19 AM12/5/24
to kivy-...@googlegroups.com
Please explain more about the api to check the hw.   Is it non-blocking?  Can you check if the hardware is ready?  If so you could schedule use schedule_interaval to poll the hardware and see if it is ready.
If reading the hw is blocking and you want to schedule reading the hw after you know it will be ready, use schedule_once.

Think about it like this the schedule_once method of Clock is putting a function on a list.  Inside the kivy run loop, kivy is checking the schedule to see it if is time to run the call back.  When the time is up, the callback is executed.

If you'd like to see an example, provide more details on the hw, and I'll share a short example.


From: kivy-...@googlegroups.com <kivy-...@googlegroups.com> on behalf of Peanut <gvnnd...@gmail.com>
Sent: Thursday, December 5, 2024 6:33 AM
To: Kivy users support <kivy-...@googlegroups.com>
Subject: [kivy-users] Re: Kivy not Responsing
 
--
You received this message because you are subscribed to the Google Groups "Kivy users support" group.
To unsubscribe from this group and stop receiving emails from it, send an email to kivy-users+...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/kivy-users/e7d3172f-d200-46fc-ab99-262f148c5570n%40googlegroups.com.

Peanut

unread,
Dec 5, 2024, 12:07:36 PM12/5/24
to Kivy users support
  Here is an example of code that needs to wait before I can get a response. This happens while scanning. The problem is that if I click something while a paper is being scanned, the app freezes.  

    def check_scan_complete(self):
        """Check if the scan is complete."""
        # Add a small delay (e.g., 50ms) before checking the scan status
        time.sleep(0.05)
       
        start_time = time.time()  # Start time for measuring execution duration
        try:
            # Call the ScanIsComplete function to check if scanning is done
            scan_complete = scanner_api.ScanIsComplete()
           
            # Measure elapsed time
            elapsed_time = time.time() - start_time
           
            # Check if the call took too long
            if elapsed_time > 0.1:  # Ensure it completes within 100ms
                self.show_message("Scan completion check took too long.")
                return False
           
            self.show_message(f"Scan complete status: {scan_complete}")
            return scan_complete  # Returns true if scanning is complete
        except Exception as e:
            self.show_message(f"Error in ScanIsComplete: {str(e)}")
            return False

ElliotG

unread,
Dec 5, 2024, 1:50:35 PM12/5/24
to Kivy users support
There are 2 things you will to change.
1) To achieve your initial pause, instead of a sleep split the method into 2 parts.  Something like:

def check_scan_complete(self):
    Clock.schedule_once(_continue_check_scan_complete, 0.05)

def _continue_scan_complete(self, dt):
    ...the code to read your scanner...

2) In order to have the scan execute concurrently with the event loop, you will want to put the scan into a seperate thread.   
The docs are good reference material, but dense.  The first examples should be helpful: https://pymotw.com/3/threading/index.html
Reply all
Reply to author
Forward
0 new messages