How to change the image source in kivy? - python

I am trying to make an app that shows one image. When I click in some button, the function will change the source of this image, therefore this image will change. So, I tried only change the line image.source, I think the correct way to do this is using a stringproperty, but I also have not had success with it. So, my code is:
.py
class PrimeiroScreen(Screen):
def __init__(self, **kwargs):
self.name = 'um'
super(Screen,self).__init__(**kwargs)
fonte = StringProperty('cafe.jpg')
def fc1(self):
self.ids.image.source = (fonte)
self.ids.image.fonte = "cafe.jpg"
#self.ids.image.source = "cafe.jpg"
class MyImage(Image):
fonte = StringProperty()
class RootScreen(ScreenManager):
pass
and .kv:
<RootScreen>:
PrimeiroScreen:
<PrimeiroScreen>:
StackLayout:
orientation: 'tb-rl'
ScrollView:
#size: 100, 100
#pos_hint: {'center_x': .5, 'center_y': .5}
GridLayout:
cols: 1
padding: 10, 10
spacing: 5, 5
size_hint: (None, None)
size_hint_y: None
width: 500
height: self.minimum_height
Button:
text: "1"
#color: 0,0,0,1
font_size: '20dp'
size: (200, 40)
size_hint: (None, None)
on_release: root.fc1()
AnchorLayout:
Image:
source:'logo.jpg'
id: image
I am learning about AnchorLayout, and StackLayout, so it's not working.
Very thanks everyone, for awser my newbie question. Nice weekend.

The thing is with your current code there is no fonte defined(at least for me with copy&paste), you need to use self.fonte.
But anyway, you should access the source directly, otherwise you'd need to make another function that handles your property updating and doing something when it changes i.e. passing it to source, which already is a StringProperty, therefore you'd go really around the solution until you reached it.
<RootScreen>:
PrimeiroScreen:
<PrimeiroScreen>:
StackLayout:
orientation: 'tb-rl'
ScrollView:
#size: 100, 100
#pos_hint: {'center_x': .5, 'center_y': .5}
GridLayout:
cols: 1
padding: 10, 10
spacing: 5, 5
size_hint: (None, None)
size_hint_y: None
width: 500
height: self.minimum_height
Button:
text: "1"
color: 0,0,0,1
font_size: '20dp'
size: (200, 40)
size_hint: (None, None)
on_release: image.source='newcafe.png'
MyImage:
source: 'cafe.jpg'
id: image

Related

Model not loading after using plyer filechooser

I have a trained model which is loading in the main python file. It is working and giving predictions when I choose kivy's FileChooseListView but I wanted to make it better so I used plyer filechooser which did load images but the problem is now my model is not loading. Its not giving any error either. Can anyone tell what the problem is?
I have tried correcting it and debugging but nothing is happening.
main.py
class UploadScreen(Screen):
def file_chooser(self):
filechooser.open_file(on_selection=self.selected)
def selected(self, filename):
try:
self.ids.my_image.source = filename[0]
print(filename[0])
CATEGORIES = ['Diving Side', # 1.
'Golf-Swing-Front', # 2.
'Golf-Swing-Side', # 3.
'Kicking-Front', # 4.
'Kicking-Side', # 5.
'Lifting', # 6
'Riding-Horse', # 7
'Run-Side', # 8.
'SkateBoarding-Front', # 9
'Swing-Bench', # 10.
'Swing-SideAngle', # 11
'Walk-Front' # 12.
]
model = tf.keras.models.load_model("./model/model") /// Model is not loading
size = (90, 90)
img_array = cv2.imread(filename[0])
pd_array = []
im = cv2.resize(img_array, size, cv2.INTER_AREA)
im = im.astype('float32')
pd_array.append(im)
np_image = np.array(pd_array)
print("NP array ")
print(np_image.shape)
predictions = model.predict(np_image)
top = np.argmax(predictions)
print(predictions)
# top=top-1
print(top)
print("prediction is "+CATEGORIES[top])
results = CATEGORIES[top]
print(results)
name = results
# Update the label
self.ids.name_label.text = name
print("Captured")
except:
pass
.kv
<UploadScreen>:
name: 'upload'
id: upload
orientation: 'vertical'
canvas:
Color:
# rgba: 0.439,0.501,0.564,1
rgb: 0.662, 0.662, 0.662, 1
Rectangle:
size: self.size
pos: self.pos
MDGridLayout:
rows:5
cols:1
spacing: 25
padding: 25
MDLabel:
id: name_label
text: "Results"
bold: True
font_size: 35
color: 0.137, 0.156, 0.419, 1
halign: 'center'
size_hint_y: None
height: self.texture_size[1]
MDRaisedButton:
text: 'Select Image'
font_size: 18
size_hint: None, None
width: root.width*1
height: root.height*0.1
md_bg_color: 0.258, 0.372, 0.921, 1
text_color: 1,1,1,1
pos_hint: {'center_x':0.5,'center_y':0.3}
on_press: root.file_chooser()
BoxLayout:
orientation: "vertical"
size: root.width, root.height
padding: 50
spacing: 20
Image:
id: my_image
source: ""
MDRaisedButton:
text: 'Back'
font_size: 18
size_hint: None, None
width: root.width*1
height: root.height*0.1
md_bg_color: 0.258, 0.372, 0.921, 1
text_color: 1,1,1,1
pos_hint: {'center_x':0.5,'center_y':0.3}
on_press: root.manager.current = 'main'

