Widgets Position not Fixed in APK file - python

I am new to kivy and i am very confuse to set the position of the widgets for mobile apllication
As i am using default size of the desktop window screen, In that widgets position look goods and in a proper allignment
i have attached PNG file of window screen and mobile screen
but when i use this in android apk file and installed in mobile, then all position of widgest are messed up and not looks to good for visibillity
so how to adjust the size and postion of widgets for android apk file
from kivymd.app import MDApp
from kivy.lang import Builder
from kivymd.uix.screen import MDScreen
from kivy.uix.screenmanager import ScreenManager
KV = ('''
<LOGIN_Window>:
name: 'login_window1'
FloatLayout:
MDToolbar:
title: 'permit me'
elevation: 10
pos_hint: {"left": 1, "top": 1}
MDLabel:
text: 'Welcome to permit me'
font_size: '35sp'
size: self.size
pos: self.pos
pos_hint: {'x': 0.21, 'y': 0.65}
size_hint_y: '0.35dp'
size_hint_x: '0.50dp'
BoxLayout:
orientation: 'vertical'
pos_hint: {'x': .25, 'y': 0.65}
size_hint: None, None
size_hint: '0.6dp', '0.08dp'
MDLabel:
text: 'Email-ID'
font_size: '15sp'
height: self.texture_size[1] + dp(10)
MDTextFieldRound:
id: login
hint_text: 'For Eg:- XXY...#gmail.com'
icon_left: "email"
input_type: 'text'
MDBoxLayout:
orientation: 'horizontal'
pos_hint: {'x':.25, 'y':4}
spacing: '50dp'
MDFillRoundFlatButton:
id: logIn
text: 'Login'
MDFillRoundFlatButton:
text: 'Register'
MDLabel:
text:'Powered By Technology'
pos_hint : {'x': 0,'y': 0}
size_hint_y: None
height: self.texture_size[1] + dp(10)
WindowManager:
LOGIN_Window:
'''
)
class LOGIN_Window(MDScreen):
pass
class WindowManager(ScreenManager):
pass
class MainApp(MDApp):
def build(self):
return Builder.load_string(KV)
if __name__ == '__main__':
MainApp().run()

Related

KivyMD MDRectangleFlatIconButton's text is in two lines when text is updated with a long text

