Black screen in kivy

It has been 2 days that my kivy program have a black screen when I load it. The problem started when I tryed to add sound in the program starting, at first I tryed to use the kivy SoundLoader but the black screen apeared I tryed to get my old code back and surprise, it doesn’t work too. The serial is ok. Here’s the code:

import serial
from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.image import Image
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
from kivy.uix.textinput import TextInput
from kivy.lang import Builder
from kivy.uix.button import ButtonBehavior
from kivy.clock import Clock
from kivy.uix.gridlayout import GridLayout
from datetime import datetime
from kivy.core.audio import SoundLoader
import csv

class ImageButton(ButtonBehavior, Image):
    pass

def setup_serial():
    try:
        ser = serial.Serial(
            port='COM10',
            baudrate=9600,
            parity=serial.PARITY_NONE,
            stopbits=serial.STOPBITS_ONE,
            bytesize=serial.EIGHTBITS,
            timeout=1
        )
        return ser
    except serial.SerialException as e:
        print(f"Erro ao abrir a porta serial: {e}")
        return None

class MenuScreen(Screen):
    def goto_settings(self):
        self.manager.current = 'settings'

    def goto_settings2(self):
        self.manager.current = 'settings2'

    def goto_new_feature(self):
        self.manager.current = 'newfeature'

class SettingsScreen(Screen):
    def goto_settings3(self):
        modelo = self.ids.modelo_input.text
        sn = self.ids.sn_input.text
        if not modelo or not sn:
            self.ids.modelo_input.hint_text = "Campo Modelo é obrigatório!"
            self.ids.sn_input.hint_text = "Campo S/N é obrigatório!"
            return
        self.manager.get_screen('settings3').update_table(modelo, sn)
        self.manager.current = 'settings3'

    def goto_menu(self):
        self.manager.current = 'menu'

class SettingsScreen2(Screen):
    def goto_menu(self):
        self.manager.current = 'menu'

class SettingsScreen3(Screen):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.readings = []
        self.ser = None

    def update_table(self, modelo, sn):
        self.readings.append([modelo, sn, '', ''])
        self.refresh_table()

    def refresh_table(self):
        layout = self.ids.grid_layout
        layout.clear_widgets()
        for reading in self.readings:
            for value in reading:
                layout.add_widget(Label(text=value))

    def start_reading(self):
        self.ser = setup_serial()
        if self.ser:
            self.event = Clock.schedule_interval(self.read_serial, 1)
        else:
            print("Falha ao conectar à porta serial.")

    def read_serial(self, dt):
        if self.ser and self.ser.in_waiting > 0:
            try:
                serial_data = self.ser.readline().decode('utf-8').strip()
                data_list = serial_data.split(',')
                if len(self.readings) > 0:
                    self.readings[-1][2] = data_list[0] if len(data_list) > 0 else ''
                    self.readings[-1][3] = data_list[1] if len(data_list) > 1 else ''
                self.refresh_table()
            except Exception as e:
                print(f"Erro ao ler da serial: {e}")

    def stop_reading(self):
        if hasattr(self, 'event'):
            Clock.unschedule(self.event)
        if self.ser:
            self.ser.close()
            self.save_to_csv()

    def save_to_csv(self):
        with open('leituras.csv', mode='w', newline='') as file:
            writer = csv.writer(file)
            writer.writerow(['Modelo', 'S/N', 'Temperatura', 'Umidade'])
            writer.writerows(self.readings)

    def goto_menu(self):
        self.manager.current = 'menu'

    def goto_settings(self):
        self.manager.current = 'settings'

class NewFeatureScreen(Screen):
    def goto_menu(self):
        self.manager.current = 'menu'

