python - 单击按钮时 kivy 加载相机(zbarscan)

标签 python kivy zbar

我刚刚开始我的第一个 kivy 应用程序。该应用程序旨在从“开始扫描”按钮启动,然后显示使用 ZBarCam 构建的 QR 扫描仪。

我使用带有ScreenManager的屏幕从按钮 View 更改为相机 View (使用zbarcam),问题是我意识到相机从一开始就被初始化了,所以在之前单击相机已打开的按钮(我知道是因为相机的 LED 已打开)。

我不知道在这种情况下是否不应使用 Screen,或者是否有办法告诉应用程序不要初始化所有屏幕。

我使用的代码如下:

QrApp.py:

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen


class QrReader(Screen):
    pass

class ScanButton(Screen):
    pass

class QrApp(App):
    pass

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

qrapp.kv:

ScreenManager:
    id: screen_manager
    ScanButton:
        id: scan_btn
        name: 'scan_btn'
        manager: 'screen_manager'
    QrReader:
        id: qr_reader
        name: 'qr_reader'
        manager: 'screen_manager'


<ScanButton>:
    BoxLayout:
        orientation: 'vertical'
        Button:
            text:'Start Scan'
            font_size:"50sp"
            color: [0, 255, 255, .67]
            on_press: app.root.current = 'qr_reader'

<QrReader>:
    #:import ZBarCam kivy_garden.zbarcam.ZBarCam
    BoxLayout:
        orientation: 'vertical'
        ZBarCam:
            id:qrcodecam
        Label:
            size_hint: None, None
            size: self.texture_size[0], 50
            text: ' '.join([str(symbol.data) for symbol in qrcodecam.symbols])

谢谢!

====基于评论的替代方案(仍然失败)====

基于comment来自n4321d我尝试将 ZBarCam 作为小部件添加到 QrReader 屏幕中。虽然我现在可以在添加小部件时启动相机,但我不知道如何获取符号,即从 QR 读取的文本。

此替代代码如下:

QrApp.py:

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.widget import Widget
from kivy.core.window import Window
from kivy.uix.label import Label
from kivy.uix.screenmanager import ScreenManager, Screen


class QrReader(Screen):
    def on_enter(self):
        from kivy_garden.zbarcam import ZBarCam
        zbarcam = ZBarCam()
        self.add_widget(zbarcam)
        self.add_widget(Label(
            text='PRINT SYMBOLS', #' '.join([str(symbol.data) for symbol in zbarcam.symbols] does not work
            size_hint=(None,None),
            size=(Window.width*0.1, Window.height*0.1),
            center=(Window.width*0.3, Window.height*0.5)))

class ScanButton(Screen):
    pass

class QrApp(App):
    pass

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

qrapp.kv

ScreenManager:
    id: screen_manager
    ScanButton:
        id: scan_btn
        name: 'scan_btn'
        manager: 'screen_manager'
    QrReader:
        id: qr_reader
        name: 'qr_reader'
        manager: 'screen_manager'

<ScanButton>:
    BoxLayout:
        orientation: 'vertical'
        Button:
            text:'Start Scan'
            font_size:"50sp"
            color: [0, 255, 255, .67]
            on_press:
                app.root.current = 'qr_reader'


<QrReader>:
    BoxLayout:
        orientation: 'vertical'

======解决方案========

我的解决方案已发布作为此问题的答案 here

最佳答案

第一: 我还会添加一个 on_leave 函数,您可以在其中删除凸轮小部件,否则每次加载时都会不断添加新的小部件。

我现在没有可用的摄像头,所以我无法测试你的代码。看看你的代码,我认为你必须使用以下函数将 Label 中的文本绑定(bind)到 zbarcam.symbols 中的文本: self.label = Label(....); zbarcam.bind(symbols=lambda *x: setattr(self.label, "text", str(x[1]))) 或类似的东西。

这是一个使用随机文本生成器而不是 ZBarCam 的示例(因为我无法运行它)。

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.widget import Widget
from kivy.core.window import Window
from kivy.uix.label import Label
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import ListProperty
import random
from kivy.clock import Clock


kv_str = """
ScreenManager:
    id: screen_manager
    ScanButton:
        id: scan_btn
        name: 'scan_btn'
        manager: 'screen_manager'
    QrReader:
        id: qr_reader
        name: 'qr_reader'
        manager: 'screen_manager'

<ScanButton>:
    BoxLayout:
        orientation: 'vertical'
        Button:
            text:'Start Scan'
            font_size:"50sp"
            color: [0, 255, 255, .67]
            on_press:
                app.root.current = 'qr_reader'


<QrReader>:
    BoxLayout:
        orientation: 'vertical'
"""

class ZBarCam(Label):
    symbols = ListProperty([])
    
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        Clock.schedule_interval(self.gen_rand_text, 1)

    def gen_rand_text(self, *args):
        self.text = random.choice(['aaaaa', 'bbbbb', 'ccccc'])
        self.symbols.append(self.text)
        if len(self.symbols) > 3:
            del self.symbols[0]


class QrReader(Screen):
    def on_enter(self):
        self.zbarcam = ZBarCam()
        self.add_widget(self.zbarcam)
        self.label = Label(
            text='PRINT SYMBOLS', #' '.join([str(symbol.data) for symbol in zbarcam.symbols] does not work
            size_hint=(None,None),
            size=(Window.width*0.1, Window.height*0.1),
            center=(Window.width*0.3, Window.height*0.5))
        self.add_widget(self.label)
        self.zbarcam.bind(symbols = lambda *x: setattr(self.label, "text", str(x[1])))
    
    def on_leave(self, *args):
        self.remove_widget(self.zbarcam)
        self.remove_widget(self.label)

class ScanButton(Screen):
    pass

class QrApp(App):
    def build(self):
        return Builder.load_string(kv_str)

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

如果仍然不起作用,您可能还需要在添加后在 on_enter 方法中调用 self.zbarcam.start()

希望这有帮助

关于python - 单击按钮时 kivy 加载相机(zbarscan),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73067952/

相关文章:

python - 寻找组织大型 kivy 项目的好方法

python - Kivy 网格布局固定某些列的列宽

c++ - 再次包含库和 Error LNK2001 : unresolved external symbol

c++ - 在 macOS 上将 Zbar 导入 C++ 项目

Android BarcodeScanner 库在 64 位设备中崩溃

python - 在当前窗口上进行 python 自动化

python - 在连接的项目更改时更新自定义 QGraphicsItem 的位置

python - 创建一个具有未知键的字典并向其附加一个列表值?

python,找到连续值时间序列直到下一次出现的等待时间

python - 如何在 KivyMD (Python) 中组合抽屉导航和多个屏幕?