繁体   English   中英

类实例作为kivy应用程序中的进程:kivy应用程序被卡住

[英]class instance as process within kivy app: kivy app gets stuck

我确实有一个界面来存储设置和启动过程。 但是,一旦进程启动,我将无法关闭所有内容,因为在调用process.run之后,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)

我在这里想念什么?

请注意, 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)
phbot = Process(target=bot.ph_control())

您正在调用 bot.ph_control- ()语法就是这样做的。 我猜想您需要传递函数本身( Process(target=bot.ph_control)) ),但是我对多重处理并不熟悉。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM