kivy Grid Layout

本文介绍了一个使用Kivy库创建的简单GUI登录界面示例。该示例通过Python代码实现了包含用户名、密码输入框及登录按钮的基本布局,并演示了如何通过调整参数来改变界面布局。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://kivy.org/docs/api-kivy.uix.gridlayout.html?highlight=gridlayout#kivy.uix.gridlayout

 

It's so nice to try this one:

from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button

class LoginScreen(GridLayout):
    
    def __init__(self, **kwargs):
        super(LoginScreen, self).__init__(**kwargs)
        #self.cols = 3       # 3 columns 
        self.rows = 3       # 3 rows 
        self.add_widget(Label(text='User Name'))        #add widget label : content User Name
        self.username = TextInput(multiline=False)      # no multiline text input support
        self.add_widget(self.username)                  #add 'username' textinput
        self.add_widget(Label(text='Pass Word'))        #add widget label : content User Name
        self.password = TextInput(multiline=False, password=True)   #password auto-hidden
        self.add_widget(self.password)
        self.btn1 = Button(text='Login', fontsize=14)
        self.add_widget(self.btn1)
    
        
        
class MyApp(App):
    def build(self):
        return LoginScreen()
        
        
if __name__ == "__main__":
    MyApp().run()

I added a button down there.

And let's see what gonna happen later.

Change the self.rows , it inherits from the class "GridLayout"

Let's see it would look like this:

now we see the login button down there :D

 

But we need event to be triggered when the "Login" button's pressed.

So

转载于:https://www.cnblogs.com/spaceship9/p/3456198.html

