AttributeError: 'Third_Window' object has no attribute 'history' - python-3.x

I am a beginner and i am trying to do a password saver app. In this i am getting a error like AttributeError: 'Third_Window' object has no attribute 'history'.
And i also want how to Label a text that is inside a file
In .py file
from kivy.app import App
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.properties import ObjectProperty
from kivy.core.window import Window
from kivy.lang import Builder
Window.clearcolor = 0, 0, 1, 0
class Second_Window(Screen):
pass
class Third_Window(Screen):
def btn2(self):
global history
file1 = open('users_input.txt', 'r')
Lines = file1.readlines()
for line in Lines:
print("{}".format(line.strip()))
self.history = ""
self.history += "{}".format(line.strip())
print(history)
class Screen_Manager(ScreenManager):
pass
class Main_Window(Screen):
pass
presentation = Builder.load_file("password_saver.kv")
class Password_Saver(App):
def build(self):
return presentation
if __name__ == "__main__":
Password_Saver().run()
In .kv file
Screen_Manager:
Main_Window:
Second_Window:
Third_Window:
<Main_Window>:
name: 'main'
<Second_Window>:
name: 'second'
<Third_Window>:
name: 'third'
GridLayout:
cols: 1
Label:
text: root.history
Button:
text: "Go Back"
on_release:
root.btn2()
app.root.current = 'main'
Please help me to solve this issue
Thanks!!

In kivy file you are using root.history. root in that part of your kv file is third screen. To access something frpm .py file use app. instead of root..

Related

Kivy ScreenManager: App stopped running after trying to add 2nd Window

I was building an app for my thesis and it worked so far quite well while using only one window. Now I was trying to add other windows for e.g. instructions. I was following the documentation for screen Manager and some examples for apps and tried to add my 2nd window alike. But somehow it fails to identifiy the ScreenManager class in my kv.file. Maybeyou can help out, I'm not sure what I'm missing.
main py: Peenomat.py
import kivy
# -*- coding: iso-8859-1 -*-
from kivy.app import App
from kivy.uix.button import Label
from kivy.uix.widget import Widget
from kivy.uix.textinput import TextInput
from kivy.lang import Builder
from kivy.uix.anchorlayout import AnchorLayout
from kivy.core.text import LabelBase
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import BooleanProperty
from kivy.properties import ObjectProperty
#additional .kv files used to speciffy layout and functions of peenomat.kv
Builder.load_file('Header.kv')
Builder.load_file('Statusbar.kv')
Builder.load_file('Inputparameters.kv')
Builder.load_file('Outputparameters.kv')
pm = Builder.load_file('peenomat.kv')
#Layout
"""
class Peenomat(AnchorLayout):
pass
"""
class Peenomat(Screen):
pass
class Instruction(Screen):
pass
class WindowManager(ScreenManager):
pass
#App
class PeenomatApp(App):
def build(self):
return pm
if __name__=="__main__":
PeenomatApp().run()
and the minimalized .kv file
peenomat.kv:
WindowManager:
Peenomat:
Instruction:
<Peenomat>
name: "peenomat"
AnchorLayout:
anchor_x: 'left'
anchor_y: 'bottom'
GridLayout:
cols: 1
Header:
id:
size_hint:
InputParameters:
id:
size_hint:
StatusBar:
id:
size_hint:
OutputParameters:
id:_
size_hint:
<Instruction>:
name: "instruction"
Button:
text: "Verstanden!"
on_release:
app.root.current = "main"
root.manager.transition.direction = "right"
So like I said the App worked before adding the Screen and ScreenManager classes and I'm getting the error:
Traceback (most recent call last):
File "C:/Users/schum/Dokumente/TUD/Masterthesis/Peenomat.py", line 21, in <module>
pm = Builder.load_file('peenomat.kv')
File "C:\Users\schum\Dokumente\TUD\Masterthesis\venv\lib\site-packages\kivy\lang\builder.py", line 301, in load_file
return self.load_string(data, **kwargs)
File "C:\Users\schum\Dokumente\TUD\Masterthesis\venv\lib\site-packages\kivy\lang\builder.py", line 399, in load_string
widget = Factory.get(parser.root.name)(__no_builder=True)
File "C:\Users\schum\Dokumente\TUD\Masterthesis\venv\lib\site-packages\kivy\factory.py", line 131, in __getattr__
raise FactoryException('Unknown class <%s>' % name)
kivy.factory.FactoryException: Unknown class <WindowManager>
eventhough they got the same name. Hope you can help me out!
So I found a solution by using an implementation of the ScreenManager in the py file. I switched this with the class WindowManager(ScreenManager) class:
sm = ScreenManager()
sm.add_widget(Peenomat(name='peenomat'))
sm.add_widget(Instruction(name='instruction'))
and therefore added to my builder:
class PeenomatApp(App):
def build(self):
return sm
I fully deleted the 3 lines with the WindowManager class out of my kv.file. Now it works perfectly fine

