Untitled

 avatar
unknown
plain_text
10 months ago
9.5 kB
23
Indexable
import os
import sqlite3
from datetime import datetime
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.popup import Popup
from kivy.uix.textinput import TextInput
from kivy.uix.image import Image
from kivy.clock import Clock
from kivy.graphics.texture import Texture
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
import cv2
import numpy as np
from pyzbar.pyzbar import decode
from kivy.core.window import Window

# Database setup
def init_db():
    conn = sqlite3.connect('qrcodes.db')
    cursor = conn.cursor()
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS qr_codes (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            content TEXT NOT NULL,
            name TEXT,
            timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
        )
    ''')
    conn.commit()
    return conn

class QRScanner(BoxLayout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.orientation = 'vertical'
        self.spacing = 10
        self.padding = 10
        
        # Camera feed
        self.image = Image()
        self.add_widget(self.image)
        
        # Scan button
        self.scan_btn = Button(
            text='Start Scanning',
            size_hint=(1, 0.1),
            background_color=(0, 0.7, 0, 1)
        )
        self.scan_btn.bind(on_press=self.toggle_scanning)
        self.add_widget(self.scan_btn)
        
        # View saved button
        self.view_btn = Button(
            text='View Saved Codes',
            size_hint=(1, 0.1),
            background_color=(0.2, 0.5, 0.8, 1)
        )
        self.view_btn.bind(on_press=self.view_saved)
        self.add_widget(self.view_btn)
        
        # Camera and scanning state
        self.capture = None
        self.scanning = False
        
    def on_kv_post(self, base_widget):
        # Initialize camera after the widget is fully loaded
        self.capture = cv2.VideoCapture(0)
        Clock.schedule_interval(self.update, 1.0 / 30.0)  # 30 fps
    
    def update(self, dt):
        if not self.scanning or not self.capture.isOpened():
            return
            
        ret, frame = self.capture.read()
        if ret:
            # Convert to texture
            buf1 = cv2.flip(frame, 0)
            buf = buf1.tostring()
            image_texture = Texture.create(
                size=(frame.shape[1], frame.shape[0]), 
                colorfmt='bgr'
            )
            image_texture.blit_buffer(buf, colorfmt='bgr', bufferfmt='ubyte')
            self.image.texture = image_texture
            
            # Try to decode QR code
            if self.scanning:
                self.decode_qr(frame)
    
    def decode_qr(self, frame):
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        qr_codes = decode(gray)
        
        for qr in qr_codes:
            data = qr.data.decode('utf-8')
            self.show_save_dialog(data)
            self.scanning = False
            self.scan_btn.text = 'Start Scanning'
            self.scan_btn.background_color = (0, 0.7, 0, 1)
            break
    
    def toggle_scanning(self, instance):
        self.scanning = not self.scanning
        if self.scanning:
            self.scan_btn.text = 'Stop Scanning'
            self.scan_btn.background_color = (0.9, 0.1, 0.1, 1)
        else:
            self.scan_btn.text = 'Start Scanning'
            self.scan_btn.background_color = (0, 0.7, 0, 1)
    
    def show_save_dialog(self, qr_data):
        content = BoxLayout(orientation='vertical', padding=10, spacing=10)
        content.add_widget(Label(text='QR Code Detected!'))
        
        data_label = Label(text=f'Data: {qr_data[:30]}...' if len(qr_data) > 30 else f'Data: {qr_data}')
        content.add_widget(data_label)
        
        name_input = TextInput(hint_text='Enter a name for this code', multiline=False)
        content.add_widget(name_input)
        
        btn_layout = BoxLayout(spacing=5)
        
        def save_code(instance):
            name = name_input.text.strip()
            if not name:
                name = f"QR Code {datetime.now().strftime('%Y%m%d%H%M%S')}"
            
            conn = sqlite3.connect('qrcodes.db')
            cursor = conn.cursor()
            cursor.execute(
                'INSERT INTO qr_codes (content, name) VALUES (?, ?)',
                (qr_data, name)
            )
            conn.commit()
            conn.close()
            popup.dismiss()
            self.show_message('QR Code Saved!', f'Successfully saved: {name}')
        
        save_btn = Button(text='Save', size_hint=(0.5, None), height=40)
        save_btn.bind(on_press=save_code)
        
        cancel_btn = Button(text='Cancel', size_hint=(0.5, None), height=40)
        cancel_btn.bind(on_press=lambda x: popup.dismiss())
        
        btn_layout.add_widget(save_btn)
        btn_layout.add_widget(cancel_btn)
        content.add_widget(btn_layout)
        
        popup = Popup(
            title='Save QR Code',
            content=content,
            size_hint=(0.9, 0.5)
        )
        popup.open()
    
    def view_saved(self, instance):
        self.parent.current = 'saved_codes'
    
    def show_message(self, title, message):
        content = BoxLayout(orientation='vertical', padding=10, spacing=10)
        content.add_widget(Label(text=message))
        
        popup = Popup(
            title=title,
            content=content,
            size_hint=(0.8, 0.4)
        )
        popup.open()
    
    def on_stop(self):
        if self.capture:
            self.capture.release()

class SavedCodesScreen(Screen):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.layout = BoxLayout(orientation='vertical')
        self.back_btn = Button(
            text='Back to Scanner',
            size_hint=(1, 0.1),
            background_color=(0.8, 0.5, 0, 1)
        )
        self.back_btn.bind(on_press=self.go_back)
        self.layout.add_widget(self.back_btn)
        
        self.scroll = BoxLayout(orientation='vertical', size_hint=(1, 0.9))
        self.layout.add_widget(self.scroll)
        
        self.add_widget(self.layout)
        
    def on_enter(self):
        self.load_saved_codes()
    
    def load_saved_codes(self):
        self.scroll.clear_widgets()
        
        conn = sqlite3.connect('qrcodes.db')
        cursor = conn.cursor()
        cursor.execute('SELECT * FROM qr_codes ORDER BY timestamp DESC')
        codes = cursor.fetchall()
        conn.close()
        
        if not codes:
            self.scroll.add_widget(Label(
                text='No QR codes saved yet!',
                halign='center',
                valign='middle'
            ))
            return
        
        for code in codes:
            code_id, content, name, timestamp = code
            
            btn = Button(
                text=f"{name}\n{timestamp}",
                size_hint=(1, None),
                height=100,
                halign='left',
                valign='middle',
                text_size=(Window.width - 40, None),
                padding=(10, 10),
                background_color=(0.2, 0.6, 0.8, 0.7)
            )
            
            # Show full content on click
            def show_code_details(code_content, *args):
                self.show_code_popup(code_content)
            
            btn.bind(on_press=lambda x, c=content: show_code_details(c))
            self.scroll.add_widget(btn)
    
    def show_code_popup(self, content):
        popup_layout = BoxLayout(orientation='vertical', padding=10, spacing=10)
        
        text_input = TextInput(
            text=content,
            readonly=False,
            size_hint=(1, 0.8),
            font_size='14sp'
        )
        popup_layout.add_widget(text_input)
        
        btn = Button(
            text='Close',
            size_hint=(1, 0.2),
            background_color=(0.8, 0.2, 0.2, 1)
        )
        
        popup = Popup(
            title='QR Code Content',
            content=popup_layout,
            size_hint=(0.9, 0.8)
        )
        
        btn.bind(on_press=lambda x: popup.dismiss())
        popup_layout.add_widget(btn)
        popup.open()
    
    def go_back(self, instance):
        self.parent.current = 'scanner'

class QRCodeApp(App):
    def build(self):
        # Initialize database
        init_db()
        
        # Set up screen manager
        self.sm = ScreenManager()
        
        # Create screens
        scanner_screen = Screen(name='scanner')
        scanner_screen.add_widget(QRScanner())
        
        saved_codes_screen = SavedCodesScreen(name='saved_codes')
        
        # Add screens to screen manager
        self.sm.add_widget(scanner_screen)
        self.sm.add_widget(saved_codes_screen)
        
        return self.sm
    
    def on_stop(self):
        # Clean up resources
        for screen in self.sm.screens:
            for widget in screen.children:
                if hasattr(widget, 'on_stop'):
                    widget.on_stop()

if __name__ == '__main__':
    QRCodeApp().run()
Editor is loading...
Leave a Comment