So, I've been trying to get a popup to open on Kivy, and close it with when pressing Escape. However I found myself having to press it twice, and then I found out that it was opening two popups.
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.core.window import Window
from kivy.uix.popup import Popup
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.config import Config
Config.set('kivy', 'exit_on_escape', '0')
class KeyDown(App):
def build(self):
self.popup_exists = 0
Window.bind(on_key_down=self.key_action)
return Widget()
def key_action(self, *args):
key1 = args[1]
key2 = args[2]
special_keys = args[4]
letter = args[3]
if special_keys == ['ctrl'] and letter == 'f': # Ctrl-F
print('Find')
self.open_find_dialog()
if key1 == 13 and key2 == 40 and self.popup_exists == 1: # ENTER KEY
pass
if key1 == 27 and key2 == 41 and self.popup_exists == 1: # ESC
self.find_window.dismiss()
def open_find_dialog(self):
content = BoxLayout(orientation='horizontal')
col1_cont = BoxLayout(size_hint_x = 2,orientation = 'vertical')
col2_cont = BoxLayout(size_hint_x = 4,orientation = 'vertical')
find_labl = Label(text='Find',size_hint_y=None, height = 40)
repl_labl = Label(text='Replace',size_hint_y=None, height = 40)
find_text = TextInput(text='', size_hint_y = None, height = 40)
repl_text = TextInput(text='', size_hint_y = None, height = 40)
col1_cont.add_widget(find_labl)
col1_cont.add_widget(repl_labl)
col2_cont.add_widget(find_text)
col2_cont.add_widget(repl_text)
content.add_widget(col1_cont)
content.add_widget(col2_cont)
self.find_window = Popup(title='Find and Replace',content = content,size_hint=(None, None), size=(240, 140))
self.find_window.open()
self.popup_exists = 1
if __name__ == '__main__':
KeyDown().run()
Does anyone know why would it open two popups? How would I prevent it from doing so?
Related
I am new to Kivy and I am sort of stuck. I am using GridLayout to make my app and I am having some trouble putting a video in my background. The code I will post makes an app with a black background. How do I replace the black background with a video, particularly mp4. I would also like to make the video darker if possible. I wanted to use AnchorPoint but I am not quite sure how to put both in there. Any help will be appreciated.
from kivy.app import App
from kivy.uix.video import Video
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.image import Image
from kivy.uix.button import Button
from kivy.uix.textinput import TextInput
class MZ_Invest(App):
def build(self):
self.root_layout = FloatLayout()
self.window = GridLayout()
self.window.cols = 1
self.window.size_hint = (0.6,0.7)
self.window.pos_hint = {"center_x":0.5, "center_y":0.5}
#add widgets
#Video
video = Video(source='birds.mp4', state='play')
video.opacity = 0.5
#Image
self.window.add_widget(Image(
source="mzi.png",
size_hint = (1.5,1.5)
))
#Label
self.greeting = Label(
text="How much would you like to invest?",
font_size = 18,
color='90EE90'
)
self.window.add_widget(self.greeting)
#User Input
self.user = TextInput(
multiline=False,
padding_y= (20,20),
size_hint = (1, 0.5)
)
self.window.add_widget(self.user)
#Button
self.button = Button(
text="Submit",
size_hint = (1,0.5),
bold = True,
background_color = '90EE90',
)
self.button.bind(on_press=self.callback)
self.window.add_widget(self.button)
#self.root_layout.add_widget(video)
self.root_layout.add_widget(self.window)
return self.root_layout
def callback(self, instance):
if self.user.text.isnumeric() and int(self.user.text) >= 10000:
self.greeting.text = "Calculating: $" + self.user.text
self.greeting.color = '90EE90'
else:
self.greeting.text = "Invalid"
self.greeting.color = "#FF0000"
if __name__ == "__main__":
MZ_Invest().run()
Most Kivy widgets have a transparent background, so you can just display a video and then display your GUI over that. Try adding something like this at the end of your build() method:
self.root_layout = FloatLayout()
video = Video(source='BigBuckBunny.mp4', state='play')
video.opacity = 0.5 # adjust to make the video lighter/darker
self.root_layout.add_widget(video) # add the video first
self.root_layout.add_widget(self.window) # now add the GUI window so it will be drawn over the video
return self.root_layout # return the root_layout instead of the window
I wanted to remove the 'bl' widget by clicking the 'horny mode' button, but it is not initially on the screen. How can I make the widget be removing by clicking on the button?
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.anchorlayout import AnchorLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.lang import Builder
from kivy.uix.button import Button
from kivy.config import Config
from kivy.core.window import Window
from kivy.uix.image import Image
from kivy.uix.widget import Widget
class ScraperApp(App, FloatLayout):
def PhotGif(self):
wentil = Image(source='img.gif', size_hint = (.5, .5), anim_loop = 99999)
photo = AnchorLayout(anchor_x='center', anchor_y='top', padding = [0, 75, 0, 0])
photo.add_widget(wentil)
return photo
def build(self):
bl = BoxLayout(orientation='horizontal', padding = [50, 100, 50, 150], spacing = 5)
bl.add_widget( Button(text = '1', on_press = self.first, font_size = 20, size_hint = (.3, .1)))
bl.add_widget( Button(text = '2', on_press = self.second, font_size = 20, size_hint = (.3, .1)))
#bl.add_widget( Button(text = 'Wallpaper mode', on_press = self.wallpaper, font_size = 20, size_hint = (.3, .1)))
wid = FloatLayout()
wid.add_widget(ScraperApp().PhotGif())
wid.add_widget(bl)
return wid
def first(self, instance):
print('Horny mode')
instance.text = 'кнопка нажата'
ScraperApp().build().remove_widget(bl)
stop()
def stop():
ScraperApp().build().remove_widget(bl)
def second(self, instance):
print('Soft mode')
instance.text = 'кнопка нажата'
if __name__ == '__main__':
ScraperApp().run()
Can you help me make so that when you click on any button, the widget with the buttons removed?
First, save a reference to the widget that you want to remove:
def build(self):
self.bl = BoxLayout(orientation='horizontal', padding=[50, 100, 50, 150], spacing=5)
self.bl.add_widget(Button(text='1', on_press=self.first, font_size=20, size_hint=(.3, .1)))
self.bl.add_widget(Button(text='2', on_press=self.second, font_size=20, size_hint=(.3, .1)))
# self.bl.add_widget( Button(text = 'Wallpaper mode', on_press = self.wallpaper, font_size = 20, size_hint = (.3, .1)))
wid = FloatLayout()
wid.add_widget(ScraperApp().PhotGif())
wid.add_widget(self.bl)
return wid
Then modify the first() method to remove it:
def first(self, instance):
print('Horny mode')
instance.text = 'кнопка нажата'
self.root.remove_widget(self.bl)
self.stop()
Note that the code:
ScraperApp().build().remove_widget(bl)
creates a new instance of the ScaperApp and tried to remove bl from that instance. Aside from other problems, nothing you do to that new instance will affect the instance that is currntly running.
i imported my kivy app to android, but on run it crashes and gives me the above error. I tried moving the location of display 0 but it did not change the error. it tells me the error happens when importing pyautogui.
Code:
import time
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.textinput import TextInput
import pyautogui
import os
class layy(App):
os.environ['DISPLAY'] = ':0'
global t
t = TextInput(hint_text='insert text')
global c
global s
s = TextInput(hint_text='insert time till begin')
c = TextInput(hint_text='insert amount')
def bot(self, instance):
am = c.text
if (am == ""):
am = '0'
l = int(am)
apm = t.text
m = str(apm)
if (m == ""):
m = 'hi'
pm = c.text
if (pm == ""):
pm = '0'
o = int(pm)
base = 0
time.sleep(o)
while (base < l):
pyautogui.typewrite(m)
pyautogui.press('enter')
base = base + 1
def build(self):
b = Button(text='Start Spam')
b.bind(on_press=self.bot)
layout = BoxLayout(orientation='vertical')
sublay1 = BoxLayout(orientation='horizontal')
sublay2 = BoxLayout(orientation='horizontal')
sublay3 = BoxLayout(orientation='horizontal')
layout.add_widget(sublay1)
sublay1.add_widget(t)
layout.add_widget(sublay2)
sublay2.add_widget(s)
sublay2.add_widget(c)
layout.add_widget(sublay3)
sublay3.add_widget(b)
return layout
if __name__ == '__main__':
layy().run()
If anyone knows what to do, please tell me. Sorry if it is simple, i'm new to python.
So at the moment in try to figure out why is my small player i wrote in kivy crashes on start. It says build successful and all modules seem to work separately in other tests (except for glob) but this one is pure python as far as i know.
here's my code
import glob
import kivy
from kivy.core.audio import SoundLoader
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.graphics import Rectangle
from kivy.graphics import Color
from kivy.uix.widget import Widget
import random
import os
from android.permissions import request_permissions, Permission
request_permissions([Permission.READ_EXTERNAL_STORAGE])
class PageI(GridLayout):
def __init__(self,**kwargs):
super().__init__( **kwargs)
self.cols = 3
self.state = False
self.music = glob.glob('/Phone/reMusic/*.mp3')#glob.glob('music\\*.mp3')
self.currname = self.music[0]
self.lasttime = 0
self.currsound = SoundLoader.load(self.currname)
fillclr = (round(random.random(),4), round(random.random(),4), round(random.random(),4), 1)
SR = Button(text='forward')
SR.bind(on_press=self.switchoR)
self.add_widget(SR)
placeholder = Label()
self.add_widget(placeholder)
SL = Button(text='backward')
SL.bind(on_press=self.switchoL)
self.add_widget(SL)
placeholder = Label()
self.add_widget(placeholder)
self.PP = Button(on_press = self.switchostate)
self.add_widget(self.PP)
placeholder = Label()
self.add_widget(placeholder)
placeholder = Label()
self.add_widget(placeholder)
self.showcase = Label(text=self.currname)
self.add_widget(self.showcase)
def PPcontrol(self):
if not self.currsound.state == 'play':
self.currsound.play()
self.currsound.seek(self.lasttime)
else:
self.lasttime = int(self.currsound.get_pos())
self.currsound.stop()
def switchostate(self,instance):
self.PPcontrol()
def showsitch(self):
self.showcase.text = self.currname
def switchoR(self,instance):
instance.background_color = (round(random.random(),4), round(random.random(),4), round(random.random(),4), 1)
ind = self.music.index(self.currname)
if ind+1 > len(self.music)-1:
self.currname = self.music[ind - len(self.music) + 1]
else:
self.currname = self.music[ind + 1]
self.lasttime = 0
self.currsound.stop()
self.currsound = SoundLoader.load(self.currname)
self.currsound.play()
self.showsitch()
def switchoL(self,instance):
instance.background_color = (round(random.random(),4), round(random.random(),4), round(random.random(),4), 1)
ind = self.music.index(self.currname)
if ind - 1 < 0:
self.currname = self.music[len(self.music) - 2]
else:
self.currname = self.music[ind - 1]
self.lasttime = 0
self.currsound.stop()
self.currsound = SoundLoader.load(self.currname)
self.currsound.play()
self.showsitch()
class Applet(App):
def build(self):
self.dircheck()
self.p = PageI()
return self.p
def dircheck(self):
try:
if not os.path.exists(os.path.join(os.getcwd(),'\\music')):
os.mkdir(os.path.join(os.getcwd(),'\\music'))
except: None
if __name__ == '__main__':
apper = Applet()
apper.run()
ik its quite messy but as you can see i tried both creating directories and accessing premade one.
and well, im not sure why it dies, i made sure it had all perms in spec file as well.
I want to create an Accordion containing content consisting of an RstDocument and a button. The Accordion shall be scrollable as well as the content of the RstDocument when this content is larger than the given space. So I came up with the following code but after some clicks on AccordionItems all further interaction is blocking. What am I doing wrong here?
from kivy.app import App
from kivy.uix.scrollview import ScrollView
from kivy.uix.rst import RstDocument
from kivy.core.window import Window
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.accordion import Accordion, AccordionItem
from kivy.uix.button import Button
class ShowrstApp (App):
def update_size(self, instance, *args):
instance.size = 60 * len(instance.children)
def build (self):
numitems = 10
root = BoxLayout()
accheight = numitems * 60
accitems = Accordion(id='acc_panel', orientation='vertical', pos_hint={'top': 1}, size_hint_y=None,
height=accheight, md_bg_color=(1, 1, 1, 1))
for i in xrange(numitems):
item = AccordionItem(title='This is item: %d' % i)
somecontent = BoxLayout(orientation='vertical')
somecontent.add_widget(RstDocument(text='Some nicely formatted text here'))
somecontent.add_widget(Button(text='click here', height=(42), size_hint=(1,None)))
item.add_widget(somecontent)
item.bind(children=self.update_size)
accitems.add_widget(item)
sv = ScrollView(do_scroll_x = False)
sv.add_widget(accitems)
root.add_widget(sv)
return root
Window.size = (350,650)
showrst = ShowrstApp()
showrst.run()
Below the scrolling effect works when the RstDocument Boxlayout is either horizontal of vertical, but an issue I saw was that when the BoxLayout was set to vertical, the toggle of each item was mute, you had to go one by one from the bottom-up. This was weird. You can click on each AccordionItem, where the RstDocument is not. This should be a great starting point. Noticed this effect doesn't occur when using a Label, so that could be a another option.
from kivy.app import App
from kivy.uix.scrollview import ScrollView
from kivy.uix.rst import RstDocument
from kivy.core.window import Window
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.accordion import Accordion, AccordionItem
from kivy.uix.button import Button
class ShowrstApp (App):
def update_size(self, instance, *args):
instance.height = 100 * len(instance.children) # set Accordion height to the number of accordionItem times the height accordionItem height
def build (self):
numitems = 10
root = BoxLayout()
accheight = numitems * 60
accitems = Accordion(id='acc_panel', orientation='vertical', size_hint_y=None, pos_hint={'top':1}
height=accheight, md_bg_color=(1, 1, 1, 1))
for i in xrange(numitems * 2): # *2 to show it works
item = AccordionItem(title='This is item: %d' % i)
somecontent = BoxLayout(orientation = 'horizontal') # couldn't solve an issue I notice so I used horizontal
somecontent.add_widget(RstDocument(text='Some nicely formatted text here' * 10))
somecontent.add_widget(Button(text='click here', height=(42), size_hint=(1,None)))
item.add_widget(somecontent)
accitems.bind(size=self.update_size)
accitems.add_widget(item)
sv = ScrollView(do_scroll_x = False)
sv.add_widget(accitems)
root.add_widget(sv)
return root
Window.size = (350,650)
showrst = ShowrstApp()
showrst.run()
I was having the same issue with RstDocuments in a ScrollView. The problem arises because RstDocuments have their own scrolling and 'intercept' the scroll command because it thinks you're trying to scroll inside the RstDocument. If you're fine with non-scrolling RstDocuments, you can set do_scroll_y: False for RstDocument, and scrolling will then work fine in the ScrollView regardless of mousing over an RstDocument.