My kivy code is not displaying anything. Please tell me where I am going wrong

i have designed a kivy form which takes some information from the user..But none of it is getting displayed..Please tell me where I am going wrong.
My code:
import kivy
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.screenmanager import ScreenManager
from kivy.uix.floatlayout import FloatLayout
class Widgets(Widget):
pass
class YourDiaryApp(App):
def build(self):
return Widgets()
if __name__ == "__main__":
YourDiaryApp().run()
Kivy code:
<Widgets>:
FloatLayout:
Label:
text:'What do you want me to call you'
TextInput:
id:username
Label:
text:'What do you wanna call me'
TextInput:
id:diaryname
Label:
text:'What will be your password'
TextInput:
id:password
Button:
text:'Complete Setup'
Is your KV file named "yourDiaryApp.kv"? From the docs:
There are two ways to load Kv code into your application:
By name convention:
Kivy looks for a Kv file with the same name as your App class in lowercase, minus “App” if it ends with ‘App’ e.g:
MyApp -> my.kv
My guess would be the KV code isn't being loaded.

How to use on_enter event to change screens on kivy?

So, here is what I'm trying to do: when entering on the first screen of my app, I want it to check if some files exist in given directory. If they exist, I want it to immediately change to another screen.
I've tried the following:
main.py
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from os import listdir
class Manager(ScreenManager):
pass
class CreateFileScreen(Screen):
def on_enter(self):
try:
files = listdir("data/files")
if "file.dat" in files:
self.parent.current = "login"
else:
pass
except FileNotFoundError:
pass
class LoginScreen(Screen):
pass
class ExampleApp(App):
def build(self):
return Manager()
if __name__ == "__main__":
ExampleApp().run()
example.kv
#:kivy 1.10.0
<CreateFileScreen>:
BoxLayout:
Label:
text: "This is Create File Screen"
font_size: "30sp"
<LoginScreen>:
BoxLayout:
Label:
text: "This is Login Screen"
font_size: "30sp"
<Manager>:
CreateFileScreen:
name: "createfile"
LoginScreen:
name: "login"
When file.dat does exist in data/files I get the following error:
kivy.uix.screenmanager.ScreenManagerException: No Screen with name "login".
Any idea on how to fix this?
The problem is that on_enter is executed before the screen gets its name.
You can make a change_screen method, then call it with Clock.schedule_once. That way it will be called the next frame.
from kivy.clock import Clock
class CreateFileScreen(Screen):
def on_enter(self):
Clock.schedule_once(self.change_screen)
def change_screen(self, dt):
try:
files = listdir("data/files")
if "file.dat" in files:
self.manager.current = "login"
else:
pass
except Exception as e:
print(e)

return a BoxLayout inside another one in Kivy?