kv_string = '''
#:kivy 2.1.0
<MenuScreen>:
    FloatLayout:
        Image:
            source: 'c:/Users/jor_d/OneDrive/Área de Trabalho/Códigos/frr.jpg'
            size_hint: (2, 2)
            pos_hint: {'center_x': 0.5, 'center_y': 0.5}
        Image:
            source: 'c:/Users/jor_d/OneDrive/Área de Trabalho/Códigos/Logo aut.png'
            size_hint: (1.5, 1.5)
            pos_hint: {'center_x': 0.5, 'center_y': 0.8}
        Button:
            text: 'Visualizar Arquivos'
            size_hint: (0.25, 0.1)
            pos_hint: {'center_x': 0.35, 'center_y': 0.4}
            background_color: (1, 1, 1, 1)
            color: (50 / 255, 50 / 255, 50 / 255, 1)
            on_press: root.goto_settings2()
        Button:
            text: 'Nova Leitura'
            size_hint: (0.25, 0.1)
            pos_hint: {'center_x': 0.65, 'center_y': 0.4}
            background_color: (1, 1, 1, 1)
            color: (50 / 255, 50 / 255, 50 / 255, 1)
            on_press: root.goto_settings()
        Button:
            text: 'Nova Função'
            size_hint: (0.25, 0.1)
            pos_hint: {'center_x': 0.5, 'center_y': 0.2}
            background_color: (1, 1, 1, 1)
            color: (50 / 255, 50 / 255, 50 / 255, 1)
            on_press: root.goto_new_feature()
        ImageButton:
            source: 'c:/Users/jor_d/OneDrive/Área de Trabalho/Códigos/4.png'
            size_hint: (0.1, 0.1)
            pos_hint: {'center_x': 0.06, 'center_y': 0.08}
            on_release: root.goto_new_feature()
        Label:
            text: 'TFJ V1.1'
            pos_hint: {'center_x': 0.95, 'center_y': 0.009}
            color: (0, 0, 0, 1)
<SettingsScreen>:
    FloatLayout:
        TextInput:
            id: modelo_input
            hint_text: 'Digite o Modelo'
            size_hint: (0.4, 0.1)
            pos_hint: {'center_x': 0.215, 'center_y': 0.9}
        TextInput:
            id: sn_input
            hint_text: 'Digite o S/N'
            size_hint: (0.4, 0.1)
            pos_hint: {'center_x': 0.215, 'center_y': 0.78}
        Button:
            text: 'Cadastrar'
            size_hint: (0.2, 0.1)
            pos_hint: {'center_x': 0.87, 'center_y': 0.1}
            background_color: (0, 1, 0, 1)
            on_press: root.goto_settings3()
        Button:
            text: 'Voltar'
            size_hint: (0.2, 0.1)
            pos_hint: {'center_x': 0.13, 'center_y': 0.1}
            on_press: root.goto_menu()
<SettingsScreen2>:
    FloatLayout:
        ImageButton:
            source: 'c:/Users/jor_d/OneDrive/Área de Trabalho/Códigos/sua_imagem.jpg'
            size_hint: (0.2, 0.1)
            pos_hint: {'center_x': 0.5, 'center_y': 0.6}
            on_release: root.goto_menu()
        Label:
            text: 'TFJ V1.0'
            pos_hint: {'center_x': 0.95, 'center_y': 0.009}
            color: (0, 0, 0, 1)
<SettingsScreen3>:
    FloatLayout:
        Image:
            source: 'c:/Users/jor_d/OneDrive/Área de Trabalho/Códigos/fa.webp'
            size_hint: (2, 2)
            pos_hint: {'center_x': 0.5, 'center_y': 0.5}
        GridLayout:
            id: grid_layout
            cols: 4
            size_hint: (0.6, 0.6)
            pos_hint: {'center_x': 0.5, 'center_y': 0.6}
            row_force_default: True
            row_default_height: 30
            spacing: 5
        Button:
            text: 'Iniciar Leitura'
            size_hint: (0.2, 0.1)
            pos_hint: {'center_x': 0.3, 'center_y': 0.1}
            background_color: (0, 1, 0, 1)
            on_press: root.start_reading()
        Button:
            text: 'Parar Leitura'
            size_hint: (0.2, 0.1)
            pos_hint: {'center_x': 0.7, 'center_y': 0.1}
            background_color: (1, 0, 0, 1)
            on_press: root.stop_reading()
        Button:
            text: 'Voltar'
            size_hint: (0.2, 0.1)
            pos_hint: {'center_x': 0.13, 'center_y': 0.1}
            on_press: root.goto_settings()
<NewFeatureScreen>:
    FloatLayout:
        Button:
            text: 'Voltar'
            size_hint: (0.2, 0.1)
            pos_hint: {'center_x': 0.13, 'center_y': 0.1}
            on_press: root.goto_menu()
'''

class TestApp(App):
    def build(self):
        sound = SoundLoader.load('c:/Users/jor_d/Downloads/ytmp3free.cc_microsoft-windows-2000-startup-sound-youtubemp3free.org.mp3')
        if sound:
            sound.play()
        sm = ScreenManager(transition=FadeTransition())
        sm.add_widget(MenuScreen(name='menu'))
        sm.add_widget(SettingsScreen(name='settings'))
        sm.add_widget(SettingsScreen2(name='settings2'))
        sm.add_widget(SettingsScreen3(name='settings3'))
        sm.add_widget(NewFeatureScreen(name='newfeature'))
        return Builder.load_string(kv_string)

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

Might it it be crashing?

Try writing messages in various places to a log file and also adding tryexcept blocks that write the exception to the log file and then maybe re-raise.

1 Like

I’ll try it thank you

You might want to make sure the sound file you passed to SoundLoader.load(‘:/Users/jor_d/Downloads/ytmp3free.cc_microsoft-windows-2000-startup-sound-youtubemp3free.org.mp3’) actually exists.
Maybe try temporarily removing SoundLoader and see if it works again.

Also since sound.play() blocks, you might want to try to play it in a non-blocking way:

def play_sound():
    sound = SoundLoader.load('c:/Users/jor_d/Downloads/ytmp3free.cc_microsoft-windows-2000-startup-sound-youtubemp3free.org.mp3')
    if sound:
        sound.play()

And then lattter call it this way:

Clock.schedule_once(lambda dt: play_sound(), 0) 

You also might want to try explicitly setting the current screen manager to ‘menu’:

sm.current = 'menu'  # Set initial screen explicitly