如何使用 kv 文件刷新 Kivy 中的 GridLayout
Posted
技术标签:
【中文标题】如何使用 kv 文件刷新 Kivy 中的 GridLayout【英文标题】:How to refresh GridLayout in Kivy with kv file 【发布时间】:2021-08-29 10:28:54 【问题描述】:我需要帮助。
我用 Kivy 创建了一个小型移动应用程序。
我有两个屏幕:ScreenList 和 ScreenDetail。
但是包含 GridLayout 的屏幕(ScreenList)不刷新
ScreenList:包含项目列表
ScreenDetail:包含单个项目的详细信息。
应用程序的工作原理:
-
当我点击按钮 1 上的第一项时
我转到项目的详细信息。
我修改了第二个字段。我替换文本:
Firt element
为 First and update data
录制后,我将应用程序重定向到包含 (ScreenList) 元素列表的屏幕。
但元素列表保持不变,然后数据库中的数据已被修改。
6.当我返回包含详细信息的屏幕(ScreenDetail)时,我看到数据已更新。
如何刷新 ScreenList 中的项目列表?
以图片为例
更新前列表
更新前
更新后
更新后列表
这是python代码:
import kivy
from kivy.app import App
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.scrollview import ScrollView
from kivy.properties import ObjectProperty, StringProperty
from kivy.lang import Builder
from kivymd.uix.picker import MDTimePicker
from kivymd.uix.picker import MDDatePicker
from kivymd.app import MDApp
import sqlite3
import os.path
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
db_path = os.path.join(BASE_DIR, "donnee/ProjetMaison.db")
def donnee_dic(cursor, row):
d =
for idx, col in enumerate(cursor.description):
d[col[0]] = row[idx]
return d
cur_id = None
class ScreenList(Screen):
data_grid = ObjectProperty()
def go_to_detail(self, instance):
global cur_id
cur_id = int(instance.text)
self.manager.current = 'screen_detail'
def __init__(self, **kwargs):
super(ScreenList, self).__init__(**kwargs)
con_list_course = sqlite3.connect(db_path)
con_list_course.row_factory = donnee_dic
curss_list_course = con_list_course.cursor()
data_list_course = curss_list_course.execute("select * FROM courses")
self.data_grid.bind(minimum_height=self.data_grid.setter('height'))
for row in data_list_course:
template_screen = GridLayout(cols=2, size_hint_y=None, height=40)
template_screen.add_widget(Label(text=row['nom']))
template_screen.add_widget(Button(text=str(row['id']), on_press=self.go_to_detail))
self.data_grid.add_widget(template_screen)
con_list_course.close()
def Maj_colonne(id, nom):
try:
sqliteConnection = sqlite3.connect(db_path)
cursor = sqliteConnection.cursor()
sqlite_update_query = """Update courses set nom = ? where id = ?"""
columnValues = (nom, id)
cursor.execute(sqlite_update_query, columnValues)
sqliteConnection.commit()
sqliteConnection.commit()
cursor.close()
except sqlite3.Error as error:
print("Erreur de connexion", error)
finally:
if sqliteConnection:
sqliteConnection.close()
class ScreenDetail(Screen):
label_id = ObjectProperty()
label_nom = ObjectProperty()
def __init__(self, **kwargs):
super(ScreenDetail, self).__init__(**kwargs)
def on_enter(self):
global cur_id
conn = sqlite3.connect(db_path)
cursor = conn.execute("select * FROM courses where id=?",str(cur_id))
for row in cursor:
self.label_id.text = str(row[0])
self.label_nom.text = str(row[1])
cursor.close()
def update_course(self):
id_pk = self.ids['label_id'].text
nom = self.ids['label_nom'].text
if id_pk:
Maj_colonne(str(id_pk), str(nom))
self.ids['label_id'].text = ''
self.ids['label_nom'].text = ''
self.manager.current = 'screen_list'
class Listapp(MDApp):
def build(self):
screenmanager = ScreenManager()
screenmanager.add_widget(ScreenList(name='screen_list'))
screenmanager.add_widget(ScreenDetail(name='screen_detail'))
return screenmanager
if __name__ == '__main__':
Listapp().run()
这是 kv 代码:
#:import utils kivy.utils
<ScreenList>:
data_grid: data_grid
MDBoxLayout:
orientation: 'vertical'
md_bg_color: app.theme_cls.primary_color
radius: [25, 0, 0, 0]
ScrollView:
MDGridLayout:
id: data_grid
cols: 1
spacing:10
size_hint_y:None
<ScreenDetail>:
label_id: label_id
label_nom: label_nom
MDBoxLayout:
orientation: 'vertical'
md_bg_color: app.theme_cls.primary_color
ScrollView:
GridLayout:
id: detail_grid
cols:2
Label:
text: 'Numéro:'
bold: True
TextInput:
id: label_id
text: ''
Label:
text: 'Nom:'
bold: True
TextInput:
id: label_nom
text: ''
Button:
text: 'OK'
size_hint_y: None
on_press: root.update_course()
谢谢
【问题讨论】:
粘贴代码时,请确保它无需太多调整即可运行。在您的代码中,有一些不允许执行的数据库内容。请更新您的代码。 嗨。很抱歉这个疏忽。下次,我会考虑的。谢谢你。我会测试你的解决方案。 【参考方案1】:一般来说,使用 Kivy 时需要注意的事项很少
当您尝试在屏幕之间共享数据时,使用app
方法而不是屏幕的特定方法通常很有用。
当您需要创建大量按钮(可能在循环内)并为其事件绑定方法(on_press
、on_release
)时,动态创建按钮实例并为其事件绑定方法通常是不好的因为您需要做额外的工作以确保在触发事件时使用正确的参数调用这些绑定方法。而是创建一个自定义类模板并使用它。
针对您的问题的有效解决方案(仅显示已添加/更新的部分
创建自定义 GridLayout:
class MyGrid(GridLayout):
pass
更新了ScreenList
中的__init__
方法:
def __init__(self, **kwargs):
#...
app = MDApp.get_running_app()
for row in data_list_course:
template_screen = MyGrid()
template_screen.ids.lbl.text = row['nom']
template_screen.ids.btn.text = str(row['id'])
self.data_grid.add_widget(template_screen)
在app
类中添加了方法:
class Listapp(MDApp):
def build(self):
self.screenmanager = ScreenManager()
self.screenmanager.add_widget(ScreenList(name='screen_list'))
self.screenmanager.add_widget(ScreenDetail(name='screen_detail'))
return self.screenmanager
def go_to_detail_(self, inst):
self.inst = inst
self.screenmanager.current = 'screen_detail'
def update_course_(self, label_id, label_nom):
c = self.inst.children[::-1]
c[0].text = label_nom.text
c[1].text = label_id.text
print(label_id.text, label_nom.text)
if label_id.text:
Maj_colonne(str(id_pk), str(nom))
label_nom.text = ''
label_id.text = ''
self.screenmanager.current = 'screen_list'
这是更新后的 kv 代码:
#:import utils kivy.utils
<ScreenList>:
data_grid: data_grid
MDBoxLayout:
orientation: 'vertical'
md_bg_color: app.theme_cls.primary_color
radius: [25, 0, 0, 0]
ScrollView:
MDGridLayout:
id: data_grid
cols: 1
spacing:10
size_hint_y:None
<ScreenDetail>:
label_id: label_id
label_nom: label_nom
MDBoxLayout:
orientation: 'vertical'
md_bg_color: app.theme_cls.primary_color
ScrollView:
GridLayout:
id: detail_grid
cols:2
Label:
text: 'Numéro:'
bold: True
TextInput:
id: label_id
text: ''
Label:
text: 'Nom:'
bold: True
TextInput:
id: label_nom
text: ''
Button:
text: 'OK'
size_hint_y: None
on_press: app.update_course_(label_id, label_nom)
<MyGrid>:
cols:2
size_hint_y:None
height:40
Label:
id: lbl
text: ''
Button:
id: btn
text: ''
on_press:
app.go_to_detail_(root)
【讨论】:
我修改了函数 go_to_detail_ (self, inst, btn) 以检索 id 以便选择项目的详细信息。在 kv 文件中,我也必须修改它: app.go_to_detail_(root,btn.text) 非常感谢,因为我已经尝试解决这个问题 1 个月了。感谢您的帮助和建议。现在效果很好。以上是关于如何使用 kv 文件刷新 Kivy 中的 GridLayout的主要内容,如果未能解决你的问题,请参考以下文章