I want to update MDRectangleFlatIconButton's text. It changes with a new text but when the new text is longer than previous text, then the text fits in two lines.
When i use a normal button, the new text fits in one line with proper adjustment.
but Since there is a Icon in MDRectangleFlatIconButton, when a new text is longer than previous text, the text fits in a two line.
To run the program,
Add a new app name which is longer than "Info" inside "Info" button's popup window, then click "Update Top Bar's name". Then, it updated title and the text of "Info" button at the front main App.
I have tried to change this by adding button's text_size: self.width, valign:"center", haling: "center", or manually adding text_size: cm(10), cm(10).
Also, i tried with on_release: "app.root.ids.bt_information.text_size = self.width, None
but nothing works so far.
I greatly appreciate your help.
Python code
'''
from kivy.uix.widget import Widget
'''Setting the size of first window for program'''
from kivy.config import Config #another way of setting size of window
Config.set('graphics', 'width', '600') # from kivy.core.window import Window
Config.set('graphics', 'height', '750') # Window.size = ("600", "750")
from kivymd.app import MDApp
from kivy.lang import Builder
from kivy.factory import Factory
from kivy.uix.popup import Popup
from kivy.properties import ObjectProperty
Builder.load_file('new_window_popup.kv')
class Dex(Popup):
pass
class Remi(Popup):
pass
class Info(Popup):
pass
class MyLayout(Widget):
pass
class AwesomeApp(MDApp):
def build(self):
self.title = "My house"
return MyLayout()
if __name__ == '__main__':
AwesomeApp().run()
'''
kivyfile: new_window_popup.kv
'''
#:import Factory kivy.factory.Factory
#:import MDRaisedButton kivymd.uix.button
<Dex>:
auto_dismiss: False
size_hint: 1, 1
title: "Weight-Based Dose Calculator "
canvas.before:
Color:
rgba: (0,1,0,1)
Rectangle:
pos:self.pos
size:self.size
BoxLayout:
orientation: "vertical"
size:root.width, root.height
Label:
text: "Dex 1"
Button:
text: "Close"
font_size: 24
on_release: root.dismiss()
<Remi>:
auto_dismiss: False
size_hint: 1, 1
title: "Weight-Based Dose Calculator "
canvas.before:
Color:
rgba: (0,1,0,1)
Rectangle:
pos:self.pos
size:self.size
BoxLayout:
orientation: "vertical"
size:root.width, root.height
Label:
text: "Remi"
Button:
text: "Close"
font_size: 24
on_release: root.dismiss()
<Info>:
appName:appName
auto_dismiss: False
size_hint: 1, 1
title: "Change Info"
canvas.before:
Color:
rgba: (0,1,0,1)
Rectangle:
pos:self.pos
size:self.size
BoxLayout:
orientation: "vertical"
size:root.width, root.height
Label:
text: "What is your App name?"
BoxLayout:
orientation: "horizontal"
MDTextField:
id: appName
hint_text: "App Name"
color_mode: 'primary'
current_hint_text_color: 1,1,1,1
hint_text_color_focus: 1,1,1,.9
line_color_focus: 1,1,1,1
font_size: '25sp'
text_color_normal: 1,1,1,.9
text_color_focus: 0,0,1,.9
focus: True
write_tab: False
Button:
text: "Update Top Bar\'s name"
font_size: 24
size_hint: .8, .2
# on_release: root.updateName()
on_release:
app.title = appName.text
app.root.ids.bt_information.text = appName.text
Button:
text: "Close"
font_size: 24
on_release: root.dismiss()
<MyLayout>
MDBoxLayout:
orientation:"vertical"
size: root.width, root.height
MDRaisedButton:
text: "Dex"
font_size: 32
text_color: 0,0,0,.9
size_hint: 1,.5
on_press: Factory.Dex().open()
MDRaisedButton:
text: "Remi"
font_size: 32
size_hint: 1,.5
on_press: Factory.Remi().open()
MDRectangleFlatIconButton:
id: bt_information
text: "Info"
icon: "youtube-studio"
font_size: 32
size_hint: 1,.2
text_size: self.width, None
md_bg_color: 0.95,0.61,0.73,1
on_press: Factory.Info().open()
'''

Take user input from Kivy App and append to google sheets using Python