Usage of kivy layouts

I am using kivy to build GUI for my program. In my kv file, I want the content of the first box layout to appear on the top right and the content of the second boxlayout to appear on the top left.
Below is the my kv file.
This is not behaving as expected. Please help
<AnchorLayout>:
anchor_x: 'right'
anchor_y: 'top'
BoxLayout:
orientation: 'horizontal'
Button:
text: 'Dashboard'
size_hint: None, None
size: 80, 40
Button:
text: 'Task'
size_hint: None, None
size: 80, 40
Button:
text: 'Work'
size_hint: None, None
size: 80, 40
BoxLayout:
orientation: 'horizontal'
Label:
text: 'Logo'
Label:
text: 'MU'
The problem is that the poorly documented AnchorLayout only really works with just a single child. In your case, both of your BoxLayouts are positioned at the right, top of the AnchorLayout. However, both BoxLayouts have the default size_hint of (1,1), so they both fill the AnchorLayout, and the right top anchor has no effect.
You can use FloatLayout instead of AnchorLayout, with size_hint and pos_hint to get your desired result:
<FloatLayout>:
BoxLayout:
orientation: 'horizontal'
pos_hint: {'right':1, 'top':1}
size_hint: None, None
size: self.minimum_size
Button:
text: 'Dashboard'
size_hint: None, None
size: 80, 40
Button:
text: 'Task'
size_hint: None, None
size: 80, 40
Button:
text: 'Work'
size_hint: None, None
size: 80, 40
BoxLayout:
orientation: 'horizontal'
pos_hint: {'x':0, 'top':1}
size_hint: None, None
size: self.minimum_size
Label:
text: 'Logo'
size_hint: None, None
size: 80, 40
Label:
text: 'MU'
size_hint: None, None
size: 80, 40

Scroll does not work in kivy Layout of buttons

<Builder_Screen>
ScrollView:
do_scroll_y:True
FloatLayout:
Button:
text:"Heading"
size_hint_x: .25
size_hint_y: .25
text_size: self.size
halign:"center"
valign:"center"
pos: 0,10
Button:
text:"Paragraph"
halign:"center"
valign:"center"
size_hint_x: .25
size_hint_y: .25
pos: (0,self.height)
I have some buttons like these with positions like pos: 0, self.height2 , self.height3 etc.
But, the scroll layout does not work as intended.
Can you help me regarding that!...
According to the documentation, regarding the child of a ScrollView:
By default, the size_hint is (1, 1), so the content size will fit your
ScrollView exactly (you will have nothing to scroll). You must
deactivate at least one of the size_hint instructions (x or y) of the
child to enable scrolling.
So, you probably need to set size_hint_y: None for your FloatLayout. That will cause further problems, because you have size_hint_y values for your Buttons. You can set the heights of your Buttons and eliminate the size_hint_y values. Another approach would be to use a GridLayout:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen
kv = '''
<Builder_Screen>
ScrollView:
do_scroll_y:True
effect_cls: 'ScrollEffect'
GridLayout:
cols: 2
size_hint_y: None
height: self.minimum_height
padding: 5
spacing: 5
Button:
text:"Heading1"
halign:"center"
valign:"center"
size_hint_y: None
height: 48
Button:
text:"Paragraph1"
halign:"center"
valign:"center"
size_hint_y: None
height: 48
Button:
text:"Heading2"
halign:"center"
valign:"center"
size_hint_y: None
height: 48
Button:
text:"Paragraph2"
halign:"center"
valign:"center"
size_hint_y: None
height: 48
Button:
text:"Heading3"
halign:"center"
valign:"center"
size_hint_y: None
height: 48
Button:
text:"Paragraph3"
halign:"center"
valign:"center"
size_hint_y: None
height: 48
'''
class Builder_Screen(Screen):
pass
class TestApp(App):
def build(self):
Builder.load_string(kv)
return Builder_Screen()
TestApp().run()
Note that every Button has an explicit height. That is required if you use height: self.minimum_height for their container.

Kivy Buttons and Labels size based on display size

