I'm trying to make an app that allows me to take pictures. I've tried to copy different examples that allow to do this, but I always get the same error:
self._camera = CoreCamera(index=self.index, stopped=True)
TypeError: 'NoneType' object is not callable
If it helps, this is the latest code I've tried:
from kivy.app import App
from kivy.uix.camera import Camera
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
class CameraExample(App):
def build(self):
layout = BoxLayout(orientation='vertical')
# Create a camera object
self.cameraObject = Camera(play=False)
self.cameraObject.play = True
self.cameraObject.resolution = (300, 300) # Specify the resolution
# Create a button for taking photograph
self.camaraClick = Button(text="Take Photo")
self.camaraClick.size_hint = (.5, .2)
self.camaraClick.pos_hint = {'x': .25, 'y': .75}
# bind the button's on_press to onCameraClick
self.camaraClick.bind(on_press=self.onCameraClick)
# add camera and button to the layout
layout.add_widget(self.cameraObject)
layout.add_widget(self.camaraClick)
# return the root widget
return layout
# Take the current frame of the video as the photo graph
def onCameraClick(self, *args):
self.cameraObject.export_to_png('/kivyexamples/selfie.png')
# Start the Camera App
if __name__ == '__main__':
CameraExample().run()
I've also tried to install the opencv-python, which is something that many people recommended, however it still returns the same error.
Related
I am using kivy and I am using Windows 10, Python 3.7.
I want to print out the name of each button when I press each button.
However, only the name of the last button is printed.
Below is the Python code
import kivy
kivy.require('2.0.0')
from kivy.app import App
from kivy.core.window import Window
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from kivy.uix.scrollview import ScrollView
import os
Window.clearcolor = (.6, 1, .8, 1)
Window.size = (563, 1001)
Window.top, Window.left = 30, 800
path_list = ["music1","music2","music3"]
music = ""
class TestApp(App):
def build(self):
global music
gl = GridLayout(cols=1, size_hint_y=None)
for music in path_list:
bt = Button(text=music, size_hint_y=None, height=50)
gl.add_widget(bt)
bt.bind(on_press=self.music_f)
sv = ScrollView(size_hint=(1, 1))
sv.add_widget(gl)
return sv
def music_f(self,name):
global music
name = music
print("pray "+str(name))
TestApp().run()
Bad design:
You use a music variable which will take the last value from the path_list due to the for loop, then you use that value to assign it to the name, this has no logic... Once the button is created with the text=music, you already have the value assign to the that button. As you bind on_press with music_f, the name should be the button, I would change that to button.
In music_f you can access the name by calling button.text
def music_f(self,button):
print("pray "+str(button.text))
I was making a program similiar to exel.
And then I ran into a issue.
StackLayout stacks good, but because the size of inputs is static it leave a blank space in some cases.
I try to do like size=(self.width/5, self.height/5).
If someone saw how exel look now that there are more inputs of the screen this is why I use ScrollLayout and I want only 5 inputs in one row(user can change it in display settings(I will do it then creating rest of UI))
Here is what I had tried for now.
main.py:
from kivy.metrics import dp
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.stacklayout import StackLayout
from kivy.uix.textinput import TextInput
class EditorGrid(BoxLayout):
def __init__(self, **kwargs):
super().__init__(**kwargs)
size = dp(self.width / 5)
print(size)
for i in range(0, 100):
b = TextInput(text=str(i + 1), size_hint=(None, None), size=(dp(size), dp(size)))
self.add_widget(b)
def on_size(self, *args):
self.size = dp(self.width/5)
print(self.size)
pass
class pxApp(App):
pass
if __name__ == "__main__":
pxApp().run()
kivy file:
Scrolling:
<Scrolling#ScrollView>
do_scroll_x: True
do_scroll_y: True
EditorGrid:
size_hint: 1, None
height: self.minimum_height
<EditorGrid>:
There is next problem that in init window size is 100x100.
I recommend using setters in binding under kv script. If you want to apply it in python, you could use a binding function for each button.
b = TextInput(.......) #omit size_hint and size attributes
#the following function is called every time EditorGrid(self) size_hint changes when the function is bind
#The function could be defined in a outer scope.
#Look at kivy callback functions to better understand the syntax
binding_function = lambda ins, *a: setattr(ins, 'size_hint', tuple((dim/5 for dim in self.size_hint))
b.bind(size_hint=binding_function)
I have currently got 3 python files. 1 which is where all the main initialisation methods happen, one for a sign in page and one for a sign up page. I cannot get the sign up button on the login page to take me to the sign up page however. Please can someone help. I have tried to change the sm.current inside of the login.py file but that did not work either.
Here is the main.py file:
# Fitness App Main Code
from kivy.app import App
from kivy.core.window import Window
from kivy.uix.screenmanager import ScreenManager
from LogInWindow import LogInWindow # importing the class from Login.py
from SignUpWindow import SignUpWindow
class WindowManager(ScreenManager): # creating a class that deals with screen management
pass
sm = WindowManager() # setting a variable to the window manager class
screens = [LogInWindow(name="Login_window"), SignUpWindow(name="Signup_window")] # setting an array of lists
for screen in screens: # going through all of the screens
sm.add_widget(screen) # adding the screen widget to each
sm.current = "Login_window" # setting current window to login
class FitnessApp(App): # the class that runs the app
def build(self):
App.title = "Fitness App" # setting the app title
Window.size = (1080, 720) # setting window size
return sm # running the app by returning the current window
if __name__ == '__main__': # The value of __name__ attribute is set to “__main__” when module is run as main program
FitnessApp = FitnessApp()
FitnessApp.run()
Here is the login.py file
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import Screen
from database import get_details
def switch_to_signup():
from main import sm
sm.current_screen = "Signup_window"
class LogInWindow(Screen): # creating LogInWindow class
kv = Builder.load_file("LogInWindow.kv") # loading the kivy file which has all the
def __init__(self, **kwargs): # defining an init method
super().__init__(**kwargs) # giving the subclass the same parameter signature as the parent
def validate_user(self): # creating a function to validate the user
username_input_kivy = self.ids.username_field # setting the input to a variable
password_input_kivy = self.ids.password_field # setting the input to a variable
info = self.ids.info # setting the input to a variable
username_input = username_input_kivy.text # getting the text from an input and putting it into a variable
password_input = password_input_kivy.text # getting the text from an input and putting it into a variable
if username_input == '' or password_input == '': # checking if the fields are empty
info.text = '[color=#FF0000]Username And / Or Password Required[/color]' # red error message
else:
user_details = get_details(username_input)
username = user_details[0] # set the username to the 1st value
users_password = user_details[1] # set the password to the 2nd value
if username_input == username and password_input == users_password: # checking if they are correct
info.text = '[color=#00FF00]Logged In successfully!!![/color]' # green success message
else:
info.text = '[color=#FF0000]Invalid Username and/or Password[/color]' # red error message
and here is the relevant kivy button:
Button:
text: "Don't have an account? Sign Up Here!" ## setting the text to the sign up
font_size:20 ## changing font size
size_hint_y: None ## setting size hint to none so it can be set to anything
height: 60 ## setting height to 60
background_color: (0, 0, 0, 1) ## setting background colour
background_normal: '' ## changing the background_normal to nothing
on_release: root.switch_to_signup() ##will change to put it to sign up screen
There is almost nothing in the signup.py file but I will include it incase that helps.
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen
class SignUpWindow(Screen): # creating LogInWindow class
kv = Builder.load_file("SignUpWindow.kv") # loading the kivy file which has all the
def __init__(self, **kwargs): # defining an init method
super().__init__(**kwargs) # giving the subclass the same parameter signature as the parent
Any help would be greatly appreciated
In your kv file you can always access the App using the keyword app. See the documentation.
So, in your kv, change the Button to:
Button:
text: "Don't have an account? Sign Up Here!" ## setting the text to the sign up
font_size:20 ## changing font size
size_hint_y: None ## setting size hint to none so it can be set to anything
height: 60 ## setting height to 60
background_color: (0, 0, 0, 1) ## setting background colour
background_normal: '' ## changing the background_normal to nothing
on_release: app.root.current = "Signup_window" ##will change to put it to sign up screen
Of course, this assumes that the name of the SignUpWindow is "Signup_window".
In a Kivy/Python program, I have a class which contains a scrollview. I instantiate this class multiple times. The scrollview is bound to the on_scroll_stop event. My desired outcome is that the on_scroll_stop event will only fire within the instantiated class to which it belongs, but it seems that the event fires across all of the instantiated classes. Am I doing something wrong or is this expected behavior? Working sample below. In this example the "Left" section shows the issue most often, however the error is seen in the right section once you scroll up at the top or scroll down once reaching the bottom. To recreate scroll only one side, preferably the "Left" side. In my actual code which is far more complex the issue is much more prevalent.
import kivy
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.scrollview import ScrollView
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.label import Label
class DisplaySection(Widget):
def CreateSection(self):
self.display_panel_main_layout = BoxLayout(orientation='vertical')
self.elements_layout = FloatLayout(size_hint_y=None)
self.sv = ScrollView()
self.sv.bind(on_scroll_stop=self.on_scrolling_stop)
self.sv.add_widget(self.elements_layout)
self.display_panel_main_layout.add_widget(self.sv)
return self.display_panel_main_layout
def LoadElements(self,section_name):
self.section_name = section_name
number_of_elemements = 100
element_hieght = 40
layout_height = number_of_elemements * element_hieght
self.elements_layout.height = layout_height
xcord = 0
for x in range(number_of_elemements):
ycord = self.elements_layout.height - element_hieght*x
name = Label(text='Name' + str(x),size_hint_y=None, height=40,pos=(xcord,ycord))
self.elements_layout.add_widget(name)
def on_scrolling_stop(self, sv, value):
#print(sv,value)
print('I am',self.section_name)
class testscrollapp(App):
def build(self):
main_layout = BoxLayout()
section_names = ['Left','Right']
for x, section_name in enumerate(section_names):
section_layout = BoxLayout(orientation='vertical')
btn = Button(text=section_name,size_hint=(1,None))
section_layout.add_widget(btn)
# instantiate the class containing the scroll view
scroll_layout = DisplaySection()
scr = scroll_layout.CreateSection()
section_layout.add_widget(scr)
scroll_layout.LoadElements(section_name)
main_layout.add_widget(section_layout)
return main_layout
testscrollapp().run()
The on_scroll_stop event is dispatched just like touch events, so any ScrollView instance that subscribes to on_scroll_stop will get all the on_scroll_stop events. And just like a touch event, the subscribing ScrollView instance must determine which of the events it is interested in, and ignore the rest. Since the value argument to your on_scrolling_stop is the MouseMotionEvent, you can do a collide_point() test to determine if the scroll event is within the ScrollView:
def on_scrolling_stop(self, sv, value):
if sv.collide_point(*value.pos):
print('\tI am',self.section_name)
I have images loading in the kivy accordion and I want to print out the x and y coordinates below the images when I press the mouse button. I can't for the life of my figure this out. Every time I add anything it seems like it shuts the whole program down. I know that the widget I have will print to the console but I want to print it to the screen.
Here is the code I am using:
from kivy.uix.accordion import Accordion, AccordionItem
from kivy.uix.image import Image
from kivy.app import App
from kivy.uix.widget import Widget
class MouseWidget(Widget):
def on_touch_down(self, touch):
print(touch)
class MyApp(App):
def build(self):
root = Accordion(orientation='horizontal')
item= AccordionItem(title='Picture1')
src = "picture1.png"
image = Image(source=src,pos=(200, 100))
# add image to AccordionItem
item.add_widget(image)
root.add_widget(item)
item= AccordionItem(title='Picture2')
src = "picture2.png"
image = Image(source=src,pos=(200, 100))
# add image to AccordionItem
item.add_widget(image)
root.add_widget(item)
return root
if __name__ == '__main__':
MyApp().run()
Here's a simple modification to your program that adds the touch position to a label below the image, using kivy language to automatically bind to the necessary properties so that the display is updated when they change.
I'm not sure what problems you had in particular, so let me know if the way it works is not clear!
from kivy.uix.accordion import Accordion, AccordionItem
from kivy.uix.image import Image
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.lang import Builder
from kivy.properties import ObjectProperty, StringProperty
from kivy.uix.boxlayout import BoxLayout
Builder.load_string('''
<MouseWidget>:
image: image
label: label
orientation: 'vertical'
Image:
id: image
source: root.source
Label:
id: label
size_hint_y: None
height: 50
text: 'no touch detected'
''')
class MouseWidget(BoxLayout):
image = ObjectProperty()
label = ObjectProperty()
source = StringProperty()
def on_touch_down(self, touch):
if self.image.collide_point(*touch.pos):
self.label.text = str(touch.pos)
def on_touch_up(self, touch):
self.label.text = 'no touch detected'
class MyApp(App):
def build(self):
root = Accordion(orientation='horizontal')
item= AccordionItem(title='Picture1')
src = "picture1.png"
image = MouseWidget(source=src)
# add image to AccordionItem
item.add_widget(image)
root.add_widget(item)
item= AccordionItem(title='Picture2')
src = "picture2.png"
image = MouseWidget(source=src)
# add image to AccordionItem
item.add_widget(image)
root.add_widget(item)
return root
if __name__ == '__main__':
MyApp().run()
Every time I add anything it seems like it shuts the whole program down.
This sounds like your changes crashed the program. You should check the output of your program by running it in a terminal. It will print information about the error that can help you track down your mistakes.