Каким-то образом в моем приложении Kivy часы не работают правильно, это не обновляет мои данные - PullRequest
0 голосов
/ 27 октября 2019

Итак, я делаю приложение для составления бюджета, его код довольно большой, поэтому я просто покажу вам основной класс приложения (кстати, у меня нет большого опыта в кодировании). Моя проблема в том, что у меня есть некоторые данные вфайл, который необходимо обновить в моем счетчике и перезапустить. Я действительно не знаю, есть ли лучшее решение для обновления этих виджетов, но сейчас я использую метод Clock для обновления данных.

Так что у меня есть эта функция on_start (), которая должна запускаться мгновеннокогда я запускаю приложение и обновляю прядильщик и перезаписываю элементы новыми обновленными данными в моем файле. Самое смешное, что это иногда работает, а иногда нет, я не понял, что заставляет его работать, а иногда нет.

Я сделал кнопку, которая делает то же самое, когда я нажимаю на нее, все работаеткак очарование, но моя главная цель в том, чтобы всякий раз, когда я запускаю приложение, я не хотел беспокоиться о том, чтобы всегда нажимать кнопку, потому что я должен, иначе мои списки не обновляются ..

Так что вы думаете, чтопроблема с кодом?

add.kv

<SelectableLabel>:
    id:selectlabel
    # Draw a background to indicate selection
    canvas.before:
        Color:
            rgba: (.0, 0.9, .1, .3) if self.selected else (.5, .5, .5, .2)
        Rectangle:
            pos: self.pos
            size: self.size
<AddWindow>:
    orientation:'vertical'
    padding: 5
    spacing: 10
    id: addwindow

    FloatLayout:
        id:actionid
        size_hint_y:None
        size: 384, 50
        ActionBar:
            pos_hint: {'top': 1}
            size_hint_x: None
            size: 384, 50
            ActionView:
                padding: 5
                ActionPrevious:
                    title:'GoToMenu'
                    on_release: root.changescreen('MainWindow')
    RecycleView:
        id:teft
        data: [{'text': str(x).strip('\n')} for x in open('proba.txt')]
        viewclass: 'SelectableLabel'
        SelectableRecycleBoxLayout:
            default_size: None, dp(56)
            default_size_hint: 1, None
            size_hint_y: None
            height: self.minimum_height
            orientation: 'vertical'
            multiselect: False
            touch_multiselect: True

    BoxLayout:
        size_hint_y:None
        height: 30
        TextInput:
            id:termeknev
            height: 30
            size_hint:(.7, 1)

            focus:False
            hint_text:'Product name...'
            halign:'center'
        TextInput:
            id:kiadas
            size_hint:(.3, 1)
            focus:False
            hint_text:'Expense'
            halign:'center'

    BoxLayout:
        size_hint_y:None
        height: 30
        TextInput:
            id:vendegszam
            size_hint:(.35, 1)
            focus:False
            hint_text:'Guests'
            halign:'center'
        Label:
            id:currentmonthlabel
            text:'<-(Optional)->'
            size_hint:(.47, 1)
        TextInput:
            id:bevetel
            size_hint:(.35, 1)
            focus:False
            hint_text:'Income'
            halign:'center'

    Button:
        text:'Submit'
        size_hint:(1, .5)
        background_color: .2, .8, .3, 1
        on_release:root.appendfile()
    BoxLayout:
        size_hint:1,None
        spacing: 5
        Button:
            text:'Delete'
            size_hint: .2, 1
            background_color: .8, .2, .3, 1
            on_release:root.delfile()
            on_release:root.refresh()

        Button:
            id:refresh
            text:'Refresh'
            size_hint:(.8, 1)
            on_release:root.refresh()
    Button:
        id:gotoview
        text:'GoToView'
        size_hint:(1, .5)
        on_release: root.changescreen('ViewWindow')


<PopupWarning>:
    id:popwarning
    orientation:'vertical'
    Label:
        text:'Please select a file from the list above.'
    Button:
        size_hint: 1, .4
        text:'OK'
        on_release:root.dismiss()

menu.kv


<MainWindow>:
    orientation: 'vertical'
    padding: 5
    spacing: 10

    Label:
        text:'Track Your Budget'
        font_size: 40
        size_hint: 1, .3
        bold: True
        outline_color: .6, .2, .1
        outline_width: 2

    Button:
        id:new
        text:'New'
        on_release: root.newpopup()

    Button:
        id:modify
        text:'Modify'
        on_release: root.changescreen('AddWindow')
    Button:
        id:view
        text:'View'
        on_release:root.changescreen('ViewWindow')

    Label:
        text:''
        size_hint:1,.2

    Button:
        id:exit
        text:'Save and exit'
        on_release: root.exitapp()


