2016-12-02 33 views
2

これは主に、私は、オブジェクト指向プログラミングを掴むが、時計機能Kivy Pythonはクラスと時計スタッフ

が関与されていない、私は私のGUIは、(時計機能を使用してスケジュール)絶えず更新機能を起動するボタンを持つようにしたいとに関する機能します。また、GUIに常に更新機能を終了させるボタンがあるようにします。ここで

import kivy 
import sqlite3 
import sched, time 
import smbus 
import time 
from Naked.toolshed.shell import execute_js, muterun_js 
import os 
import signal 
import multiprocessing, signal 
from kivy.uix.behaviors.button import ButtonBehavior 
from kivy.uix.button import Button 
from kivy.app import App 
from kivy.uix.label import Label 
from kivy.uix.widget import Widget 
from kivy.base import runTouchApp 
from kivy.clock import Clock 
from kivy.properties import ListProperty 
from kivy.properties import ObjectProperty 
from kivy.vector import Vector 
from kivy.core.window import Window 
from kivy.lang import Builder 
from kivy.uix.floatlayout import FloatLayout 
from kivy.event import EventDispatcher 
from kivy.uix.boxlayout import BoxLayout 
from kivy.uix.gridlayout import GridLayout 
from kivy.uix.stacklayout import StackLayout 
from kivy.core.image import Image 
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition, WipeTransition, SwapTransition 

bus = smbus.SMBus(1) 
address = 0x04 

p = multiprocessing.Process(target = muterun_js,args=('iss_telemetry.js',)) #might delete this 

conn = sqlite3.connect('iss_telemetry.db') #sqlite database call change to include directory 
c = conn.cursor() 
val = "" 

def StringToBytes(val): 
    retVal = [] 
    for c in val: 
      retVal.append(ord(c)) 
    return retVal 

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

class CalibrateScreen(Screen): 
    pass 

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

    def i2cWrite(self, *args): 
     bus.write_i2c_block_data(address, 0, StringToBytes(*args)) 

class MimicScreen(Screen, EventDispatcher): 
    def __init__(self, **kwargs): 
     super(MimicScreen, self).__init__(**kwargs) 

class MainScreenManager(ScreenManager): 
    pass 

class MyButton(Button): 
    pass 

def point_inside_polygon(x, y, poly): 
    ... 

class TriangleButton(ButtonBehavior, Widget): 
    ... 

class MainApp(App): 

    event = Clock.schedule_interval(self.update_labels, 1) 
    event() 
    event.cancel() 

    def build(self): 
     self.mimic_screen = MimicScreen(name = 'mimic') 
     root = ScreenManager(transition=WipeTransition()) 
     root.add_widget(MainScreen(name = 'main')) 
     root.add_widget(CalibrateScreen(name = 'calibrate')) 
     root.add_widget(self.mimic_screen) 
     root.add_widget(ManualControlScreen(name = 'manualcontrol')) 
     root.current= 'main' 

     # Clock.schedule_interval(self.update_labels, 1) 
     return root 

    def clockStart(self): 
     event() 

    def clockEnd(self): 
     event.cancel() 

    def i2cWrite(self, *args): 
     bus.write_i2c_block_data(address, 0, StringToBytes(*args)) 

    def update_labels(self, dt): 
     c.execute('select two from telemetry') 
     values = c.fetchall() 
     psarj = values[0] 
     ssarj = values[1] 
     ptrrj = values[2] 
     strrj = values[3] 
     beta1b = values[4] 
     beta1a = values[5] 
     beta2b = values[6] 
     beta2a = values[7] 
     beta3b = values[8] 
     beta3a = values[9] 
     beta4b = values[10] 
     beta4a = values[11] 
     aos = values[12] 
     self.mimic_screen.ids.psarjvalue.text = str(psarj[0])[:-5] 
     self.mimic_screen.ids.ssarjvalue.text = str(ssarj[0])[:-5] 
     self.mimic_screen.ids.ptrrjvalue.text = str(ptrrj[0])[:-5] 
     self.mimic_screen.ids.strrjvalue.text = str(strrj[0])[:-5] 
     self.mimic_screen.ids.beta1bvalue.text = str(beta1b[0])[:-5] 
     self.mimic_screen.ids.beta1avalue.text = str(beta1a[0])[:-5] 
     self.mimic_screen.ids.beta2bvalue.text = str(beta2b[0])[:-5] 
     self.mimic_screen.ids.beta2avalue.text = str(beta2a[0])[:-5] 
     self.mimic_screen.ids.beta3bvalue.text = str(beta3b[0])[:-5] 
     self.mimic_screen.ids.beta3avalue.text = str(beta3a[0])[:-5] 
     self.mimic_screen.ids.beta4bvalue.text = str(beta4b[0])[:-5] 
     self.mimic_screen.ids.beta4avalue.text = str(beta4a[0])[:-5] 



