I want to keep the Navigationbar on all my screen, I am able to switch screen and display what I want but I don't seem to keep the Navigationbar.
Also for some reason my side menu seems to appear twice, overlapping each other and I'm not sure why, I've tried refactoring the code and it just seems to appear again
Can anyone offer any help?
*.py
import kivy
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.properties import ObjectProperty
from kivy.properties import StringProperty
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.uix.scrollview import ScrollView
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.anchorlayout import AnchorLayout
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.clock import Clock
from kivy.uix.button import Button
from kivy.core.window import Window
from kivymd.app import MDApp
from kivymd.uix.card import MDCard
from kivymd.uix.label import MDLabel
class FirstWindow(Screen):
pass
class ThirdWindow(Screen):
def on_pre_enter(self):
anchor = AnchorLayout(size=(1,1))
test = "This is the new window"
card = MDCard(orientation='vertical',padding="8dp",size_hint=(1,0.5),pos_hint={'top': 0.1,'right':1},radius=[5, ])
card.test = test
card.add_widget(MDLabel(text=test, halign="center"))
anchor.add_widget(card)
self.anchorID.add_widget(anchor)
class WindowManager(ScreenManager):
pass
class NearMeApp(MDApp):
def build(self):
self.theme_cls.theme_style ="Dark"
self.theme_cls.accent_palette = "Red"
self.theme_cls.primary_palette = "Purple"
self.root = Builder.load_file('NearMe.kv')
if __name__ == '__main__':
NearMeApp().run()
*.kv
#:import hex kivy.utils.get_color_from_hex
#:kivy 1.10.1
WindowManager:
FirstWindow:
ThirdWindow:
<FirstWindow>:
name:"FirstWindow"
Screen:
MDNavigationLayout:
ScreenManager:
Screen:
BoxLayout:
orientation: 'vertical'
MDToolbar:
title: "NearMe Application"
elevation: 10
left_action_items: [['menu', lambda x: nav_drawer.set_state("open")]]
Widget:
MDNavigationDrawer:
id: nav_drawer
BoxLayout:
orientation:'vertical'
Button:
text:"ThirdWindow"
on_release: root.manager.current = "ThirdWindow"
<ThirdWindow>:
name:"ThirdWindow"
anchorID:anchorID
AnchorLayout:
id:anchorID
canvas.before:
Color:
rgba: .2, .2, .2, 1
Rectangle:
pos: self.pos
size: self.size
Your md toolbar needs to be above the main windowmanager.
With your mdtoolbar as a child of firstwindow (child of windowmanager), your windowmanager acts on it and the other children of firstwindow at same during change in current window. By moving the mdtoolbar out of firstwindow and above windowmanager the mdtoolbar will remain present.
from kivymd.app import MDApp
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager
from kivy.uix.screenmanager import Screen
class FirstWindow(Screen):
pass
class ThirdWindow(Screen):
pass
class WindowManager(ScreenManager):
pass
kv = """
Screen:
MDNavigationDrawer:
id: nav_drawer
BoxLayout:
orientation:'vertical'
Button:
text:"ThirdWindow"
on_release: root.ids.manager.current = "ThirdWindow"
StackLayout:
MDToolbar:
title: "NearMe Application"
size_hint: (1, 0.1)
elevation: 10
left_action_items: [['menu', lambda x: nav_drawer.set_state("open")]]
WindowManager:
id: manager
FirstWindow:
ThirdWindow:
<FirstWindow>:
name:"FirstWindow"
Screen:
BoxLayout:
orientation: 'vertical'
Widget:
<ThirdWindow>:
name:"ThirdWindow"
anchorID:anchorID
AnchorLayout:
id:anchorID
canvas.before:
Color:
rgba: .2, .2, .2, 1
Rectangle:
pos: self.pos
size: self.size
"""
class Test(MDApp):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.screen = Builder.load_string(kv)
def build(self):
return self.screen
the_app = Test()
the_app.run()
The above removes the toolbar from your FirstWindow and places it on its own. In your example the toolbar is a child of FirstWindow so when you change the current window (screen) to ThirdWindow the toolbar disappears with its parent (FirstWindow). Now the toolbar is not a child of either window.
Related
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.properties import ObjectProperty
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.uix.button import Button
Window.size = (500,700)
Builder.load_file('calc.kv')
class MyLayout(Widget):
pass
class App(App):
def build(self):
return MyLayout()
if __name__ == "__main__":
App().run()
this is my calc.py please help me to solve the problem
#:kivy 2.0.0
BoxLayout:
orientation:"vertical"
size: root.width, root.height
TextInput:
id: clac_input
text: "0"
halign: "right"
font_size : 65
size_hint: (1, .15)
GridLayout:
cols:4
rows:5
Button:
size_hint: (.2, .2)
font_size: 32
text: "%"
this is my calc.kv
From what I'm seeing the app is not returning any screens for your widgets to show on. I've changed a bit of your code to what I believe is correct that solves the issue.
.py
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.properties import ObjectProperty
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.core.window import Window
from kivy.uix.button import Button
Window.size = (500,700)
Builder.load_file('calc.kv')
class MyLayout(Widget):
pass
class Screen1(Screen):
pass
class WindowManager(ScreenManager):
pass
class App(App):
def build(self):
return WindowManager()
if __name__ == "__main__":
App().run()
calc.kv
<WindowManager>:
Screen1
<Screen1>:
BoxLayout:
orientation:"vertical"
size: root.width, root.height
GridLayout:
cols:4
rows:5
TextInput:
id: clac_input
text: "0"
halign: "right"
font_size : 65
size_hint: (1, .15)
Button:
size_hint: (.2, .2)
font_size: 32
text: "%"
This should be a pretty easy fix. I'm new to Kivy. I'm trying to have the canvas cleared on a button press, and then display a new widget to essentially move to another page. When I run it and press the button, the canvas is cleared, but I get nothing from IntroPage.
Python Script:
import kivy
kivy.require('2.0.0')
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from kivy.uix.image import Image
from kivy.uix.widget import Widget
from kivy.properties import ObjectProperty
class ABT(App):
def build(self):
return WelcomePage()
class WelcomePage(Widget):
def btn(self):
self.canvas.clear()
print('pressed')
return IntroPage()
class IntroPage(Widget):
def __init__(self):
pass
if __name__ == '__main__':
ABT().run()
KV File:
<WelcomePage>
canvas.before:
Color:
rgba: (.43,.51,.92,.26)
Rectangle:
pos: self.pos
size: self.size
GridLayout:
cols:1
size: root.width, root.height
Image:
source: 'abt1t.png'
size_hint: (1,.8)
Button:
text:"begin"
background_color: (.43,.51,.92,.26)
size_hint: (1,.2)
on_press: root.btn()
<IntroPage>
GridLayout:
cols:1
Label:
text:"This won't show up!"
Returning IntroPage from btn won't work, as btn isn't a build method.
The best way to implement multiple pages is probably to use ScreenManager:
from kivy.uix.screenmanager import ScreenManager, Screen
class ABT(App):
def build(self):
sm = ScreenManager()
sm.add_widget(WelcomePage(name="welcome"))
sm.add_widget(IntroPage(name="intro"))
return sm
class WelcomePage(Screen):
def btn(self):
print('pressed')
self.manager.current = "intro"
class IntroPage(Screen):
def __init__(self):
pass
I'm trying to make a app. On button click on the bottom right of the screen there appears a dialog window(popup). On "Done" click the popup window closes (close_dialog method), and a new List Item appears. The text of the List Item is expected to be obtained from MDTextField of the popup by this code:
mylist = TwoLineAvatarListItem(text = DialogContent().textfield.text,
secondary_text = "1,2,3...")
As far as I know I need to refer to DialogContent class from another class Container in the .kv file, but I don't know how to do it properly. How can I fix it?
Code.py:
from kivy.lang import Builder
from kivy.core.window import Window
from kivymd.app import MDApp
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.scrollview import ScrollView
from kivymd.uix.button import MDFlatButton
from kivymd.uix.dialog import MDDialog
from kivymd.uix.textfield import MDTextField
from kivy.uix.textinput import TextInput
from kivy.uix.screenmanager import Screen, ScreenManager
from kivymd.uix.list import TwoLineAvatarListItem
Window.size = (288, 511)
class DialogContent(BoxLayout):
pass
class Container(Screen):
dialog = None
def show_dialog(self, *args):
'''
Create group creation popup
'''
if not self.dialog:
self.dialog = MDDialog(
title="Create new group",
type="custom",
content_cls=DialogContent(),
auto_dismiss=False
)
self.dialog.open()
def close_dialog(self, *args):
'''
Close popup on Done click
'''
self.dialog.dismiss()
self.new_window()
def new_window(self, *args):
'''
Create new group button
'''
mylist = TwoLineAvatarListItem(text = DialogContent().textfield.text,
secondary_text = "1,2,3...")
self.mdlist.add_widget(mylist)
class grudget4App(MDApp):
def build(self):
container = Container()
scroll = ScrollView()
return container
if __name__ == '__main__':
grudget4App().run()
Code .kv:
<DialogContent>:
textfield: textfield
orientation: "vertical"
spacing: "12dp"
size_hint_y: None
height: "120dp"
MDTextField:
id: textfield
hint_text: "Group name"
MDFlatButton:
id: btn1
text: "Done"
text_color: self.theme_cls.primary_color
on_release: app.root.close_dialog()
<Container>:
mdlist: mdlist
FloatLayout:
size_hint: 1, 0.89
ScrollView:
MDList:
id: mdlist
MDFloatingActionButton:
pos_hint: {'right': 0.95, 'y': 0.05}
icon: "icon.png"
theme_text_color: "Custom"
text_color: app.theme_cls.primary_color
on_release:
root.show_dialog()
Screen:
NavigationLayout:
ScreenManager:
Screen:
BoxLayout:
orientation: 'vertical'
MDToolbar:
title: ''
size_hint: 1, 0.14
left_action_items: [["menu", lambda x: nav_drawer.toggle_nav_drawer()]]
elevation:10
Widget:
MDNavigationDrawer:
id: nav_drawer
The code:
mylist = TwoLineAvatarListItem(text = DialogContent().textfield.text,
secondary_text = "1,2,3...")
is creating a new instance of DialogContent, unrelated to the DialogContent that appears in the display. To access the correct instance use:
mylist = TwoLineAvatarListItem(text = self.dialog.content_cls.textfield.text,
secondary_text = "1,2,3...")
I basically have no clue on why the ScrollView isn't scrolling
Here is the python code:
from kivy.app import App
from kivy.config import Config
from kivy.clock import Clock
from kivy.core.window import Window
from kivy.properties import ObjectProperty
from kivy.properties import StringProperty
from kivy.properties import NumericProperty
from kivy.properties import ListProperty
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.screenmanager import *
from kivy.uix.scrollview import ScrollView
class ScrollButton(Button):
pass
class DropperScrollView(ScrollView):
layout=ObjectProperty()
class MainWindow(FloatLayout):
mainbox=ObjectProperty()
dropper=ObjectProperty()
mainbutton=ObjectProperty()
dropper_button_1=ObjectProperty()
dropper_button_2=ObjectProperty()
dropper_button_3=ObjectProperty()
dropper_button_4=ObjectProperty()
scroll_list=ObjectProperty()
def open_dropper(self,dt):
self.dropper.open(self.mainbutton)
def btn_1(self,a):
if self.scroll_list.layout.children==[]:
btn_1=ScrollButton(text='Button 1')
btn_2=ScrollButton(text='Button 2')
self.scroll_list.layout.add_widget(btn_1)
self.scroll_list.layout.add_widget(btn_2)
class BioWikiaApp(App):
ratio=1/7
window_width=360
window_height=640
squared_ratio=NumericProperty(ratio)
squared_dropper_size_hint=ListProperty([ratio,ratio*9/16])
squared_dropper_size=ListProperty([window_width*ratio,window_height*ratio*9/16])
def build(self):
Window.size=(self.window_width,self.window_height)
Window.clearcolor=(155/255,220/255,160/255,1)
return MainWindow()
if __name__=='__main__':
app=BioWikiaApp()
app.run()
And the kivy file:
#:import Clock kivy.clock.Clock
#:import App kivy.app.App
#:import Window kivy.core.window.Window
#:import NoTransition kivy.uix.screenmanager.NoTransition
<DropperScrollView>:
layout:scroll_layout
size_hint_x:app.squared_ratio
pos_hint:{'x':app.ratio,'y':0}
GridLayout:
id:scroll_layout
cols:1
size_hint_y:None
<ScrollButton>:
size_hint_y:None
height:400
<MainWindow>:
id:mainwindow
mainbox:mainbox
dropper:dropper
dropper_button_1:dropper_button_1
dropper_button_2:dropper_button_2
dropper_button_3:dropper_button_3
dropper_button_4:dropper_button_4
mainbutton:mainbutton
scroll_list:scroll_list
BoxLayout:
id:mainbox
Label:
text:'This will hold the title'
Button:
id:mainbutton
text:'Home'
size_hint:app.squared_dropper_size_hint[0],app.squared_dropper_size_hint[1]
pos_hint:{'x':0,'y':1-app.squared_dropper_size_hint[1]}
on_parent:
dropper.dismiss()
Clock.schedule_once(root.open_dropper,-1)
on_release:dropper.open(self)
DropDown:
id:dropper
dismiss_on_select:False
on_select: mainbutton.text = '{}'.format(args[1])
Button:
id:dropper_button_1
text:'1'
size_hint_y:None
height:mainbutton.height
on_release:root.btn_1(self)
Button:
id:dropper_button_2
text:'2'
size_hint_y:None
height:mainbutton.height
on_release:root.btn_1(self)
Button:
id:dropper_button_3
text:'3'
size_hint_y:None
height:mainbutton.height
on_release:root.btn_1(self)
Button:
id:dropper_button_4
text:'4'
size_hint_y:None
height:mainbutton.height
on_release:root.btn_1(self)
DropperScrollView:
id:scroll_list
Although what really matters for me in the moment is making this damned ScrollView scroll, feel free to correct me on anything else I might have done wrong (like making Drop_Down List a child of the mainwindow cause I couldn't make it work otherwise)
Many thanks in advance
Solution
Please refer to the example for details.
DropDown is a special widget just like Popup. Don't try to add it as a child to any other widget. If you do, DropDown will be handled like an ordinary widget and dropdown list will be opened i.e. won't be closed in the background. In kv file, create a dynamic class <CustomDropDown#DropDown>: and add widgets to it.
Buttons in the ScrollView are bigger than the ScrollView because size_hint_y: None was not specified.
Set the height to minimum height such that there is something to scroll.
ScrollView » Managing the Content Size and Position
layout = GridLayout(cols=1, spacing=10, size_hint_y=None)
# Make sure the height is such that there is something to scroll.
layout.bind(minimum_height=layout.setter('height'))
for i in range(100):
btn = Button(text=str(i), size_hint_y=None, height=40)
layout.add_widget(btn)
root = ScrollView(size_hint=(1, None), size=(Window.width, Window.height))
ScrollView » bar_width
bar_width
Width of the horizontal / vertical scroll bar. The width is
interpreted as a height for the horizontal bar.
bar_width is a NumericProperty and defaults to 2.
Example
main.py
from kivy.app import App
from kivy.core.window import Window
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.button import Button
from kivy.uix.scrollview import ScrollView
from kivy.properties import ListProperty, NumericProperty, ObjectProperty
class ScrollButton(Button):
pass
class DropperScrollView(ScrollView):
layout = ObjectProperty(None)
class MainWindow(FloatLayout):
mainbutton = ObjectProperty(None)
scroll_list = ObjectProperty(None)
def btn_1(self):
if not self.scroll_list.layout.children: # empty list
btn_1 = ScrollButton(text='Button 1')
btn_2 = ScrollButton(text='Button 2')
self.scroll_list.layout.add_widget(btn_1)
self.scroll_list.layout.add_widget(btn_2)
class BioWikiaApp(App):
ratio = 1/7
window_width = 360
window_height = 640
squared_ratio = NumericProperty(ratio)
squared_dropper_size_hint = ListProperty([ratio, ratio*9/16])
squared_dropper_size = ListProperty([window_width*ratio, window_height*ratio*9/16])
def build(self):
Window.size = (self.window_width, self.window_height)
Window.clearcolor = (155/255, 220/255, 160/255, 1)
return MainWindow()
if __name__ == '__main__':
BioWikiaApp().run()
biowikia.kv
#:kivy 1.11.0
#:import Factory kivy.factory.Factory
<DropDownButton#Button>:
size_hint_y: None
height: app.root.mainbutton.height
<CustomDropDown#DropDown>:
on_select: app.root.mainbutton.text = '{}'.format(args[1])
DropDownButton:
id: dropper_button_1
text: '1'
on_release:
root.select(self.text)
app.root.btn_1()
DropDownButton:
id: dropper_button_2
text: '2'
on_release:
root.select(self.text)
app.root.btn_1()
DropDownButton:
id: dropper_button_3
text: '3'
on_release:
root.select(self.text)
app.root.btn_1()
DropDownButton:
id: dropper_button_4
text: '4'
on_release:
root.select(self.text)
app.root.btn_1()
<DropperScrollView>:
layout: scroll_layout
size_hint: (app.squared_ratio, None)
pos_hint: {'x': app.ratio, 'y': 0}
bar_width: 10
bar_color: 0, 1, 0, 1 # green
bar_inactive_color: 1, 0, 0, 1 # red
effect_cls: "ScrollEffect"
scroll_type: ['bars']
GridLayout:
id: scroll_layout
cols: 1
size_hint_y: None
height: self.minimum_height
<ScrollButton>:
size_hint_y: None
height: 400
<MainWindow>:
mainbox: mainbox
mainbutton: mainbutton
scroll_list: scroll_list
BoxLayout:
id: mainbox
Label:
text:'This will hold the title'
Button:
id: mainbutton
text: 'Home'
size_hint: app.squared_dropper_size_hint[0], app.squared_dropper_size_hint[1]
pos_hint: {'x':0, 'y': 1 - app.squared_dropper_size_hint[1]}
on_release: Factory.CustomDropDown().open(self)
DropperScrollView:
id:scroll_list
Output
I'm a beginner in kivy and python. I've been trying to create a scrollview in a page that displays selected video on the screen. But after a while when i selected 5-6 videos to display even though i delete the video widget it starts to lag. And i'm open to any suggestions to better way to handle this kind of application.
from kivy.config import Config
Config.set('graphics', 'width', '1920')
Config.set('graphics', 'height', '1080')
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
from kivy.uix.widget import Widget
from kivy.uix.image import Image
from kivy.properties import StringProperty
from kivy.uix.scrollview import ScrollView
from kivy.uix.label import Label
from kivy.clock import Clock
from kivy.uix.button import Button
import os
from kivy.uix.video import Video
from kivy.uix.videoplayer import VideoPlayer
from kivy.clock import mainthread
from functools import partial
from kivy.core.window import Window
Window.clearcolor = (0, 0, 0, 0)
isThereVideo=False
picture_path="/home/linux/kivyFiles/kivyLogin/assets"
video_path="/home/linux/kivyFiles/kivyLogin/videoAssets/"
class Image(Image):
pass
class MainScreen(Screen):
pass
class AnotherScreen(Screen):
pass
class Selfie(Screen):
pass
class RootWidget(Widget):
def __init__(self, **kwargs):
super(RootWidget, self).__init__(**kwargs)
Clock.schedule_once(self.createMultipleButton)
#mainthread
def createMultipleButton(self, dt):
self.root = Widget()
size_y=150;
size_x=150;
for i in range(1):
folderList = os.listdir(picture_path)
if len(folderList)==0:
time.sleep(1)
break
fileList = os.listdir(picture_path)
print fileList
for file in fileList:
x = (picture_path+"/"+file)
button = Button(id=str(file),text="" + str(file),size_hint=(None, None),height=size_y,width=size_x, pos_hint={'x': 0, 'y': 1},background_normal=x)
button.bind(on_release=partial(self.VideoContainer, file))
print file
self.scrollview.content_layout.add_widget(button)
print button.id
print("Parent of ScreenTwo: {}".format(self.parent))
#print(button.pos)
def VideoContainer(self,name,btn):
global isThereVideo
if isThereVideo==True:
#self.videocontainer.video_layout.unload()
self.videocontainer.clear_widgets()
mylist=name.split('.')
emailButton = Button(id='email')
video = Video(source="/home/linux/kivyFiles/kivyLogin/videoAssets/"+mylist[0]+".mp4", state='play',options={'eos': 'loop'})
video.size=(self.parent.width,self.parent.height)
video_pos=(self.parent.x,self.parent.y)
#video.pos_hint={'x': self.parent.width /2, 'y': self.parent.height/2}
video.play=True
#video.pos=(self.parent.width /2 , self.parent.height/2)
#self.videocontainer.video_layout.add_widget(emailButton)
self.videocontainer.add_widget(emailButton)
emailButton.add_widget(video)
isThereVideo=True
print("Parent of ScreenTwo: {}".format(self.parent))
return 0
class ScreenManagement(ScreenManager):
pass
class VideoContain(Widget):
pass
class ScrollableContainer(ScrollView):
pass
presentation = Builder.load_file("login.kv")
class MainApp(App):
def build(self):
return presentation
if __name__ == '__main__':
Window.fullscreen = True
app=MainApp()
app.run()
And my Kv file
ScreenManagement:
MainScreen:
Selfie:
<MainScreen>:
name: 'main'
Button:
on_release: app.root.current = 'selfie'
text: 'Another Screen'
font_size: 50
<Selfie>:
name: 'selfie'
Button:
on_release: app.root.current = 'login'
text: 'Selfie Screen'
font_size: 10
pos_hint: {"right": 1, 'top':1}
size_hint: (0.1, 0.1)
RootWidget:
<RootWidget>
size_hint: (0.1, None)
scrollview: scrollview
videocontainer:videocontainer
size:(self.parent.width, self.parent.height)
VideoContain:
id:videocontainer
##size:(self.parent.width, self.parent.height)
size:(root.width, root.height)
ScrollableContainer:
id: scrollview
size: root.size
pos: root.pos
<VideoContain>
video_layout:video_layout
FloatLayout:
cols:1
id: video_layout
<ScrollableContainer>:
scroll_timeout: 75
scroll_distance: 10
app: app
content_layout: content_layout
GridLayout:
id: content_layout
cols: 1
size_hint: (0.1, None)
pos: root.pos
height: self.minimum_height
padding: 25
spacing: 25
I posted all my code since i don't know which part may causing the problem i'm facing.
Solved it.
def VideoContainer(self,name,btn):
global isThereVideo
if isThereVideo:
# self.videocontainer.video_layout.unload()
self.videocontainer.clear_widgets()
In this part i'm clearing the widgets but i also need to unload the video somehow.
self.video.unload() solved my problem