I'm trying to make a simple Python Kivy app (using a kv file for the layout) that I will use to keep inventory of my parts for work. I am very new to python and kivy, so I need a little bit of direction on this.
One of the basic functions will be to allow the user to input a new part on the "Add Part to Inventory" screen (one of four screens). The user input consists of four items (part name, serial number, on-hand quantity, and the minimum amount needed).
Once the user enters this info and presses the 'Submit' button, I would like that data to be appended to a new row in a google sheet that I'm using as a backend database using the Google Drive/Sheets API (which I was able to get working).
Most of the example apps that I've found online only have one screen, and are only dealing with one type of user input (usually text, whereas my input will be text and integers).
I'm confused as to where I need to put my ids in the kv file (I'm assuming under the AddPartWindow layout), how to call a function when a button is pressed that is not in the root class, how to store the user input into a list since I'm not sure what the ObjectProperty function is really doing, and finally, how to append that list to a new row in my google sheet.
I'm not looking for a cut and paste answer, just some direction would be nice as I have not been able to find a good reference for exactly what I'm trying to do. My main confusion lies in having multiple screens, and how to transfer data between the different screens and their respective classes. Should data only be funneled through a single root class? Or can each class be used to handle data coming from their respective screens (windows) in the app? What exactly is the ObjectProperty function doing? I find the kivy website to be a bit convoluted when describing the properties class.
Any help/direction woud be greatly appreciated.
Here is the main.py code:
import kivy
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.core.window import Window
from kivy.uix.button import Button
from kivy.properties import ObjectProperty
import gspread
from oauth2client.service_account import ServiceAccountCredentials
scope = ['https://www.googleapis.com/auth/drive']
creds = ServiceAccountCredentials.from_json_keyfile_name('My_First_Project-3d753d98320e.json', scope)
client = gspread.authorize(creds)
iQue_sheet = client.open("InventoryBackend").sheet1
#root layout
class InventoryWindow(Screen):
pass
#Layout in question
class AddPartWindow(Screen):
#Is there anything else I need to do with these before saving into a list or dictionary?
part_name = ObjectProperty(None)
serial_number = ObjectProperty(None)
on_hand_cnt = ObjectProperty(None)
min_needed = ObjectProperty(None)
#This function should save the user input into a list, np, and then append to the google sheet iQue_sheet
#Wasn't sure if it should be a list or a dictionary.
#I'm assuming .text is type-casting each object to a string. Can this be used for numerical inputs?
def new_part(self):
np = [self.part_name.text, self.serial_number.text, self.on_hand_cnt.text, self.min_needed.text]
iQue_sheet.append(np)
class OnOrderWindow(Screen):
pass
class OrderFormWindow(Screen):
pass
class WindowManager(ScreenManager):
pass
class InventoryApp(App):
def build(self):
#These are used to enable going back and forth between screens using buttons
sm = ScreenManager()
sm.add_widget(InventoryWindow(name='inv_window'))
sm.add_widget(OnOrderWindow(name='on_order_window'))
sm.add_widget(AddPartWindow(name='add_part_window'))
sm.add_widget(OrderFormWindow(name='order_form_window'))
return sm
if __name__ == "__main__":
InventoryApp().run()
Here is the my .kv file for the layout, the Add Part window is the last layout towards the end:
WindowManager:
InventoryWindow:
OnOrderWindow:
OrderFormWindow:
AddPartWindow:
<ItemLabel#Label>
font_size: '15sp'
halign: 'left'
valign: 'middle'
text_size: self.size
<ItemButton#Button>
pos_hint: {'center_x':0.5, 'center_y':0.5}
size_hint: 0.65, 0.2
<ItemButton2#Button>
pos_hint: {'center_x':0.5, 'center_y':0.5}
size_hint: 0.65, 0.2
on_release:
app.root.current = "order_form_window"
<InventoryWindow>:
name: "inv_window"
add_probe: add_probe
FloatLayout:
Label:
text: 'Inventory'
font_size: '25sp'
size_hint: (1, 0.17)
pos_hint: {'x': 0, 'y': 0.87}
GridLayout:
cols: 4
padding:[10, 65, 10, 10]
spacing: 5
BoxLayout:
orientation: 'vertical'
ItemLabel:
text:'iQue3: Probe/Tubing'
BoxLayout:
orientation: 'vertical'
ItemButton:
text:'Add'
on_release:
root.new_part()
BoxLayout:
orientation: 'vertical'
ItemButton:
text:'Sub'
BoxLayout:
orientation: 'vertical'
ItemButton2:
text:'Order'
BoxLayout:
orientation: 'vertical'
ItemLabel:
text:'Gen2: Probe/Tubing'
BoxLayout:
orientation: 'vertical'
ItemButton:
text:'Add'
BoxLayout:
orientation: 'vertical'
ItemButton:
text:'Sub'
BoxLayout:
orientation: 'vertical'
ItemButton2:
text:'Order'
BoxLayout:
orientation: 'vertical'
ItemLabel:
text:'Beads'
BoxLayout:
orientation: 'vertical'
ItemButton:
text:'Add'
BoxLayout:
orientation: 'vertical'
ItemButton:
text:'Sub'
BoxLayout:
orientation: 'vertical'
ItemButton2:
text:'Order'
BoxLayout:
orientation: 'vertical'
ItemLabel:
text:'iQue3 Fluid Maint. Kit'
BoxLayout:
orientation: 'vertical'
ItemButton:
text:'Add'
BoxLayout:
orientation: 'vertical'
ItemButton:
text:'Sub'
BoxLayout:
orientation: 'vertical'
ItemButton2:
text:'Order'
BoxLayout:
orientation: 'vertical'
ItemLabel:
text:'Screener Fluid Maint. Kit'
BoxLayout:
orientation: 'vertical'
ItemButton:
text:'Add'
BoxLayout:
orientation: 'vertical'
ItemButton:
text:'Sub'
BoxLayout:
orientation: 'vertical'
ItemButton2:
text:'Order'
BoxLayout:
orientation: 'vertical'
GridLayout:
cols: 2
size_hint: 1, 0.15
padding: [10, 0, 10, 10]
BoxLayout:
Button:
text: 'Add Part to Inventory'
font_size: '18sp'
size_hint: (1, 0.75)
on_release:
app.root.current = "add_part_window"
root.manager.transition.direction = "right"
Button:
text: 'On Order'
font_size: '18sp'
size_hint: (1, 0.75)
on_release:
app.root.current = "on_order_window"
root.manager.transition.direction = "left"
<OnOrderWindow>:
name: "on_order_window"
FloatLayout:
Label:
text: 'On Order'
font_size: '25sp'
size_hint: (1, 0.17)
pos_hint: {'x': 0, 'y': 0.87}
GridLayout:
cols: 2
size_int: 1, .15
padding:[10, 510, 10, 10]
Button:
text: "Inventory"
font_size: '18sp'
size_hint: (1, 0.6)
on_release:
app.root.current = "inv_window"
root.manager.transition.direction = "right"
Button:
text:"Add Part to Inventory"
size_hint: (1, 0.6)
font_size: '18sp'
on_release:
app.root.current = "add_part_window"
root.manager.transition.direction = "left"
<OrderFormWindow>
name: "order_form_window"
FloatLayout:
Label:
text: 'Order Form'
font_size: '25sp'
size_hint: (1, 0.17)
pos_hint: {'x': 0, 'y': 0.87}
GridLayout:
cols:2
padding: [50, 50, 50, 120]
ItemLabel:
text: "Part: "
ItemLabel:
text: "Populate Part Here"
ItemLabel:
text: "Serial Number: "
ItemLabel:
text: "Populate SN Here"
ItemLabel:
text: "On Hand: "
ItemLabel:
text: "Populate On Hand Count Here"
ItemLabel:
text: "Minimum Needed: "
ItemLabel:
text: "Populate Min Needed Here"
ItemLabel:
text: "Order Quantity"
TextInput:
halign: 'left'
valign: 'middle'
input_type: 'number'
input_filter: 'int'
multiline:False
GridLayout:
cols:2
size_hint: 1, 0.15
padding: [10, 0, 10, 10]
Button:
text:"Cancel"
on_release: app.root.current = "inv_window"
Button:
text:"Submit Order"
on_release: app.root.current = "on_order_window"
#This is the add part screen layout I'm referring to
<AddPartWindow>
name: "add_part_window"
#These are the id's I was referring to:
part_name: part_name
serial_number: serial_number
on_hand_cnt: on_hand_cnt
min_needed: min_needed
FloatLayout:
Label:
text: 'Add Part to Inventory'
font_size: '25sp'
size_hint: (1, 0.17)
pos_hint: {'x': 0, 'y': 0.86}
GridLayout:
cols:2
padding: [50, 100, 50, 120]
spacing: 5
ItemLabel:
text: "Name of Part: "
TextInput:
id: part_name
halign: 'left'
valign: 'middle'
multinline:False
ItemLabel:
text: "Serial Number: "
TextInput:
id: serial_number
halign: 'left'
valign: 'middle'
multiline:False
ItemLabel:
text: "How Many On Hand?: "
TextInput:
id: on_hand_cnt
halign: 'left'
valign: 'middle'
multinline:False
ItemLabel:
text: "Minimum Needed?: "
TextInput:
id: min_needed
halign: 'left'
valign: 'middle'
multiline:False
GridLayout:
cols:2
size_hint: 1, 0.15
padding: [10, 0, 10, 10]
Button:
text:"Cancel"
on_release:
app.root.current = "inv_window"
root.manager.transition.direction = "left"
#Here is the button I'm referring to, I realize that putting "root." in front of new_part() is not
#the correct thing to put, so it's a placeholder for now:
Button:
text:"Submit"
on_release:
root.new_part()
app.root.current = "inv_window"
root.manager.transition.direction = "left"
Here is a screen shot of the Add Part Screen
The current error I'm getting when I enter input into the four fields and click on the Submit button is this:
File "C:\Users\edr27\kivy_venv\lib\site-packages\kivy\uix\behaviors\button.py", line 179, in on_touch_up
self.dispatch('on_release')
File "kivy\_event.pyx", line 705, in kivy._event.EventDispatcher.dispatch
File "kivy\_event.pyx", line 1248, in kivy._event.EventObservers.dispatch
File "kivy\_event.pyx", line 1132, in kivy._event.EventObservers._dispatch
File "C:\Users\edr27\kivy_venv\lib\site-packages\kivy\lang\builder.py", line 57, in custom_callback
exec(__kvlang__.co_value, idmap)
File "C:\Users\edr27\PycharmProjects\pythonProject\inventory.kv", line 345, in <module>
root.new_part()
File "C:\Users\edr27\PycharmProjects\pythonProject\main.py", line 35, in new_part
np = [self.part_name.text, self.serial_number.text, self.on_hand_cnt.text, self.min_needed.text]
AttributeError: 'NoneType' object has no attribute 'text'
Edit:
Here is how I implemented Oussama's answer in order to get this to work, all I had to do was update the AddPartWindow class:
class AddPartWindow(Screen):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.np = []
def submit(self):
self.part_name = self.ids.part_name.text
self.serial_number = self.ids.serial_number.text
self.on_hand_cnt = self.ids.on_hand_cnt.text
self.min_needed = self.ids.min_needed.text
self.np = [self.part_name, self.serial_number, self.on_hand_cnt, self.min_needed]
iQue_sheet.append_row(self.np)
I also made this change in order to append to sheet 3 of the workbook instead of sheet 1:
iQue_sheet = client.open("InventoryBackend").get_worksheet(2)
this main.py feel free to import what u need. this a simple example of what u want to do
from kivy.uix.button import Button
from kivy.uix.textinput import TextInput
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.lang import Builder
from kivy.app import App
Builder.load_file('the.kv')
class fscreen(widget):
def __init__(self, **kwargs):
supper().__init__(**kwargs)
self.np = []
def submit(self):
self.part_name = self.ids.Pname.text
self.serial_number = self.ids.Snumber.text
self.on_hand_cnt = self.ids.onhabdcnt.text
self.min_needed = self.ids.minneeded.text
self.np = [self.part_name, self.serial_number, self.on_hand_cnt, self.min_needed]
iQue_sheet.append(self.np)
class secscreen(widget):
def __init__(self, **kwargs):
supper().__init__(**kwargs)
pass
class thscreen(widget):
def __init__(self, **kwargs):
supper().__init__(**kwargs)
pass
class theapp(App):
def build(self):
self.screenm = ScreenManager()
self.screen = Screen(name = "first screen")
screen.add_widget(self.fscreen)
self.screenm.add_widget(screen)
if __name__ = "__main__":
theapp.run()
this is the.kv file
<fscreen>
TextInput:
id: Pname
hint_text: 'partname'
TextInput:
id: Snumber
hint_text: 'serialnumber'
TextInput:
id: onhandcnt
hint_text: 'on hand cnt'
TextInput:
id: minneeded
hint_text: 'min nedded'
Button:
text: 'Submit'
on_press: root.submit()

