2016-02-16 30 views
0

我確實有一個存儲設置和啓動進程的界面。但是,一旦進程啓動,我無法關閉所有內容,因爲在調用process.run後,kivy卡住了。下面是一個小例子:在kivy應用程序中將類實例作爲進程:kivy應用程序被卡住

#! /usr/bin/env python 

""" 
Activate the touch keyboard. It is important that this part is on top 
because the global config should be initiated first. 
""" 
from kivy.config import Config 
Config.set('kivy', 'keyboard_mode', 'multi') 

# the main app 
from kivy.app import App 

# The Builder is used to define the main interface. 
from kivy.lang import Builder 

# The start screen is defined as BoxLayout 
from kivy.uix.boxlayout import BoxLayout 

# The pHBot class 
from phbot import pHBot 

# The pHBot is defined as process. Otherwise it would not be possible to use the close button. 
from multiprocessing import Process, Queue 



# Definition of the Main interface 
Builder.load_string(''' 
<Interface>: 
    orientation: 'vertical' 
    Button: 
     text: 'Run pH-Bot' 
     font_size: 40 
     on_release: app.run_worker() 
    Button: 
     text: 'Close pH-Bot' 
     font_size: 40 
     on_release: app.stop_phbot() 
''') 


# Interface as a subclass of BoxLayout without any further changes. This part is used by kivy. 
class Interface(BoxLayout): 
    pass 


class SettingsApp(App): 
    """ 
    The settings App is the main app of the pHBot application. It is initiated by kivy and contains the functions 
    defining the main interface. 
    """ 

    def build(self): 
     """ 
     This function initializes the app interface and has to be called "build(self)". It returns the user interface 
     defined by the Builder. 
     """ 

     # A queque for the control all processes. 
     self.qu_stop = Queue() 

     # returns the user interface defined by the Builder 
     return Interface() 

    def run_worker(self): 
     """ 
     The pHBot application is started as a second process. 
     """ 
     bot = pHBot(self.qu_stop) 
     phbot = Process(target=bot.ph_control()) 
     # start the process 
     phbot.run() 

    def stop_phbot(self): 
     self.qu_stop.put('STOP') 

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

第二類是一個叫phbot.py文件中:

import time 


class pHBot: 

    def __init__(self, qu_stop_in): 
     self.qu_stop_in = qu_stop_in 

    def ph_control(self): 

     while True: 
      if self.qu_stop_in.full(): 
       if self.qu_stop_in.get() == 'STOP': 
        break 
      print('Back and forth forever ...') 
      time.sleep(2) 

缺少什麼我在這裏?

回答

1

請注意,Processstart()開頭。調用run()確實會立即從同一進程啓動該工作,並因此阻塞。因此run_worker相關的行應該是:

bot = pHBot(self.qu_stop) 
    phbot = Process(target=bot.ph_control) 
    # start the process 
    phbot.start() 

此外,在你的工人,不檢查Queue是否已滿。相反,做一個非阻塞get和處理Queue.Empty例外:

import Queue 
... 
    def ph_control(self): 

     while True: 
      try: 
       item = self.qu_stop_in.get(False) 
       if item == 'STOP': 
        break 
      except Queue.Empty: 
       print "Nothing to see" 
      print('Back and forth forever ...') 
      time.sleep(2) 
0
phbot = Process(target=bot.ph_control()) 

調用 bot.ph_control - 這是()語法做什麼。我猜你需要通過函數本身(Process(target=bot.ph_control))),但我不熟悉多處理。

+0

沒有什麼區別 – Moritz