<PopupContent>:
    orientation: 'vertical'
    spacing: 5
    TextInput:
        id:popinput
        multiline: False
        size_hint: 1, .05
        hint_text: 'Month Name'
        halign: 'center'
        font_size: 30
        password: False
    Button:
        id:create
        text:'Create'
        size_hint: 1, .05
        background_color: .2, .8, .3, 1
        on_release: root.createfile(popinput.text)
        on_release: root.dismiss()

    Button:
        id:cancel
        text:'Cancel'
        size_hint: 1, .04
        background_color: .8, .2, .3, 1
        on_release: root.dismiss()

TesterApp.py

import os, sys
import csv
import time
# os.environ['KIVY_NO_CONSOLELOG'] = '1'
from kivy.config import Config
Config.set('graphics', 'width', '384')  # 768
Config.set('graphics', 'height', '683')  # 1366
Config.set('graphics', 'resizable', '0')
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.popup import Popup
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.scrollview import ScrollView
from kivy.properties import ObjectProperty, BooleanProperty, StringProperty
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
from kivy.uix.label import Label

from kivy.uix.behaviors import FocusBehavior
from kivy.uix.recycleboxlayout import RecycleBoxLayout
from kivy.uix.recycleview import RecycleView
from kivy.uix.recycleview.layout import LayoutSelectionBehavior
from kivy.uix.recycleview.views import RecycleDataViewBehavior
from kivy.uix.recycleview import RecycleViewBehavior

from kivy.clock import Clock

from kivy.lang import Builder
Builder.load_file('menu.kv')
Builder.load_file('add.kv')
Builder.load_file('view.kv')


#  FŐ ABLAK
class MainWindow(BoxLayout, Screen):

    # ADD WINDOWRA VÁLT
    def changescreen(self, screenname):
        self.manager.current = screenname

    def newpopup(self):
        global popup
        popup = Popup(title='Create New Month', content=PopupContent(), size_hint=(None,None), size=(350, 200))
        popup.open()

    def exitapp(self):
        sys.exit()


#  POPUP
class PopupContent(BoxLayout):

    # CSV filet létrehozza
    def createfile(self, name):
        with open(name + '.csv', 'w', encoding='utf-8') as f:
            fieldnames = ['val1', 'val2', 'val3', 'val4', 'val5']
            dictwriter = csv.DictWriter(f, fieldnames=fieldnames, delimiter='/')
            dictwriter.writeheader()
        with open('proba.txt', 'a', encoding='utf-8') as f:
            f.write(name+'\n')
    # MAGÁT A POUP ABLAKOT ELTŰNTETI

    def dismiss(self):  # KILÉPIK A MAINWINDOW newpopup()POPUP-ból
        Popup.dismiss(popup)


class PopupWarning(BoxLayout):
    def dismiss(self):
        Popup.dismiss(AddWindow.selectedpopup)


class AddWindow(BoxLayout, Screen, RecycleViewBehavior):
    def __init__(self, **kwargs):
        super(AddWindow, self).__init__(**kwargs)

        self.addwindowdata = self.ids.teft.data

    selectedpopup = Popup(title='No file selected !', content=PopupWarning(), size_hint=(None, None), size=(350, 200))

    def refresh(self):
        Clock.schedule_interval(self.refreshData, 1)  # CSAK AKKOR MŰKÖDIK HA FUNKCIÓT ADOK NEKI
                                                    # ÉS AZ A FUNKCIÓ VALAMI ÉRTÉKET MEGVÁLTOZTAT

    def refreshData(self, *args):
        self.ids.teft.data = [{'text': str(x).strip('\n')} for x in open('proba.txt')]

    # FŐOLDALRA VISSZA VÁLT
    def changescreen(self, screenname):
        self.manager.current = screenname

    def appendfile(self):###################### EZTMÉG ÁTNÉZNI ÉS CSISZOLNI
        try:
            with open(selectedvalue + '.csv', 'a', encoding='utf-8', newline='') as f:
                writer = csv.writer(f, delimiter='/')
                termek = self.ids.termeknev.text
                kiadas = self.ids.kiadas.text
                vendegszam = self.ids.vendegszam.text
                bevetel = self.ids.bevetel.text
                datum = time.strftime('%Y-%m-%d')
                if termek == '':
                    termek = ' . . . '
                if kiadas == '':
                    kiadas = 0
                if vendegszam == '':
                    vendegszam = 0
                if bevetel == '':
                    bevetel = 0
                lista = termek, kiadas, vendegszam, bevetel, datum
                writer.writerow(lista)
                self.ids.termeknev.text = ''
                self.ids.kiadas.text = ''
                self.ids.vendegszam.text = ''
                self.ids.bevetel.text = ''
        except NameError:
            self.selectedpopup.open()

    def delfile(self):
        try:
            os.remove(selectedvalue + '.csv')
            with open('proba.txt', 'r+') as f:
                r = f.read()
                l = list(r.split('\n'))
                l.remove(selectedvalue)
                o = str('\n'.join(l))
            with open('proba.txt', 'w') as f:
                f.write(o)
        except:
            self.selectedpopup.open()