I'm trying to make a simple application in Python 3.5 and kivy that starts with a simple screen and when you click on it, goes to another one which shows 3 lists that let you chose the data:
The Python file:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.listview import ListItemButton
from kivy.properties import ListProperty
from dataTopy import rlists
# Transition des ecrans:
class MainScreen(Screen):
pass
class AnotherScreen(Screen):
pass
class ScreenManagement(ScreenManager):
pass
presentation = Builder.load_file("ex44.kv")
#
class FirstListItemButton(ListItemButton):
pass
class SecondListItemButton(ListItemButton):
pass
class ThirdListItemButton(ListItemButton):
pass
class Ex44(BoxLayout):
d1 = ListProperty([str(i) for i in range(1990,2014)] )
d2 = ListProperty(['']*100)
d3 = ListProperty(['']*100)
def change(self,c):
try: self.d2,self.d3 = rlists(int(c.text))
except:
import os
CurDir = os.getcwd()
print('Can not find data in ' + CurDir)
def change1(self,c):
print('M => '+c.text)
def change2(self,c):
print('F => '+c.text)
class Ex44App(App):
def build(self):
return presentation
if __name__ == '__main__':
Ex44App().run()
The kivy file:
#: import FadeTransition kivy.uix.screenmanager.FadeTransition
#: import ListAdapter kivy.adapters.listadapter.ListAdapter
#: import ex44 ex44
ScreenManagement:
transition: FadeTransition()
MainScreen:
AnotherScreen:
<MainScreen>:
name: "main"
Button:
on_release: app.root.current = "other"
text: "Next Screen"
font_size: 50
<AnotherScreen>:
name: "other"
BoxLayout:
Ex44
Button:
color: 0,1,0,1
font_size: 25
size_hint: 0.3,0.2
text: "Back Home"
on_release: app.root.current = "main"
pos_hint: {"right":1, "top":1}
<FirstListItemButton>:
on_press: app.root.change(*args)
<SecondListItemButton>:
on_press: app.root.change1(*args)
<ThirdListItemButton>:
on_press: app.root.change2(*args)
<Ex44>:
ListView:
adapter:
ListAdapter(data=root.d1,
selection_mode='single',
cls=ex44.FirstListItemButton)
ListView:
adapter:
ListAdapter(data=root.d2,
selection_mode='single',
cls=ex44.SecondListItemButton)
ListView:
adapter:
ListAdapter(data=root.d3,
selection_mode='single',
cls=ex44.ThirdListItemButton)
When I try to run the app, it tells me: "Unknown class "
It is weird because the class Ex44 works alone but not when I'm trying to add it into the main application logic.
I've tried to return a widget instead of a BoxLayout for the class, to return Ex44 alone in the kivy file, etc. but I always get the same error in return.
Is it possible to return a BoxLayout inside another one in Kivy?
You are building the kv file too soon (before the class is defined). move the Builder.from_file call to the build method
...
def build(self):
return Builder.load_file("ex44.kv")

How to load string from text file to kivy label, Python 3.5

I've been searching around for answers on stackoverflow for a couple of days now to be honest but I could not find the thing for me, lets say I have a text file named bind.txt with a couple lines of text, how can i load that text file to a kivy label? be it directly or indirectly. I've been trying to teach myself python and this is kind of in the way of me building my first app. Thank you in advance, and heres the code.
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.scrollview import ScrollView
from kivy.uix.widget import Widget
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder
from kivy.properties import StringProperty
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
class MainScreen(Screen):
pass
class MainLabel(ScrollView):
text = StringProperty("")
class ScreenManagement(ScreenManager):
pass
presentation = Builder.load_file("bind.kv")
class MainApp(App):
def build(self):
return presentation
if __name__ == "__main__":
MainApp().run()
And the kv file.
#: import FadeTransition kivy.uix.screenmanager.FadeTransition
ScreenManagement:
transition: FadeTransition()
MainScreen:
<MainLabel>:
text: #bind.txt here, somehow..
Label:
text: root.text
font_size: 15
text_size: self.width, None
size_hint_y: None
height: self.texture_size[1]
<MainScreen>:
name: "main"
canvas.before:
Rectangle:
pos: self.pos
size: self.size
source: 'img/Fundal.png'
MainLabel
You can open file in reading mode, store contents in a variable and assign it to the text property.
For an example
with open("bind.txt") as f:
contents = f.read()
main_label.text = contents # main_label is an instance of kivy's Label class.

Resources