I want to use kivy scatter in order to resize the widgets which scatter contains. So, I created box_total contained in scatter, contained in floatlayout.
This is the code:
from kivy.app import App
from kivy.uix.scatter import Scatter
from kivy.uix.label import Label
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
class TutorialApp(App):
def build(self):
b = BoxLayout(orientation='vertical')
button = Button(text = 'something')
b.add_widget(button)
box_labels = BoxLayout(orientation = 'horizontal')
label1 = Label(text = 'hello')
box_labels.add_widget(label1)
label2 = Label(text = 'world')
box_labels.add_widget(label2)
box_buttons = BoxLayout(orientation = 'horizontal')
button1 = Button(text = 'hello')
box_buttons.add_widget(button1)
button2 = Button(text = 'world')
box_buttons.add_widget(button2)
box_total = BoxLayout(orientation = 'vertical')
box_total.add_widget(box_labels)
box_total.add_widget(box_buttons)
f = FloatLayout()
s = Scatter()
f.add_widget(s)
s.add_widget(box_total)
b.add_widget(f)
return b
if __name__ == "__main__":
TutorialApp().run()
and this is what I get:
How can I resize the inner widget box_total in order to occupy the whole FloatLayout area? (the bottom half of the window)
Scatter isn't a layout, therefore the automatical setting of the position won't work here. Use ScatterLayout to behava like both a Scatter and a FloatLayout.
from kivy.uix.scatterlayout import ScatterLayout
ScatterLayout()
Or do that manually with setting the positions of the widgets inside the FloatLayout, but remember you'll need to do size_hint=(None, None) first.
Related
Hi I am new to Kivy and I am trying to make a GUI using kivy to deploy machine learning model. I am importing a data set with drag and drop feature in kivy but I want to change the label to file path after I drag and drop the csv file.
Here is my code:
from kivy.app import App
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.core.window import Window
import pandas as pd
from kivy.uix.textinput import TextInput
class Amplicon_Coverage_Prediction(App):
def build(self):
self.window = GridLayout()
self.window.cols = 1
# Drag and drop feature initialize
Window.bind(on_drop_file = self.on_file_drop)
#add widgets to window
# adding Image to widget
self.window.add_widget(Image(source = "DNA.png"))
# Label Widget
self.head = Label(text = "Amplicon Coverage Prediction")
self.window.add_widget(self.head)
# File Path to CSV Label
self.label_csv_path = Label(text = "Please choose a csv file to begin")
self.window.add_widget(self.label_csv_path)
self.csv_button = Button(text = "Choose CSV",
size_hint = (1, 0.5))
self.window.add_widget(self.csv_button)
self.csv_button.bind(on_press = self.call_csv_path)
self.csv_button.bind(on_press=self.load_csv)
return self.window
# Calling drag and drop feature
def on_file_drop(self, window, path_to_csv, x, y):
self.path_to_csv = str(path_to_csv)
self.path_to_csv = self.path_to_csv[2:(len(self.path_to_csv) -1)]
def call_csv_path(self, instace):
self.label_csv_path.text = self.path_to_csv
return self.path_to_csv
def load_csv(self, instace):
self.dataset = pd.read_csv('/' + self.path_to_csv[1:])
print(self.dataset.head())
if __name__ == "__main__":
Amplicon_Coverage_Prediction().run()
It's me again, trying to understand Kivy concepts.
I have a widget with a base class of RelativeLayout containing a chessboard image displaying in a splitter. I want to display a label, and 2 buttons horizontally below the chessboard spaced a small distance away from the chessboard and still have everything resizable with splitter. I've tried numerous ways to no avail. What I currently have is this:
What I want is this: (How do I achieve it?)
Here is the code:
import kivy
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.splitter import Splitter
from kivy.uix.image import Image
kivy.require('2.0.0')
class ChessBoardWidget(RelativeLayout): # FloatLayout
def __init__(self, **kwargs):
super(ChessBoardWidget, self).__init__(**kwargs)
repertoire_boxlayout = BoxLayout(orientation='horizontal')
repertoire_boxlayout.add_widget(Label(text='Repertoire for:'))
repertoire_boxlayout.add_widget(Button(text='White'))
repertoire_boxlayout.add_widget(Button(text='Black'))
chessboard_gui_boxlayout = BoxLayout(orientation='vertical')
chessboard_gui_boxlayout.add_widget(
Image(source="./data/images/chess-pieces/DarkerGreenGreyChessBoard.png", pos=self.pos,
size_hint=(1, 1), keep_ratio=True, allow_stretch=True))
chessboard_gui_boxlayout.add_widget(repertoire_boxlayout)
self.add_widget(chessboard_gui_boxlayout)
class SplitterGui(BoxLayout):
def __init__(self, **kwargs):
super(SplitterGui, self).__init__(**kwargs)
self.orientation = 'horizontal'
# Splitter 1
split1_boxlayout = BoxLayout(orientation='vertical')
split1 = Splitter(sizable_from='bottom', min_size=74, max_size=1100)
chessboard_widget = ChessBoardWidget()
split1.add_widget(chessboard_widget)
split1_boxlayout.add_widget(split1)
s3_button = Button(text='s3', size_hint=(1, 1))
split1_boxlayout.add_widget(s3_button)
self.add_widget(split1_boxlayout)
# Splitter 2
split2 = Splitter(sizable_from='left', min_size=74, max_size=1800)
s2_button = Button(text='s2', size_hint=(.1, 1))
split2.add_widget(s2_button)
self.add_widget(split2)
class ChessBoxApp(App):
def build(self):
return SplitterGui() # root
if __name__ == '__main__':
ChessBoxApp().run()
In a BoxLayout (see the documentation), you can use size_hint and size (or height, width) to adjust sizes. So, you can set the height of your Buttons, and let the Image use the remaining height of the BoxLayout:
class ChessBoardWidget(RelativeLayout):
def __init__(self, **kwargs):
super(ChessBoardWidget, self).__init__(**kwargs)
repertoire_boxlayout = BoxLayout(orientation='horizontal', size_hint=(1, None), height=30) # set height of Buttons
repertoire_boxlayout.add_widget(Label(text='Repertoire for:'))
repertoire_boxlayout.add_widget(Button(text='White'))
repertoire_boxlayout.add_widget(Button(text='Black'))
chessboard_gui_boxlayout = BoxLayout(orientation='vertical')
chessboard_gui_boxlayout.add_widget(
Image(source="./data/images/chess-pieces/DarkerGreenGreyChessBoard.png", pos=self.pos, keep_ratio=True, allow_stretch=True)) # default size_hint of (1,1) claims all of remaining height
chessboard_gui_boxlayout.add_widget(repertoire_boxlayout)
self.add_widget(chessboard_gui_boxlayout)
I am trying to make tambola coin picker with Python and Kivy and I am new to kivy.
Here, I created gridlayout buttons from 1 to 90. I want to change the color of particular button in gridlayout when its number is picked. I am facing issues to update gridlayout with new colored button. Here I am attaching my code. screenshot
#!/usr/bin/python
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.gridlayout import GridLayout
from kivy.graphics import Color
import random
coins = random.sample(range(1,91), 90)
#print(coins)
picked_coins=[]
current_coin=0
#print(picked_coins)
class Housie(FloatLayout):
def __init__(self,**kwargs):
super(Housie,self).__init__(**kwargs)
self.title = Label(text="Housie Coin Picker",font_size = 50,size_hint=(1, .55),pos_hint={'x':0, 'y':.45})
self.main_label = Label(text = "Click PICK NUMBER", size_hint=(1, .60),pos_hint={'x':0, 'y':.35})
self.picked_ones = Label(text = "picked_coins", size_hint=(1, .40),pos_hint={'x':0, 'y':.40})
self.help_button = Button(text = "PICK NUMBER", size_hint=(.3, .1),pos_hint={'x':.65, 'y':.1},on_press = self.update)
self.add_widget(self.title)
self.add_widget(self.main_label)
self.add_widget(self.picked_ones)
self.add_widget(self.help_button)
self.add_widget(self.userinterface())
def userinterface(self):
self.layout = GridLayout(cols = 10,size_hint=(.50, .50))
for i in range(1,91):
self.layout.add_widget(Button(background_color=(1,0,0,1),text =str(i)))
return self.layout
def update(self,event):
for coin in coins:
if coin not in picked_coins:
current_coin=coin
picked_coins.append(coin)
self.main_label.text = str(coin)
for i in self.layout.children:
if i.text == str(coin):
#What to do Here?
break
self.picked_ones.text = "Picked coins = {}".format(" ".join(str(sorted(picked_coins))))
class app1(App):
def build(self):
return Housie()
if __name__=="__main__":
app1().run()
You can bind a method to each Button like this:
def userinterface(self):
self.layout = GridLayout(cols = 10,size_hint=(.50, .50))
for i in range(1,91):
self.layout.add_widget(Button(background_color=(1,0,0,1),text=str(i), on_release=self.butt_pressed))
return self.layout
def butt_pressed(self, button):
button.background_normal = ''
button.background_color = (1,0,0,1)
Th butt_pressed() method changes the background color of the pessed Button.
So i manage to get focus in the TextInput > tracknumb. at start of the app, but still when i confirm the input, finally i can do it with enter now too, but it looses the focus from textinput once i submit it.
Can you please advice what am I missing?
Whole Code here
import kivy
import kivy
import mysql.connector
from datetime import datetime
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
from kivy.uix.textinput import TextInput
from kivy.uix.image import Image
from kivy.core.audio import SoundLoader
from kivy.core.window import Window
from kivy.clock import Clock
Window.size = (480, 800)
class MyGrid(GridLayout):
def __init__(self, **kwargs):
super(MyGrid, self).__init__(**kwargs)
self.cols = 1 # Set columns for main layout
self.inside = GridLayout(cols=2, row_force_default=True,
row_default_height=50, padding=20,
spacing=10) # Create a new grid layout
self.add_widget(Label(text="Tracking Number \n Checker", halign="center", font_size=40)) # Top Label
self.inside.add_widget(Label(text="Work Number:", halign="center", font_size=20)) # Add a label widget
self.worknumb = TextInput(text_validate_unfocus=True, multiline=False, font_size=20, halign="center")
self.inside.add_widget(self.worknumb)
self.inside.add_widget(Label(text="Tracking \nNO. Scan:", halign="center", font_size=20))
self.tracknumb = TextInput(multiline=False, font_size=15, halign="center") # Create a Text input box stored in the name variable
self.inside.add_widget(self.tracknumb) # Add the text input widget to the GUI
self.add_widget(self.inside) # Add the interior layout to the main
self.submit = Button(text="Submit", font_size=40, size_hint =(.5, .5)) # Submit button
self.add_widget(self.submit)
self.submit.bind(on_press=self.send_tracknumb)
self.resultbox = Image(source="status.png") #image box on bottom
self.add_widget(self.resultbox)
Window.bind(on_key_down=self.pressed)
Clock.schedule_once(self.focus_tracknumb, 1)
def pressed(self, instance, keyboard, keycode, text, modifiers):
if keycode == 40 or keycode == 13:
self.send_tracknumb(None)
def focus_tracknumb(self, _):
self.tracknumb.focus = True
def send_tracknumb(self, _):
tracknumb = self.tracknumb.text
worknumb = self.worknumb.text
errorsound = SoundLoader.load("incorrect.mp3") # add sound to the scanning
correctsound = SoundLoader.load("correct.ogg")
self.tracknumb.text = "" # Reset text to blank in each text input
I think you can change focus back to the TextInput in the pressed() method:
def pressed(self, instance):
tracknumb = self.tracknumb.text
worknumb = self.worknumb.text
errorsound = SoundLoader.load("incorrect.mp3") #add sound to the scanning
correctsound = SoundLoader.load("correct.ogg")
self.tracknumb.text = "" # Reset text to blank in each text input
self.tracknumb.focus = True # Change focus back to tracknumb
Och dong, I missed it :D it was so simple, I had to put the function to that part
def send_tracknumb(self, _):
I missed that one in all the text :{
Clock.schedule_once(self.focus_tracknumb, 0.1)
I want to create an UI with Buttons on top and a few Labels on bottom and if the labels exceeds the height it should be scrollable.
Something like this:
So far this is my code:
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.scrollview import ScrollView
from kivy.uix.gridlayout import GridLayout
class MyApp(App):
main_layout = BoxLayout(orientation='vertical')
top_layout = BoxLayout(orientation='horizontal')
scrollView = ScrollView()
gridLayout = GridLayout()
gridLayout.cols = 1
gridLayout.minimum_height = 10
gridLayout.padding = [0, 0, 0, 0]
scrollView.add_widget(gridLayout)
main_layout.add_widget(top_layout)
main_layout.add_widget(scrollView)
def btn_create(self, instance):
self.gridLayout.add_widget(Label(text='test'))
def btn_edit(self, instance):
pass
def btn_delete(self, instance):
pass
def build(self):
self.top_layout.size_hint=(1, .1)
# Button 'Erstellen'
btnCreate = Button()
btnCreate.text = 'Erstellen'
btnCreate.bind(on_press=self.btn_create)
# Button 'Bearbeiten'
btnEdit = Button()
btnEdit.text = 'Bearbeiten'
btnEdit.bind(on_press=self.btn_edit)
# Button 'Löschen'
btnDelete = Button()
btnDelete.text = 'Löschen'
btnDelete.bind(on_press=self.btn_delete)
self.top_layout.add_widget(btnCreate)
self.top_layout.add_widget(btnEdit)
self.top_layout.add_widget(btnDelete)
return self.main_layout
if __name__ == '__main__':
MyApp().run()
I added a GridLayout to a ScrollView, but this doesn't seem to work.
How can i make a scrollable list?
You have to set the size_hint_y of the GridLayout to None so that the height does not depend on the ScrollView and the size is minimum equal to the size of the GridLayout. On the other hand the Label must have size_hint_y to None so that the height does not depend on the GridLayout.
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.scrollview import ScrollView
from kivy.uix.gridlayout import GridLayout
class MyApp(App):
main_layout = BoxLayout(orientation='vertical')
top_layout = BoxLayout(orientation='horizontal')
scrollView = ScrollView()
gridLayout = GridLayout(size_hint_y=None)
gridLayout.cols = 1
gridLayout.padding = [0, 0, 0, 0]
gridLayout.bind(minimum_height=gridLayout.setter('height'))
scrollView.add_widget(gridLayout)
main_layout.add_widget(top_layout)
main_layout.add_widget(scrollView)
def btn_create(self, instance):
self.gridLayout.add_widget(Label(text='test', size_hint_y=None))
def btn_edit(self, instance):
pass
def btn_delete(self, instance):
pass
def build(self):
self.top_layout.size_hint=(1, .1)
# Button 'Erstellen'
btnCreate = Button()
btnCreate.text = 'Erstellen'
btnCreate.bind(on_press=self.btn_create)
# Button 'Bearbeiten'
btnEdit = Button()
btnEdit.text = 'Bearbeiten'
btnEdit.bind(on_press=self.btn_edit)
# Button 'Löschen'
btnDelete = Button()
btnDelete.text = 'Löschen'
btnDelete.bind(on_press=self.btn_delete)
self.top_layout.add_widget(btnCreate)
self.top_layout.add_widget(btnEdit)
self.top_layout.add_widget(btnDelete)
return self.main_layout
if __name__ == '__main__':
MyApp().run()