我不太确定你的代码是关于什么的:(((但我想我明白你的意思(?)当你从kivy.app.App继承MDApp而不是App时,小部件是未更新。当我尝试将kivymd 的东西实现为“正常的 kivy 事物”时,我遇到了这个问题。我的解决方案如下:
- 你有一个布局(GUI)的主/基类-->
class Main(Widget)
- 并且您获得了一种方法来更新基类中的那些小部件(在
Main() 中)
- 在应用程序类中(用
MDApp 继承):在方法build 中:用值=Main() 命名一个变量
- 使用
kivy.clock.Clock.schedule_interval调用Main()中的更新方法进行更新
这样的:
import kivy
from kivy.uix.widget import Widget
from kivymd.app import MDApp
from kivymd.uix.picker import MDDatePicker
from kivy.clock import Clock
kv_file = """
#:kivy 2.0.0
<Main>:
Label:
id: my_label
text: "a label here"
font_size: 25
MDRaisedButton:
id: my_raised_button
text: "this is a md raised button"
font_size: 25
center: root.center
"""
kivy.lang.Builder.load_string(kv_file)
class Main(Widget): # base class , I just name it Main , lol
num = 0
def update(self, dt): # method to update widgets
self.ids.my_raised_button.center = self.center
self.ids.my_label.text = str(self.num)
self.num += 1
class MyKivyMDApp(MDApp): # app class ( inherit with MDApp )
def build(self):
self.theme_cls.theme_style = "Dark" # theme ( just know it by watching a youtube tutorial lol )
self.main = Main() # although it's a bit illegal ( not a right way to declare class variable )
# but it works lol
Clock.schedule_interval(self.main.update, 1/60) # schedule interval to update
return self.main
if __name__ == "__main__":
MyKivyMDApp().run()
exit()
编辑
对于on_press回调,MDList好像没有这样的方法(KivyMD Documentation)也许你可以试试on_release?
以及我目前正在进行的项目(我知道这真的很乱,哈哈)(只是一个例子):
import datetime
from streamlit import caching
import gc
from goose3 import Goose
import webbrowser as web
import cv2
settings = """..."""
import kivy
from kivy.app import App
from kivymd.app import MDApp
from kivy.uix.widget import Widget
from kivy.clock import Clock
from kivy.graphics.texture import Texture
from kivy.animation import Animation
from kivy.core.window import Window
from kivy.properties import NumericProperty, StringProperty
kv_file = """
#:kivy 2.0.0
<Main>:
# background color
canvas.before:
Color:
rgb: [0, 0, 0] if root.theme == "Dark" else [0.9, 0.9, 0.9]
Rectangle:
pos: self.pos
size: self.size
# bottom bar
canvas.after:
Color:
rgb: [1, 1, 1] if root.theme == "Dark" else [.25, .25, .25]
Rectangle:
pos: self.center_x - self.width /3 /2, 15 - 2.5
size: self.width /3, 5
# Screen
ScreenManager:
id: screen_manager
size: root.size
Screen:
name: "main"
Label:
id: main_center_label
markup: True
text: f"[ref=main_center_label]{root.main_center_label_text}[/ref]"
font_size: root.font_size
size_hint: None, None
size: self.texture_size
right: -(self.size[0])
center_y: root.center_y
Screen:
name: "app"
Button:
id: clear_cache
text: "Clear Cache"
size_hint: None, None
size: self.texture_size[0] *1.5, self.texture_size[1] *1.5
font_size: root.font_size
on_release:
root.clear_cache()
GridLayout:
id: app_grid_layout
rows: 3
cols: 3
size_hint: .5, .5
center: root.center
spacing: 15, 15
Button:
on_release:
app.open_settings()
background_color: 0, 0, 0
Image:
source: "sources/setting.png"
allow_stretch: True
center: self.parent.center
size: self.parent.size
Button:
on_release:
root.ids.screen_manager.current = "bmi"
background_color: 0, 5, 0
Image:
source: "sources/BMI.png"
allow_stretch: True
center: self.parent.center
size: self.parent.size
Button:
on_release:
root.ids.screen_manager.current = "search"
background_color: 0, 2, 5
Image:
source: 'sources/search.png'
allow_stretch: True
center: self.parent.center
size: self.parent.size
Button:
on_release:
root.ids.screen_manager.current = "scan"
background_color: 0, 5, 5
Image:
source: "sources/qrcode.png"
allow_stretch: True
center: self.parent.center
size: self.parent.size
Button:
on_release:
root.ids.screen_manager.current = "timer"
background_color: 0, 0, 0
Image:
source: "sources/timer.png"
allow_stretch: True
center: self.parent.center
size: self.parent.size
Button:
on_release:
root.ids.screen_manager.current = "reminder"
background_color: 3, 2.7, 0
Image:
source: "sources/reminder.png"
allow_stretch: True
center: self.parent.center
size: self.parent.size
Button:
on_release:
root.ids.screen_manager.current = "device"
background_color: 5, 0.5, 5
Image:
source: "sources/device.png"
allow_stretch: True
center: self.parent.center
size: self.parent.size
Button:
on_release:
root.ids.screen_manager.current = "file"
background_color: 0, 2.5, 5
Image:
source: "sources/file.png"
allow_stretch: True
center: self.parent.center
size: self.parent.size
Button:
on_release:
root.ids.screen_manager.current = "screen_recorder"
background_color: 5, 1.5, 0
Image:
source: "sources/screenrecorder.png"
allow_stretch: True
center: self.parent.center
size: self.parent.size
Screen:
name: "bmi"
Label:
id: bmi_header
text: "BMI Calculator"
font_size: root.font_size * 1.5
color: [1, 1, 1] if root.theme == "Dark" else [0, 0, 0]
Label:
id: bmi_mass_label
text: "Mass : "
font_size: root.font_size
size_hint: None, None
size: self.texture_size
color: [1, 1, 1] if root.theme == "Dark" else [0, 0, 0]
TextInput:
id: bmi_mass_textinput
hint_text: "In KG"
size_hint: .3, None
height: root.font_size * 2
font_size: root.font_size
write_tab: False
multiline: False
background_color: [.25, .25, .25] if root.theme == "Dark" else [.75, .75, .75]
foreground_color: [1, 1, 1] if root.theme == "Dark" else [0, 0, 0]
cursor_color: self.foreground_color
Label:
id: bmi_height_label
text: "Height : "
font_size: root.font_size
size_hint: None, None
size: self.texture_size
color: [1, 1, 1] if root.theme == "Dark" else [0, 0, 0]
TextInput:
id: bmi_height_textinput
hint_text: "In CM"
size_hint: .3, None
height: root.font_size * 2
font_size: root.font_size
write_tab: False
multiline: False
background_color: [.25, .25, .25] if root.theme == "Dark" else [.75, .75, .75]
foreground_color: [1, 1, 1] if root.theme == "Dark" else [0, 0, 0]
cursor_color: self.foreground_color
Label:
id: bmi_display_label
text: "Your BMI : None"
size_hint: None, None
size: self.texture_size
font_size: root.font_size
color: [1, 1, 1] if root.theme == "Dark" else [0, 0, 0]
halign: "center"
BoxLayout:
id: bmi_info_boxlayout
orientation: "vertical"
size_hint: 1, None
height: bmi_display_label.y - 15
BoxLayout:
orientation: "horizontal"
# left boxlayout --> info
BoxLayout:
orientation: "vertical"
Label:
text: "Very Severely Underweight"
font_size: root.font_size
color: [1, 1, 1] if root.theme == "Dark" else [0, 0, 0]
halign: "center"
Label:
text: "Severely Underweight"
font_size: root.font_size
color: [1, 1, 1] if root.theme == "Dark" else [0, 0, 0]
halign: "center"
Label:
text: "Underweight"
font_size: root.font_size
color: [1, 1, 1] if root.theme == "Dark" else [0, 0, 0]
halign: "center"
Label:
text: "Normal ( Healthy Weight )"
font_size: root.font_size
color: [1, 1, 1] if root.theme == "Dark" else [0, 0, 0]
halign: "center"
Label:
text: "Overweight"
font_size: root.font_size
color: [1, 1, 1] if root.theme == "Dark" else [0, 0, 0]
halign: "center"
Label:
text: "Obese Class I ( Moderately obese )"
font_size: root.font_size
color: [1, 1, 1] if root.theme == "Dark" else [0, 0, 0]
halign: "center"
Label:
text: "Obese Class II ( Severely obese )"
font_size: root.font_size
color: [1, 1, 1] if root.theme == "Dark" else [0, 0, 0]
halign: "center"
Label:
text: "Obese Class III ( Very severely obese )"
font_size: root.font_size
color: [1, 1, 1] if root.theme == "Dark" else [0, 0, 0]
halign: "center"
# right boxlayout --> range
BoxLayout:
orientation: "vertical"
# size_hint_x: 0.3
Label:
text: "<= 15"
font_size: root.font_size
color: [1, 1, 1] if root.theme == "Dark" else [0, 0, 0]
halign: "center"
Label:
text: "15 ~ 16"
font_size: root.font_size
color: [1, 1, 1] if root.theme == "Dark" else [0, 0, 0]
halign: "center"
Label:
text: "16 ~ 18.5"
font_size: root.font_size
color: [1, 1, 1] if root.theme == "Dark" else [0, 0, 0]
halign: "center"
Label:
text: "18.5 ~ 25"
font_size: root.font_size
color: [1, 1, 1] if root.theme == "Dark" else [0, 0, 0]
halign: "center"
Label:
text: "25 ~ 30"
font_size: root.font_size
color: [1, 1, 1] if root.theme == "Dark" else [0, 0, 0]
halign: "center"
Label:
text: "30 ~ 35"
font_size: root.font_size
color: [1, 1, 1] if root.theme == "Dark" else [0, 0, 0]
halign: "center"
Label:
text: "35 ~ 40"
font_size: root.font_size
color: [1, 1, 1] if root.theme == "Dark" else [0, 0, 0]
halign: "center"
Label:
text: ">= 40"
font_size: root.font_size
color: [1, 1, 1] if root.theme == "Dark" else [0, 0, 0]
halign: "center"
Label:
text: "*** Just For Reference ***"
font_size: root.font_size
size_hint_y: 0.3
color: [1, 1, 1] if root.theme == "Dark" else [0, 0, 0]
halign: "center"
valign: "middle"
Screen:
name: "search"
Label:
id: search_header_label
text: "Quick Search"
font_size: root.font_size * 1.5
color: [1, 1, 1] if root.theme == "Dark" else [0, 0, 0]
Label:
id: search_wiki_label
text: "Search On Wikipedia : "
font_size: root.font_size
size_hint: None, None
size: self.texture_size
color: [1, 1, 1] if root.theme == "Dark" else [0, 0, 0]
TextInput:
id: search_wiki_textinput
hint_text: "Keywords"
size_hint: .3, None
height: root.font_size * 2
font_size: root.font_size
multiline: False
background_color: [.25, .25, .25] if root.theme == "Dark" else [.75, .75, .75]
foreground_color: [1, 1, 1] if root.theme == "Dark" else [0, 0, 0]
cursor_color: self.foreground_color
Label:
id: search_web_label
text: "Search On Browser : "
font_size: root.font_size
size_hint: None, None
size: self.texture_size
color: [1, 1, 1] if root.theme == "Dark" else [0, 0, 0]
TextInput:
id: search_web_textinput
hint_text: "Search on Web . . ."
size_hint: .3, None
height: root.font_size * 2
font_size: root.font_size
multiline: False
background_color: [.25, .25, .25] if root.theme == "Dark" else [.75, .75, .75]
foreground_color: [1, 1, 1] if root.theme == "Dark" else [0, 0, 0]
cursor_color: self.foreground_color
Label:
id: search_wiki_url_display_label
text: ""
size_hint: None, None
size: self.texture_size
font_size: root.font_size
markup: True
color: [1, 1, 1] if root.theme == "Dark" else [0, 0, 0]
TextInput:
id: search_wiki_result_display_textinput
text: ""
size_hint: 1, None
height: search_web_label.y - 50
font_size: root.font_size
background_color: [0, 0, 0] if root.theme == "Dark" else [1, 1, 1]
foreground_color: [1, 1, 1] if root.theme == "Dark" else [0, 0, 0]
cursor_color: self.foreground_color
readonly: True
Screen:
name: "scan"
Label:
id: scan_header_label
text: "Auto Scan"
font_size: root.font_size * 1.5
size_hint: None, None
size: self.texture_size
color: [1, 1, 1] if root.theme == "Dark" else [0, 0, 0]
Image:
id: scan_camera_display_image
size_hint_y: .8
Button:
id: scan_change_camera_index_button
text: "Current Camera Index Will Be Displayed Here"
font_size: root.font_size
size_hint: None, None
size: self.texture_size[0] + 20, self.texture_size[1] + 15
background_color: 0.55, .55, .55
Screen:
name: "timer"
Label:
id: timer_header_label
text: "Timer"
font_size: root.font_size * 1.5
size_hint: None, None
size: self.texture_size
color: [1, 1, 1] if root.theme == "Dark" else [0, 0, 0]
Screen:
name: "reminder"
Label:
id: reminder_header_label
text: "Reminder"
font_size: root.font_size * 1.5
size_hint: None, None
size: self.texture_size
color: [1, 1, 1] if root.theme == "Dark" else [0, 0, 0]
TextInput:
id: reminder_input_item_textinput
size_hint: 1, None
height: root.font_size * 1.75
hint_text: "Remind . . ."
font_size: root.font_size
multiline: False
background_color: [.25, .25, .25] if root.theme == "Dark" else [.75, .75, .75]
foreground_color: [1, 1, 1] if root.theme == "Dark" else [0, 0, 0]
cursor_color: self.foreground_color
MDRaisedButton:
text: "This is a MDRaisedButton"
Screen:
name: "device"
Screen:
name: "file"
Screen:
name: "screen_recorder"
# Always on display
Label:
id: date_label
text: "____day XX _______"
font_size: root.font_size
size: self.texture_size
x: 15
y: root.height
Label:
id: time_label
text: "XX : XX : XX __"
font_size: root.font_size
size: self.texture_size
x: root.right - self.size[0] - 15
y: root.height
TextInput:
id: main_textinput
font_size: root.font_size
size_hint: None, None
width: root.width * 0.7
height: root.font_size *2
center_x: root.center_x
top: 0
border: 3, 3, 3, 3
background_color: .3, .3, .3
cursor_color: 1, 1, 1
foreground_color: self.cursor_color
multiline: False
"""
kivy.lang.Builder.load_string(kv_file)
class ScanQRCode:
...
class Search:
...
class BMI:
...
class Main(Widget):
# font size
font_size = NumericProperty(25)
# theme
theme = StringProperty("Dark") # options : Dark, Light -> str
# datetime
now = str()
# screen | main
main_center_label_text = "Hello World !"
# screen | scan
camera_index = 0
scan = ScanQRCode(camera_index)
def clear_cache(self):
...
def change_theme(self):
...
def toggle_main_textinput(self, show: bool):
...
def on_button_release(self, instance):
...
def animation(self, obj, _center_pos, _duration, _mode):
...
def update(self, dt):
# datetime
self.now = datetime.datetime.now()
self.ids.date_label.text = self.now.strftime("%A %d %B")
self.ids.time_label.text = self.now.strftime("%I : %M : %S %p")
...
# main textinput
...
self.ids.main_textinput.bind(on_text_validate = self.on_textinput_text_validate)
# screen | main
if self.ids.screen_manager.current == "main":
# center label
...
self.ids.main_center_label.text = f"[ref=main_center_label]{self.main_center_label_text}[/ref]"
if self.ids["main_center_label"].height > 150:
_new_text = self.main_center_label_text.split("\n")
self.ids.main_center_label = "\n".join(_new_text[-3:])
self.ids["main_center_label"].bind(on_ref_press = self.on_label_ref_press)
# screen | app
if self.ids.screen_manager.current == "app":
# grid layout
self.ids.app_grid_layout.center = self.center
# screen | bmi
if self.ids.screen_manager.current == "bmi":
# header
self.ids.bmi_header.center = [self.center_x, self.height * 6 / 7]
# mass label
...
# height label
...
# mass textinput
...
# height textinput
...
# display label
...
if any(self.ids.bmi_mass_textinput.text) and any(self.ids.bmi_height_textinput.text):
_mass = self.ids.bmi_mass_textinput.text # kg
_height = self.ids.bmi_height_textinput.text # cm
if _mass.isnumeric() and _height.isnumeric():
_bmi = BMI().get_bmi(float(_mass), float(_height) / 100)
self.ids.bmi_display_label.text = f"Your BMI : {_bmi}"
# info boxlayout
self.ids.bmi_info_boxlayout.top = self.ids.bmi_display_label.y - 15
# screen | search
if self.ids.screen_manager.current == "search":
# header
self.ids.search_header_label.center = [self.center_x, self.height * 6 / 7]
# search wiki label
self.ids.search_wiki_label.right = self.center_x
self.ids.search_wiki_label.y = self.height * 5 / 7
# search web label
self.ids.search_web_label.right = self.center_x
self.ids.search_web_label.y = self.height * 4 / 7
# search wiki textinput
self.ids.search_wiki_textinput.x = self.ids.search_wiki_label.right
self.ids.search_wiki_textinput.center_y = self.ids.search_wiki_label.center_y
self.ids.search_wiki_textinput.bind(on_text_validate = self.on_textinput_text_validate)
self.ids.search_wiki_textinput.bind(focus = self.on_textinput_focus)
# search web textinput
...
self.ids.search_web_textinput.bind(on_text_validate = self.on_textinput_text_validate)
self.ids.search_web_textinput.bind(focus = self.on_textinput_focus)
# wiki url display label
...
self.ids.search_wiki_url_display_label.bind(on_ref_press = self.on_label_ref_press)
# screen | scan
if self.ids.screen_manager.current == "scan":
# header
...
# change camera index button
...
self.ids.scan_change_camera_index_button.bind(on_release = self.on_button_release)
# camera display image
self.ids.scan_camera_display_image.top = self.ids.scan_header_label.y
if self.scan.get_data():
self.scan.destroy_all_windows()
self.ids.screen_manager.current = "app"
Search().search_browser(self.scan.get_data())
self.scan.clear_all_data()
else:
self.ids.scan_camera_display_image.texture = self.scan.decode_and_return_texture()
# screen | timer
if self.ids.screen_manager.current == "timer":
# header
...
# screen | reminder
if self.ids.screen_manager.current == "reminder":
# header
...
# input item textinput
...
def on_touch_move(self, touch):
...
def on_touch_up(self, touch):
...
class MyFirstApp(MDApp):
key_pressed = set()
# keyboard shortcut
def on_key_down(self, modifier, keycode1, keycode2, keytext, keylist):
...
def on_key_up(self, modifier, keycode1, keycode2):
...
# settings
def on_config_change(self, config, section, key, value):
# todo : settings
...
# build config
def build_config(self, config):
...
# build settings
def build_settings(self, _settings):
...
# build
def build(self):
self.title = "My First Kivy App"
self.icon = ""
self.use_kivy_settings = False
self.main = Main() ########## I did this to make it works ##########
# settings
...
# startup animation
...
# keyboard key bind
...
# screen manager
self.main.ids.screen_manager.transition.direction = "up"
# main update
Clock.schedule_interval(self.main.update, 0.1) ########## use clock to schedule interval the update function to update widget ( I do in this way )
return self.main ########## finally return the widget class ##########
if __name__ == "__main__":
MyFirstApp().run()
exit()
// 由于字数限制,部分代码被省略
// 希望对你有帮助:)