use of ScreenManager in Kivy file and python file

I'm new to Kivy, I'm working on a tracking app for vehicle repair and I've got a list of appointments and I'm trying to go to a different screen when you press an item on the list and I I have no clue on why it isn't working for me as it says that it is on a different screen but it isn't on the app
from kivymd.app import MDApp
from kivy.lang.builder import Builder
from kivymd.uix.list import ThreeLineAvatarIconListItem
from kivymd.uix.list import ImageLeftWidget
from kivy.uix.screenmanager import Screen, ScreenManager, SwapTransition, CardTransition
from kivy.core.window import Window
import sqlite3
DatabaseConnection = sqlite3.connect('CarWorkshopDB.db')
cursor = DatabaseConnection.cursor()
Window.size= (400, 650)
class MainScreen(Screen):
pass
class AddScreen(Screen):
pass
class DetailsScreen(Screen):
pass
class WorkApp(MDApp):
def build(self):
self.screen_manager = ScreenManager(transition=CardTransition())
self.screen_manager.add_widget(MainScreen(name='MainScreen'))
self.screen_manager.add_widget(AddScreen(name='AddScreen'))
self.screen_manager.add_widget(DetailsScreen(name='DetailsScreen'))
screen = Builder.load_file("test2.kv")
return screen
def on_start(self):
client = 'John smith'
cursor.execute("SELECT TrackingNumber, Plate, Status FROM Appointments WHERE Customer =?", (client,))
for i in cursor:
self.new_message(i[0], i[1], i[2])
def new_message(self, TrackingNumber, Vehicle, Process):
new_message = ThreeLineAvatarIconListItem(text=TrackingNumber, secondary_text=Vehicle, tertiary_text=Process)
new_message.add_widget(ImageLeftWidget(source='RepairIMG.jpg'))
new_message.bind(on_release=self.on_touch_down)
self.root.ids.list.add_widget(new_message)
def on_touch_down(self, x):
print(self.screen_manager.current)
self.screen_manager.current = "DetailsScreen"
self.screen_manager.transition.direction = 'right'
print(self.screen_manager.current)
WorkApp().run()
this is the list code in the kv file
NavigationLayout:
ScreenManager:
id: screen_manager
MainScreen:
name : "MainScreen"
BoxLayout:
orientation:'vertical'
MDBottomNavigation:
panel_color: 1, .643, 0, 1
MDBottomNavigationItem:
name: 'screen 1'
text: 'Home'
icon: 'alpha-h-circle'
MDToolbar:
title: 'Add Repair'
md_bg_color: 1, .643, 0, 1
elevation: 6
pos_hint: {'top':1}
Widget:
MDBottomNavigationItem:
name: 'screen 2'
text: 'Track'
icon: 'alpha-t-circle'
MDToolbar:
id: toolbar
title: 'Track History'
md_bg_color: 1, .643, 0, 1
elevation: 6
pos_hint: {'top':1}
NavigationLayout:
x: toolbar.height
size_hint_y: 1.0 - toolbar.height/root.height
ScreenManager:
Screen:
name: 'ScrollViewScreen'
ScrollView:
MDList:
id: list
MDFloatingActionButton:
icon: 'plus'
md_bg_color: 1, .643, 0, 1
on_release:
screen_manager.current = 'AddScreen'
screen_manager.transition = CardTransition()
screen_manager.transition.direction = "down"
pos_hint: {'x': .84, 'y': .02}
MDBottomNavigationItem:
name: 'screen 4'
text: 'More'
icon: 'dots-horizontal'
MDToolbar:
title: 'More'
md_bg_color: 1, .643, 0, 1
elevation: 6
pos_hint: {'top':1}
Widget:
MDLabel:
text: 'dfsfdsf'
halign: 'center'
AddScreen:
name: 'AddScreen'
id: Add
FloatLayout:
orientation: 'vertical'
MDToolbar:
id: toolbar2
title: 'Add Tracking Number'
md_bg_color: 1, .643, 0, 1
elevation: 6
pos_hint: {'top':1}
MDIconButton:
icon : 'close'
pos_hint : {'top':0.98, 'x':0.85}
on_release :
screen_manager.current = "Main"
screen_manager.transition = CardTransition()
screen_manager.transition.direction = "up"
FloatLayout:
x: toolbar2.height
size_hint_y: 1.0 - toolbar.height/root.height
ScatterLayout:
MDLabel:
text: 'Track Repair'
font_style: 'H4'
valign: 'top'
pos_hint: {'top':1}
text_size: self.size
size_hint: None, None
MDTextFieldRound:
icon_left: 'alpha-t-circle'
hint_text: 'Tracking Number'
normal_color: 1, .643, 0, 1
pos_hint: {'y':.7}
text_size: self.size
MDTextFieldRound:
icon_left: 'alpha-p-circle'
hint_text: 'Postcode'
normal_color: 1, .643, 0, 1
pos_hint: {'y':.6}
text_size: self.size
MDTextButton:
text: "Cant find your tracking number?"
custom_color: 1, .643, 0, 1
pos_hint: {'y':.5}
halign: 'center'
MDRectangleFlatButton:
text: 'confirm'
pos_hint: {'y':.4}
valign: 'middle'
text_size: self.size
DetailsScreen:
name: 'DetailsScreen'
id: Details
BoxLayout:
orientation: 'vertical'
MDLabel:
text: 'details Screen?'
The problem is that in your build() method you are building a widget tree in the lines:
self.screen_manager = ScreenManager(transition=CardTransition())
self.screen_manager.add_widget(MainScreen(name='MainScreen'))
self.screen_manager.add_widget(AddScreen(name='AddScreen'))
self.screen_manager.add_widget(DetailsScreen(name='DetailsScreen'))
But this widget tree is not used in your GUI. The widget tree in your GUI is built from the kv file by:
screen = Builder.load_file("test2.kv")
When your code tries to change the current Screen by using:
self.screen_manager.current = "DetailsScreen"
it is changing the current Screen of a ScreenManager that is not in your GUI.
A fix is to assign the correct value to self.screen_manager, like this:
class WorkApp(MDApp):
def build(self):
screen = Builder.load_file("test2.kv")
self.screen_manager = screen.ids.screen_manager
return screen

