Kivy error: NameError 'Clock' is not defined - python

I am picking up Kivy and stuck on the titled error. I am simply trying to run a function 1 min after the app started:
import kivy
kivy.require('1.9.1')
from kivy.app import App
class ScreamApp(App):
def on_start(self):
Clock.schedule_interval(self.wakemeup, 60)
def wakemeup(self, nap):
#vibrate here
pass
if __name__=="__main__":
ScreamApp().run()
When I run it, it says:
NameError: name 'Clock' is not defined. It is a built in class, according to the documentation. What am i mmissing?

you need to import Clock before using it. Put this at the top:
from kivy.clock import Clock
I guess you copy/pasted that from an example on their documentation. For the sake of brevity, many examples leave out the imports at the start, so you need to figure our the imports yourself.

Related

Python, Kivy - QRScanner and ScreenManager

I want to create an app with 2 (an more) screens (screen manager).
When i make app without that QR reader, i know how to move values from one screen to another. But here i have problem with that.
I spend 3 days on this problem and still dont have answer. Can You help me?
Heres code:
https://github.com/fornakter/Terminarz-Kivy-MD/blob/master/main.py
Errors are on class SecoundWindow, on line 16.
Comments explained errors wit i recive.
Thank You.
The documentation says connect_camera() must be called after on_start(). So change the definition of SecoundWindow to simply:
class SecoundWindow(Screen):
pass
And in your ReadQR App, add the following methods:
def on_start(self):
Clock.schedule_once(self.connect_camera)
def connect_camera(self, dt):
secoundWindow = self.root.get_screen('secound')
secoundWindow.ids.preview.connect_camera(camera_id='front', enable_analyze_pixels=True, default_zoom=0.0)
I needed to add camera_id to avoid SEGFAULT.
Unrelated, but the following lines of your code do nothing and can be deleted:
sm = ScreenManager()
sm.add_widget(FirstWindow(name='first'))
sm.add_widget(SecoundWindow(name='secound'))

Kivy button: how to assign on_press command defined in another function within same class

I should probably start by saying I am an absolute beginner with Python and Kivy, so please excuse me if the question is very naive.
I am trying to get a Kivy button to run a command on_press. The command is defined in another function which belongs to the same class. However, I always get the following error:
self.searchButton.bind(on_press=self.searchRecipe())
File "kivy_event.pyx", line 419, in kivy._event.EventDispatcher.bind
AssertionError: None is not callable
I have already looked at similar questions (here and here) but still could not figure out what I am doing wrong.
I should also add that, for the sake of learning, I do not want to use .kv files at the moment, but include everything in my python script. After getting a nice understanding of it, I will try to migrate some parts to a .kv file.
Below is a minimal (non-working) example. Of course the searchRecipe function should do more than just printing (connect to a SQLite db and perform some other stuff), but this is just a tryout.
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
class RootWindow(BoxLayout):
def __init__(self, **kwargs):
super(RootWindow, self).__init__(**kwargs)
self.orientation = 'vertical'
self.searchButton = Button(text="Search")
self.searchButton.bind(on_press=self.searchRecipe())
self.add_widget(self.searchButton)
def searchRecipe(self):
print("It works!")
class RecipApp(App):
def build(self):
return RootWindow()
if __name__ == "__main__":
RecipApp().run()
self.searchButton.bind(on_press=self.searchRecipe())
self.searchRecipe() evaluates to None. You want self.searchButton.bind(on_press=self.searchRecipe).

No name 'ObjectProperty' in module 'kivy.properties' - Python Kivy

