如何一起运行kivy和烧瓶应用程序?

时间:2018-04-17 17:53:36

标签: python flask kivy

我有一个烧瓶应用程序作为服务器,我有一个kivy应用程序作为服务器的前端。我如何运行烧瓶然后kivy应用程序,以便它们同时一起工作?

Flask app:

from flask import Flask

app = Flask(__name__)


@app.route('/')
def hello():
    return 'Hello'

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

Kivy app:

from kivy.app import App
from kivy.builder import Builder
from kivy.uix.screenmanager import Screen, ScreenManager
kivy.require('1.10.0')

Builder.load_file('kivy.kv')

sm = ScreenManager()

class MainScreen(Screen)
    pass

class OtherScreen(Screen)
    pass

sm.add_widget(MainScreen(name='main'))
sm.add_widget(OtherScreen(name='other'))

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


MyApp().run()

更新 如果有人在使用apache实现web服务器时遇到问题,请在我看来尝试docker,更简单,更快速的解决方案!

2 个答案:

答案 0 :(得分:2)

Flask中的开发服务器是Werkzeug的一部分。它应该仅用于开发目的,因为它不能像生产部署那样容纳高负载。我建议您使用Apache设置mod_wsgi服务器,以便同时运行这两个应用。这也将提供隔离和并行性同时适用于开发,测试和生产部署。

threading的解决方案有效但警告:Werkzeug服务器可以在单独的线程中运行,但应用程序重新加载器需要在主线程中运行。这意味着当您对应用程序进行任何更改时,您的Flask应用程序将不会重新加载。看一下这个answer

以下代码使用两个单独的线程来运行每个应用程序。 A' Hello World'窗口出现在Kivy应用程序中,同时可以显示“Hello World'在http://localhost:5000/上运行Flask应用程序时,浏览器中显示消息。

import threading
import kivy
from kivy.app import App
from flask import Flask
import os
from kivy.uix.label import Label

kivy.require('1.10.0')
new_environ = os.environ.copy()

app = Flask(__name__)

@app.route('/')
def hello():
    return 'Hello World'
def start_app():
    print("Starting Flask app...")
    app.run(port=5000, debug=False)     #specify separate port to run Flask app

class MyApp(App):

    def build(self):
        return Label(text='Hello world')

if __name__ == '__main__':
    if os.environ.get("WERKZEUG_RUN_MAIN") != 'true':
        threading.Thread(target=start_app).start()
    MyApp().run()

答案 1 :(得分:0)

我发现此线程正在寻找一种连续运行Flask的方法,始终侦听分配的地址和端口以及Kivy以并行运行。我尝试了提议的解决方案,按照@amanb的建议将它们作为线程一起运行,但是我发现Flask阻止了Kivy,反之亦然,无论线程的时间安排或安排如何。因此,我尝试了多处理,似乎可以正常工作。希望对您有所帮助。

代码

#!/usr/bin/python2.7 python2.7
# -*- coding: utf-8 -*-

# kivy modules first, if not Kivy may cause problems
import kivy
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.label import Label
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.screenmanager import ScreenManager, Screen
kivy.require('1.10.0')


# common modules
import sys
import signal
from multiprocessing import Process


# Flask & similar modules
from flask import Flask
from flask_restful import reqparse, abort, Api, Resource
import eventlet
from eventlet import wsgi


# async server setup
eventlet.monkey_patch()
app = Flask(__name__)
api = Api(app)


def start_Flask():
    print("Starting Flask...")
    # deploy as an eventlet WSGI server on port 5000
    wsgi.server(eventlet.listen(('', 5000)), app)     


def signal_handler(signal, frame):
    # for fetching CTRL+C and relatives
    print " CTRL + C detected, exiting ... "
    exit(1)


# Kivy screen class
class MainScreen(Screen):
    def __init__(self, **kwargs):
        self.name="MAIN SCREEN"
        super(Screen, self).__init__(**kwargs)


# Kivy app class
class Kivy(App):
    w_MessageBox10_1 = "MAIN SCREEN"
    w_MessageBox10_2 = "One golden glance of what should be"
    w_MessageBox30_2 = "CHORUS"
    w_MessageBox30_3 = "EXIT"


    # exit button action   
    def exit(self):
        print "exiting... one shaft of light will show the way..."
        p1.terminate()  # terminate Flask by pressing on cancel
        exit(1)


    # do magic button action
    def do_magic(self):
        # your code goes here or maybe not
        print "***** it's a kind of magic *************************"


    # Kivy UI builder file
    def build(self):
        sm = Builder.load_string("""

ScreenManager
    MainScreen:
        size_hint: 1, .7
        auto_dismiss: False
        title: app.w_MessageBox10_1       
        title_align: "center"

        BoxLayout:
            orientation: "vertical"
            Label:
                text: app.w_MessageBox10_2
            BoxLayout:
                orientation: "horizontal"
                spacing: 10
                size_hint: 1, .5
                Button:
                    text: app.w_MessageBox30_2  # DO MAGIC
                    on_press:
                        app.do_magic()
                Button:
                    text: app.w_MessageBox30_3  # EXIT
                    on_press:
                        app.exit()


        """)

        return sm


if __name__ == '__main__':    

    # #CTRL+C signal handler
    signal.signal(signal.SIGINT, signal_handler)
    signal.signal(signal.SIGTERM, signal_handler)

    global p1
    p1 = Process(target=start_Flask)    # assign Flask to a process
    p1.start()                          # run Flask as process
    Kivy().run()                        # run Kivy UI