I am new to Python UI programming. I want to build a GUI in which when you enter a letter and you will get the code to print that letter using a star pattern or any other character pattern. I stored the codes of pattern codes of all letters in a separate text file like a.txt,b.txt etc.. I also wrote code for some special characters like a love symbol or a cake. But for now, I am working on displaying the pattern code for letters. I have to read input from the user say 'm' and I read the text from the m.txt file. All I have to do now is to display these contents on GUI using the Label tag. My code doesn't print anything on the screen.
Please Can someone make time for me and look into my code. Thanks in advance
Here's my Python File
import kivy
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.widget import Widget
from kivy.properties import ObjectProperty
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.popup import Popup
def show_popup():
show = P()
popupWindow = Popup(title = "Error",content = show,size_hint = (None,None),size =(400,400))
popupWindow.open()
class P(FloatLayout):
pass
class Code(Screen):
def display(self,char):
try:
with open("{}.txt".format(char),"r") as f:
contents = f.read()
# I am sure that the contents are read properly
# bcoz I printed them on IDLE and it worked
main_label = Label()
main_label.txt = contents
except:
show_popup()#if it is an invalid letter like(@,*,&)
class SecondPage(Screen):
#SecondPage asks the user to enter a letter
letter = ObjectProperty(None)
def Enter(self):
#this method checks whether the user entered a valid letter or not
if len(self.letter.text)==1:
char = self.letter.text
char = char.lower()
c = Code()
c.display(char)#passing this character display method
else:
show_popup()
class MainPage(Screen):
#Main Page has two buttons asking the user whether
#he want code for special character or a letter
pass
class WindowManager(ScreenManager):
pass
class Sowmya(App):
def build(self):
return WindowManager()
if __name__ == "__main__":
Sowmya().run()
And here's my .kv file
<P>:
Label:
text:"Please enter a valid letter"
size_hint:0.6,0.2
pos_hint:{"x":0.2,"top":1}
<WindowManager>:
MainPage:
SecondPage:
Code:
<MainPage>:
name:"main"
Button:
text: 'Letters'
pos_hint : {'x':.4,'y':.2,'left':.3}
on_release:
app.root.current = "second"
root.manager.transition.direction = "left"
font_size: 20
background_color: (1, 1, 1, 1)
color: (1, 1, 1, 1)
size_hint:.4,.3
Button:
text: 'Special'
pos_hint : {'x':.4,'y':.5,'left':.3}
font_size: 20
background_color: (1, 1, 1, 1)
color: (1, 1, 1, 1)
size_hint:.4,.3
<SecondPage>:
letter:letter
name:"second"
GridLayout:
cols:1
GridLayout:
cols:2
Label:
text:"Enter Letter:"
TextInput:
id:letter
multiline:False
Button:
text : "Enter"
on_release:
root.Enter()
app.root.current = "code"
Button:
text:"Go Back"
on_release:
app.root.current = "main"
root.manager.transition.direction = "right"
<Code>:
name:"code"
Label:
size_hint:0.6,0.2
pos_hint:{"x":0.2,"top":1}
Two similar problems in your code:
First, in your Code
class, the line:
main_label = Label()
creates a new Label
, which is not in your GUI, so setting the text of that new Label
will not have any effect on your GUI. So, you can correct this by accessing the actual Label
that is in your Code
Screen
:
class Code(Screen):
def display(self, char):
try:
with open("{}.txt".format(char), "r") as f:
contents = f.read()
# don't create a new Label, use the one in this Screen
self.ids.main_label.text = contents
# switch to this Screen
self.manager.current = 'code'
except:
show_popup() # if it is an invalid letter like(@,*,&)
For this to work, you need to add the id
main_label
in the kv
:
<Code>:
name:"code"
Label:
id: main_label # id for accessing this Label
size_hint:0.6,0.2
pos_hint:{"x":0.2,"top":1}
A similar error in your SecondPage
class where you are creating a new instance of Code
rather than accessing the one that is already part of your GUI. This can be corrected by using the ScreenManager
to access the Code
Screen
:
class SecondPage(Screen):
# SecondPage asks the user to enter a letter
letter = ObjectProperty(None)
def Enter(self):
# this method checks whether the user entered a valid letter or not
if len(self.letter.text) == 1:
char = self.letter.text
char = char.lower()
# c = Code()
c = self.manager.get_screen('code') # get Code Screen that was created by the `kv`
c.display(char) # passing this character display method
else:
show_popup()
Note that whenever you use a class name followed by ()
you are creating a new instance of that class that likely has no relation to any instance of that class that is already in your App.