class SelectableRecycleBoxLayout(FocusBehavior, LayoutSelectionBehavior,
                                 RecycleBoxLayout):
    ''' Adds selection and focus behaviour to the view. '''


class SelectableLabel(RecycleDataViewBehavior, RecycleViewBehavior, Label):
    ''' Add selection support to the Label '''
    index = None
    selected = BooleanProperty(False)
    selectable = BooleanProperty(True)

    def refresh_view_attrs(self, rv, index, data):
        ''' Catch and handle the view changes '''
        self.index = index
        return super(SelectableLabel, self).refresh_view_attrs(
            rv, index, data)

    def on_touch_down(self, touch):
        ''' Add selection on touch down '''
        if super(SelectableLabel, self).on_touch_down(touch):
            return True
        if self.collide_point(*touch.pos) and self.selectable:
            return self.parent.select_with_touch(self.index, touch)

    def apply_selection(self, rv, index, is_selected):
        ''' Respond to the selection of items in the view. '''
        self.selected = is_selected
        global selectedvalue # EZ AZ ALÁBBI IF STATEMENTBŐL
                                # KISZEDI AZ ÉRTÉKET AMIT VISSZA FOG ADNI az ADDWINDOW CLASSNAK
                                    # ÉS AZON BELÜL AZ APPEND FUNKCIÓNAK
        if is_selected:
            print("selection changed to {0}".format(rv.data[index].get('text')))
            selectedvalue = rv.data[index].get('text')
        else:
            print("selection removed for {0}".format(rv.data[index]))


class ViewPopup(BoxLayout):
    def dismiss(self):
        Popup.dismiss(ViewWindow.viewpopup)


class ViewWindow(BoxLayout, Screen):
    def __init__(self, **kwargs):
        super(ViewWindow, self).__init__(**kwargs)

        self.viewwindowdata = self.ids.filespinner.values

    viewpopup = Popup(title='INFO', content=ViewPopup(), size_hint=(None, None), size=(350, 200))

    def getHonap(*args):
        global honapok
        honapok = []
        with open('proba.txt', 'r', encoding='utf-8') as f:
            for file in f:
                honapok.append(file.strip('\n'))
        return honapok

    def showdata(self):
        filename = self.ids.filespinner.text
        if filename == '':
            pass
        else:
            with open(filename + '.csv', 'r', encoding='utf-8') as f:
                reader = csv.DictReader(f, delimiter='/')
                nevkiadas = []
                kiadasbevetel = []
                bevetelvendeg = []
                for sor in reader:
                    val1 = str(sor['val1'])
                    val2 = str(sor['val2'])
                    val3 = str(sor['val3'])
                    val4 = str(sor['val4'])
                    val5 = str(sor['val5'])
                    nevkiadas.append(val1.ljust(20)+' '+val2.center(10) + ' ' + val5)
                    kiadasbevetel.append(val2.ljust(20)+' '+val4.center(10) + ' ' + val5)
                    bevetelvendeg.append(val4.ljust(20)+' '+val3.center(10) + ' ' + val5)



            # EZTMAJD LE EGYSZERŰSÍTENI HA LEHETSÉGES
            with open('temp.txt', 'w', encoding='utf-8') as f:
                f.write('=' * 20 + ' ' + '=' * 10 + ' ' + '=' * 10 + '\n')
                f.write('      Product       ' + ' Expense  ' + '   Date   ' + '\n')
                f.write('=' * 20 + ' ' + '=' * 10 + ' ' + '=' * 10 + '\n')
                for teszt1 in nevkiadas:
                    f.write(teszt1 + '\n')
                f.write('=' * 20 + ' ' + '=' * 10 + ' ' + '=' * 10 + '\n')
            with open('temp.txt', 'r', encoding='utf-8') as f:
                content1 = f.read()
                self.ids.productexpense.text = content1
        # ---------------------------------------------------------
            with open('temp2.txt', 'w', encoding='utf-8') as f:
                f.write('=' * 20 + ' ' + '=' * 10 + ' ' + '=' * 10 + '\n')
                f.write('      Expense       ' + ' Income  ' + '   Date   ' + '\n')
                f.write('=' * 20 + ' ' + '=' * 10 + ' ' + '=' * 10 + '\n')
                for teszt2 in kiadasbevetel:
                    f.write(teszt2 + '\n')
                f.write('=' * 20 + ' ' + '=' * 10 + ' ' + '=' * 10 + '\n')
            with open('temp2.txt', 'r', encoding='utf-8') as f:
                content2 = f.read()
                self.ids.expenseincome.text = content2
        # ---------------------------------------------------------
            with open('temp3.txt', 'w', encoding='utf-8') as f:
                f.write('=' * 20 + ' ' + '=' * 10 + ' ' + '=' * 10 + '\n')
                f.write('      Income        ' + ' Guests  ' + '   Date   ' + '\n')
                f.write('=' * 20 + ' ' + '=' * 10 + ' ' + '=' * 10 + '\n')
                for teszt3 in bevetelvendeg:
                    f.write(teszt3 + '\n')
                f.write('=' * 20 + ' ' + '=' * 10 + ' ' + '=' * 10 + '\n')
            with open('temp3.txt', 'r', encoding='utf-8') as f:
                content3 = f.read()
                self.ids.incomeguests.text = content3

    # ---------------------------------------------------------