kivymd text field stills shows the hint_text in the field after typing

I am having trouble with MDTextField. It carries on displaying the hint inside the textfield while typing. I have tried setting the background color to hide it but that didn't work. I have looked at a few tutorials and everyone seems to be doing it the same way as me and it just works for other people so i feel i have done something really wrong.
Image of what happens this is my first post so i am not aloud to post images :)
Any help will be greatly appreciated. Thanks in advance.
main.py
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.floatlayout import FloatLayout
from kivy.core.window import Windowfrom kivy.config import Config
from kivy.uix.screenmanager import ScreenManager, Screen
from kivymd.theming import ThemeManager
from kivy.lang import Builder
from kivymd.app import MDApp
from kivy.graphics import Rectangle, Color
import pymysql
class WelcomeScreen(Screen):
pass
class LoginScreen(Screen):
pass
class RegisterScreen(Screen):
pass
class WindowManager(ScreenManager):
pass
class MainApp(MDApp):
def build(self):
# theme_cls = ThemeManager()
return Builder.load_file("main.kv")
def change_screen(self, screen, direction):
self.root.transition.direction = direction
self.root.current = screen
if __name__ == "__main__":
MainApp().run()
main.kv
#: import Window kivy.core.window.Window
#: import MDLabel kivymd.uix.label.MDLabel
#: import Rectangle kivy.graphics.Rectangle
#: import Color kivy.graphics.Rectangle
WindowManager:
WelcomeScreen:
LoginScreen:
RegisterScreen:
<WelcomeScreen>:
name: "welcome_screen"
FloatLayout:
orientation: "vertical"
MDToolbar:
id: toolbar
title: "SecureIT 24/7"
pos_hint: {'top': 1}
Button:
text: 'Login'
color: 1, 1, 1, 1
size_hint: 0.25, 0.25
pos_hint: {"right":0.625, "top":0.80}
on_release:
app.root.current = "login_screen"
Button:
text: 'Register'
color: 1,1,1,1
size_hint: 0.25, 0.25
pos_hint: {"right":0.625, "top":0.55 }
on_release:
app.root.current = "register_screen"
<LoginScreen>:
name: "login_screen"
FloatLayout:
MDBanner:
id: banner
text: "Login"
# The widget that is under the banner.
# It will be shifted down to the height of the banner.
MDToolbar:
id: toolbar
title: "Login"
elevation: 10
pos_hint: {'top': 1}
left_action_items: [['arrow-left', lambda screen: app.change_screen('welcome_screen', 'right')]]
FloatLayout:
padding: [50,50,50,50]
spacing: 50
FloatLayout:
orientation: 'vertical'
Label:
text: 'Login'
font_size: 18
halign: 'center'
text_size: root.width-20, 20
color: 0,0,0,1
pos_hint: {"right":1, "top":1.25}
TextInput:
id: login
multiline:False
font_size: 28
size_hint: 0.50, 0.10
pos_hint: {"right":0.75, "top":0.70}
FloatLayout:
orientation: 'vertical'
Label:
text: 'Password'
halign: 'center'
font_size: 18
text_size: root.width-20, 20
color: 0,0,0,1
TextInput:
id: password
multiline:False
password:True
font_size: 28
size_hint: 0.50, 0.10
pos_hint: {"right":0.75, "top":0.45}
Button:
text: 'Login'
size_hint: 0.25, 0.25
font_size: 24
pos_hint: {"right":0.625, "top":0.30}
<WhiteLabel#MDLabel>
height: self.texture_size[1]
theme_text_color: "Custom"
text_color: 1, 1, 1, 1
<CustomInput#MDTextField>
multiline:False
# required: True
mode: "line"
pos_hint: {"right": 0.456}
current_hint_text_color: [0,0,0,0.5]
<RegisterScreen>:
name: "register_screen"
FloatLayout:
MDBanner:
id: banner
text: "ioshrdioaoisdhf"
MDToolbar:
id: toolbar
title: "Register"
elevation: 10
pos_hint: {'top': 1}
left_action_items: [['arrow-left', lambda screen: app.change_screen('welcome_screen', 'right')]]
BoxLayout:
orientation: "vertical"
height: self.minimum_height * 2
size_hint_y: None
pos_hint: {"top": 2}
CustomInput:
id: firstname
hint_text: "color_mode = 'custom'"
CustomInput:
id: surname
hint_text: 'Surname'
CustomInput:
id: email
hint_text: 'Email'
By naming your kv file as main.kv, you are taking advantage of the automatic loading of correctly named kv files as described in the documentation. However, you are also loading the same file using Builder.load_file("main.kv"). Loading the same kv file more than once can cause the sort of problems you are seeing. You can fix your problem by simply eliminating the call to Builder.load_file("main.kv"), or removing the entire build() method, or by changing the name of either the kv file or the MainApp class.