When I try to import ObjectProperties from kivy.properties, I get an error:
"No name 'ObjectProperty' in module 'kivy.properties'pylint(no-name-in-module)"
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.textinput import TextInput
from kivy.uix.label import Label
from kivy.config import Config
from kivy.event import EventDispatcher
from kivy.properties import ObjectProperty
Config.set('graphics', 'width', 1000)
Config.set('graphics', 'height', 1000)
Config.set('graphics', 'resizable', False)
class GridContainer(GridLayout):
text_input1 = ObjectProperty()
label1 = ObjectProperty()
def count_sum(self):
self.label1.text = int(self.text_input1.text[0]) + int(self.text_input1.text[1])
class MyApp(App):
def build(self):
GridContainer()
return GridContainer()
Are there any ways to solve this problem?
I found myself in the same situation simply because I thought python only accepts libraries written in python. Python codes/libraries can be made to run faster by compiling them into a mixture of C and Python codes as observed with the properties library located in the kivy directory of site-packages of your python installation folder. Using this method, the compiled python codes can be imported without any troubles just as prior to compilation.
Myself, I have not seen any extension that lints cython codes and they are all built to work with libraries developed with python not cython. Thus, they tend to have problems linting those that have been written/compiled to cython.
As inclement clearly stated, this is not an issue you should worry about if the program runs fine. It is a problem with IDE linting extensions, they cant lint cython codes. You can go with Jayden solution if you dont want to be seeing the squiggy red lines all the time.
I hope this clearifies things..?
I found a workaround:
replace from kivy.properties import ObjectProperty with import kivy.properties as kyprops
type kyprops anytime you need to declare ObjectProperty
Let me know if that helps!
If the code runs fine, this is just a bug in your linter. As already linked by others, it is probably not capable of properly understanding imports from cython-built libraries.

Maximum recursion depth exceeded in kivy but only when packaging, not when developing the app in python

I am trying to pack an app that requires several imports, among those matplotlib.pyplot
The kivy app (simplified, but still working) is:
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder
import matplotlib.pyplot
Builder.load_string("""
<MyWidget>:
id: my_widget
FileChooserIconView:
id: filechooser
on_selection: my_widget.selected(filechooser.selection)
Image:
id: image
source: ""
""")
class MyWidget(BoxLayout):
def selected(self,filename):
self.ids.image.source = filename[0]
class MyApp(App):
def build(self):
return MyWidget()
if __name__ == '__main__':
MyApp().run()
This app works perfectly in python using spyder.
However, when I try to pack it as an independent kivy app it gives me error maximum recursion depth exceeded.
I am surprised and I do not know what the problem is because:
1.There are no recursive functions in the app.
2.Works perfectly in python spyder while developing it and testing it, the only problem is during packaging.
3.I have tried multiple options, including commenting out several portions and, most surprising, when I comment out the import matplotlib.pyplot the app packages well. However I need matplotlib.pyplot for this app so taking it out is not an option.
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder
#import matplotlib.pyplot
Builder.load_string("""
<MyWidget>:
id: my_widget
FileChooserIconView:
id: filechooser
on_selection: my_widget.selected(filechooser.selection)
Image:
id: image
source: ""
""")
class MyWidget(BoxLayout):
def selected(self,filename):
self.ids.image.source = filename[0]
class MyApp(App):
def build(self):
return MyWidget()
if __name__ == '__main__':
MyApp().run()
The above code works and packages well.
Is it that there is some limit of the size of the files one can import to a kivy app? I have already tried to increase the recursion limit with sys.setrecursionlimit(high numbers) but it is not a solution to this problem.
I am really lost. Any insight appreciated.
Thank you
Edit 2/4/2019:
It has been suggested that the question: pyinstaller creating EXE RuntimeError: maximum recursion depth exceeded while calling a Python object is a duplicate and answers this question. Although this is definitively a related question and is helpful, my error occurs in the first stage of the creation of the kivy package:
python -m PyInstaller --name touchtracer examples-path\demo\touchtracer\main.py
Thank you so MUCH to everybody who tried to help.
I found an answer and I hope it helps other people who tries to create a kivy package and there is a problem importing python module(s).
Once you have your main.py script ready to package:
1.Start with the instructions at
https://kivy.org/doc/stable/guide/packaging-windows.html
and do the first step:
python -m PyInstaller --name touchtracer examples-path\demo\touchtracer\main.py
This will give you the error of maximum recursion depth exceeded or whatever error this gives to you originally. No worries. The purpose of this step is to create an initial spec file.
2.Open the spec file and add all the extras that the kivy instructions give you at
https://kivy.org/doc/stable/guide/packaging-windows.html
that is:
from kivy.deps import sdl2, glew
Tree('examples-path\\demo\\touchtracer\\'),
*[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)],
3.In addition to that, add at the beginning of the spec file the following:
import sys
sys.setrecursionlimit(5000) # (or some big number)
4.Also add any imports in the hidden imports that you might need.
hiddenimports=[] # change to (example importing pandas and matplotlib) hiddenimports=['pandas', 'matplotlib']
5.Just follow the last step at
https://kivy.org/doc/stable/guide/packaging-windows.html
that is:
python -m PyInstaller touchtracer.spec
and get your app built
When we go into a recursion, there is a risk of stack overflow and the Cpython working under the hood does not take it upon itself to optimize tail recursion, so if you go too deep, you will move closer towards a stack overflow. Generally different Cpython/python flavors have different recursion permit depth, The version of python you have running locally has a more liberal depth limit (Generally because it is assumed developers have good enough computers that this can take place). But when you use tools to package your application they generally override the sys.setrecursionlimit to a more conservative value as they try to make sure you don't cause an stack overflow on systems with lower hardware.
Sadly there is no silver bullet for this problem, you can try to look into your specific manager and change the limit (Not recommended) or you can try to convert your recursive blocks into iterative blocks.