I'm trying to figure out how to make my buttons and labels fix perfectly depending on my display size. So if the phone display is different, it will always be in fixed size.
Python Code:
import kivy
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
class OpeningScreen(Screen):
pass
class LoginScreen(Screen):
pass
class SignupScreen(Screen):
pass
class ScreenManagement(ScreenManager):
pass
AppKv = Builder.load_file("App.kv")
class MyApp(App):
def build(self):
return AppKv
if __name__ == '__main__':
MyApp().run()
Kv code:
#: import FadeTransition kivy.uix.screenmanager.FadeTransition
#: import hex kivy.utils.get_color_from_hex
#------------------------------------------------------------#
ScreenManagement:
transition: FadeTransition()
OpeningScreen:
LoginScreen:
SignupScreen:
#------------------------------------------------------------#
<OpeningScreen>:
name: "OpeningScreen"
canvas:
Color:
rgb: 1, 1, 1
Rectangle:
pos: self.pos
size: self.size
Label:
text: "Welcome"
color: 1,1,1,1
font_size: 45
size_hint: 0.2,0.1
pos_hint: {"x":0.40, "top":0.995}
Button:
size: 100,75
on_release: app.root.current = "LoginScreen"
text: "Login"
font_size: 50
color: 1,1,1,1
background_color: (0,0,0,1)
background_normal: ""
background_down: ""
size_hint: 0.3,0.2
pos_hint: {"x":0.35, "top":0.7}
Button:
size: 100,75
on_release: app.root.current = "SignupScreen"
text: "Sign up"
font_size: 50
color: 1,1,1,1
background_color: (0,0,0,1)
background_normal: ""
background_down: ""
size_hint: 0.3,0.2
pos_hint: {"x":0.35, "top":0.4}
#------------------------------------------------------------#
<LoginScreen>:
name: "LoginScreen"
canvas:
Color:
rgb: 1, 1, 1
Rectangle:
pos: self.pos
size: self.size
Label:
text: "Login In"
color: 0,0,0,1
font_size: 45
size_hint: 0.2,0.1
pos_hint: {"x":0.40, "top":0.995}
#------------------------------------------------------------#
<SignupScreen>:
name: "SignupScreen"
canvas:
Color:
rgb: 1, 1, 1
Rectangle:
pos: self.pos
size: self.size
Label:
text: "Sign Up"
color: 0,0,0,1
font_size: 45
size_hint: 0.2,0.1
pos_hint: {"x":0.40, "top":0.995}
I would really appreciate if anyone could help me with this. I was trying to find out how to do this but I couldn't
Button and Label sizes can be set using several different approaches:
Use Kivy Metrics. You can set sizes using dp (for example dp(100)), this is a Density-independent Pixel size. There is also a sp (used similarly) that is Scale-independent Pixels (normally used for font sizes)
Use self.texture_size. You can set sizes using this as size: self.texture_size. This will make your Button and Label widgets just large enough to fit the text in it. You can add some padding by using something like:
width: self.texture_size[0] + dp(10)
height: self.texture_size[1] + dp(10)
Use size_hint. This will ensure that the Button and Label widgets take up the same percentage of your display, regardless of the device.
Don't forget to set size_hint to None, None for the first two above to work.

Kivy: ScrollViewApp example in Kivy Language

I'm having trouble with going back and forth between the concepts in the Kivy language, vs. Python language. I'm not very good at explaining things, and i've thought about how to explain my specific problem, but the best way i can think to do that is:
How would one implement the ScrollViewApp using the Builder function?
hm, something like
ScrollView:
size_hint: None, None
size: 500, 320
pos_hint: {'center_x': .5, 'center_y': .5}
do_scroll_x: False
GridLayout:
cols: 1
padding: 10
spacing: 10
size_hint_y: None
height: self.minimum_height
ScrollButton:
text: '1'
ScrollButton:
text: '2'
ScrollButton:
text: '3'
ScrollButton:
text: '4'
ScrollButton:
text: '5'
ScrollButton:
text: '6'
<ScrollButton#Button>
size_hint: None, None
size: 480, 40
here, however we don't really have a way to dynamically create the children (well, there would be ways, but they are ugly), so i put a few manualy, idealy you would create the ScrollView and GridLayout in kv, and then put the children inside from python (using ids, as explained in the doc).
edit: more complete version using an app and ObjectProperty
kv file (scroll.kv):
ScreenManager:
Screen:
ScrollView:
size_hint: None, None
size: 500, 320
pos_hint: {'center_x': .5, 'center_y': .5}
GridLayout:
cols: 1
padding: 10
spacing: 10
height: self.minimum_height
size_hint: None, None
do_scroll_x: False
id: container
<ScrollButton>
size_hint: None, None
size: 480, 40
python file (main.py):
from kivy.app import App
from kivy.uix.button import Button
class ScrollButton(Button):
pass
class ScrollApp(App):
def build(self):
super(ScrollApp, self).build()
container = self.root.ids.container
for i in range(30):
container.add_widget(ScrollButton(text=str(i)))
return self.root # return root does not work
if __name__ == '__main__':
ScrollApp().run()

Categories