# FORCED REFRESH IF THE on_start REFRESH NOT WORKING
    def refresh(self, *args):
        Clock.schedule_interval(self.refreshData, 1)
        try:
            self.showdata()
        except:
            self.ids.productexpense.text = ''
            self.ids.expenseincome.text = ''
            self.ids.incomeguests.text = ''
            pass

    def refreshData(self, *args):
        self.ids.filespinner.values = self.getHonap()

    def changescreen(self, screenname):
        self.manager.current = screenname


#  ALKALMAZÁS FUTTATÓ
class TesterApp(App):
    title = 'Budget App'

    def on_start(self):
        Clock.schedule_interval(self.update_data, 1)

    def update_data(self, *args):
        AddWindow.addwindowdata = [{'text': str(x).strip('\n')} for x in open('proba.txt')]
        ViewWindow.viewwindowdata = ViewWindow.getHonap()  # TALÁN BUGOL

    def build(self):
        # PÉLDA A SCREEN VÁLTÁSRA
        transition = FadeTransition(duration=.06)
        screenmanager = ScreenManager(transition=transition)
        mainscreen = MainWindow(name='MainWindow')
        addscreen = AddWindow(name='AddWindow')
        viewscreen = ViewWindow(name='ViewWindow')
        screenmanager.add_widget(mainscreen)
        screenmanager.add_widget(addscreen)
        screenmanager.add_widget(viewscreen)
        return screenmanager


if __name__ == '__main__':
    TesterApp().run()

view.kv

<ViewWindow>:
    orientation:'vertical'
    padding: 5
    spacing: 10
    id: viewwindow
    FloatLayout:
        id:actionid
        size_hint_y:None
        size: 384, 50
        ActionBar:
            pos_hint: {'top': 1}
            size_hint_x: None
            size: 384, 50
            ActionView:
                padding: 5
                ActionPrevious:
                    title:'GoToMenu'
                    on_release: root.changescreen('MainWindow')
    Spinner:
        id:filespinner
        text:'Choose a file'
        values:root.getHonap()
        text_autoupdate:False
        on_text:root.showdata()
        on_text:root.refresh()
        size_hint: 1, .1

    BoxLayout:
#        TextInput:
#            id:showstat
#            readonly:True
#            text:''
        TabbedPanel:
            title:'Asd'
            do_default_tab:False
            tab_width: 150
            tab_height: 30
            TabbedPanelItem:
                text:'Product/Expense'
                RstDocument:
                    id:productexpense
                    readonly:True
                    text:''
                    line_spacing:5
                    scroll_y:1

            TabbedPanelItem:
                text:'Expense/Income'
                RstDocument:
                    id:expenseincome
                    readonly:True
                    text:''
                    scroll_y:1

            TabbedPanelItem:
                text:'Income/Guests'
                RstDocument:
                    id:incomeguests
                    readonly:True
                    text:''
                    scroll_y:1

    Button:
        text:'Refresh'
        size_hint_y: .1
        on_release:root.refresh()


<ViewPopup>:
    id:viewwarning
    orientation:'vertical'
    Label:
        text:'Choose a file.'
    Button:
        size_hint: 1, .4
        text:'OK'
        on_release:root.dismiss()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...