kivy - KivyMD:无论如何尝试,小部件文本都不会更新
问题描述
首先,我只是在很短的时间内学习 Python 和 Kivy,所以这就解释了为什么代码对你来说看起来结构不好。我愿意接受建议,但实际上我在 Kivy/KivyMD 遇到了一个具体问题。
另外我相信你认为这个问题很常见,我不应该多发帖子。我已经搜索了很多,但是如果您可以参考一篇真正回答我的问题的文章,我也将不胜感激。
我想用用户在输入中输入的任何内容来更新 Planlist - plan1 文本。基础工作就在那里,StingProperty 确实按照预期主动更改为 UserInput。但是,Planlist 中的 test-label 和实际的 listitem 都不会更新文本。将实际的字符串属性作为文本放入 kv 中,或者从 on_text_validate 函数中更改文本都不能解决问题。我在这里有什么不同的做法?
py:'''
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.metrics import dp
from kivy.properties import StringProperty, ObjectProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import Screen, ScreenManager
from kivymd.app import MDApp
from kivymd.uix.button import MDFlatButton
from kivymd.uix.dialog import MDDialog
from kivymd.uix.textfield import MDTextField
from kivymd.uix.list import MDList
class RootWidget(BoxLayout):
def __init__(self, **kwargs):
super().__init__(**kwargs)
class MyScreenManager(ScreenManager):
my_screen_manager = ObjectProperty()
class ScreenOverview(Screen):
my_screen_manager = MyScreenManager()
class ScreenPlan1(Screen):
pass
class Content(BoxLayout):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.planlist = Planlist()
self.MainApp = MainApp()
self.cdialog = MainApp().dialog
class Planlist(MDList):
def __init__(self, **kwargs):
self.text_input_str = StringProperty("")
# self.text_input_str = "plan-unmodifiziert"
super().__init__(**kwargs)
class MainApp(MDApp):
dialog = None
def __init__(self, **kwargs):
self.plan1 = None
self.planlist = Planlist()
self.root = RootWidget()
super().__init__(**kwargs)
def build(self):
self.theme_cls.theme_style = "Dark"
self.theme_cls.primary_palette = "BlueGray"
return Builder.load_file("fit_app.kv")
def show_confirmation_dialog(self):
if not self.dialog:
self.dialog = MDDialog(
title="Namenseingabe:",
type="custom",
content_cls=Content(),
buttons=[
MDFlatButton(
text="CANCEL", text_color=self.theme_cls.primary_color,
on_release=self.dialog_close
),
],
md_bg_color=(.38, .38, .38, 1)
)
self.dialog.open()
def dialog_close(self, *args):
self.dialog.dismiss(force=True)
def on_text_validate(self, widget):
self.planlist.text_input_str = widget.text
print(self.planlist.text_input_str)
print(widget.text)
self.planlist.ids.plan1.text = widget.text
MainApp().run()
'''
千伏:'''
RootWidget:
orientation: "vertical"
MDToolbar:
title: "FitApp"
md_bg_color: .2,.2,.2,1
specific_text_color: 1, 1, 1, 1
MDBottomNavigation:
# panel_color: .2, .2, .2, 1
MDBottomNavigationItem:
name: "nav1"
text: "Dashboard"
icon: "desktop-mac-dashboard"
MDLabel:
text: "Python"
halign: "center"
MDBottomNavigationItem:
name: "nav2"
text: "Workout"
icon: "dumbbell"
MyScreenManager:
Screen:
name: "screen_overview"
BoxLayout:
orientation: "vertical"
MDBoxLayout:
size_hint: 1, .2
pos_hint: {"top": 1}
MDLabel:
text: "Neuer Trainingsplan"
pos_hint: {"center_x":1, "top":1}
text_size: self.size
halign: 'left'
valign: 'top'
padding: "30dp", "30dp"
MDIconButton:
icon: "plus"
pos_hint: {"center_x":1, "center_y":.92}
# valign: "top"
on_release: app.show_confirmation_dialog()
Planlist:
Screen:
name: "plan1"
MDLabel:
text: "Screen"
halign: "center"
Button:
text: "change"
on_press:
screen_manager.current = 'overview'
MDBottomNavigationItem:
name: "nav3"
text: "History"
icon: "history"
MDLabel:
text: "Cobra"
halign: "center"
<Content>:
orientation: "horizontal"
spacing: "12dp"
size_hint_y: None
height: "100dp"
MDTextField:
id: plan_name
hint_text: "Planname"
on_text_validate: root.MainApp.on_text_validate(self)
MDFlatButton:
text: "OK"
size: "70dp", "30dp" # size_hint MDFlatButton buggy?
pos_hint: {"right": 1}
on_release:
root.MainApp.on_text_validate(plan_name)
<MyScreenManager>:
id: screen_manager
<Planlist>:
OneLineListItem:
id: plan1
text: "plan-unmodifiziert1"
on_press: screen_manager.current = "plan1"
Label:
text: str(root.text_input_str)
OneLineListItem:
text: "plan-unmodifiziert2"
on_press: screen_manager.current = "plan1"
OneLineListItem:
text: "plan-unmodifiziert3"
on_press: screen_manager.current = "plan1"
'''
旁注:MDlist 项的 on_press 命令实际上并没有工作,因为代码现在是结构化的。我仍在努力与来自不同地方的小部件之间的通信。一些关于如何实现该工作的提示将是一个奖励,但无论如何我都会在解决上述问题后尝试解决这个问题。
非常感谢你的帮助。
解决方案
我不太确定你的代码是关于什么的:(((但我想我明白你的意思(?)当你用MDApp
而不是App
从小kivy.app.App
部件继承时,小部件没有更新。我在尝试实现时遇到这个问题kivymd
东西“正常的东西”。我的解决方案如下:
- 你有一个布局的主/基类(GUI)-->
class Main(Widget)
- 你有一个方法来更新基类中的那些小部件( in
Main()
) - 在应用程序类中(继承于
MDApp
):在方法内部build
:用 value = 命名一个变量Main()
- 用于
kivy.clock.Clock.schedule_interval
调用update方法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 文档)也许你可以试试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()
// 由于字数限制,有些代码被省略了 // 希望对你有帮助:)
推荐阅读
- optimization - 在具有等式约束的乘积之和中查找系数
- node.js - 订阅了如此多的 Outlook 推送通知
- reactjs - 如何使用 Formik 管理表单状态
- ios - Xcode 发布构建配置反映了过时的 git 分支
- text - GPT-3 提示句子级和段落级文本摘要/文本缩短/文本重写
- sql - Rails 在连接表上加入条件
- python - 在python中的列表中分隔字符串
- webpack - Webpack - less-loader 中构建和生产 css 的不同字体路径
- c# - 在flowlayoutpanel内的用户控件中获取所有选中复选框的标签文本
- ios - 部分在 Objective C 和部分在 Swift 中实现协议