从运行的Kivy应用程序访问数据

发布于 2025-01-22 23:25:16 字数 3723 浏览 1 评论 0原文

我正在使用使用Kivy应用程序实现的GUI界面的程序。我的最终目标是在Kivy Textbox中输入所需的电压,并使用Arduino + DAC转换器进行设置。目前,我只是想从我的主体中的Kivy应用程序外部的文本输入中访问电压,以便我可以清晰地将GUI与与Arduino的通信和其他必要的计算分开。

问题在于,在app.run()之后,该程序不会继续进行,直到关闭Kivy应用程序并丢失了输入的电压为止。我已经尝试使用多处理库,但是只要应用程序运行,start()函数也可以运行。我也不确定访问电压的最佳方法是什么,我尝试将其作为GUI的班级成员,但这也许不是一个好主意。

这是我的gui.py代码:

    from kivy.app import App
    from kivy.uix.label import Label
    from kivy.uix.gridlayout import GridLayout
    from kivy.uix.textinput import TextInput
    from kivy.properties import StringProperty, NumericProperty
    from kivy.uix.button import Button
    
    class GUI_GridLayout(GridLayout):
    
        voltage_label_1 = StringProperty("Voltage 1?")
        voltage_label_2 = StringProperty("Voltage 2?")
    
        voltage_input_1 = TextInput()
        voltage_input_2 = TextInput()
    
        submit_button_label_1 = StringProperty("Submit 1")
        submit_button_label_2 = StringProperty("Submit 2")
    
        voltage_output_1 = NumericProperty(0)
        voltage_output_2 = NumericProperty(0)
    
        def press_1(self):
            voltage_1 = self.voltage_input_1.text
            self.voltage_output_1  = float(voltage_1)
    
        def press_2(self):
            voltage_2 = self.voltage_input_2.text
            self.voltage_output_2 = float(voltage_2)
    
        def build(self):
            self.add_widget(Label(text=self.voltage_label_1))
            self.add_widget(self.voltage_input_1)
    
            self.add_widget(Label(text=self.voltage_label_2))
            self.add_widget(self.voltage_input_2)
    
            self.submit_button_1 = Button(text=self.submit_button_label_1)
            self.submit_button_1.bind(on_press=self.press_1)
            self.add_widget(self.submit_button_1)
    
            self.submit_button_2 = Button(text=self.submit_button_label_2)
            self.submit_button_2.bind(on_press=self.press_2)
            self.add_widget(self.submit_button_2)
    
    
    
    class apason_GUIApp(App):
        def build(self):
            return GUI_GridLayout()

相应的kv文件:

#:kivy 1.0.9

<GUI_GridLayout>:

    cols: 3

    voltage_input_1: input_1
    voltage_input_2: input_2

    Label:
        font_size: 50
        text: str(root.voltage_label_1)

    TextInput:
        id: input_1
        font_size: 50
        multiline: False
        text: root.voltage_input_1.text

    Button:
        font_size: 50
        text: str(root.submit_button_label_1)
        on_press: root.press_1()

    Label:
        font_size: 50
        center_x: root.width / 4
        text: str(root.voltage_label_2)

    TextInput:
        id: input_2
        font_size: 50
        multiline: False
        text: root.voltage_input_2.text

    Button:
        font_size: 50
        text: str(root.submit_button_label_2)
        on_press: root.press_2()

这是我的主要:

import GUI.GUI as gui
import multiprocessing as multiproc
import time

class GetVoltage:

    def __init__(self):
        self.voltage_1 = 0
        self.voltage_2 = 0

    def fetchVoltage(self, interface):
        self.voltage_1 = interface.voltage_output_1
        self.voltage_2 = interface.voltage_output_2

    def run(self, interface):
        while (True):

            self.fetchVoltage(interface)

            print(self.voltage_1)
            print(self.voltage_2)

            time.sleep(1)

if __name__ == '__main__':

    interface = gui.apason_GUIApp()
    interface_process = multiproc.Process(target=interface.run())

    checker = GetVoltage()
    checker_process = multiproc.Process(target=checker.run(interface))

    interface_process.start()
    checker_process.start()

I'm working on a program with a GUI interface, which I've implemented using a kivy app. My end-goal is to enter a desired voltage in the kivy textbox and for it to be set using an Arduino + a DAC converter. For now I'm just trying to access the voltage from the text input from outside the kivy app in my main, so that I can separate the GUI cleanly from communication with the arduino, and other necessary calculations.

The problem is that the program doesn't continue after App.run() until the kivy app has been closed and the entered voltage has been lost. I've tried using the multiprocessing library, but the start() function also runs as long as the app is running. I'm also not sure what the best way is to access the voltage, I tried having it as a class member of the GUI, but maybe that's not a good idea.

