【问题标题】:How to make changes to a widget in another class in kivy如何在kivy中对另一个类中的小部件进行更改
【发布时间】:2021-07-03 18:56:15
【问题描述】:

我是 OOP 和 kivy 的新手,我创建了一个考试时间表,每个时间表都有 2 个按钮 Editremove。 我希望每当我单击 remove 按钮时,都会调用 Exam 类中的 remove_entry() 函数,并且该函数应该删除该特定条目。
对于 编辑按钮,点击时会打开一个对话框,其中包含一些文本字段,我希望在用户点击保存按钮时,make_changes() 函数从 Exam 到被调用并且该函数应该对某些时间表进行更改。

这是python文件

from kivymd.app import MDApp
from kivy.uix.boxlayout import BoxLayout
from kivy.core.window import Window
from kivy.lang import Builder
from kivy.properties import ObjectProperty, StringProperty
from kivy.factory import Factory
from kivy.uix.screenmanager import ScreenManager, Screen
from kivymd.uix.button import MDFlatButton
from kivymd.uix.dialog import MDDialog
from kivymd.uix.textfield import MDTextField
from kivymd.uix.picker import MDTimePicker
from kivy.metrics import dp
import datetime
Window.keyboard_anim_args = {'d': .2, 't': 'in_out_expo'}
Window.softinput_mode = "below_target"


class Menu(Screen):
    pass
    
#exam timetable screen
class Exam(Screen):
    exam_btn = ObjectProperty()
    dept_exam = ObjectProperty()
    
    def on_enter(self):
        for item in self.Entries():
            self.dept_exam.add_widget(item, 1)
    
    #automatically insert the saved entries
    def Entries(self):
        global num
        
        ##The saved entries
        #f = [line.strip() for line in open('courses.txt') if line.strip() != '']
        f = ['CSC 221@27/4/2021@03:00 - 06:00@Gado Nasko',
              'CSC 212@2/5/2021@02:00 - 04:00@Gado Nasko']
        L = [Factory.OneEntry() for i in range(len(f))]
        
        #set  data to each of the entry
        num = 0
        for entry in L:
            items = f[num].split('@')
            entry.ids.exam_index.text = str(num+1)
            entry.ids.code.text = items[0]
            entry.ids.date.text += self.manp_date(items[1])
            entry.ids.time.text += items[2]
            entry.ids.venue.text += items[3]
            num += 1
            
        return L
    
    #add an entry by releasing the add button
    def adds(self):
        global num
        
        num += 1
        new = Factory.OneEntry()
        new.ids.exam_index.text = str(num)
        self.dept_exam.add_widget(new,1)
        

    #change date format
    def manp_date(self, dt):
        dy,mt,yr = dt.split('/')
        x = datetime.datetime(int(yr), int(mt), int(dy))
        return x.strftime('%d %b, %Y')
    
    #this should be called from TimeTabelApp
    def make_changes(self, change):
        pass
    
    #this should remove entry
    def remove_entry(self):
        pass
        
        
        
#The dialog box for editing an entry class
class Content(BoxLayout):
    #setting date function
    def show_date(self):
        self.ids.date_ent.hint_text = ''
        self.ids.date_ent.helper_text_mode = 'persistent'
        self.ids.date_ent.helper_text = 'dd/mm/yyyy'
    
        
    #setting time function
    def get_time(self, instance, time):
        self.ids.from_time.text = time
        self.ids.from_time.hint_text = ''
        self.ids.from_time.helper_text_mode = 'persistent'
        self.ids.from_time.helper_text = 'From'
    
    def show_time_picker(self):
        time_dialog = MDTimePicker()
        time_dialog.bind(time=self.get_time)
        time_dialog.open()

class MainMenu(ScreenManager):
    pass

kv = Builder.load_file('newfile.kv')



class TimeTableApp(MDApp):
    def build(self):
        return kv
    
    #The dialog box for editing an entry function
    dialog = None
    def show_exam_dialog(self, counter):

        if not self.dialog:
            self.dialog = MDDialog(title="Set: Time, Venue, ...",
                                type="custom", content_cls=Content(),
                                    buttons=[ MDFlatButton(text="CANCEL", on_release=self.close_dialog,
                                                            text_color=self.theme_cls.primary_color),
                                                  MDFlatButton(text="SAVE", on_release=self.save_dialog,
                                                            text_color=self.theme_cls.primary_color)])
        self.dialog.open()
        self.dialog.set_normal_height()
     
     #closing editing dialog
    def close_dialog(self, *args):
        self.dialog.dismiss()
    
    #saving changes from dialog
    def save_dialog(self, inst):
        exam_code = self.dialog.content_cls.ids.exam_code
        from_time = self.dialog.content_cls.ids.from_time
        date_ent = self.dialog.content_cls.ids.date_ent
        exam_venue = self.dialog.content_cls.ids.exam_venue
        
        change = exam_code.text.upper()+'@'+date_ent.text+'@'+exam_venue.text.title()
        #self.Exam().make_change(change)
        self.dialog.dismiss()
            
      
if __name__ == '__main__':
    TimeTableApp().run()

这是kv文件

MainMenu:
    Menu:
    Exam:

