I need to create an app that works on a VR glasses, as in this example below:
But I have two problems:
I can not make two simultaneous accesses to the camera and create two widgets.
I can not make the widgets created in kv file (in this case a label) stay on the camera, to write information about the view.
Any way to create this dual camera widget and write it over?
my code:
main:
__version__ = '1.0'
from kivy.lang import Builder
from kivy.app import App
from kivy.properties import ObjectProperty, ListProperty, BooleanProperty, \
NumericProperty
from kivy.uix.widget import Widget
from kivy.uix.boxlayout import BoxLayout
from jnius import autoclass, PythonJavaClass, java_method, cast
from android.runnable import run_on_ui_thread
PythonActivity = autoclass('org.renpy.android.PythonActivity')
Camera = autoclass('android.hardware.Camera')
SurfaceView = autoclass('android.view.SurfaceView')
LayoutParams = autoclass('android.view.ViewGroup$LayoutParams')
class PreviewCallback(PythonJavaClass):
__javainterfaces__ = ('android.hardware.Camera$PreviewCallback', )
def __init__(self, callback):
super(PreviewCallback, self).__init__()
self.callback = callback
class SurfaceHolderCallback(PythonJavaClass):
__javainterfaces__ = ('android.view.SurfaceHolder$Callback', )
def __init__(self, callback):
super(SurfaceHolderCallback, self).__init__()
self.callback = callback
#java_method('(Landroid/view/SurfaceHolder;III)V')
def surfaceChanged(self, surface, fmt, width, height):
self.callback(fmt, width, height)
class AndroidWidgetHolder(Widget):
view = ObjectProperty(allownone=True)
def __init__(self, **kwargs):
self._old_view = None
from kivy.core.window import Window
self._window = Window
kwargs['size_hint'] = (None, None)
super(AndroidWidgetHolder, self).__init__(**kwargs)
def on_view(self, instance, view):
activity = PythonActivity.mActivity
activity.addContentView(view, LayoutParams(*self.size))
view.setZOrderOnTop(True)
view.setX(self.x)
view.setY(self._window.height - self.y - self.height)
class AndroidCamera(Widget):
index = NumericProperty(0)
__events__ = ('on_preview_frame', )
def __init__(self, **kwargs):
self._holder = None
self._android_camera = None
super(AndroidCamera, self).__init__(**kwargs)
self._holder = AndroidWidgetHolder(size=self.size, pos=self.pos)
self.add_widget(self._holder)
self.start()
#run_on_ui_thread
def stop(self):
if self._android_camera is None:
return
self._android_camera.setPreviewCallback(None)
self._android_camera.release()
self._android_camera = None
self._holder.view = None
#run_on_ui_thread
def start(self):
if self._android_camera is not None:
return
self._android_camera = Camera.open(self.index)
self._android_surface = SurfaceView(PythonActivity.mActivity)
surface_holder = self._android_surface.getHolder()
self._android_surface_cb = SurfaceHolderCallback(self._on_surface_changed)
surface_holder.addCallback(self._android_surface_cb)
self._holder.view = self._android_surface
self._holder2.view = self._android_surface
def _on_surface_changed(self, fmt, width, height):
params = self._android_camera.getParameters()
params.setPreviewSize(width, height)
self._android_camera.setParameters(params)
self._previewCallback = PreviewCallback(self._on_preview_frame)
self._android_camera.setPreviewCallbackWithBuffer(self._previewCallback);
self._android_camera.setPreviewDisplay(self._android_surface.getHolder())
self._android_camera.startPreview();
def _on_preview_frame(self, camera, data):
self.dispatch('on_preview_frame', camera, data)
self._android_camera.addCallbackBuffer(data)
def on_preview_frame(self, camera, data):
pass
def on_size(self, instance, size):
if self._holder:
self._holder.size = size
def on_pos(self, instance, pos):
if self._holder:
self._holder.pos = pos
class vrtest(App, BoxLayout):
def build(self):
return Builder.load_file('qrcode.kv')
camera_size = ListProperty([640, 480])
xpos = NumericProperty(-190)
ypos = 25
def __init__(self, **kwargs):
super(vrtest, self).__init__(**kwargs)
self._camera = AndroidCamera(
size=self.camera_size,
size_hint=(None, None),
pos=(self.xpos, self.ypos))
self.add_widget(self._camera)
def start(self):
self._camera.start()
if __name__ == '__main__':
vrtest().run()
kv:
FloatLayout:
Label:
text: 'Label Test12345678987654321'
pos_hint:{'x':0, 'y':0}
Related
I tried to make Galaxy project. I am having A Mistake in between!
This I am try through freecodecamp.org kivy full course.
I am beginner to kivy.
See if there is problem in canvas.
I wasn't able to see my drawn lines on kivy window.
Here are My files:
main.py
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.graphics import *
from kivy.lang import Builder
from kivy.properties import NumericProperty
Builder.load_file('galaxy.kv')
class MainWidget(Widget):
perspective_point_x = NumericProperty(0)
perspective_point_y = NumericProperty(0)
V_NB_LINES = 7
V_NB_SPACING = .1
vertical_lines = []
def __init__(self, **kwargs):
super(MainWidget, self).__init__(**kwargs)
self.init_vertical_lines()
def on_parent(self, widget, parent):
pass
def on_size(self, *args):
self.update_vertical_lines()
def on_perspective_point_x(self, widget, value):
pass
def on_perspective_point_y(self, widget, value):
pass
def init_vertical_lines(self):
with self.canvas:
Color(1, 1, 1)
for i in range(0, self.V_NB_LINES):
self.vertical_lines.append(Line())
def update_vertical_lines(self):
central_line_x = int(self.width/2)
spacing = int(self.V_NB_SPACING * self.width)
offset = -int(self.V_NB_LINES/2)
for i in range(0, self.V_NB_LINES):
line_x = central_line_x + offset*spacing
self.vertical_lines[i].points = [line_x, 0, line_x, self.height]
offset += 1
class GalaxyApp(App):
pass
GalaxyApp().run()
galaxy.kv
<MainWidget>
perspective_point_x: self.width / 2
perspective_point_y: self.height * 0.75
You where missing the build function in GalaxyApp
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.graphics import *
from kivy.lang import Builder
from kivy.properties import NumericProperty
Builder.load_file('galaxy.kv')
class MainWidget(Widget):
perspective_point_x = NumericProperty(0)
perspective_point_y = NumericProperty(0)
V_NB_LINES = 7
V_NB_SPACING = .1
vertical_lines = []
def __init__(self, **kwargs):
super(MainWidget, self).__init__(**kwargs)
self.init_vertical_lines()
def on_parent(self, widget, parent):
pass
def on_size(self, *args):
self.update_vertical_lines()
def on_perspective_point_x(self, widget, value):
pass
def on_perspective_point_y(self, widget, value):
pass
def init_vertical_lines(self):
with self.canvas:
Color(1, 1, 1)
for i in range(0, self.V_NB_LINES):
self.vertical_lines.append(Line())
def update_vertical_lines(self):
central_line_x = int(self.width/2)
spacing = int(self.V_NB_SPACING * self.width)
offset = -int(self.V_NB_LINES/2)
for i in range(0, self.V_NB_LINES):
line_x = central_line_x + offset*spacing
with self.canvas:
self.vertical_lines[i].points = [line_x, 0, line_x, self.height]
offset += 1
class GalaxyApp(App):
def build(self):
return MainWidget()
GalaxyApp().run()
I have a music player app that reads the cover of songs and displays them on the screen. For this I created my own class ByteFitImage for the image to read bytes and for it to adapt to different sizes.
The problem I am encountering is that if I decide to change the data, I get a key error:
KeyError: 'source'
And obviously this line is causing the problem:
self.kv.ids.img.data = BytesIO(second_img.read())
Why is it asking for source? My Code:
from io import BytesIO
from kivy.clock import Clock
from kivy.core.image import Image
from kivy.graphics.context_instructions import Color
from kivy.graphics.vertex_instructions import Rectangle
from kivy.lang import Builder
from kivy.properties import BooleanProperty, ObjectProperty, VariableListProperty, Property
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.widget import Widget
from kivy.app import App
class ByteFitImage(BoxLayout):
data = Property(None)
radius = VariableListProperty([0], length=4)
mipmap = BooleanProperty(False)
_container = ObjectProperty()
def __init__(self, **kwargs):
super().__init__(**kwargs)
Clock.schedule_once(self._late_init)
def _late_init(self, *args):
self._container = Container(self.data)
self.bind(data=self._container.setter("source"))
self.add_widget(self._container)
def reload(self):
self._container.image.reload()
class Container(Widget):
# source = ObjectProperty()
image = ObjectProperty()
def __init__(self, source, **kwargs):
super().__init__(**kwargs)
# self.image = AsyncImage(mipmap=mipmap)
self.bind(size=self.adjust_size, pos=self.adjust_size)
self.image = Image(source, ext="jpg")
self.image.bind(on_load=self.adjust_size)
# self.source = source
def on_source(self, instance, value):
if isinstance(value, str):
self.image.source = value
else:
self.image.texture = value
self.adjust_size()
def adjust_size(self, *args):
if not self.parent or not self.image.texture:
return
(par_x, par_y) = self.parent.size
if par_x == 0 or par_y == 0:
with self.canvas:
self.canvas.clear()
return
par_scale = par_x / par_y
(img_x, img_y) = self.image.texture.size
img_scale = img_x / img_y
if par_scale > img_scale:
(img_x_new, img_y_new) = (img_x, img_x / par_scale)
else:
(img_x_new, img_y_new) = (img_y * par_scale, img_y)
crop_pos_x = (img_x - img_x_new) / 2
crop_pos_y = (img_y - img_y_new) / 2
subtexture = self.image.texture.get_region(
crop_pos_x, crop_pos_y, img_x_new, img_y_new
)
with self.canvas:
self.canvas.clear()
Color(1, 1, 1)
Rectangle(texture=subtexture, pos=self.pos, size=(par_x, par_y))
class Example(App):
def __init__(self, **kwargs):
with open("images/song_img.jpg", "rb") as song_img:
self.song_img_bytes = BytesIO(song_img.read())
super(Example, self).__init__(**kwargs)
self.kv = Builder.load_string('''
#:kivy 2.0.0
BoxLayout:
orientation: "vertical"
padding: 10
ByteFitImage:
id: img
data: app.song_img_bytes
Button:
text: "Change cover!"
font_size: 32
on_release: app.change_cover()''')
def build(self):
return self.kv
def change_cover(self):
with open("images/second_img.jpg", "rb") as second_img:
self.kv.ids.img.data = BytesIO(second_img.read())
if __name__ == '__main__':
Example().run()
How to resolve widget overlapping in kivy framework, I am adding widgets in for cycle so I have more than one widget but all of them comes to be in one place, how can I prevent this?
My python code:
from kivy.app import App
from kivymd.app import MDApp
from kivy.uix.label import Label
from kivy.clock import Clock
from kivy.graphics import Color
from kivy.uix.widget import Widget
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
from kivymd.uix.card import MDCard
from kivy.properties import StringProperty
from kivy.lang import Builder
import requests, time, collections
class request_sender():
return 'DATA'
class CustomLabel(Label):
pass
class CustomBox(BoxLayout):
pass
class AuctionCard(Widget):
auc_timer = ''
auc_img = ''
auc_name = ''
def __init__(self, **kwargs):
super(AuctionCard, self).__init__(**kwargs)
with self.canvas.before: Color(1, 0, .4, mode='rgb')
Clock.schedule_once(self.load_info)
def load_info(self, dt):
print(self.auc_name)
self.size_hint = None, None
box = BoxLayout(orientation='vertical', size = (800, 600))
box.size_hint_x = 50;
box.height = 100
AuctionName = CustomLabel(text=self.auc_name, pos_hint={'top': 300.9})
AuctionImage = CustomLabel(text=self.auc_img)
AuctionTimer = CustomLabel(text=self.auc_name)
box.add_widget(AuctionName)
box.add_widget(AuctionTimer)
box.add_widget(AuctionImage)
self.add_widget(box)
class MyWidget(Widget):
prop = StringProperty('')
array_of_labels = []
prop1 = StringProperty('Second card')
n = 0
all_cards = collections.defaultdict()
def __init__(self, **kwargs):
super(MyWidget, self).__init__(**kwargs)
self.screen_load()
def timer_le(self, dt):
returned_data = request_sender().sender_update('ajax.php')
for key in self.all_cards:
for data in returned_data:
if data['pid'] == key:
self.all_cards[key][0].text = str(data['remaining_time'])
def screen_load(self):
returned_data = request_sender().sender_update('ajax.php')
box = GridLayout(cols=2)
self.size_hint = None, None
for data in returned_data:
AucCard = AuctionCard()
AucCard.auc_name = str(data['auc_name'])+'\n\n'
AucCard.auc_timer = str(data['remaining_time'])+'\n\n'
AucCard.auc_img = str(data['auc_img'])+'\n\n'
box.add_widget(AucCard)
print('Widget added')
self.add_widget(box)
#self.all_cards[str(data['pid'])] = [AucCard]
#Clock.schedule_interval(self.timer_le, 1/30)
class TestApp(App):
def build(self):
box = GridLayout(cols=2)
return MyWidget()
TestApp().run()
My kv code:
<CustomLabel>:
size_hint_y: None
text_size: self.width, None
height: self.texture_size[1]
Result:
Kind of result that I want to create:
Actually I found easy way to solve this issue. The problem was in parent class of my AuctionCard and MyWidget classes, I set parent class to Widget but for the AuctionCard it should be BoxLayout and for MyWidget GridLayout. So from there I managed to set cols = 2 and size to window.size. From here it works exactly how it should work.
from kivy.lang import Builder
from kivy.app import App
from kivy.core.window import Window
from kivy.uix.widget import Widget
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.clock import Clock
from kivy.uix.gridlayout import GridLayout
class AuctionCard(BoxLayout):
auc_timer = ''
auc_img = ''
auc_name = ''
def __init__(self, **kwargs):
super(AuctionCard, self).__init__(**kwargs)
Clock.schedule_once(self.load_info)
def load_info(self, dt):
self.orientation = 'vertical'
AuctionName = Label(text=self.auc_name)
AuctionImage = Label(text=self.auc_img)
AuctionTimer = Label(text=self.auc_timer)
self.add_widget(AuctionName)
self.add_widget(AuctionTimer)
self.add_widget(AuctionImage)
class MyWidget(GridLayout):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.cols = 2
self.size = (Window.size[0], self.size[1])
self.load_app()
print('MyWidget size: '+str(self.size))
def load_app(self):
self.size_hint = None, None
returned_data = [{'auc_name':'name 1', 'remaining_time':'100', 'auc_img':'https://img.src'},
{'auc_name':'name 2', 'remaining_time':'200', 'auc_img':'https://img.src'},
{'auc_name':'name 3', 'remaining_time':'300', 'auc_img':'https://img.src'}]
for data in returned_data:
AucCard = AuctionCard()
AucCard.auc_name = str(data['auc_name'])+'\n\n'
AucCard.auc_timer = str(data['remaining_time'])+'\n\n'
AucCard.auc_img = str(data['auc_img'])+'\n\n'
self.add_widget(AucCard)
print('Widget added')
class MyTestApp(App):
def __init__(self, **kwargs):
self.title = "My Material Application"
super().__init__(**kwargs)
def build(self):
return MyWidget()
if __name__ == "__main__":
MyTestApp().run()
Result:
Result
i'm using kivy for building an app screen with 3 screens.
my main screen ( class Base) is showing data from a SQL request.
i would like the user to be able to update these data using a button.
first this class Base is called in the screen manager which is itself called in my root class.
So my question is , how do i clear the data in my class Base and update it with the new data?
i tried to clear the data in my class screen manager.
the refresh function is called from the root class.
i have the below error:
'ScreenManager uses remove_widget only for removing Screens'
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from kivy.uix.label import Label
from sql import runsql2
from kivy.core.window import Window
class Manager(ScreenManager):
def __init__(self):
super(Manager, self).__init__()
for i in range(2):
txt = 'Screen {}'.format(i)
lbl = Label(text=txt)
screen = Screen(name=txt)
screen.add_widget(lbl)
self.add_widget(screen)
base=Base('main')
self.add_widget(base)
def refresh(self):
self.clear_widgets(screens='main')
base=Base('main')
self.add_widget(base)
class Nav(GridLayout):
def __init__(self,sm=None):
super(Nav, self).__init__()
self.sm = sm
self.cols =3
self.size_hint = (1,0.1)
self.add_widget(Button(text="Clearing Screen", on_release=self.change))
self.add_widget(Button(text="Go screen 2", on_release=self.goscreen))
self.add_widget(Button(text="Quit", on_release=self.quit))
def change(self, btn):
#self.sm.current = btn.text
self.sm.current='main'
def quit(self,ins):
exit()
def goscreen(self,ins):
self.sm.current='Screen 1'
class Base(Screen):
def __init__(self,name):
super(Base, self).__init__()
self.lay=GridLayout()
self.name=name
self.bout=['[color=33ff99]Refresh[/color]','',"","","","","","","","",""]
self.data=runsql2()
self.lay.cols = 11
self.titre=['[color=ff9900]Market[/color]', '[color=ff9900]B/S[/color]', '[color=ff9900]Volume[/color]', '[color=ff9900]Contract[/color]',
'[color=ff9900]C/P[/color]', '[color=ff9900]Expiry[/color]', '[color=ff9900]Strike[/color]', '[color=ff9900]Price[/color]',
'[color=ff9900]Account[/color]', '[color=ff9900]Give up Member[/color]', '[color=ff9900]Allocation Account[/color]']
#self.lay.add_widget(Button(text='[color=33ff99]Refresh[/color]', size_hint=(1, 0.15), markup=True,on_release=self.do))
for i in range(11):
self.lay.add_widget(Label(text='', size_hint=(1, 0.15)))
for j in range(11):
self.lay.add_widget(Label(text=str(self.titre[j]),size_hint=(0.2,0.2),markup=True))
long = len(self.data)
for i in range(long):
for j in range(11):
self.lay.add_widget(Label(text=str(self.data[i][j])))
self.add_widget(self.lay)
class Root(BoxLayout):
def __init__(self):
super(Root, self).__init__()
self.orientation = "vertical"
#Window.clearcolor = (0.6, 0.6, 0.6,1)
sm = Manager()
self.add_widget(Nav(sm=sm))
self.add_widget(sm)
self.add_widget(Button(text='refresh',size_hint=(0.2,0.2),on_release=self.refresh))
Window.size = (1500, 900)
def refresh(self,ins):
sm=Manager()
sm.refresh()
class TestApp(App):
def build(App):
return Root()
if __name__ == '__main__':
TestApp().run()
Two problems with your code. First, in your refresh() method, the self.clear_widgets(screens='main') is incorrect. The screens arg must be a list of screens. So it should be
def refresh(self):
self.clear_widgets(screens=[self.get_screen('main')])
base=Base('main')
self.add_widget(base)
Since you are only removing one screen, you could use self.remove_widget(self.get_screen('main')) instead.
And, second, your refresh() method in the Root class is creating a new Manager class and calling the refresh() method of that new Manager rather than the one you have displayed. To correct this, you can save a reference to the original Manager, and use that reference in the refresh() method:
class Root(BoxLayout):
def __init__(self):
super(Root, self).__init__()
self.orientation = "vertical"
#Window.clearcolor = (0.6, 0.6, 0.6,1)
sm = Manager()
self.sm = sm # keep a reference for later use
self.add_widget(Nav(sm=sm))
self.add_widget(sm)
self.add_widget(Button(text='refresh',size_hint=(0.2,0.2),on_release=self.refresh))
Window.size = (1500, 900)
def refresh(self,ins):
self.sm.refresh()
I'm trying to make a screen that has two rows, one of those rows are the actual game screen and the another one is a button to clear the table above. But the problem here is that the first row is blank when I run the app. That's the code that I am stuck till now:
import kivy
from kivy.app import App
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
kivy.require('1.9.2')
class VelhaGame(GridLayout, Screen):
def __init__(self, **kwargs):
super(VelhaGame, self).__init__(**kwargs)
self.cols = 3
self.rows = 3
self.font_size = 100
self.buttons = []
for i in range(9):
button = Button(text='', font_size=self.font_size)
button.bind(on_release=self.player_turn)
self.add_widget(button)
self.buttons.append(button)
self.player1 = True
def player_turn(self, button, *args):
if self.player1 and button.text == '':
self.player1 = False
button.text = 'X'
elif not self.player1 and button.text == '':
self.player1 = True
button.text = 'O'
class MainMenu(GridLayout, Screen):
def __init__(self, **kwargs):
super(MainMenu, self).__init__(**kwargs)
self.cols = 1
self.rows = 2
self.button_play = Button(text='PLAY', font_size=40)
self.button_play.bind(on_release=self.play)
self.add_widget(self.button_play)
self.button_exit = Button(text='EXIT', font_size=40)
self.button_exit.bind(on_release=self.exit)
self.add_widget(self.button_exit)
def play(self, *args):
screen_manager.current = 'velhaPage'
def exit(self, *args):
App.get_running_app().stop()
game_screen_manager = ScreenManager()
game_screen_manager.add_widget(VelhaGame(name='velhaGame'))
class VelhaScreen(GridLayout, Screen):
def __init__(self, **kwargs):
super(VelhaScreen, self).__init__(**kwargs)
self.rows = 2
self.add_widget(game_screen_manager)
self.clear_button = Button(text='Clear', font_size=40)
self.add_widget(self.clear_button)
screen_manager = ScreenManager()
screen_manager.add_widget(MainMenu(name='menu'))
screen_manager.add_widget(VelhaScreen(name='velhaPage'))
class VelhaGameApp(App):
def build(self):
return screen_manager
if __name__ == '__main__':
VelhaGameApp().run()
Do you know what I could do to accomplish this task?
The answer to you question, is "You cannot do that".
Screenmanager only shows one screen at a time.
you can read about that in the docs https://kivy.org/docs/api-kivy.uix.screenmanager.html
But to acheive something like you are trying to, you could do like this:
Instead of screens inside another screen, you could put the gridlayout, and button inside a vertical orientated boxlayout like this:
import kivy
from kivy.app import App
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.properties import ListProperty
kivy.require('1.9.1')
class VelhaGame(Screen):
buttons = ListProperty([])
def __init__(self, **kwargs):
super(VelhaGame, self).__init__(**kwargs)
self.game_window = BoxLayout(orientation="vertical")
self.add_widget(self.game_window)
self.game_table = GridLayout(cols=3,rows=3)
for i in range(9):
button = Button(text='', font_size="100sp")
button.bind(on_release=self.player_turn)
self.game_table.add_widget(button)
self.buttons.append(button)
self.player1 = True
self.clear_button = Button(on_press=self.clear,text='Clear', font_size="40sp")
self.game_window.add_widget(self.game_table)
self.game_window.add_widget(self.clear_button)
def clear(self,*args):
for button in self.buttons:
button.text = ""
def player_turn(self, button, *args):
if self.player1 and button.text == '':
self.player1 = False
button.text = 'X'
elif not self.player1 and button.text == '':
self.player1 = True
button.text = 'O'
class MainMenu(GridLayout, Screen):
def __init__(self, **kwargs):
super(MainMenu, self).__init__(**kwargs)
self.cols = 1
self.rows = 2
self.button_play = Button(text='PLAY', font_size="40sp")
self.button_play.bind(on_release=self.play)
self.add_widget(self.button_play)
self.button_exit = Button(text='EXIT', font_size=40)
self.button_exit.bind(on_release=self.exit)
self.add_widget(self.button_exit)
def play(self, *args):
screen_manager.current = 'velhaPage'
def exit(self, *args):
App.get_running_app().stop()
screen_manager = ScreenManager()
screen_manager.add_widget(MainMenu(name='menu'))
screen_manager.add_widget(VelhaGame(name='velhaPage'))
class VelhaGameApp(App):
def build(self):
return screen_manager
if __name__ == '__main__':
VelhaGameApp().run()