This is my GUI.py code:

    from kivy.app import App
    from kivy.uix.label import Label
    from kivy.uix.gridlayout import GridLayout
    from kivy.uix.textinput import TextInput
    from kivy.properties import StringProperty, NumericProperty
    from kivy.uix.button import Button
    
    class GUI_GridLayout(GridLayout):
    
        voltage_label_1 = StringProperty("Voltage 1?")
        voltage_label_2 = StringProperty("Voltage 2?")
    
        voltage_input_1 = TextInput()
        voltage_input_2 = TextInput()
    
        submit_button_label_1 = StringProperty("Submit 1")
        submit_button_label_2 = StringProperty("Submit 2")
    
        voltage_output_1 = NumericProperty(0)
        voltage_output_2 = NumericProperty(0)
    
        def press_1(self):
            voltage_1 = self.voltage_input_1.text
            self.voltage_output_1  = float(voltage_1)
    
        def press_2(self):
            voltage_2 = self.voltage_input_2.text
            self.voltage_output_2 = float(voltage_2)
    
        def build(self):
            self.add_widget(Label(text=self.voltage_label_1))
            self.add_widget(self.voltage_input_1)
    
            self.add_widget(Label(text=self.voltage_label_2))
            self.add_widget(self.voltage_input_2)
    
            self.submit_button_1 = Button(text=self.submit_button_label_1)
            self.submit_button_1.bind(on_press=self.press_1)
            self.add_widget(self.submit_button_1)
    
            self.submit_button_2 = Button(text=self.submit_button_label_2)
            self.submit_button_2.bind(on_press=self.press_2)
            self.add_widget(self.submit_button_2)
    
    
    
    class apason_GUIApp(App):
        def build(self):
            return GUI_GridLayout()

The corresponding kv file:

#:kivy 1.0.9

<GUI_GridLayout>:

    cols: 3

    voltage_input_1: input_1
    voltage_input_2: input_2

    Label:
        font_size: 50
        text: str(root.voltage_label_1)

    TextInput:
        id: input_1
        font_size: 50
        multiline: False
        text: root.voltage_input_1.text

    Button:
        font_size: 50
        text: str(root.submit_button_label_1)
        on_press: root.press_1()

    Label:
        font_size: 50
        center_x: root.width / 4
        text: str(root.voltage_label_2)

    TextInput:
        id: input_2
        font_size: 50
        multiline: False
        text: root.voltage_input_2.text

    Button:
        font_size: 50
        text: str(root.submit_button_label_2)
        on_press: root.press_2()

And here's my main:

import GUI.GUI as gui
import multiprocessing as multiproc
import time

class GetVoltage:

    def __init__(self):
        self.voltage_1 = 0
        self.voltage_2 = 0

    def fetchVoltage(self, interface):
        self.voltage_1 = interface.voltage_output_1
        self.voltage_2 = interface.voltage_output_2

    def run(self, interface):
        while (True):

            self.fetchVoltage(interface)

            print(self.voltage_1)
            print(self.voltage_2)

            time.sleep(1)

if __name__ == '__main__':

    interface = gui.apason_GUIApp()
    interface_process = multiproc.Process(target=interface.run())

    checker = GetVoltage()
    checker_process = multiproc.Process(target=checker.run(interface))

    interface_process.start()
    checker_process.start()

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

春庭雪 2025-01-29 23:25:16

由于运行main.py.py时,您已经有一个进程,因此您实际上只需要启动第二个进程即可。您可以使用a queue 。这是使用此方法的main.py.py的修改版本:

import GUI as gui
import multiprocessing as multiproc


class GetVoltage:
    def run(self, queue):
        while True:
            voltage = queue.get()  # get the data from the other process by using the Queue
            print(voltage)


if __name__ == '__main__':
    q = multiproc.Queue()

    # start the GetVoltage process
    checker = GetVoltage()
    checker_process = multiproc.Process(target=checker.run, args=(q,), daemon=True)
    checker_process.start()

    # start the App
    interface = gui.apason_GUIApp()
    interface.q = q
    interface.run()  # this does not return until the App closes

    # kill the GetVoltage process after the App exits
    checker_process.kill()

app代码中的几个次要更改:

def press_1(self):
    voltage_1 = self.voltage_input_1.text
    self.voltage_output_1 = float(voltage_1)
    App.get_running_app().q.put('voltage_1 = ' + voltage_1)  # put the data in the Queue

def press_2(self):
    voltage_2 = self.voltage_input_2.text
    self.voltage_output_2 = float(voltage_2)
    App.get_running_app().q.put('voltage_2 = ' + voltage_2)  # put the data in the Queue

Since you already have one process when you run main.py, you really only need to start the second process. And you can communicate between the processes using a Queue. Here is a modified version of your main.py that uses this approach:

import GUI as gui
import multiprocessing as multiproc


class GetVoltage:
    def run(self, queue):
        while True:
            voltage = queue.get()  # get the data from the other process by using the Queue
            print(voltage)


if __name__ == '__main__':
    q = multiproc.Queue()

    # start the GetVoltage process
    checker = GetVoltage()
    checker_process = multiproc.Process(target=checker.run, args=(q,), daemon=True)
    checker_process.start()

    # start the App
    interface = gui.apason_GUIApp()
    interface.q = q
    interface.run()  # this does not return until the App closes

    # kill the GetVoltage process after the App exits
    checker_process.kill()

And a couple minor changes in the App code:

def press_1(self):
    voltage_1 = self.voltage_input_1.text
    self.voltage_output_1 = float(voltage_1)
    App.get_running_app().q.put('voltage_1 = ' + voltage_1)  # put the data in the Queue

def press_2(self):
    voltage_2 = self.voltage_input_2.text
    self.voltage_output_2 = float(voltage_2)
    App.get_running_app().q.put('voltage_2 = ' + voltage_2)  # put the data in the Queue
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文