2017-02-19 5 views
1

私はしばらくの間、Kivyフレームワークに苦労しています。私はオンラインで自分の問題への答えを見つけることができません。ラベルに関数変数を渡します。

私はmain.pyと.kvファイルの2つのファイルを持っています。 main.pyファイルにはBoxlayoutの中に関数があります。例えば

:あなたが見ることができるように

class Box(BoxLayout): 

    def change(self): 
      variable = 0 

      while variable < 10: 
       text = "Some text " + str(variable) 
       variable += 1 

は、文字列変数「テキスト」があると、この変数は各ループに異なっています。

今、.kvファイルにはラベルがあります。たとえば は:

Box: 
    BoxLayout: 
     Button: 
      id: butt 
      text: "" 
      on_press: root.change() 
     Label: 
      id: label_text 

私は、機能変更を()を実行するためのボタンを希望し、私はラベルに表示された「テキスト」変数の値を参照したいと思います。 ユーザーがボタンをクリックすると、ラベル上でテキストが変わるのが表示されます: 「一部のテキスト0」、「一部のテキスト1」、「一部のテキスト2」....「一部のテキスト9」

私は次のようにmain.pyファイルにラベルIDを使用しようとしました:(チェンジ関数内)

label = self.ids['label_text'] 
self.count = str(variable) 
label.text = "Some text " + self.count 

何もで終わります。 私は関数の最後に "return text"でこれを行うことができると思いますが、最後の "text"変数をループから渡したくありません。ループ中に変数が変化したときにラベルがテキストを変更したい。

助けてください!

答えて

0

from kivy.properties import StringPropertyラベルのテキストをlabel_text = StringProperty()と定義すると、ロジック内で変更されたときにGUIで更新されます。あなたの.kvファイル内 はLabelプロパティにtext: root.label_textを追加し、.pyファイルに:

class Box(BoxLayout): 
    label_text = StringProperty() 

    def change(self): 
      variable = 0 
      while variable < 10: 
       self.label_text = "Some text " + str(variable) 
       variable += 1 

これはGUIでラベルのテキスト値を更新に関するご質問への答えです。しかし、while Trueのようなループを使用しないでください。そうしないと、kivyのGUIスレッドが自動的に更新されなくなります。その代わりにkivy Clock(from kivy.clock import Clock)を使用してタスクをスケジュールし、GUIスレッドがブロックされないように特定の間隔で実行してください。何かのように

class Box(BoxLayout): 

    label_text = StringProperty() 
    interval = 0.5 # Second 
    offset = 0 

    def change(self): 
     # You ask the clock to update the label's value every self.interval (0.5) second 
     self.event = Clock.schedule_interval(self.update_label_text, self.interval) 

    def update_label_text(self, dt): 
     if self.offset < 10: 
      self.label_text = "some_text" + str(self.offset) 
      self.offset += 1 
     else: 
      # Finally ask the clock to forget about updating 
      Clock.unschedule(self.event) 
+0

ありがとうございます。これは私の問題を解決しましたが、これがどういう仕組みになっているかはまだ100%明らかではありません。あなたは良いkivyチュートリアルをお勧めできますか? – Maciejjy

+0

@Maciejjyそれがうまくいけば、答えを受け入れて投票するのがいいでしょう:) これを受け取りましたか? https://kivy.org/docs/tutorials/pong.html – Juggernaut

+0

もちろん。しかし、私は投票することはできません。 15人未満の担当者の場合は、ポストスコアを変更しないというメッセージが表示されます。 – Maciejjy

0

まだラベルにテキストを表示することにいくつかの問題があります。短いの機能を使用すると、すべてが正常に思えるが、私は、ファイル、IFSを開き、データベースへの書き込みの多いこの機能があります。もちろん

def add_to_base(self, dt): 
    self.adding = "Adding to database..." 
    with open("new_links.txt", "r", encoding='utf-8') as f: 
     for line in f: 
      working on html here 
      xxx = got list of string here 
      for x in xxx: 
       if .... 
        zzz = got another list with string 
      for i in xxx: 
       if 
       . 
       . 
       Lots of elif's 
      write element to database 
      print("Added to databes") 
      if element is last element: 
       Clock.unschedule(self.event) 

これは実際のコード、それがどのように動作するかだけのモデルではありませんが。 私はこの機能から "self.adding"テキストを表示して更新したいと思います。 .kvファイルでは、私はテキスト:self.addingプロパティを持つラベルを持っています。そのテキストは、ラベルではなく、この関数の最後に表示されている、

def update_base(self): 
    self.event = Clock.schedule_interval(self.add_to_base, self.interval) 

問題がある: ではと、このadd_to_base機能を実行します。この機能は終了するまでに長い時間がかかります(要素をトラブしてデータベースに追加するには約15分)、機能が終了するとテキストが表示されます。私はこのテキストを最初に表示したいと思います。

+0

'add_to_base()'関数は、kivy GUIスレッドが終了するまでそれをブロックしています。私が言ったように、 'for'と' while'を使ってこのようなループを実行せず、kivy Clockを使ってそれらのループをスケジュールしてください。あなたのファイルのすべての行を 'Queue()'に追加し、その 'Queue()'から読み込み、GUIスレッドをブロックしたものではなく、その上で動作するように間隔を設定することをお勧めします。 Python 'Queue()'について読んでください – Juggernaut

+0

ああ。だから、もし私たちが(15分のように)終了するのに非常に長い関数を持っていれば、kivy.Clockはこの関数の変数を15分ごとに速くリフレッシュできません。この場合の間隔は、機能時間よりも小さいため重要ではありませんか? – Maciejjy

+0

どういうわけか、私は小さなタスクにタスクを壊して、クロックに各タスクを間隔で尋ねることを意味します。 – Juggernaut

関連する問題