<Menu>:
    name: 'menu'
    BoxLayout:
        orientation: 'vertical'
        
        Button:
            text: 'Exam Timetable'
            on_release: app.root.current = 'exam'
    


<Exam>:
    name: 'exam'
    dept_exam: dept_exam

    BoxLayout:
        orientation: 'vertical'
        padding: [0,20,0,0]
        
        ScrollView:
            effect_cls: 'ScrollEffect'
            GridLayout:
                id: dept_exam
                size_hint:(1, None)
                width: self.minimum_width
                height: self.minimum_height
                cols: 1
                spacing: 30
                padding: [10]
         
                
                #add entry button layout
                BoxLayout:
                    orientation: 'vertical'
                    size_hint: 1, None
                    height: 150
                    
                    Button:
                        id: btn
                        size_hint: None,1
                        width: 150
                        text: '+'
                        font_size: 80
                        background_color: 0,0,0,0
                        pos_hint: {'center_x':.5}
                        on_release: root.adds()
                        canvas.before:
                            Color:
                                rgba: (.7, .1, .4, 1) if self.state=='normal' else (0,.7,.7,1)
                            RoundedRectangle:
                                size: self.size
                                pos: self.pos
                                radius: [80]

#An entry class
<OneEntry@BoxLayout>:
    orientation: 'vertical'
    size_hint_y: None
    height: 250
    canvas.before:
        Color:
            rgba: (0, 117/255, 1, 1)
        RoundedRectangle:
            size: self.size
            pos: self.pos
            radius: [20]
    
    BoxLayout:
        orientation: 'horizontal'
        size_hint_y: .45
        Label:
            id: exam_index
            bold: True
            italic: True
            color: (114/255, 47/255, 55/255, 1)
            
        Label:
            id: code
            bold: True
            text_size: self.size
            halign: 'left'
            size_hint_x: 1.8
            font_size: 43
            
    #line
    Separator:
    
    GridLayout:
        cols: 2
        GridLayout:
            rows: 2
            size_hint_x: .8
            Label:
                id: date
                markup: True
                text: '[size=35][b]Date:[/b][/size] '
            Label:
                id: time
                markup: True
                text: '[size=35][b]Time:[/b][/size] '
                
        BoxLayout:
            orientation: 'vertical'
            Label:
                id: venue
                markup: True
                text: '[size=35][b]venue:[/b][/size] '
                text_size: self.size
                halign: 'left'
                valign: 'middle'
            Label:
                text_size: self.size
                halign: 'left'
                valign: 'middle'
                markup: True
                text: '[size=35][b]Status:[/b][/size] '
                
    GridLayout:
        size_hint_y: .6
        padding: [20,10]
        cols: 2
        spacing: 10

        Button:
            text: 'Edit'
            background_color: (0, 117/255, 1, 1)
            on_release: app.show_exam_dialog(root.ids.exam_index.text)
        Button:
            text: 'Remove'
            background_color: (1, 0, 0, 1)
            on_release: root.remove_entry()


<Separator@Widget>
    size_hint_y: None
    height: 1
    canvas:
        Color:
            rgb: 1, 1, 1
        Rectangle:
            pos: self.pos
            size: self.size
            
            
<Content>
    orientation: "vertical"
    spacing: "12dp"
    size_hint_y: None
    height: 550

    MDTextField:
        id: exam_code
        hint_text: "Course Code"
        max_text_length: 7
        helper_text_mode: 'on_focus'
        helper_text: 'Not more than 7 character'
        required: True

    
    MDTextField:
        id: from_time
        hint_text: "Set Time"
        on_focus: if self.focus: root.show_time_picker
           
    MDBoxLayout:
        orientation: 'vertical'
        spacing: 5
        
        MDLabel:
            text: 'Set Date'
        
        MDBoxLayout:
            orientation: 'horizontal'
            MDTextField:
                id: date_ent
                on_focus: if self.focus: root.show_date() 
                hint_text: "dd/mm/yyyy"
                required: True
    
    MDTextField:
        id: exam_venue
        hint_text: "Venue"
        max_text_length: 20
        helper_text_mode: 'on_focus'
        helper_text: 'Not more than 20 character'
        required: True
            

【问题讨论】:

  • 我建议您专门创建一个“时间表”类。它可以是一个小部件或只是一个对象,但通过创建它,您可以限制函数“remove_entry”的范围,以便更轻松地“删除条目”。
  • @Darnell Baird,你是什么意思
  • @Abudl,我的错。你的“考试”课就是我说的。你已经拥有它了。

标签: python kivy kivymd


【解决方案1】:

问题 1

在 Kivy 中,您可以绑定事件。在kvlangPython 中。

Exam:
...
    Button:
        text:"Remove Button"
        on_release: root.remove_entry()    #'root' is a keyword

问题 2

要获得一个对话框,我建议您使用Popup 小部件。 在代码中打开弹出窗口。

#:import Factory kivy.factory.Factory #at the start of kv script
...
MyPopup@Popup:
    title:"Whatever Title"
    Content:
    ...
...
Button:
    Button:
        text:"Edit"
        on_release:Factory.MyPopup()

在保存按钮下,输入:

on_release: app.save_dialog(self)     #'app' is a keyword
#I am not sure what 'inst' argument represents.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-12
    • 1970-01-01
    • 2018-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-11
    相关资源
    最近更新 更多