2016-12-02 70 views
2

這主要是我不掌握面向對象編程,但涉及時鐘功能Kivy Python函數類和時鐘東西

我想我的GUI有一個按鈕,開始不斷地更新功能(使用時鐘功能定) 。並且還希望該GUI具有結束不斷更新功能的按鈕。 (或者是有沒有更好的方式來做到這一點?把它放在一個if語句?布爾當我按下該按鈕改變,將蟒側值更新?)

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() 

下面是相關類:

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): 
     ... 

而這裏的KV代碼的相關部分(減少)

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

所以,當我嘗試這樣運行它,它抱怨不知道事件是什麼。我感到很震驚,宣佈它在課堂職能範圍之外將使整個班級都可以使用它。

對此提出建議?建議嗎?感謝您的幫助

回答

2

這是抱怨,因爲您需要將變量定義爲全局變量,以便在未將函數傳入或將其附加到與self.varname對象的函數中。此外,您正在創建事件,然後在構建被調用之前馬上取消它。

您應該有一個按鈕,該按鈕的方法on_release啓動schedule_interval函數調用Clock。按下此按鈕後應該被禁用。然後您的第二個按鈕將使用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