I have a fullscreen app and I'm trying to hide the mouse cursor. The setup is Kivy 1.9.0 on Python 3.4.1 for Windows, using the prepared packages.
I have tried the following approaches, with no success:
1- Using Config object:
from kivy.config import Config
Config.set("graphics", "show_cursor", 0)
2- Editing .kivy\config.ini:
[graphics]
.
.
.
show_cursor = 0
3- Using pygame:
import pygame
pygame.init()
pygame.mouse.set_visible(False)
4- Moving the mouse off-screen:
def move_mouse_away(etype, motionevent):
# this one doesn't get called at all
Window.mouse_pos = [1400, 1000]
Window.bind(on_motion=move_mouse_away)
5- Using Clock for a similar effect:
Clock.schedule_interval(self._reset_mouse, 0.05)
def _reset_mouse(self, time):
Window.mouse_pos = [1400, 1400]
I'm a little out of ideas now.
You can use Window.show_cursor
It was added in kivy version 1.9.1
from kivy.core.window import Window
Window.show_cursor = False
I just read the documentation, tried it and fixed it (version 1.9.0). To hide the cursor from the application window permanently (even if you are using a touchscreen) :
>>> from kivy.config import Config
>>> Config.set('graphics','show_cursor','0')
>>> Config.write()
>>> quit()
I use a touch screen (LG 19MB15T) which works 'out_of_the_box'.
I'm having the same kind of problem: I need to hide or change my mouse cursor in a kivy app.
I don't have a perfect solution only a partial one:
from kivy.uix.widget import Widget
from kivy.core.window import Window
import win32api
class NoCursorWindow(Widget):
def __init__(self, **kwargs):
super(NoCursorWindow, self).__init__(**kwargs)
Window.bind(mouse_pos=self.on_mouse_pos)
def on_mouse_pos(self, *args):
win32api.SetCursor(None)
if __name__ == '__main__':
from kivy.base import runTouchApp
runTouchApp(NoCursorWindow())
It works only partially:
The problem when you use win32api.SetCursor() is that when the mouse moves, the window gets a WM_SETCURSOR Message which changes the cursor back to default. This is why the win32api.SetCursor() must be triggered for each change of the mouse_pos.
But even like that sometimes we can see the default cursor blinking.
If anyone knows how to hook the WM_SETCURSOR, to prevent the call back of the default cursor, it could solve this...
Related
When I run a kivy program in Pycharm, the kivy window doesn't have the default kivy app title, the kivy logo in top-left nor the 3 control buttons in the top-right. It completely occupies my screen and I can't do anything anymore. I'm on Windows 10. Need help, please.
I'm using Python 3.9.0, kivy 2.0.0
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.uix.label import Label
class MainWidget(Widget):
pass
class boxLayoutExample(BoxLayout):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.orientation = "vertical"
item1 = Button(text='a button')
self.add_widget(item1)
item2 = Label(text='a label')
self.add_widget(item2)
item3 = Button(text='a button')
self.add_widget(item3)
class myApp(App):
pass
myApp().run()
the key is the configuration which can either be modified using the config.ini file or the config object.
on my windows system the config file is in C:\users<username>.kivy\config.ini
and you may have to change Windows Explorer to show hidden items if you want to see the .kivy directory.
inside that configuration file, the borderless property being set to 1 could cause this behavior so set this to 0. The curios thing is that by default this should have been 0 so I don't know why it would have changed.
[graphics]
borderless = 0
and you may also be interested in these properties
width = 1200
height = 600
fullscreen = 0
from kivy import Config
Config.set("graphics", "fullscreen", "0")
RTFM -> go here
Following a previous StackOverflow answer I made additions to one of the basic Kivy tutorial apps to position the window at the top left corner of the screen. This works as expected under Xorg, but not under Wayland/xwayland.
How do you change the Kivy window position when running under xwayland?
Code:
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.core.window import Window
class MyPaintWidget(Widget):
pass
class MyPaintApp(App):
def build(self):
# Works under Xorg, not under Wayland
Window.top = 0
Window.left = 0
return MyPaintWidget()
if __name__ == '__main__':
MyPaintApp().run()
Kivy does have Wayland support, but it may not be compiled-in. See setup.py. Also note that this will require SDL2 support to be compiled-in, as well:
# change both to "True"
c_options['use_wayland'] = False
c_options['use_sdl2'] = False
I recently learnt about the Python framework kivy and started to follow the simple paint app tutorial. Now I want to save what was drawn as a .png file but instead of the colored dots it only exports the black background.
This is my code example:
import kivy
kivy.require("1.9.1")
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.graphics import Color, Ellipse, Line
class MyPaintWidget(Widget):
def on_touch_down(self,touch):
color=(0,0,1)
with self.canvas:
Color(*color)
d=30.
Ellipse(pos=(touch.x-d/2., touch.y-d/2.), size=(d,d))
class MyPaintApp(App):
def build(self):
parent=Widget()
self.painter=MyPaintWidget()
ssbtn=Button(text='Save')
ssbtn.bind(on_release=self.save_screenshot)
parent.add_widget(self.painter)
parent.add_widget(ssbtn)
return parent
def save_screenshot(self,obj):
self.painter.export_to_png("screenshot.png")
if __name__ == '__main__':
MyPaintApp().run()
What am I doing wrong? Thanks for your help.
You are missing one thing - Widget won't set its size and position automatically to whole Window size, but only to default ones i.e. pos = [0, 0] size = [100, 100] because Window != Layout and even adding it to something that doesn't inherit from a Layout won't make it better (Widget != Layout) which you can easily see if you look a that saved png (is too small).
self.painter=MyPaintWidget(size=[800,600])
will make the job for you if you plan to stay only on pc and only with the default Window size. If not, then use:
from kivy.core.window import Window
self.painter=MyPaintWidget(size=Window.size)
which seems to be more practical, yet you're still not there. An optimal solution would be using a Layout which does these things for you such as BoxLayout, GridLayout or some others.
And a perfect solution for you would be to use a StencilViewin a Layout, which when is placed won't take a screenshot of the whole canvas, but only the part you'd think it'll take i.e. the part sized as the Widget itself placed on its position.
Try drawing outside of the red box. Inspector will provide you with showing widgets in a color and other functions, so definitely try it as it was mentioned in the comments.
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.core.window import Window
from kivy.uix.stencilview import StencilView
from kivy.graphics import Color, Ellipse, Line, Rectangle
class MyPaintWidget(StencilView):
def on_touch_down(self,touch):
color=(0,0,1)
with self.canvas:
Color(*color)
d=30.
Ellipse(pos=(touch.x-d/2., touch.y-d/2.), size=(d,d))
class MyPaintApp(App):
def build(self):
parent=Widget()
self.painter=MyPaintWidget(size=[i/2.0 for i in Window.size])
with self.painter.canvas:
Color(1, 0, 0, 0.3)
Rectangle(pos=self.painter.pos, size=self.painter.size)
ssbtn=Button(text='Save')
ssbtn.bind(on_release=self.save_screenshot)
parent.add_widget(self.painter)
parent.add_widget(ssbtn)
return parent
def save_screenshot(self,obj):
self.painter.export_to_png("screenshot.png")
MyPaintApp().run()
I created a simple text-to-speech app with Kivy, using the FloatLayout option but am having trouble changing the color of the GUI without actually creating a .kv file (which I do not wish to do). The code of my app is here:
import kivy
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.image import Image
import requests
from threading import Thread
import os
class ButtonApp(App):
def talk(self):
self.info.text = self.text.text
command = "say %s" % (self.text.text)
os.system(command)
def say(self,instance):
t = Thread(target=self.talk)
t.start()
def build(self):
self.b = FloatLayout()
self.info = Label(text="Hello!", pos=(20,400) ,size_hint=(1,0.5), font_size="40sp")
self.text = TextInput(text='Hello!', pos=(20,200), size_hint=(1,0.5))
self.submit = Button(on_press=self.say,text='Submit',pos=(20,100), size_hint=(1,0.5))
self.b.add_widget(self.info)
self.b.add_widget(self.text)
self.b.add_widget(self.submit)
self.b.bind()
return self.b
if __name__ == "__main__":
ButtonApp().run()
Like I mentioned beforehand, all the suggestions I found doing prior research involved either Canvas (which I am not using), or creating a .kv file. Is there a pure python-kivy method of changing the color of a GUI?
You can do anything in pure python, though the reason you see so many kv examples is because it's easier and more concise due to being a more domain specific language, so I don't recommend avoiding it.
What kind of change do you actually want to make? For instance, you can change the background image of the Button with the background_normal or background_down properties (which take a filepath to an image), or tint its colour by setting its background_color to e.g. (1, 0, 0, 1) for red.
I have this sample program written in Python and Kivy:
#!/usr/bin/env python2.7
# -*- coding: utf-8 -*-
import time
from kivy.app import App
from kivy.core.window import Window
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.image import AsyncImage
from kivy.uix.label import Label
class Application(App):
def build(self):
keyboard = Window.request_keyboard(None, self)
keyboard.bind(on_key_down=self.__on_key_down)
box_layout = BoxLayout(orientation='vertical')
self.__label = Label(text='Ready')
box_layout.add_widget(self.__label)
self.__img = AsyncImage()
box_layout.add_widget(self.__img)
return box_layout
def __on_key_down(self, keyboard, keycode, text, modifiers):
self.__set_status('Loading, please wait...')
print(self.__label.text)
time.sleep(3) # simulates long image download time
self.__img.source = 'http://pl.python.org/forum/Smileys/default/cheesy.gif'
def __set_status(self, text):
self.__label.text = text
# self.__label.canvas.ask_update()
app = Application()
app.run()
Basically what I want to do is label which displays status of application like: Ready, loading, done, etc. but my widget is not updating text when it should.
What can I do to immediately update text in self.__label widget?
I've tried ask_update() method but it seems to not work for this case.
You're blocking Kivy from doing anything when you call time.sleep. Kivy can't update the screen or process input until your function returns control to the main loop.
When you set the source of the AsyncImage, the image will be downloaded in the background without blocking the main loop. This widget is designed to just work automatically. It will display a loading animation until the image is downloaded, so you don't need to show any text.
If you want to show your own loading text, however, you can do so by using Loader directly. It will return a ProxyImage which you can use to determine when the image has loaded:
def __on_key_down(self, keyboard, keycode, text, modifiers):
self.__set_status('Loading, please wait...')
proxy = Loader.image('http://pl.python.org/forum/Smileys/default/cheesy.gif')
proxy.bind(on_load=self.__image_loaded)
def __image_loaded(self, proxy):
if proxy.image.texture:
self.__img.texture = proxy.image.texture
self.__set_status('Done')