Kivy Multiple Screen Transitions not taking place

I am trying to builng a multiple screen kivy app in python. There are no compile time errors. App Compiles successfully. I am using Screen Manager in kivy to achieve multiple screens. On clicking the buttons no transitions are taking place. Please help me perform transitions. Here are actual snippets of my code.
main.py file
import kivy
from kivy.app import App
from kivy.app import ObjectProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmamager import ScreenManager, Screen
class LoginScreen(Screen):
pass
class SignUpScreen(Screen):
pass
class MainScreen(BoxLayout):
pass
class MyScreenManager(ScreenManager):
pass
class AuthenticationApp(App):
def build(self):
return MyScreenManager()
if __name__ == '__main__':
AuthenticationApp().run()
Authentication.kv file
<MyScreenManager>
MainScreen:
SecondScreen:
<SecondScreen>:
name: 'Second'
BoxLayout:
orientation: 'vertical'
canvas:
Rectangle:
source: 'images/blue.png'
pos: self.pos
size: self.size
BoxLayout:
orientation: 'vertical'
size_hint: 1,0.25
Label:
text: 'Vigilantdsjkadhakjshdakjsd Dollop'
font_size: '15sp'
size_hint: 1, 0.20
BoxLayout:
orientation: 'horizontal'
size_hint: 1, 0.1
Button:
id: login_button
text: 'Login'
font_size: '15sp'
on_release: app.root.current = 'Main'
Button:
id: login_button
text: 'Sign Up'
font_size: '15sp'
Button:
id: login_button
text: 'Recover'
font_size: '15sp'
Button:
id: login_button
text: 'Reset'
font_size: '15sp'
BoxLayout:
orientation: 'vertical'
size_hint: 1,0.75
Button:
text: 'Page'
<MainScreen>:
name: 'Main'
BoxLayout:
orientation: 'vertical'
canvas:
Rectangle:
source: 'images/blue.png'
pos: self.pos
size: self.size
BoxLayout:
orientation: 'vertical'
size_hint: 1,0.25
Label:
text: 'Vigilant Dollop'
font_size: '15sp'
size_hint: 1, 0.20
BoxLayout:
orientation: 'horizontal'
size_hint: 1, 0.1
Button:
id: login_button
text: 'Login'
font_size: '15sp'
Button:
id: login_button
text: 'Sign Up'
font_size: '15sp'
on_press: root.current = 'Second'
Button:
id: login_button
text: 'Recover'
font_size: '15sp'
Button:
id: login_button
text: 'Reset'
font_size: '15sp'
BoxLayout:
orientation: 'vertical'
size_hint: 1,0.75
Button:
text: 'Page'
declare the screen manager a global variable
import kivy
from kivy.app import App
from kivy.app import ObjectProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmamager import ScreenManager, Screen
screen_manager = ScreenManager()
class LoginScreen(Screen):
pass
and return the screen_manager instance in the build method.
class AuthenticationApp(App):
def build(self):
screen_manager.add_widget(LoginScreen(name='login'))
return sceen_manager
then in your .kv file any where you want to switch between screens. try for example:
Button:
id: login_button
text: 'Login'
font_size: '15sp'
on_release: root.manager.current = 'login'

Categories

Resources