"AttributeError: 'Turtle' object has no attribute 'colormode'" despite Turtle.py having colormode atttribute

I tried running the code that uses the Turtle library on this site, shown here,
import turtle
import random
def main():
tList = []
head = 0
numTurtles = 10
wn = turtle.Screen()
wn.setup(500,500)
for i in range(numTurtles):
nt = turtle.Turtle() # Make a new turtle, initialize values
nt.setheading(head)
nt.pensize(2)
nt.color(random.randrange(256),random.randrange(256),random.randrange(256))
nt.speed(10)
wn.tracer(30,0)
tList.append(nt) # Add the new turtle to the list
head = head + 360/numTurtles
for i in range(100):
moveTurtles(tList,15,i)
w = tList[0]
w.up()
w.goto(0,40)
w.write("How to Think Like a ",True,"center","40pt Bold")
w.goto(0,-35)
w.write("Computer Scientist",True,"center","40pt Bold")
def moveTurtles(turtleList,dist,angle):
for turtle in turtleList: # Make every turtle on the list do the same actions.
turtle.forward(dist)
turtle.right(angle)
main()
in my own Python editor and I got this error:
turtle.TurtleGraphicsError: bad color sequence: (236, 197, 141)
Then, based on this answer on another site, I added in this line before "nt.color(......)"
nt.colormode(255)
Now it's showing me this error
AttributeError: 'Turtle' object has no attribute 'colormode'
Okay, so I checked my Python library and looked into the contents of Turtle.py. The colormode() attribute is definitely there. What is making the code able to run on the original site but not on my own computer?
The issue is that your Turtle object (nt) doesn't have a colormode method. There is one in the turtle module itself though.
So you just need:
turtle.colormode(255)
instead of
nt.colormode(255)
Edit: To try to clarify your question in the comment, suppose I create a module called test.py, with a function, and a class, 'Test':
# module test.py
def colormode():
print("called colormode() function in module test")
class Test
def __init__(self):
pass
Now, I use this module:
import test
nt = test.Test() # created an instance of this class (like `turtle.Turtle()`)
# nt.colormode() # won't work, since `colormode` isn't a method in the `Test` class
test.colormode() # works, since `colormode` is defined directly in the `test` module
Screen class in turtle module has colormode() method.
You can call screen_object.colormode(255).
In your code it would be:
wn.colormode(255)
The problem is that you need to set up the colormode() attribute = 255. The class to reference is Screen(), based on your code you referenced this code as wn = turtle.Screen(). In order for you to make your code work, just by adding the following line of code.
wn.colormode(255)

Categories