2016-01-23 3 views
0

Я ограничил вызов функции кнопкой Kivy, которая строит и запускает два потока. Я использую ярлык Kivy, чтобы показать, что я действительно вхожу в функцию my_function() и прохожу до конца. Кажется, что потоки не строятся должным образом.Нити Python не выполняются должным образом при вызове функции (Kivy)

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

Python:

import kivy 
kivy.require('1.9.1') 

from kivy.app import App 
from kivy.uix.screenmanager import Screenmanager, Screen 
from kivy.properties import StringProperty 
from Adafruit_MotorHAT import Adafruit_MotorHAT, Adafruit_DCMotor, Adafruit_StepperMotor 
import threading 
import random 
import time 
import atexit 

class ScreenManager(ScreenManager): 
    pass 

class StartMenu(Screen): 
    pass 

Это верный и код:

class MyScreen(Screen): 
    entered = StringProperty("Not Entered") 

    # create a default object, no changes to I2C address or frequency 
    mh = Adafruit_MotorHAT() 

    # create empty threads (these will hold the stepper 1 and 2 threads) 
    st1 = Threading.thread() 
    st2 = Threading.thread() 

    # recommended for auto-disabling motors on shutdown! 
    def turnOffMotors(mh): 
     mh.getMotor(1).run(Adafruit_MotorHAT.RELEASE) 
     mh.getMotor(2).run(Adafruit_MotorHAT.RELEASE) 
     mh.getMotor(3).run(Adafruit_MotorHAT.RELEASE) 
     mh.getMotor(4).run(Adafruit_MotorHAT.RELEASE) 

    atexit.register(turnOffMotors(mh)) 

    myStepper1 = mh.getStepper(200, 1)  # 200 steps/rev, motor port #1 
    myStepper2 = mh.getStepper(200, 2)  # 200 steps/rev, motor port #1 
    myStepper1.setSpeed(60)     # 30 RPM 
    myStepper2.setSpeed(60)     # 30 RPM 


    stepstyles = [Adafruit_MotorHAT.SINGLE, Adafruit_MotorHAT.DOUBLE, Adafruit_MotorHAT.INTERLEAVE, Adafruit_MotorHAT.MICROSTEP] 

    def stepper_worker(stepper, numsteps, direction, style): 
     stepper.step(numsteps, direction, style) 

Размещение кода в my_function() и применяя 'я'; потоки больше не работают. Повторите код для второго потока. Я хочу подчеркнуть, что этот код работает, когда не внутри функции и не используя «Я»:

def my_function(self, *args): 
     if (True): 
      time.sleep(0.005) 
      if not self.st1.isAlive(): 
       randomdir = random.randint(0, 1) 
       if (randomdir == 0): 
        dir = Adafruit_MotorHAT.FORWARD 
       else: 
        dir = Adafruit_MotorHAT.BACKWARD 

       randomsteps = random.randint(10,50) 
       self.st1 = threading.Thread(target=self.stepper_worker, args=(self.myStepper1, randomsteps, dir, self.stepstyles[random.randint(0,3)],)) 
       self.st1.start() 
       self.entered = "Entered" 

Сложение:

class MyApp(App): 
    def build(self): 
     return ScreenManager() 

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

Kivy: my.kv

Я оставил некоторые ненужные детали, такие как макет и размер виджета.

#:kivy 1.9.1 

<ScreenManager>: 
    StartMenu: 
    MyScreen: 

<StartMenu>: 
    name: 'StartMenu' 
    Button: 
     on_release: 
      root.manager.current = 'MyScreen' 

<MyScreen>: 
    name: 'MyScreen' 
    Label: 
     text: root.entered 
    Button: 
     on_release: 
      root.my_function() 

Спасибо за ваше время!

ответ

0

Вы определяете stepper_worker как метод под MyScreen, поэтому первым параметром, который он получит, будет экземпляр MyScreen.

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

# len(args) == 4 so you have too many parameters (the first is fixed to "self") 
self.st1 = threading.Thread(target=self.stepper_worker, args=(self.myStepper1, randomsteps, dir, self.stepstyles[random.randint(0,3)],)) 

можно починок, как упомянет выше:

#added self... 
def stepper_worker(self, stepper, numsteps, direction, style): 
    stepper.step(numsteps, direction, style) 

Я надеюсь, что это поможет. также посмотреть, если вам действительно нужно определить эти методы под MyScreen ...

Также обратите внимание, что если потоки хотят получить доступ к kivy UI они должны сделать это с помощью звонков в часы (так что вы будете иметь потокобезопасность)

+0

Добавление себя как первого arg в stepper_worker исправлено! Благодарю. – Finksterr

Смежные вопросы