Builder.load_string(''' 
#:kivy 1.8 
#:import kivy kivy 
#:import win kivy.core.window 
<MainScreen>: 
    ... 
<ManualControlScreen>: 
    ...  
<CalibrateScreen>: 
    ... 
<MimicScreen>: 
    name: 'mimic' 
    FloatLayout: 
     psarjvalue: psarjvalue 
     id: mimicscreenlayout 
     Image: 
      source: 'iss1.png' 
      allow_stretch: True 
      keep_ratio: False 
     ... 
     Button: 
      id: mimicstartbutton 
      size_hint: 0.25,0.1 
      pos_hint: {"x": 0.07, "y": 0.6} 
      text: 'MIMIC' 
      disabled: False 
      font_size: 30 
      on_release: telemetrystatus.text = 'Sending Telemetry...' 
      on_release: app.clockStart() 
      on_release: mimicstopbutton.disabled = False 
      on_release: mimicstartbutton.disabled = True 
     Button: 
      id: mimicstopbutton 
      size_hint: 0.25,0.1 
      pos_hint: {"x": 0.07, "y": 0.4} 
      text: 'Stop' 
      disabled: True 
      font_size: 30 
      on_release: telemetrystatus.text = 'I2C Stopped' 
      on_release: app.clockStop() 
      on_release: mimicstopbutton.disabled = True 
      on_release: mimicstartbutton.disabled = False 
     Button: 
      size_hint: 0.3,0.1 
      pos_hint: {"Left": 1, "Bottom": 1} 
      text: 'Return' 
      font_size: 30 
      on_release: app.clockStop() 
      on_release: root.manager.current = 'main' 

<TriangleButton>: 
    ... 

''') 

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

関連するクラスです(または、これを達成するためのより良い方法は、希望のpython側のその値の更新は?、私はそのボタンを押したときに変化するif文?ブールにそれを置く?あります) :

class MainApp(App): 

    event = Clock.schedule_interval(self.update_labels, 1) 
    event() 
    event.cancel() 

    def build(self): 
     self.mimic_screen = MimicScreen(name = 'mimic') 
     root = ScreenManager(transition=WipeTransition()) 
     root.add_widget(MainScreen(name = 'main')) 
     root.add_widget(CalibrateScreen(name = 'calibrate')) 
     root.add_widget(self.mimic_screen) 
     root.add_widget(ManualControlScreen(name = 'manualcontrol')) 
     root.current= 'main' 

     # Clock.schedule_interval(self.update_labels, 1) 
     return root 

    def clockStart(root): 
     event() 

    def clockEnd(root): 
     event.cancel() 

    def i2cWrite(self, *args): 
     bus.write_i2c_block_data(address, 0, StringToBytes(*args)) 

    def update_labels(self, dt): 
     ... 

そして、ここでは、私はこのようにそれを実行しようとすると、

<MimicScreen>: 
    name: 'mimic' 
    FloatLayout: 
     ... 
     Button: 
      ... 
      on_release: app.clockStart() 
     Button: 
      ... 
      on_release: app.clockStop() 
     Button: 
      ... 
      on_release: app.clockStop() 

だから、それは文句を言う(縮小)KVコードの関連部分ですイベントが何であるかを知らない。クラスの外で宣言すると、クラス全体で使用できるようになるという印象を受けました。

提案?助言?助けてくれてありがとう

答えて

2

self.varnameでオブジェクトに渡したり貼り付けたりしていない関数の中で変数を使用するには、変数をグローバルとして定義する必要があるので不満です。さらに、イベントを作成してからすぐに取り消してから、ビルドが呼び出されます。

Clockschedule_interval関数呼び出しを開始するメソッドon_releaseを持つボタンが必要です。このボタンは、押された後は無効になります。 2番目のボタンはcancelを使用してスケジュール解除されます。

ここでは基本的な作業例です:

from kivy.app import App 
from kivy.uix.boxlayout import BoxLayout 
from kivy.uix.button import Button 
from kivy.clock import Clock 

class MyLayout(BoxLayout): 
    pass 

class StartButton(Button): 
    def on_release(self): 
     self.event_handle = Clock.schedule_interval(self.clocks_are_fun,0.5) 
     self.disabled = True 
    def clocks_are_fun(self,dt): 
     self.parent.parent.ids.mylabel.text = 'Frames: ' + str(Clock.frames) 
    def closing_time(self): 
     self.event_handle.cancel() 

class StopButton(Button): 
    def on_release(self): 
     self.parent.parent.ids.button1.closing_time() 
     self.parent.parent.ids.button1.disabled = False 

class MyApp(App): 
    def build(self): 
     boxyFunTime = MyLayout() 
     return boxyFunTime 

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

そして.kvファイル:

<MyLayout>: 
    id: mylayoutid 
    orientation: 'vertical' 
    BoxLayout: 
     orientation: 'horizontal' 
     StartButton: 
      text: 'start' 
      id: button1 
     StopButton: 
      text: 'stop' 
      id: button2 
    Label: 
     id: mylabel 
+0

本当にありがとうございました!私の唯一の問題は、MainAppクラスのupdate_values関数をそのクロックスケジューラから呼び出しようとしていることです。これは引数について不平を言っています。呼び出しはClock.schedule_interval(MainApp、update_labels()、1)です。それは、MainAppのインスタンスで呼び出されなければならないバインドされていないメソッドについては、それは私がすでにやっていることではないのですか? (私は、クラス間で更新する方法を完全に理解していない多くの子ウィジェットを扱うため、MainAppからupdate_labels関数を移動したくない)。何かご意見は? – Asterlux

+0

あなたは本当にあなたのメインのアプリケーションインスタンス内でそのメソッドを使用すべきではありません。あなたのメインアプリケーションインスタンスは、あなたが構築したウィジェットツリーを返すために使用されるだけです。すべての関数呼び出しをウィジェットツリーに配置します。物事を動かすのは苦痛かもしれないが、作業がより簡単になるだろう。 – Daniel