import time import random 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.slider import Slider from kivy.uix.textinput import TextInput from kivy.uix.spinner import Spinner from kivy.uix.screenmanager import ScreenManager, Screen from kivy.clock import Clock from kivy.properties import StringProperty, NumericProperty, BooleanProperty from kivy.animation import Animation from kivy.core.audio import SoundLoader from kivy.uix.popup import Popup from kivy.uix.progressbar import ProgressBar from kivy_garden.graph import Graph, MeshLinePlot class InitialScreen(Screen): """初始界面:设置音乐参数""" def __init__(self, **kwargs): super(InitialScreen, self).__init__(**kwargs) # 创建主布局 layout = BoxLayout(orientation='vertical', padding=20, spacing=15) # 添加标题 title = Label( text="音乐创作助手", font_size=32, size_hint=(1, 0.1) ) layout.add_widget(title) # 添加节拍选择 layout.add_widget(Label(text="节拍:", size_hint=(1, 0.05))) self.beats_spinner = Spinner( text='请选择', values=('2/4', '3/4', '4/4', '6/8'), size_hint=(1, 0.08) ) layout.add_widget(self.beats_spinner) # 添加音速控制 layout.add_widget(Label(text="音速 (BPM):", size_hint=(1, 0.05))) self.tempo_slider = Slider( min=60, max=200, value=120, step=1, size_hint=(1, 0.1) ) self.tempo_value = Label( text=f"{int(self.tempo_slider.value)} BPM", size_hint=(1, 0.05) ) self.tempo_slider.bind(value=lambda instance, value: setattr(self.tempo_value, 'text', f"{int(value)} BPM")) layout.add_widget(self.tempo_slider) layout.add_widget(self.tempo_value) # 添加音调选择 layout.add_widget(Label(text="音调:", size_hint=(1, 0.05))) self.pitch_spinner = Spinner( text='请选择', values=('C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G'), size_hint=(1, 0.08) ) layout.add_widget(self.pitch_spinner) # 添加风格选择 layout.add_widget(Label(text="风格:", size_hint=(1, 0.05))) self.style_spinner = Spinner( text='请选择', values=('Pop', 'Rock', 'Jazz', 'Classical', 'Electronic', 'Folk', 'Blues', 'Country'), size_hint=(1, 0.08) ) layout.add_widget(self.style_spinner) # 添加伴奏音型选择 layout.add_widget(Label(text="伴奏音型:", size_hint=(1, 0.05))) self.accompaniment_spinner = Spinner( text='请选择', values=('Piano', 'Guitar', 'Strings', 'Drums', 'Bass', 'Synth', 'Choir', 'Orchestra'), size_hint=(1, 0.08) ) layout.add_widget(self.accompaniment_spinner) # 添加旋律音高序列输入 layout.add_widget(Label(text="旋律音高序列:", size_hint=(1, 0.05))) self.pitch_sequence = TextInput( multiline=False, hint_text="例如: C4 D4 E4 F4 G4", size_hint=(1, 0.08) ) layout.add_widget(self.pitch_sequence) # 添加开始录制按钮 self.start_button = Button( text="开始录制", font_size=24, size_hint=(1, 0.15), background_color=(0.2, 0.6, 0.9, 1) ) self.start_button.bind(on_press=self.validate_and_start) layout.add_widget(self.start_button) self.add_widget(layout) def validate_and_start(self, instance): """验证表单并切换到录音界面""" if (self.beats_spinner.text != '请选择' and self.pitch_spinner.text != '请选择' and self.style_spinner.text != '请选择' and self.accompaniment_spinner.text != '请选择' and self.pitch_sequence.text.strip()): # 获取当前选中的值 app = App.get_running_app() app.beats = self.beats_spinner.text app.tempo = int(self.tempo_slider.value) app.pitch = self.pitch_spinner.text app.style = self.style_spinner.text app.accompaniment = self.accompaniment_spinner.text app.pitch_sequence = self.pitch_sequence.text # 切换到录音界面 self.manager.current = 'recording' else: # 显示错误提示 self.show_error("请完成所有参数选择") def show_error(self, message): """显示错误提示""" # 简单实现:改变按钮颜色 self.start_button.background_color = (0.9, 0.2, 0.2, 1) Clock.schedule_once(lambda dt: setattr(self.start_button, 'background_color', (0.2, 0.6, 0.9, 1)), 1) class RecordingScreen(Screen): """录音界面:控制录音过程""" def __init__(self, **kwargs): super(RecordingScreen, self).__init__(**kwargs) # 录音状态 self.is_recording = False self.is_paused = False self.is_playing = False self.recording_time = 0 self.timer_event = None self.waveform_bars = [] self.recording_data = [] # 存储录音数据 # 创建主布局 layout = BoxLayout(orientation='vertical', padding=20, spacing=15) # 返回按钮 back_layout = BoxLayout(orientation='horizontal', size_hint=(1, 0.05)) back_button = Button( text="返回", size_hint=(0.2, 1), background_color=(0.6, 0.6, 0.6, 1) ) back_button.bind(on_press=self.go_back) back_layout.add_widget(back_button) layout.add_widget(back_layout) # 添加标题 title = Label( text="正在录音", font_size=32, size_hint=(1, 0.1) ) layout.add_widget(title) # 参数显示区域 self.params_layout = BoxLayout(orientation='vertical', size_hint=(1, 0.25)) layout.add_widget(self.params_layout) # 录音时间显示 self.time_label = Label( text="00:00", font_size=48, size_hint=(1, 0.1) ) layout.add_widget(self.time_label) # 波形可视化 self.graph = Graph( xlabel='时间', ylabel='振幅', x_ticks_minor=5, x_ticks_major=25, y_ticks_major=1, y_grid_label=True, x_grid_label=True, padding=5, x_grid=True, y_grid=True, xmin=0, xmax=100, ymin=-1, ymax=1, size_hint=(1, 0.25) ) self.plot = MeshLinePlot(color=[0.2, 0.6, 0.9, 1]) self.graph.add_plot(self.plot) layout.add_widget(self.graph) # 控制按钮区域 control_layout = BoxLayout(orientation='horizontal', size_hint=(1, 0.15), spacing=10) # 录音/停止按钮 self.record_button = Button( text="开始", font_size=24, background_color=(0.2, 0.8, 0.2, 1) ) self.record_button.bind(on_press=self.toggle_recording) control_layout.add_widget(self.record_button) # 生成按钮 self.generate_button = Button( text="生成", font_size=24, background_color=(0.8, 0.6, 0.2, 1), disabled=True ) self.generate_button.bind(on_press=self.generate_music) control_layout.add_widget(self.generate_button) layout.add_widget(control_layout) # 功能按钮区域 function_layout = BoxLayout(orientation='horizontal', size_hint=(1, 0.15), spacing=10) # 暂停/继续按钮 self.pause_button = Button( text="暂停", font_size=24, background_color=(0.8, 0.8, 0.2, 1), disabled=True ) self.pause_button.bind(on_press=self.toggle_pause) function_layout.add_widget(self.pause_button) # 播放/暂停按钮 self.play_button = Button( text="播放", font_size=24, background_color=(0.2, 0.6, 0.9, 1), disabled=True ) self.play_button.bind(on_press=self.toggle_play) function_layout.add_widget(self.play_button) layout.add_widget(function_layout) # 下载按钮 self.download_button = Button( text="下载", font_size=24, size_hint=(1, 0.1), background_color=(0.6, 0.2, 0.8, 1), disabled=True ) self.download_button.bind(on_press=self.download_recording) layout.add_widget(self.download_button) self.add_widget(layout) def on_enter(self): """进入屏幕时更新参数显示""" app = App.get_running_app() # 清空参数布局 self.params_layout.clear_widgets() # 添加参数显示 params = [ f"节拍: {app.beats}", f"音速: {app.tempo} BPM", f"音调: {app.pitch}", f"风格: {app.style}", f"伴奏: {app.accompaniment}", f"旋律音高: {app.pitch_sequence}" ] for param in params: label = Label( text=param, font_size=18, size_hint=(1, 0.2), halign='left' ) self.params_layout.add_widget(label) def toggle_recording(self, instance): """开始/停止录音""" if not self.is_recording: # 开始录音 self.is_recording = True self.record_button.text = "停止" self.record_button.background_color = (0.8, 0.2, 0.2, 1) self.pause_button.disabled = False self.play_button.disabled = True self.download_button.disabled = True self.generate_button.disabled = True # 重置录音数据 self.recording_data = [] self.plot.points = [] # 启动计时器 self.recording_time = 0 self.update_time() self.timer_event = Clock.schedule_interval(self.update_time, 0.1) # 100ms更新一次 # 显示录音中提示 app = App.get_running_app() app.show_message("开始录音...") else: # 停止录音 self.is_recording = False self.record_button.text = "开始" self.record_button.background_color = (0.2, 0.8, 0.2, 1) self.pause_button.disabled = True self.play_button.disabled = False self.download_button.disabled = False self.generate_button.disabled = False # 停止计时器 if self.timer_event: self.timer_event.cancel() # 显示录音完成提示 app = App.get_running_app() app.show_message(f"录音完成,时长: {self.recording_time//10}秒") def update_time(self, dt=None): """更新录音时间和波形数据""" self.recording_time += 1 seconds = self.recording_time // 10 # 转换为秒 tenths = self.recording_time % 10 # 十分之一秒 self.time_label.text = f"{seconds:02d}:{tenths:01d}" # 生成随机波形数据(实际应用中会从麦克风获取) if self.is_recording and not self.is_paused: x = len(self.recording_data) y = random.uniform(-0.8, 0.8) self.recording_data.append((x, y)) # 更新波形显示 if len(self.recording_data) > 100: self.plot.points = self.recording_data[-100:] else: self.plot.points = self.recording_data def toggle_pause(self, instance): """暂停/继续录音""" if not self.is_paused: # 暂停录音 self.is_paused = True self.pause_button.text = "继续" if self.timer_event: self.timer_event.cancel() else: # 继续录音 self.is_paused = False self.pause_button.text = "暂停" self.timer_event = Clock.schedule_interval(self.update_time, 0.1) def toggle_play(self, instance): """播放/暂停录音""" if not self.is_playing: # 开始播放 self.is_playing = True self.play_button.text = "暂停" # 模拟播放波形动画 self.play_index = 0 self.play_timer = Clock.schedule_interval(self.update_play, 0.1) else: # 暂停播放 self.is_playing = False self.play_button.text = "播放" if hasattr(self, 'play_timer'): self.play_timer.cancel() def update_play(self, dt): """更新播放时的波形显示""" if not self.recording_data: return self.play_index += 1 if self.play_index >= len(self.recording_data): self.play_index = 0 self.is_playing = False self.play_button.text = "播放" self.play_timer.cancel() return # 更新波形显示 start = max(0, self.play_index - 50) end = self.play_index + 50 if end > len(self.recording_data): end = len(self.recording_data) start = max(0, end - 100) self.plot.points = self.recording_data[start:end] def generate_music(self, instance): """生成音乐""" if not self.is_recording: # 显示生成中对话框 self.progress_popup = Popup( title="生成音乐", size_hint=(None, None), size=(400, 200) ) progress_layout = BoxLayout(orientation='vertical', padding=20) progress_label = Label(text="正在生成音乐...") progress_bar = ProgressBar(max=100, value=0) progress_layout.add_widget(progress_label) progress_layout.add_widget(progress_bar) self.progress_popup.content = progress_layout self.progress_popup.open() # 模拟生成过程 self.progress = 0 self.generate_timer = Clock.schedule_interval(lambda dt: self.update_progress(progress_bar, progress_label), 0.1) else: # 提示用户先停止录音 app = App.get_running_app() app.show_message("请先停止录音") def update_progress(self, progress_bar, progress_label): """更新生成进度""" self.progress += 1 progress_bar.value = self.progress progress_label.text = f"正在生成音乐... {self.progress}%" if self.progress >= 100: self.generate_timer.cancel() self.progress_popup.dismiss() # 显示成功提示 app = App.get_running_app() app.show_message("音乐生成成功") def download_recording(self, instance): """下载录音""" # 显示下载中提示 app = App.get_running_app() app.show_message("准备下载...") # 模拟下载过程 Clock.schedule_once(self.on_download_complete, 2) def on_download_complete(self, dt): """下载完成回调""" # 显示成功提示 app = App.get_running_app() app.show_message("下载完成") def go_back(self, instance): """返回初始界面""" # 停止所有活动 if self.is_recording: self.toggle_recording(None) if hasattr(self, 'play_timer') and self.play_timer.is_triggered: self.play_timer.cancel() # 返回初始界面 self.manager.current = 'initial' class MusicRecorderApp(App): """音乐录音应用主类""" beats = StringProperty("") tempo = NumericProperty(120) pitch = StringProperty("") style = StringProperty("") accompaniment = StringProperty("") pitch_sequence = StringProperty("") def build(self): """构建应用UI""" # 创建屏幕管理器 sm = ScreenManager() # 添加屏幕 sm.add_widget(InitialScreen(name='initial')) sm.add_widget(RecordingScreen(name='recording')) return sm def show_message(self, message): """显示消息提示""" popup = Popup( title='提示', content=Label(text=message), size_hint=(None, None), size=(300, 200), auto_dismiss=True ) popup.open() if __name__ == '__main__': # 启动应用 MusicRecorderApp().run()
05-15
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值